6. random - Pwnable.kr 해설

2020. 3. 17. 20:38문제연습/Pwnable.kr (PWN)

반응형

티스토리 블로그는 PC 환경에 최적화되어 있습니다.

모바일 유저분들은 아래 네이버 블로그를 이용해 주세요.

 

6. random - Pwnable.kr 해설

네이버 블로그는 모바일 환경에 최적화되어 있습니다.PC 유저분들은 아래 티스토리 블로그를 이용해 주세...

blog.naver.com

안녕하세요, ICMP입니다.

이번 시간에는 random 문제를 풀어보도록 하겠습니다.

 

문제 내용

Daddy, teach me how to use random value in programming!

ssh random@pwnable.kr -p2222 (pw:guest)

 

들어가기 전

What is Random number?

 

난수 : 정의된 범위 내에서 무작위로 추출된 수를 일컫는다.

난수는 누구라도 그다음에 나올 값을 확신할 수 없어야 한다.

 

문제 해설

이번 문제는 아마 가장 짧은 해설이 될 듯합니다. (난수 발생 코드의 문제점을 이용하는 문제입니다.)

 

리눅스 터미널을 열어서ssh random@pwnable.kr -p2222로 접속하고 pw 입력합니다.

일단 어떤 파일이 있는지 보도록 하겠습니다.( ls 명령어)

 

그러면 random.c 파일을 한번 읽어 보도록 하겠습니다. ( cat 명령어 )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
 
int main(){
    unsigned int random;
    random = rand();    // random value!
 
    unsigned int key=0;
    scanf("%d"&key);
 
    if( (key ^ random) == 0xdeadbeef ){
        printf("Good!\n");
        system("/bin/cat flag");
        return 0;
    }
 
    printf("Wrong, maybe you should try 2^32 cases.\n");
    return 0;
}
 

소스 코드 내용은 random이라는 변수에 rand() 함수를 이용하여 난수 값을 집어넣고 있습니다.

 

(rand 함수에 대한 설명은 아래 링크를 이용해 주세요.)

 

[C언어/C++] rand, srand, time 랜덤함수에 대해서 (난수생성)

안녕하세요. BlockDMask 입니다. 오늘은 C/C++로 개발할때 가끔 사용하는 랜덤한 수(난수)를 생성하는 함수에 대해서 알아보겠습니다. 랜덤한 값을 가지고올때 필요한데요. 그럼 시작해보겠습니다. 1. rand 함수원..

blockdmask.tistory.com

 

그런데 // random value!이라는 주석 부분의 코드를 보면 아주 큰 문제가 있습니다.

rand 함수는 한번 프로그램이 생성되면 값이 고정이 됩니다.

 

다시 말해 rand 함수 단독으로만 쓰이면 컴파일 후 몇 번을 실행하든 random이라는 변수에 저장되는 값이 똑같다는 말입니다. (rand 함수에서 seed를 이용하는 이유도 이것 때문입니다.)

 

 

여기까지 보시고 방법이 떠오르셨다면 다시 한번 풀어보세요!!!

그럼 풀이를 진행하겠습니다.

 

 

문제의 핵심은 rand 함수에 저장되는 값을 찾는 것입니다.

즉 프로그램의 실행되는 특정한 곳에 중단점을 설정하고 rand 함수의 리턴 값이 저장되는 레지스터나 주소의 값을 조회해 보면 바로 문제가 풀릴듯합니다.

 

그럼 본격적으로 시작해 보겠습니다.

gdb로 main 함수를 분석하니 다음과 같은 코드가 나왔습니다.

소스코드와 어셈블리 코드를 비교해보면, 초록색 박스는 scanf 함수로 입력을 받고 if 조건문에서 비교하는 구문의 위치와 같습니다.

 

그리고 파란색 박스는 rand 함수 호출 후 리턴 값을 eax에 저장 후 0x400760 주소에 저장했습니다.

(여기서 eax를 주목한 이유는 보통 함수의 리턴 값 저장에 쓰이는 레지스터이기 때문입니다.

레지스터에 대한 정확한 내용은 아래 링크를 참고해 주세요.)

 

레지스터(Register)의 이해 #1 - 레지스터의 개요

이어진 내용 레지스터(Register)의 이해 #1 - 레지스터의 개요 레지스터(Register)의 이해 #2 - 레지스터...

blog.naver.com

 

그럼 0x0000000000400609 주소에 중단점을 설정하고 실행시키도록 하겠습니다.

(gdb에 b* 0x0000000000400609 입력 후 Enter, r 입력 후 Enter)

 

이제 eax 레지스터의 값을 알아보도록 하겠습니다.

(info register $eax 입력 후 Enter)

현재 eax 레지스터에 들어가 있는 값은 0x6b8b4567(십진수로 1804289383)가 저장되어 있습니다.

 

아까 소스코드에서 조건문에서 scanf로 입력받은 key 값을 0x6b8b4567과 xor 연산한 결괏값이 deadbeef와 일치하면 프로그램에서 플래그를 출력할 것입니다.

 

그럼 key 값은 0xdeadbeef xor 0x6b8b4567 = 0xb526fb88이 되어야겠습니다.

그런데 scanf가 key를 %d 즉 10진수로 입력을 받고 있으므로3039230856을 입력해야겠군요.

 

한번 gdb를 종료하고 random을 실행하여 key를 입력해 보도록 하겠습니다.

 

오케이!! 플래그가 출력되었습니다.

이번 문제는 rand 코딩의 문제를 눈치채면 쉽게 풀 수 있는 문제였습니다.

다음 시간에는 input 문제를 풀어보도록 하겠습니다.

이상, ICMP였습니다!!!

 

반응형