ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [pwnable.kr][Toddler's Bottle] 6. random
    Wargame/pwnable.kr 2019. 7. 26. 16:51

    random

    ID: random, PW: guest로 접속한 후 파일을 확인해보니 random 파일과 flag 파일이 존재했다.

    ls

     

    random.c 파일로 소스코드를 확인해보았다.

    cat random.c

    rand() 함수를 통해 생성된 난수를 random 변수에 저장하고, 사용자의 입력값을 key에 저장한다. 그리고 이 두 값을 XOR 연산한 값이 0xdeadbeef와 같으면 flag가 출력된다.

     

    rand() 함수는 난수를 생성해주는 함수이지만, 프로그램을 실행할 때마다 항상 같은 난수를 생성한다는 취약점이 있다. 따라서 rand() 함수가 생성한 난수값을 알아내면 문제가 해결될 것이다.

     

    random 값을 알아내기 위해 gdb를 실행하여 디스어셈블링해보았다.

     

    disas main

    위의 코드를 보면, rand 함수를 통해 생성된 난수는 [rbp-0x4]에 저장되고, scanf를 통해 입력받은 입력값은 [rbp-0x8]에 저장되는 것을 알 수 있다.

    두 값이 XOR 연산 되기 전에 breakpoint를 걸고(<main+56>) 실행하여 key에 아무 값이나 입력해준다.

    (key: 0xaaaaaaaa = 2863311530)

    b *main+56

     

    breakpoint까지 실행한 후 스택을 확인해보면, random의 값이 0x6b8b4567임을 알 수 있다.

     

    random 값을 알았으니, 이제 key ^ random == 0xdeadbeef 조건을 만족하는 key 값을 찾으면 된다.

    XOR 연산은 (A ^ B) ^ B = A라는 성질을 만족하므로, (0xdeadbeef ^ random) ^ random == 0xdeadbeef가 될 것이다. 즉, key의 값은 0xdeadbeef ^ random = 0xdeadbeef ^ 0x6b8b4567 = 3039230856이 된다.

     

    random 프로그램을 실행한 후 계산한 key값을 입력하면 flag가 나타난다.

    flag: Mommy, I thought libc random is unpredictable...

     

    ※ random 값을 알아내는 다른 방법

    더 간단하게 알아낼 수 있는 방법이 있어서 추가한다.

    rand() 함수가 실행되어 random 변수에 난수가 저장된 부분까지 breakpoint를 걸고(<main+21>) 실행한 후 rax 레지스터를 확인하면 random 값을 알아낼 수 있다.

     

    [참고자료]

    XOR 연산의 성질: https://sunnykwak.tistory.com/119

Designed by Tistory.