2017-02-12 5 views
-1

私は非常にfreshmeat_linux/Linux]で(基本的なものを知っている)新しいです。私は、Linux仮想マシンで、キャプチャ・ザ・フラッグ(CTF)スタイルの課題を完了しようとしています。だから私は基本的に私はCのプログラムファイルとフラグがあります。私はフラグを立てることはできません。私はプログラムファイルを読んで実行することができます。このCコード:Linuxフラグのプログラミングのパズルをキャプチャ

#include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 

    void check() { 

    int invalid; 
    if (invalid) { 
    printf ("Password invalid!\n"); 

    } 

    else{ 
    printf ("Password accepted!\n"); 
    system ("/bin/cat flag3"); 
    } 
    } 
    void password() { 

    char password [200]; 
    printf ("Enter the password: "); 
    scanf ("%s" , password); 
    } 

    int main() { 
    password(); 
    check(); 
    return 0; 
    } 

私はそれをデバッグしようとしたアセンブラの内容を見たが、私は、フラグの内容を知るためにパスワードをキャプチャする方法を理解することはできませんしています。私はこのリンクの助けを借りてパスワードを解読しようとしましたhttp://eliteinformatiker.de/2012/11/16/howto-crack-a-small-c-program-with-assemblerしかし、私はCプログラムのバイナリファイルを編集できるかどうかはわかりません。だから、私はどのように私はバイナリ(おそらく私は間違っている)を変更することができます私はCファイルを変更することはできませんと思います。この時点で私は固執しています。私はそれをデバッグしようとしましたが、アセンブリの内容を見ましたが、バイナリを編集できるかどうかわかりません。フラグをキャプチャするにはどのようなアプローチが必要ですか?

+1

ここで/はどのように '無効 'に設定されていますか?私はそれが 'check'関数で使われているのを見ていますが、どのように設定されているのかわかりません。 – thurizas

+0

私はそれについては分かりません。実際に私はこの点についても混乱していました。私はこのコードを書いていません。私はこのコードを手に入れました。私はそれを実行すると、フラグの内容にアクセスできるようにパスワードを要求します。私はパスワードを知らないので、今、私はフラグにアクセスするためにパスワードを推測するためにいくつかの悪用/バックドアを見つけなければなりません。そして私はどんな悪用も見つけられないようです。 – sar

+0

プログラムをデバッグできる場合は、比較を変更できるはずです。たとえば、invalidはローカル変数であり、スタックに格納されます。テストの前に値を変更することができます。 – thurizas

答えて

-1

バッファオーバーフローの破損が必要です。 200文字を超えるパスワードを入力すると、デフォルトのゼロ値から無効な値が破損しますか?

+0

私はすでにそれを試みました。パスワードが200文字を超えると、セグメント化エラーが発生します。 – sar

+0

これはコメントであり、答えではありません。 – Olaf

+0

変数にヌル文字までの文字を格納するため、Scantは安全ではありません。 '\ 0'を使って面白いことをすることはできますか? – GandhiGandhi

0

免責事項:私はUbuntu-12.04とgcc-4.8.-2とgdb-7.7.1デバッガを使用しています。

checkを入力してifにステップするまでは、デバッガでプログラムを実行しました。私は、コードを逆アセンブルし、アセンブリを見て:

(gdb) disass 
Dump of assembler code for function check: 
    0x000000000040062d <+0>: push %rbp 
    0x000000000040062e <+1>: mov %rsp,%rbp 
    0x0000000000400631 <+4>: sub $0x10,%rsp 
=> 0x0000000000400635 <+8>: cmpl $0x0,-0x4(%rbp) 
    0x0000000000400639 <+12>: je  0x400647 <check+26> 
    0x000000000040063b <+14>: mov $0x400754,%edi 
    0x0000000000400640 <+19>: callq 0x4004e0 <[email protected]> 
    0x0000000000400645 <+24>: jmp 0x400651 <check+36> 
    0x0000000000400647 <+26>: mov $0x400766,%edi 
    0x000000000040064c <+31>: callq 0x4004e0 <[email protected]> 
    0x0000000000400651 <+36>: leaveq 

そして、私は私のレジスタ(単に重要なものを示す)の値を見て:

