Search code examples
exploitshellcodeassemblyx86

Segfault when running hello world shellcode in C program


sorry if this question sounds dumb but I am very new to shellcoding and I was trying to get a hello world example to work on a 32 bit linux machine.

As this is shellcoding, I used a few tricks to remove null bytes and shorten the code. Here it is:

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

This code works fine when I compile and link it with the following commands:

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

However, I tried running it within the following C code: $ cat 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)

Could someone please explain what is happening there? I tried running the code in gdb and noticed something weird happening with esp. But as I said before, I still lack experience to really understand what is going on here.

Thanks in advance!


Solution

  • Your shellcode does not work, because it is not entered in the correct endianness. You did not state how you extracted the bytes from the file print4, but both objdump and xxd gives the bytes in correct order.

    $ 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
    ...
    

    The changes you need to do is to swap the byte order, '\x04\x6a' -> '\x6a\x04'. When I run your code with this change, it works!

    $ 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$