Bugku Web 25
提示是SQL约束攻击
解题过程
进入场景,看到是一个web管理系统,需要登陆,旁边可以看到注册的通道,先随意注册一个账号
推测只有管理员账户才会显示出flag,利用SQL约束攻击,SQL语句会将查询的字段后的空格格式化,随意我们注册的用户名为admin
,此时再登录就可以得到flag
SQL约束攻击
例如下面的代码中,输入的字符串末尾空格会被删除,admin
与admin
是一样的,这是因为在“字符串比较”期间,SQL会在内部使用空格来填充字符串,以便在比较之前使其它们的长度保持一致。
<?php
$username = mysql_real_escape_string($_GET['username']);
$password = mysql_real_escape_string($_GET['password']);
$query = "SELECT *
FROM users
WHERE username='$username'";
$res = mysql_query($query, $database);
if($res) {
if(mysql_num_rows($res) > 0) {
}
else {
$query = "INSERT INTO users(username, password)
VALUES ('$username','$password')";
当注册时,后台一般先select一下用户名看看是否存在,然后再insert
<?php
$username = mysql_real_escape_string($_GET['username']);
$password = mysql_real_escape_string($_GET['password']);
$query = "SELECT *
FROM users
WHERE username='$username'";
$res = mysql_query($query, $database);
if($res) {
if(mysql_num_rows($res) > 0) {
}
else {
$query = "INSERT INTO users(username, password)
VALUES ('$username','$password')";
这里注册时使用用户名+【大量空格】和随机密码注册即可完成攻击。
主要原理就是`insert`时候有`varchar(n)`的限制,大于n的时候会截取前n个存入。在数据库对字符串进行比较时,即select操作,如果两个字符串的长度不一样,则会将较短的字符串末尾填充空格,使两个字符串的长度一致。注册时select语句不会将`admin+[大量空格]`删减到n位,所以不会被select查出与admin重复,不会返回数据,接下来就可以插入`admin+[空格](截取)`和自定义密码了。
如果使用用户名`“vampire”`和密码“`random_pass`”登录的话,对比时是`admin`与`admin+[大量空格]`,会将前面的`admin`添加空格与后面的长度相同在进行对比,那么返回的只能是我们自己注册的用户信息,而不会返回目标用户信息。SQL查询语句是一个and操作,如果密码不一样怎么会把目标用户的信息也返回回来?
当登陆时使用admin与自定义密码登陆,数据库将返回我们自己注册的账户信息,但是注意此处的`return $username`,虽然此时查询出来的是我们自己的用户信息,但是返回的用户名则是目标的用户名。如果此后的业务逻辑直接以该用户名为准,则我们就达到了水平越权的目的。