2017-10-05 22 views
0

申し訳ありませんが、この質問はダムと聞こえますが、シェルコーディングには新しく、32ビットLinuxマシンで動作するように世界の例を取得しようとしていました。Cプログラムでhello world shellcodeを実行するとSegfaultが発生する

これはシェルコードであるため、nullバイトを削除してコードを短縮するためにいくつかのトリックを使用しました。ここでは、次のとおりです。

section .data 

section .text 
global _start 
_start: 

;Instead of xor eax,eax 
;mov al,0x4 
push byte 0x4 
pop eax 
;xor ebx,ebx 
push byte 0x1 
pop ebx 
;xor ecx,ecx 
cdq ; instead of xor edx,edx 

;mov al, 0x4 
;mov bl, 0x1 
mov dl, 0x8 
push 0x65726568 
push 0x74206948 
;mov ecx, esp 
push esp 
pop ecx 
int 0x80 

mov al, 0x1 
xor ebx,ebx 
int 0x80 

私がコンパイルし、以下のコマンドでそれをリンクする際にこのコードは正常に動作します:

$ nasm -f elf print4.asm 
$ ld -o print4 -m elf_i386 print4.o 

しかし、私は、次のCコード内でそれを実行してみました: $猫shellcodetest。 C の#include の#include

char *shellcode = "\x04\x6a\x58\x66\x01\x6a\x5b\x66\x99\x66\x08\xb2\x68\x68\x68\x65\x69\x48\x54\x66\x59\x66\x80\xcd\x01\xb0\x31\x66\xcd\xdb\x80"; 

int main(void) { 
    (*(void(*)()) shellcode)(); 
} 
$ gcc shellcodetest.c –m32 –z execstack -o shellcodetest 
$ ./shellcodetest 
Segmentation fault (core dumped) 

は、誰かがそこに何が起こっているのかを説明してくださいもらえますか?私はgdbでコードを実行しようとし、何か変わったことに気づいた。しかし、私が前に言ったように、私はまだここで何が起こっているのかを本当に理解するための経験が不足しています。

ありがとうございます!

+0

ポインターの値をコードとして実行していますが、ポインターの値が指す文字列のリテラルではありません。 'const char shellcode [] =" ... "'を使ってください。 '.data'セクション(データセグメント=読み込み+書き込み)ではなく、テキストセグメント(読み込み+実行)に入る' .rodata'セクションに入るように、 'const'でなければなりません。 –

+0

ねえ、私が間違っている場合は私を修正してください。[このリンク](https://stackoverflow.com/questions/16626857/shellcode-in-c-program)は、バイトコードが実際にパラメータなしの関数()です。だから、16進数の文字列はAXの.textセクションで終わると思います。さらに、LarsHはendiannessを変更するだけでCプログラムでシェルコードを実行することができました(私はそれを見ていないのでnoobを感じます...)。 – warsang

+0

ええ、私のコメントは間違っていました。 Cの 'shellcode'は、' char * shellcode'を書くときにメモリからポインタをロードします。指さした文字列リテラル自体は '.rodata'にあります。しかし、call [absolute_address_of_pointer]の代わりに 'call eax'(あるいは' call rel32')を使用して、 'const char shellcode []'を使用する間接指示のレベルを節約します。 (そして、 'char shellcode []'(constではない)はクラッシュします)。 –

答えて

0

正しいエンディアンで入力されていないため、シェルコードが機能しません。あなたはファイルprint4からバイトをどのように抽出したのか述べなかったが、objdumpxxdの両方が正しい順序でバイトを返す。 > '\ X6A X04 \' -

$ xxd print4 | grep -A1 here 
0000060: 6a04 586a 015b 99b2 0868 6865 7265 6848 j.Xj.[...hherehH 
0000070: 6920 7454 59cd 80b0 0131 dbcd 8000 2e73 i tTY....1.....s 
$ objdump -d print4 

print4:  file format elf32-i386 


Disassembly of section .text: 

08048060 <_start>: 
8048060:  6a 04     push $0x4 
8048062:  58      pop %eax 
8048063:  6a 01     push $0x1 
... 

あなたがする必要がある変更は、バイト順、 '\ X04 \ X6A' を交換することです。 この変更でコードを実行すると、機能します。

$ cat shellcodetest.c 
char *shellcode = "\x6a\x04\x58\x6a\x01\x5b\x99\xb2\x08\x68\x68\x65\x72\x65\x68\x48\x69\x20\x74\x54\x59\xcd\x80\xb0\x01\x31\xdb\xcd\x80"; 
int main(void) { 
     (*(void(*)()) shellcode)(); 
} 
$ gcc shellcodetest.c -m32 -z execstack -o shellcodetest 
$ ./shellcodetest 
Hi there$ 
関連する問題