SQLI LABS | Less-24 POST-Second Oder Injections Real Treat-Stored Injections
关注这个靶场的其它相关笔记:SQLI LABS —— 靶场笔记合集-CSDN博客
0x01:过关流程
输入下面的链接进入靶场(如果你的地址和我不一样,按照你本地的环境来):
http://localhost/sqli-labs/Less-24/
本关考察的是二次注入,二次注入是一种存储型的注入方式,可以简单理解为用户构造的恶意数据被服务端存储到数据库后,在某个功能点该数据又被服务端从数据库中读取并执行而导致的漏洞。
本关二次注入的位置是发生在用户注册与密码重置的位置,我们的过关目标是通过二次注入,重置管理员账户的密码,从而以管理员权限登录系统。(笔者一开始也想读取数据库信息,后面发现它对长度进行了限制,导致很多语句无法利用,读不出信息)
点击 New User Click Here?
,进入用户注册界面,如果你输入用户名为 admin
,那么系统会出现下面的提示:
如上,我们确定了该系统的管理员账户的名称为 admin
。如果,你用户名写的很长,比如:123456789012345678sjkdajdlasjdk
,这种,它会提示:
Data Too Long For Column 'username' At Row 1
,直接给我们爆了一个后端数据库的字段。但是,很可惜无法利用(服务端通过限制长度,限制了我们二次注入的发挥)。
本关二次注入的点是在登陆后的更新密码位置,既然是更新,其后端语句的模板大致如下:
update users set password='$_POST["pwd"]' where username='$_POST["name"]';
针对上面的更新模板,我们可以注册如下用户名,来尝试修改管理员的账号(密码任意):
admin'#
点击 update password
后,出现如下界面,OK,管理员的账号密码已经被改了:
此时,我们就可以通过 admin : 你设置的密码
来登录系统了:
本关的漏洞点就是由 SQL 注入导致的,任意用户密码重置漏洞。至此,SQLI LABS Less-24 POST-Second Oder Injections Real Treat-Stored Injections 成功过关。
0x02:源码分析
下面是 SQLI LABS Less-24 POST-Second Oder Injections Real Treat-Stored Injections 后端的部分源码,以及笔者做的笔记:
// FileName: login_create.php
// 这个是创建用户时执行的 SQL 语句,无法逃逸出 " 号
$sql = "insert into users (username, password) values(\"$username\", \"$pass\")";
mysqli_query($con1, $sql) or die('Error Creating your user account, : '.mysqli_error($con1));
// FileName: pass_change.php
# Validating the user input........
// 从 Session 中获取 username,这里的 username 是从数据库中 GET 到的
$username= $_SESSION["username"];
// 下面的过滤没有针对 username
$curr_pass= mysqli_real_escape_string($con1, $_POST['current_password']);
$pass= mysqli_real_escape_string($con1, $_POST['password']);
$re_pass= mysqli_real_escape_string($con1, $_POST['re_password']);
if($pass==$re_pass)
{
// 由于没有对 username 字段进行过滤就直接拼接进 SQL 语句中执行,所以导致了二次注入。
// 笔者备注:它们甚至对用户输入的密码进行了过滤,要是没有过滤,密码处也是可以利用的
$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";
$res = mysqli_query($con1, $sql) or die('You tried to be smart, Try harder!!!! :( ');
$row = mysqli_affected_rows($con1);
echo '<font size="3" color="#FFFF00">';
echo '<center>';
if($row==1)
{
echo "Password successfully updated";
}
else
{
header('Location: failed.php');
//echo 'You tried to be smart, Try harder!!!! :( ';
}
}