2016-04-05 17 views
-2

私は、64ビットLinux上でCでFormat String Vulnerabilityの簡単な例を実装しようとしています。ここに私のソースコードは次のとおりです。フォーマットストリングExplorit、unexpected result

void not_called() { 
    printf("Exploited\n"); 
} 

int main(int argc, char **argv) { 

    // Buffer overflow vulnerability 
    char buffer[256]; 
    gets(buffer); 

    // User may input the format string 
    printf(buffer); 
} 

私は入力次の文字列が

AAAABBBB-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x 

をプログラムすると、結果は私がBBBBは以下の41414141としてAAAAを見つけることはできませんが

AAAABBBB-8608002c-f458fe00-fbad2288-78252d78-252d7825-5e5c51a8-0-41414141-2d78252d-78252d78-252d7825-2d78252d 

ですこれはバッファ内の同じ入力文字列の不可欠な部分です。

これは何らかの保護メカニズムですか、何かを誤解していますか?私の目標はリターンアドレスを上書きすることです。私は64ビットマシンで作業しているので、8バイト(AAAABBBB)を読み込む必要があります。文字列を悪用するための

擬似コードは、この

RETRNPTR%[decimal address of not_called - 8]u%[offset of RETRNPTR]$n 

RETRNPTRようになりますことは、現在のスタックフレームの戻りアドレスを格納するメモリのアドレスです。

私の最大の懸念は、8バイトのRETRNPTRが、私が期待しているように、メモリに連続しているようには見えないということです。 2番目の懸案事項は、%nはintポインタです。つまり、4バイトしか書き込まれません。私はまた、AAAAに先立つそれらの値がどこから来ているのか混乱しています。

+0

あなたは未定義の動作を起動さを得ました。正確に何が起こるかを理解するために分解を見てください。 –

+0

C言語では 'gets'という関数はありません。 C知識を更新する必要があります。「取得」は17年前に廃止されたとフラグされました。 – Lundin

+0

あなたは 'printf(" AAAABBBB-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x "変数リストが指定されていないとしますか? – Lundin

答えて

2

最初に、コードがあると尋ねる未定義の動作;実際のコードの振る舞いは、実際のCプログラマによって定義されていないと考えられる部分の大部分について確かにすべきです。

ここでは、BBBBが表示されない理由について説明します。 x86-64システムでこのプログラムを実行しているからです。呼び出し規約では、スタックに格納されている値に対して64ビットのプッシュを行う方法があります。しかし、%xは、32ビットのintを印刷します。 64ビットのスタック値の最下位32ビット。 64ビットlong値を印刷するには、%lxを使用します。

(また、システム-VのAPIにx86-64で6最初の整数/ポインタ引数が全くスタック上に行っていないため、彼らはRDIRSIRDXRCXR8にいる、とR9登録)。

たとえば私は、入力された:

AAAABBBB %lx %lx %lx %lx %lx %lx %lx %lx %lx %lx 

を出力

AAAABBBB 7f7c0a88f030 7f7c0a66b980 7f7c0a669980 7f7c0a88f031 786c2520786c2520 7ffc1456b6f8 
100000000 4242424241414141 786c2520786c2520 786c2520786c2520 
+0

また、最初のn個の引数はレジスタ内にあってもスタック上になくてもかまいません。 –

+0

@MichaelWalzが追加されました。 –

+0

したがって、書式文字列の場合、プレースホルダ変数は常に書式タイプ自体ではなく、デフォルトのワードサイズ(x86-64では8バイト)に揃えられますか? %xは1ワードの下位4バイトを読み込み、%xの後ろは下位4バイトを読み込みます。 –