CTFshow-Web-RCE任意文件上传

一、靶场:ctfshow web红包题第二弹
二、解题步骤:
步骤一:打开靶场,发现和web12的界面一样,打开源码看看,依然存在 ?cmd= 的提示

image1

image2

步骤二:这里按照web12的方法直接查看当前文件的源码,可以看到源码和web12相比复杂了许多,后面进行代码审计

image3

步骤三:代码审计(主要是看php代码)

<?php

if(isset($_GET['cmd'])){

        $cmd=$_GET['cmd'];

        highlight_file(__FILE__);

        if(preg_match("/[A-Za-oq-z0-9$]+/",$cmd)){

            die("cerror");

    }

    if(preg_match("/|||||||||||||||||||||/",$cmd)){

        die("serror");

    }

    eval($cmd);

}

?>

通过代码审计可以得到以下结论:

1、$cmd=$_GET['cmd']; 这是rce的根源,可以利用这个进行代码执行

2、可以看到两个判断语句,要求cmd不能含有除了p以外的大小写字母和数字,且不能含有特殊字符:$~!@#%^&等等。可以使用的有:p ` ? / + < > =

解题方法:

通过可用的字符构造cmd=?><?=`.+/??p/p?p??????`,由eval($cmd)来运行临时文件

构造原理:

1、<?= $cmd ?> 等于 <?php echo($cmd) ?>

在php中,<? ?>称为短标签,<?php ?>称为长标签。修改PHP.ini文件配置 short_open_tag = On 才可使用短标签。php5.4.0以后, <?= 总是可代替 <? echo。

例:以下代码在php7.4环境下运行,结果均为2021。

<?php echo(date('Y')) ?>

<?php eval("echo(date('Y'));") ?>

<?= date('Y'); ?>

<?php eval("?><?= date('Y');") ?>

2、反引号``(键盘Tab键上面那个键)

在php中反引号的作用是命令替换,将其中的字符串当成shell命令执行,返回命令的执行结果。反引号包括的字符串必须是能执行的shell命令,否则会出错。如下语句可得系统日期:<?= `date` ?>

3、点 .

点命令等于source命令,用来读取并执行文件内容。

source /home/user/bash 等同于 . /home/user/bash

image4

ls指令写入了文件中,使用 . 文件名 就读取并执行了文件内容

4、加号 +

URL编码中空格为%20,+表示为%2B,=为3D%。然而url中+也可以表示空格,要表示+号必须得用%2B。

5、/??p/p?p??????

5.1:临时文件夹目录

php上传文件后会将文件存储在临时文件夹,然后用move_uploaded_file() 函数将上传的文件移动到新位置;

临时文件夹可通过php.ini的upload_tmp_dir 指定,默认是/tmp目录。

5.2:临时文件命名规则

默认为 php+4或者6位随机数字和大小写字母,在windows下有tmp后缀,linux没有;

比如windows下:phpXXXXXX.tmp linux下:phpXXXXXX。

6、通配符

问号?代表一个任意字符,通配符/??p/p?p??????匹配/tmp/phpxxxxxx

7、第一个 ?> 用于拼接前面的 <? ,后面的那个 <? 用于拼接后面结尾的 ?>

步骤四:抓包,改包bp抓包post先上传一个内容为 ls 的文件,然后执行,看根目录下有些什么文件,发现有一个flag.txt

image5

步骤五:再次上传文件,读取flag.txt的内容

image6

三、注释
数据包添加内容详解:

Content-Type:

Content-Type有两个值:

①application/x-www-form-urlencoded(默认值) :上传键值对

②multipart/form-data:上传文件

boundary为边界分隔符:

文件开始标记:-----------------------------10242300956292313528205888

文件结束标记:-----------------------------10242300956292313528205888--

其中10242300956292313528205888是浏览器随机生成的,只要足够复杂就可以。

Content-Length下必须空一行,这是数据包规定的格式

posted @ 2025-12-03 09:33  shinianyunyan  阅读(24)  评论(0)    收藏  举报