気まぐれブログ(日記・技術記事・研究のことなど)

気まぐれに更新します.温かい目で見ていただければ...

pwnable.kr writeup [random]

今回は, pwnable.krのrandomという問題のwriteupを紹介します.
C言語のrand()関数の使い方が誤っていると, randomな数字が得られませんよって感じの問題ですね.

問題

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

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

解説

とりあえずscpでファイルを取得しましょう.

$ scp -r -P 2222 random@pwnable.kr:~/ ./

ファイルを取得したら, random.cをのぞいて見ましょう.

#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;
}

rand()関数を使用してrandomにその返り値を渡して, ユーザが入力した数値をkeyに代入し, それらのXORが0xdeadbeefと一致したらflagがgetできます.

ここで大事なのは, rand()関数は種(seed)を設定しないと毎回同じ数字を出力してしまうのです. よってrandom.cに「printf("random value: %d\n", random);」という記述を追加して, randomがどんな値になるか確かめてみましょう.

$ ./a.out
random value: 1804289383

randomの値は1804289383となるそうです. これは毎回実行しても同じ数字が返ってきます.

あとは, (key ^ random) == 0xdeadbeefを満たすkeyを見つければOKですね. XORの性質より, key == random ^ 0xdeadbeef を満たすkeyを計算しましょう.

>>> bin(0xdeadbeef)
'0b11011110101011011011111011101111'
>>> bin(1804289383)
'0b1101011100010110100010101100111'
>>> 0b11011110101011011011111011101111 ^ 0b1101011100010110100010101100111
3039230856

よってkeyは3039230856であるとわかりました. あとはscanf()関数にこの値を渡してやればOKですね.