본문으로 바로가기

[pwnable.kr] random 풀이, write-up

category Wargame/pwnable.kr 2018. 11. 6. 00:15

pwnable.kr --- random



ssh random@pwnable.kr 2222 (passwd:guest)로 접속하면 random 문제를 만날 수 있다.


windows 환경의 cmd로 접속한것이 아니라 xshell5로 접속했다.


windows 환경의 cmd로 접속하려면  ssh random@pwnable.kr -p2222 이와 같이 접속 해야한다.




우선 현재 디렉터리에 어떤 파일이 있는지 확인해보자.





우선 flag를 알아야 하는데 현재 id가 random이기 때문에 flag를 볼 수 있는 권한이 없다.


random이라는 실행파일이 존재하고, setuid가 random_pwn의 권한으로 걸려있다.


random elf 파일을 통해 random_pwn의 권한으로 flag를 볼 수 있을것 같다.


random.c를 가지고 random elf 파일을 만들었을 확률이 높으므로 random.c를 분석해보자.






unsigned int 형 지역변수 random를 선언한다.



1
unsigned int random;                                                                
cs




rand() 함수를 통해 난수를 생성한 뒤 random에 저장한다.



1
random = rand()    // random value!                                                    
cs




unsigned int 형 지역변수 key를 선언한다.

key에 사용자로부터 입력을 받는다.



1
2
unsigned int key = 0;
scanf("%d"&key);                                                                    
cs



key^random == 0xdeadbeef이면 flag를 보여주고 프로그램을 종료한다.



1
2
3
4
5
if( (key ^ random) == 0xdeadbeef) {
        printf("Good!\n");
        system("/bin/cat flag");                                                    
        return 0;
}
cs




"Wrong, maybe you should try 2^32 cases.\n"을 출력한다.



1
2
printf("Wrong, maybe you should try 2^23 case.\n");                                    
return 0;
cs



난수를 생성하는 함수는 대표적으로 srand() 함수와 rand() 함수가 있다.


srand() 함수는 seed를 설정할 수 있지만 rand()는 seed를 설정할 수 없다.


seed가 있고 없고는 난수 생성에서 엄청난 차이가 있다.


seed를 설정하면, 몇 번을 실행해도 같은 값이 나오지 않지만 seed가 없으면 똑같은 값이 나오기 때문이다.


아래의 예제를 보고 쉽게 이해해보자.


소스코드는 아래와 같다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
int main(){
        unsigned int random;
        random = rand();        // random value!                                    
        printf("random: %d\n", random);
 
        srand(time(NULL));
        random = rand();        // s_random value!
        printf("s_random: %d\n", random);
 
        return 0;
}
 
cs



실행화면은 아래와 같다.





random 값은 항상 고정되고 s_random 값은 항상 바뀌는 것을 확인할 수 있다.



random 문제도 역시 random 값은 고정될 것이다.



이제 문제를 풀어보자.



key ^ random == 0xdeadbeef이다.


같은 비트를 xor 연산 두번하면 xor 연산이 사라진다는 것은 기본적으로 알고 있을 것이다.


key == 0xdeadbeef ^ random


key = 3039230856