攻防世界Cat(Django框架+php curl使用@路径读取文件+宽字节注入)

打开题目以后他让我们输入一个域名,我这里习惯一般填入127.0.0.1

 

可以发现是一个ping命令,立马想到命令执行。然后进行尝试命令执行的payload_fuzz,

发现这里只有四个字符没有被过滤,其他全报Invalid URL,还有一个神奇的发现点是,当我们输入字符以后,

 

 

 发现url里面给我们自动进行了url编码------>于是这里考虑到可能是宽字符注入。(不懂为啥记住,或者可以进行fuzz_url尝试,发现在%80的时候进行了报错!%80已经超出了ascii码的128。)

 

 

 将里面的html代码粘贴复制出来运行发现,这是一个Django框架的报错页面!

 

 

 在这个页面我们可以发现几个有用的信息。第一,我们url明明是以GET方式发送的请求,在这里却显示的POST方式,还有在下面的这个页面我们发现,

 

 

CONTENT_TYPE居然是“multipart/form-data”,而这个类型是需要在表单中进行文件上传时,就需要使用该格式。

对于该题目还有一个提示:RTFM of PHP CURL===>>read the fuck manul of PHP CURL???

意思是说,用@可以读取文件的内容,也正好符合上面的CONTENT_TYEPE。

这里数据提交的逻辑是:客户端将get数据提交给PHP,php使用post方式给Djanjo写的api,在报错页面中可以看到应该是/api/ping。Django对php传进的POST参数进行GBK编码,编码后执行ping命令。

这样,我们利用@ + 路径读取文件后,php通过post传给Django做编码,django中无法对传来的文件中超过%7F的字符做gbk编码,就会报错,而django又开启了Debug模式,报错的内容可以回显到浏览器中,因此我们就可以读取到文件了。

我们可以使用?url=@index.php来查看当前页面的源代码

 

 整理后如下所示:

<?php if(isset($_GET['url']))
{
# 初始话一个curl对象
$ch = curl_init("http://127.0.0.1:8000/api/ping");
$params = array("url"=>"$_GET[url]");

curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$data = curl_exec($ch);curl_close($ch);

echo htmlspecialchars($data);

}
?>

上面的代码告诉我们:php会将?url查询字符串的内容通过curl的方式发送给Django编写的ping接口
curl_setopt中的相关参数:

CURLOPT_HEADER — 启用时会将头文件的信息作为数据流输出
CURLOPT_SAFE_UPLOAD — FALSE为启用,@开头的value会被当做文件上传。CURLOPT_SAFE_UPLOAD选项配置不当结合其他情况可造成任意文件读取 --- 这里是解这道题的关键点。
CURLOPT_POSTFIELDS — 全部数据使用HTTP协议中的"POST"操作来发送。要发送文件,在文件名前面加上@前缀并使用完整路径。这个参数可以通过urlencoded后的字符串类似’para1=val1&para2=val2&…'或使用一个以字段名为键值,字段数据为值的数组。如果value是一个数组,Content-Type头将会被设置成multipart/form-data。
CURLOPT_RETURNTRANSFER — 将curl_exec()获取的信息以文件流的形式返回,而不是直接输出

 

在Django项目下一般有一个settings.py文件,是设置网站数据库路径的(Django默认使用sqlites数据库),如果使用了其他的数据库settings.py会设置用户名和密码,settings.py文件还会对项目的整体设置进行定义。这里读取settings.py文件(django项目生成的settings.py文件会存放在以项目目录下再以项目名称命名的文件夹下面),执行:?url =@/opt/api/api/settings.py 读取。然后在里面找到数据库的存放路径,再次利用@查看访问数据库的内容寻找flag即可。

 

总结:

1.Django框架的相关文件

2.宽字符注入

3.php curl 利用@可以读取文件内容

 

posted @ 2022-09-27 17:20  hithub  阅读(223)  评论(0编辑  收藏  举报