web-dev-qa-db-ja.com

x64システムで文字列形式のエクスプロイトを実行できますか?

フォーマット文字列のエクスプロイトについて Gray Hat Hacking-Third Edition 、第12章で実験を再現しようとしましたが、それらのアーキテクチャはIA32であり、私のものはAMD 64ビットです。したがって、次のようなコマンドでスタック内の値を確認すると、

$ ./fmtstr "AAAAAAAA %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x"   

何も表示されず、メモリでの表示に似ています(41414141 41414141)。エクスプロイトバッファーが実際のシーケンシャルメモリデータを返さないのはなぜですか?詳細については、 彼のコンソールイメージ ヘルプを参照してください。

7
Fernando Pérez

本(下記)のサンプルコードを使用している場合、ある時点で "AAAAAAAA"パターン(0x41)に到達するはずです。要素をスタックに8バイトずつ格納する64ビットマシンで実行しているため、代わりに$ ./fmtstr "AAAAAAAA %016x %016x %016x %016x %016x %016x %016x %016x %016x %016x %016x %016x %016x"を使用して実行する必要があります。そうしないと、スタックの各要素の一部が失われます。

#include <stdlib.h>
int main(int argc, char *argv[]){
        static int canary=0;   // stores the canary value in .data section
        char temp[2048];       // string to hold large temp string
      strcpy(temp, argv[1]);   // take argv1 input and jam into temp
      printf(temp);            // print value of temp
      printf("\n");            // print carriage return
      printf("Canary at 0x%08x = 0x%08x\n", &canary, canary); //print canary
}

あなたは本の中で引用されている引用に注意を払うべきです:

(スタックから)4番目に表示される項目がフォーマット文字列であるという事実は、使用されるフォーマット関数の性質と、脆弱なプログラムでの脆弱な呼び出しの場所によって異なります。この値を見つけるには、ブルートフォースを使用し、フォーマット文字列の先頭が見つかるまで%08xトークンの数を増やし続けます。簡単な例(fmtstr)では、オフセットと呼ばれる距離は4と定義されています。

printfに解析されるパラメーターは、文字列そのものではなく、文字列のアドレスであることを忘れないでください。したがって、printfスタックに対するプログラムのメモリレイアウト上の位置は、それを見つけるためにさらに検索する必要があることを定義するものです。

5
murphsghost