(gdb) info reg 
    rbp   0x7fffffffdf00 0x7fffffffdf00 
    rsp   0x7fffffffdef0 0x7fffffffdef0 
    rip   0x400635 0x400635 <check+8> 
    eflags   0x206 [ PF IF ] 

次に、私が指示(gdb) niを踏んシングル道cmp作品はそのSIMUであることを

(gdb) disass 
Dump of assembler code for function check: 
    0x000000000040062d <+0>: push %rbp 
    0x000000000040062e <+1>: mov %rsp,%rbp 
    0x0000000000400631 <+4>: sub $0x10,%rsp 
    0x0000000000400635 <+8>: cmpl $0x0,-0x4(%rbp) 
=> 0x0000000000400639 <+12>: je  0x400647 <check+26> 
    0x000000000040063b <+14>: mov $0x400754,%edi 
    0x0000000000400640 <+19>: callq 0x4004e0 <[email protected]> 
    0x0000000000400645 <+24>: jmp 0x400651 <check+36> 
    0x0000000000400647 <+26>: mov $0x400766,%edi 
    0x000000000040064c <+31>: callq 0x4004e0 <[email protected]> 
    0x0000000000400651 <+36>: leaveq 
    0x0000000000400652 <+37>: retq 
End of assembler dump. 
(gdb) info reg 
eflags   0x206 [ PF IF ] 

リコール:と解体とeflagsの値を取得繰り返しますjeが利用するフラグを適切に設定する減算を実行します。したがって、このコードは0から-0x4(%rpb)の減算を実行します(ゼロフラグを適切に設定します)。数字が同じ場合、jzはジャンプを行います。ゼロ・フラグは、現在設定されていることを

(gdb) set $ZF = 6 
(gdb) set $eflags |= (1 << $ZF) 
(gdb) print $eflags 
$1 = [ PF ZF IF ] 

お知らせ:

は、だから私は、コマンドシーケンスとフラグレジスタを修正しました。他のブロックである

(gdb) ni 
(gdb) disass 
Dump of assembler code for function check: 
    0x000000000040062d <+0>: push %rbp 
    0x000000000040062e <+1>: mov %rsp,%rbp 
    0x0000000000400631 <+4>: sub $0x10,%rsp 
    0x0000000000400635 <+8>: cmpl $0x0,-0x4(%rbp) 
    0x0000000000400639 <+12>: je  0x400647 <check+26> 
    0x000000000040063b <+14>: mov $0x400754,%edi 
    0x0000000000400640 <+19>: callq 0x4004e0 <[email protected]> 
    0x0000000000400645 <+24>: jmp 0x400651 <check+36> 
=> 0x0000000000400647 <+26>: mov $0x400766,%edi 
    0x000000000040064c <+31>: callq 0x4004e0 <[email protected]> 
    0x0000000000400651 <+36>: leaveq 
    0x0000000000400652 <+37>: retq 
End of assembler dump. 

を、あなたはフラグが表示されるはずです:単一の命令セット(ni)とは、解体を見てみましょう。 (私のテストプログラムでは、猫の旗の行をコメントアウトしたことに注意してください)。

+0

私はあなたのロジックを理解し、私はこれを試しました。しかし、フラグを表示するのではなく、フラグが開かれず、許可が拒否されていることが表示されました。 – sar

+0

ゼロフラグを設定した後、それはelseにジャンプしますが、フラグの内容を呼び出す命令になると、私はフラグをオープンできません。私はルートアクセスを持っていないと思うので、なぜ私はまだフラグを開くことができません。私はフラグにアクセスするためにいくつかの他の悪用方法を見つけなければなりません。 – sar

+0

@sar drat ...プログラムを見ると、 'system'コマンドは、フラグがプログラムがあるディレクトリにあると信じています(' system/bin/cat flag3'は相対パスです絶対パスではありません)。私は、あなたがflag3が見つかったディレクトリに移動できるかどうか、そしてそのアクセス許可が何であるかを知ることに興味があります。私はこれを熟考しているのだろうか、フラグがあるフォルダに行き、結果が何であるか 'cat flag3'を実行すればいいのか疑問に思っています。 (恐らく許可は拒否されましたが、あなたは知らないでしょう)。 – thurizas

関連する問題