pwnable.kr(6) ~random~
ctf布教かつ地力上げ用の記事6つ目です。
pwnable.kr
今回はどちゃくそ簡単なやつでした。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
で出た。
そういえば、セキュリティキャンプのツイートが最近流れてましたね。めちゃめちゃたのしそうでした。来年は頑張りたいです。