pwnable.kr(6) ~random~

ctf布教かつ地力上げ用の記事6つ目です。

pwnable.kr

http://pwnable.kr/play.php


今回はどちゃくそ簡単なやつでした。1点問題。

$ ssh random@pwnable.kr -p2222
random@ubuntu:~$ ls
flag  random  random.c
random@ubuntu:~$ cat 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;
}

random@ubuntu:~$ 

なるほど。書き込みにもおかしな点はなさそう。keyとrandomをxorで合わせれば、フラグは出る。
randのアルゴリズムを推測するのか、別の方法があるのかこの時点ではわからなかった。
とりあえず、rand関数について、google先生に尋ねる。得られた情報は、

rand を使って発生させた擬似乱数は srand関数 で乱数の発生系列を変更しない限り、実行のたびに同じ擬似乱数を発生します。

なるほどね。randomは実行ごとに変わらないみたい。
gdbで値を調べて、排他的論理和して、与えるkeyを出す。

random@ubuntu:~$ gdb -q ./random
Reading symbols from ./random...(no debugging symbols found)...done.
(gdb) disas main
Dump of assembler code for function main:
   0x00000000004005f4 <+0>:	push   %rbp
   0x00000000004005f5 <+1>:	mov    %rsp,%rbp
   0x00000000004005f8 <+4>:	sub    $0x10,%rsp
   0x00000000004005fc <+8>:	mov    $0x0,%eax
   0x0000000000400601 <+13>:	callq  0x400500 <rand@plt>
   0x0000000000400606 <+18>:	mov    %eax,-0x4(%rbp)
   0x0000000000400609 <+21>:	movl   $0x0,-0x8(%rbp)
   0x0000000000400610 <+28>:	mov    $0x400760,%eax
   0x0000000000400615 <+33>:	lea    -0x8(%rbp),%rdx
   0x0000000000400619 <+37>:	mov    %rdx,%rsi
   0x000000000040061c <+40>:	mov    %rax,%rdi
   0x000000000040061f <+43>:	mov    $0x0,%eax
   0x0000000000400624 <+48>:	callq  0x4004f0 <__isoc99_scanf@plt>
   0x0000000000400629 <+53>:	mov    -0x8(%rbp),%eax
   0x000000000040062c <+56>:	xor    -0x4(%rbp),%eax
   0x000000000040062f <+59>:	cmp    $0xdeadbeef,%eax
   0x0000000000400634 <+64>:	jne    0x400656 <main+98>
   0x0000000000400636 <+66>:	mov    $0x400763,%edi
   0x000000000040063b <+71>:	callq  0x4004c0 <puts@plt>
   0x0000000000400640 <+76>:	mov    $0x400769,%edi
   0x0000000000400645 <+81>:	mov    $0x0,%eax
   0x000000000040064a <+86>:	callq  0x4004d0 <system@plt>
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) b *0x400606
Breakpoint 1 at 0x400606
(gdb) r
Starting program: /home/random/random 

Breakpoint 1, 0x0000000000400606 in main ()
(gdb) p/x $eax
$1 = 0x6b8b4567

これがrandom変数に格納される値。
ここで、

A xor B = C のとき、

B = A xor C なので、(適当なサンプル出せばわかる)

(gdb) p/u $eax^0xdeadbeef
$2 = 3039230856

これを入力する。
したがって、入力を 1 行にすると

random@ubuntu:~$ echo 3039230856 | ./random

で出た。
そういえば、セキュリティキャンプのツイートが最近流れてましたね。めちゃめちゃたのしそうでした。来年は頑張りたいです。