freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

对一道n1ctf赛题的详细分析
蚁景科技 2021-11-26 14:21:34 128037
所属地 湖南省

最近做了一道N1CTF2021的题目,学到了不少,分享给大家共同学习。

0x01 题目详情

题目如下:

1637906871_61a079b77a46a3e4e96a3.png!small

源码如下:

<?php//flag is /flag$path=$_POST['path'];$time=(isset($_GET['time'])) ? urldecode(date(file_get_contents('php://input'))) : date("Y/m/d H:i:s");$name="/var/www/tmp/".time().rand().'.txt';$black="f|ht|ba|z|ro|;|,|=|c|g|da|_";$blist=explode("|",$black);foreach($blist as $b){if(strpos($path,$b) !== false){•    die();}}if(file_put_contents($name, $time)){• echo "<pre class='language-html'><code class='language-html'>logpath:$name</code></pre>";}$check=preg_replace('/((\s)*(\n)+(\s)*)/i','',file_get_contents($path));if(is_file($check)){• echo "<pre class='language-html'><code class='language-html'>".file_get_contents($check)."</code></pre>";}

页面下方输出的是日志文件。要拿到flag,我首先关注到下方的两个if语句,先看最下面这个:

if(is_file($check)){echo "<pre class='language-html'><code class='language-html'>".file_get_contents($check)."</code></pre>";}

如果$check是一个文件,那么读取他的内容,并输出。如果$check的值刚好是/flag,那这道题就解出来了。而$check是由这行代码来的:

$check=preg_replace('/((\s)*(\n)+(\s)*)/i','',file_get_contents($path));

此处使用了preg_replace函数,将$path文件内容里的换行空格等内容删除。而$path最初是通过POST请求提交的,之后进行了过滤,不能包含一些字符:

$black="f|ht|ba|z|ro|;|,|=|c|g|da|_";$blist=explode("|",$black);foreach($blist as $b){if(strpos($path,$b) !== false){die();}

除了POST请求提交path参数我们可以控制,另外一个参数time通过GET方式和伪协议的方式我们也可以控制:

$time=(isset($_GET['time'])) ? urldecode(date(file_get_contents('php://input'))) : date("Y/m/d H:i:s");$name="/var/www/tmp/".time().rand().'.txt';if(file_put_contents($name, $time)){echo "<pre class='language-html'><code class='language-html'>logpath:$name</code></pre>";

而$time的内容会被写入$name所在的文件中。

0x02 利用思路

整个过程如下:

1637906946_61a07a02c6692bf1e8181.png!small

我们可控的地方有path参数和time参数,time参数的内容最终会写入到name文件中。name文件会在每次请求的时候输出,我们不可控,但能够得知name文件的路径。path参数对应的文件名可控,但其文件内容不可控,而check文件名来源于path文件的内容,最终会读取并输出check文件的内容。

所以,我们要想读取/flag的内容,我们就要使check文件内容等于/flag,即可直接在网页中显示出/flag的内容。check文件名可通过path参数进行控制,而name文件内容我们可以通过time参数控制,所以,我们要想方法把/flag这个字符串写入name文件内容中,然后将check文件名设置为name文件即可。

0x03 利用过程

第一步,我们首先将/flag字符串写入time文件。

程序通过如下代码获得time的值:

$time=(isset($_GET['time'])) ? urldecode(date(file_get_contents('php://input'))) : date("Y/m/d H:i:s");

其中涉及到php的伪协议php://input,它可以读取我们POST请求的内容,time参数如果被设置,同时有POST数据,POST数据将会赋值给$time,我在本机进行调试如下:

1637906962_61a07a12c1655b980738a.png!small

内容写入到time对应的txt文件中:

1637907063_61a07a779a64a3d9589e4.png!small

为什么写入的内容不是/flag?因为有date函数并结果urldecode,所以,改成如下即可:

1637907076_61a07a8490f38d9a1e26d.png!small

查看对应的文件即为/flag:

1637907092_61a07a949a09b9acecddd.png!small

而我们将path参数设置为time对应的txt文件名,那么check文件名就会被设置为/flag,最终读取输出flag。

按照本地测试的效果,首先传递time参数,将/flag写入文件,然后记下页面输出的txt文件路径:

1637907125_61a07ab58de39f01e6afb.png!small

然后再次请求时,指定path为txt文件路径/var/www/tmp/16375737971145120615.txt,得到flag内容:

1637907031_61a07a570c8d0dd3b681b.png!small


# CTF # 网络安全技术
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 蚁景科技 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
蚁景科技 LV.9
湖南蚁景科技有限公司主要从事在线教育平台技术研究及网络培训产品研发,专注网络空间安全实用型人才培养,全面提升用户动手实践能力。
  • 907 文章数
  • 677 关注者
蚁景科技荣膺双项殊荣,引领网络安全教育新潮流
2025-03-28
FlowiseAI 任意文件写入漏洞(CVE-2025–26319)
2025-03-27
路由器安全研究:D-Link DIR-823G v1.02 B05 复现与利用思路
2025-03-18
文章目录