一、基础知识
xml
Extractvalue
我们试着用mysql操作一下
使用上述命令就可以提取出admin这个数据
Updataxml
我们刚刚人数的 Extractvalues 是提取数据,Updataxml是替换数据
前两个参数和我们的 Extractvalues 是一样的,第三个参数填写我们要替换的数据
我们来测试一下:
我们可以看到username元素里面的admin就被成功替换成了123456
concat
二、Extractvalue报错注入
简介
上图中的payload 我们通过在extractvalue函数里的第一个参数随便填,第二个参数里填入我们要执行的sql查询语句,这里的concat是必要的,如果缺少concat , 例如:select extractvalue(1,(select database()));
那么服务器会原封不动的把我们想要执行的sql语句返回,如上图小问题的执行结果,但如果加上concat服务器会把我们concat里面第二个参数里的sql语句执行后再和我们的1拼接,形成报错再返回给我们,就能达成我们想要的目的如下图:
注入练习
下面我们做一道题来练习一下,练习之前我们复习一下数字型注入和字符型注入的区别
下面我们看题目,这道题里,我们看到if那行过滤了union,我们无法使用union来进行注入:
找到注入点
我们直接在id后面加单引号看看有没有注入:
我们看到服务器返回了报错信息,那么注入点就是我们的id这个参数,并且返回了报错,我们就可以利用报错注入
数字型或字符型
首先先判断是字符型注入还是数字型注入,我们通过在后面加上and 1=1%23 来测试是否为字符型注入,但我们看到服务器还是返回了报错信息:
那么我们把单引号去掉,我们看到成功回显了数据,那么就是数字型注入:
拿数据库名
我们直接使用 id=1 and (extractvalue(1,concat(1,(select database()))))%23
现在我们就可以看到,服务器直接报出了我们的数据库名web:
拿表名
表名我们这里使用之前讲到的information_schema这个数据库,里面有shemata、tables
columns,分别是记录数据库名、表名、列名。下面我们用这个tables拿表名,我们在concat函数的第二个参数里填入:
select table_name from information_schema.tables where table_schema=database()
我们构造好后发包,发现返回内容说超过了一行:
我们来数据库里面具体操作一下看为什么会产生这样的结果:
我们看到查询结果提示超过了一行,我们把要查询的语句单独拿出来执行看看会怎么样:
执行后我们看到有两条返回结果,所以说超过了一行就会出现报错,我们接下来把两行结果合并成一行
group_concat
我们使用group_concat()函数可以把多条结果合并成一行,我们在原来的语句中加入这个函数:
我们可以看到,它在原来的语句中把刚刚的两行结果合并成了一行,中间用逗号分隔开,接着我们返回注入点测试一下:
成功执行,拿到了两个表名,一个是flag,一个是user
拿列名
拿到表名后,我们拿flag的列名:
select group_concat(column_name) from information_schema.columns where table_name='flag'
成功后爆出了id和flag列
拿数据
select flag from flag
直接查flag列:
查询后我们发现,似乎flag并不是完整的,他前面只有一个括号,后面没有闭合,那是 因为我们的Extractvalue报错信息最多只能显示32位,也就是说我们的flag长度超出了限制,那么我们要如何获取后面的数据
substr
substr('123',2)
这个函数里的123是我们需要提取的数据,2是我们要从第2位开始一直获取数据到结尾,上面这个函数执行的结果:
+----------------+
| SUBSTR('123', 2) |
+----------------+
| '23' |
+----------------+
他们可以从我们给定起始位置一直返回到字符串的末尾,我们使用以下代码来截取没有显示的flag:
select substr(flag,30) from flag
现在就成功回显了后面的数据:
三、Updataxml报错注入
Updataxml的报错原因和我们的Extractvalue报错原因基本上是一样的,不一样的地方就是多了一个参数,但这个参数也是随便写的
下面是updataxml使用的payload
这些payload的执行流程和我们之前的步骤一样,同样有超过一行的问题,同样只显示30位,这里就不复述了