Ein C Programm, welches bei der Shellcode-Entwicklung helfen soll.
/* Utility for Shellcode Work 2010 tuxwave.net Have phun! */ #include <unistd.h> #include <stdlib.h> #include <termios.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <errno.h> #include <stdio.h> struct code { long length; void *code; }; static void usage(char *argv[]); static void encode(char *val, char *exec, char *output); static void decode(char *val, char *exec, char *output); static void execute(void *code); static void tool(char *output); static int is_little_endian(void); static int fileread(char *filename, struct code *codeinfo); static short htos (const short *ptr); void ascii_hex(char *output); void hex_ascii(char *output); void decimal_hex(char *output); void hex_decimal(char *output); int main(int argc, char *argv[], char *envp[]) { int option; char *encval = (char *) 0, *decval = (char *) 0, *exeval = (char *) 0, *tval = (char *) 0, *output = (char *) 0; if(argc == 1) usage(argv); while((option = getopt(argc, argv, ":he:d:xt")) != -1) { switch(option) { case 'e': encval = optarg; break; case 'd': decval = optarg; break; case 'x': exeval = (char *)0x1; break; case 't': tval = (char *)0x1; break; case 'h': case '?': default: usage(argv); break; } } if(argv[optind] != NULL) { output = argv[optind]; } if(encval != (char *) 0) encode(encval, exeval, output); else if(decval != (char *) 0) decode(decval, exeval, output); else if(tval != (char *) 0) tool(output); else exit(EXIT_SUCCESS); } static void usage(char *argv[]) { fprintf(stderr, "%s " "[options] {output}\n" "----------------------------------------------------------------\n" "\t-h = help\n" "\t-e [file] = encode binary file to hexencoded-binary\n" "\t-d [file] = decode hexencoded-binary from file\n" "\t-x = execute code\n" "\t-t = interactive tool for small stuff\n", argv[0]); exit(EXIT_FAILURE); } static void encode(char *val, char *exec, char *output) { struct code codeinfo; int count = 0, col = 0, cols = 14; FILE *outfile = NULL; if(output == NULL || output[0] == '-') { outfile = stdout; } else if(output != NULL) { outfile = fopen(output, "w"); if(outfile == NULL) { fprintf(stderr, "Error opening %s for writing. Error: %s", output, strerror(errno)); exit(EXIT_FAILURE); } } fileread(val, &codeinfo); fprintf(outfile, "char shellcode[] = \n"); for(count = 0; count < codeinfo.length; ++count) { if(col >= cols) { fprintf(outfile, "\"\n"); col = 0; } if(col == 0) { fprintf(outfile, "\""); } fprintf(outfile, "\\x%02x", ((unsigned char *)codeinfo.code)[count]); ++col; } fprintf(outfile, "\";\n"); fflush(outfile); if(exec != NULL) { execute(codeinfo.code); } free(codeinfo.code); } static void decode(char *val, char *exec, char *output) { struct code codeinfo; FILE *outfile = NULL; if(output == NULL || output[0] == '-') { outfile = stdout; } else if(output != NULL) { outfile = fopen(output, "w"); if(outfile == NULL) { fprintf(stderr, "Error opening %s for writing. Error: %s", output, strerror(errno)); exit(EXIT_FAILURE); } } fileread(val, &codeinfo); int i = 0, buflen = 0; char *buffer = (char *) malloc(codeinfo.length); memset(buffer, '\0', codeinfo.length); for(i = 0;i < codeinfo.length;i++) { if(i < 19) continue; /*bypass char shellcode[] =*/ if(((char *)codeinfo.code)[i] == '"') continue; if(((char *)codeinfo.code)[i] == ';') continue; if(((char *)codeinfo.code)[i] == '\\') continue; if(((char *)codeinfo.code)[i] == 'x') continue; if(((char *)codeinfo.code)[i] == '\n') continue; buffer[buflen] = ((char *)codeinfo.code)[i]; buflen++; } int byc = 0; short *buf = (short *) malloc(2); memset(buf, 0, 2); short byte; memset(codeinfo.code, '\0', codeinfo.length); codeinfo.length = 0; for(i = 0;i < buflen;i++) { if(buffer[i] == '\0') break; buf[byc] = buffer[i]; byc++; if(byc == 2) { byte = htos(buf); ((unsigned char *)codeinfo.code)[codeinfo.length] = byte; codeinfo.length++; if(!((fwrite(&byte, 1, 1, outfile)) > 0)) { fprintf(stderr, "Error writing to file %s. Error: %s\n", output, strerror(errno)); exit(EXIT_FAILURE); } byc = 0; continue; } } fflush(outfile); if(exec != NULL) { execute(codeinfo.code); } free(buffer); free(codeinfo.code); } static void execute(void *code) { printf("Executing code...\n"); void (*fptr)(void); /*function pointer fptr*/ fptr = (void (*)(void)) code; /*fptr gets address of -> code gets casted into -> void function(void)*/ (*fptr)(); /*call function*/ return; } static int fileread(char *filename, struct code *codeinfo) { FILE *file = fopen(filename, "r"); struct stat statbuf; if(stat(filename, &statbuf) != 0) { fprintf(stderr, "Could not stat file: %s Error: %s\n", filename, strerror(errno)); exit(EXIT_FAILURE); } codeinfo->length = (long)statbuf.st_size; if(!(codeinfo->code = (void *) malloc(codeinfo->length))) { fprintf(stderr, "malloc error: %s\n", strerror(errno)); exit(EXIT_FAILURE); } memset(codeinfo->code, '\0', codeinfo->length); if(fread(codeinfo->code, 1, codeinfo->length, file) != codeinfo->length) { fprintf(stderr, "fread error: %s\n", strerror(errno)); exit(EXIT_FAILURE); } return(0); } static int is_little_endian(void) { unsigned short word = 0x1234; unsigned char *p = (unsigned char *) &word; if(p[0] == 0x34) { return(1); } return(0); } static short htos (const short *ptr) { short value = 0; short ch = *ptr; while (ch == ' ' || ch == '\t') ch = *(++ptr); for (;;) { if (ch >= '0' && ch <= '9') value = (value << 4) + (ch - '0'); else if (ch >= 'A' && ch <= 'F') value = (value << 4) + (ch - 'A' + 10); else if (ch >= 'a' && ch <= 'f') value = (value << 4) + (ch - 'a' + 10); else return value; ch = *(++ptr); } } static void tool(char *output) { if(!isatty(0)) { fprintf(stderr, "Must be a tty!\n"); exit(EXIT_FAILURE); } struct termios oldterm, newterm; tcgetattr(0,&oldterm); newterm = oldterm; newterm.c_lflag &= ~ECHO; newterm.c_lflag &= ~ICANON; while(1) { printf( ".........................................\n" "Chose:\n" ".........................................\n" "a - ascii to hex\n" "h - hex to ascii\n" "d - decimal to hex\n" "n - hex to decimal\n" "q - quit\n" ".........................................\n"); tcsetattr(0, TCSANOW, &newterm); int choice = getchar(); tcsetattr(0, TCSANOW, &oldterm); if(choice == EOF || choice == 'q') { exit(EXIT_SUCCESS); } switch(choice) { case 'a': ascii_hex(output); break; case 'h': hex_ascii(output); break; case 'd': decimal_hex(output); break; case 'n': hex_decimal(output); break; default: break; } } } /* * Ausgabe: * Endianness beachten! * ascii-to-hex -> hex, hex little endian, hex-ascii codiert(rückwärts+vorwärts), 0xfff und 0xff 0xff * hex to ascii -> nach ascii, 0xfffff und 0xff 0xff 0xff formate * decimal-to-hex -> hex, hex little endian * hex-to-decimal -> decimal little endian, big endian */ void ascii_hex(char *output) { FILE *outfile = NULL; if(output != NULL) { outfile = fopen(output, "w"); if(outfile == NULL) { fprintf(stderr, "Error opening %s for writing. Error: %s", output, strerror(errno)); exit(EXIT_FAILURE); } } int in, size = 100, count = 0; char *input = (char *) malloc(sizeof(char)*size); struct termios oldterm, newterm; tcgetattr(0,&oldterm); newterm = oldterm; newterm.c_lflag &= ~ICANON; if(input == NULL) { perror("malloc"); } memset(input, '\0', sizeof(char)*size); printf("Enter String: "); tcsetattr(0, TCSANOW, &newterm); fflush(stdin); while((in = fgetc(stdin))) { if((char)in == '\n') {break;} *(input+count) = (char) in; count++; if(size == count) { size += 100; if((input = realloc(input, sizeof(char)*size)) == NULL) { perror("realloc"); exit(EXIT_FAILURE); } memset(input+count, '\0', (sizeof(char)*size)-count); } } tcsetattr(0, TCSANOW, &oldterm); if(*(input) == '\0') return; int i; if(output != NULL) fprintf(outfile, "%s\n", input); printf("String (reversed): "); for(i = count-1;i >= 0;i--) { if(*(input+i) == '\0') break; printf("%c", *(input+i)); if(output != NULL) fprintf(outfile, "%c", *(input+i)); } if(output != NULL) fprintf(outfile, "\n"); printf("\nHex-String: 0x"); if(output != NULL) fprintf(outfile, "0x"); for(i = 0;i < count;i++) { if(*(input+i) == '\0') break; printf("%02x", *(input+i)); if(output != NULL) fprintf(outfile, "%02x", *(input+i)); } if(output != NULL) fprintf(outfile, "\n"); printf("\nHex-String (reversed): 0x"); if(output != NULL) fprintf(outfile, "0x"); for(i = count-1;i >= 0;i--) { if(*(input+i) == '\0') break; printf("%02x", *(input+i)); if(output != NULL) fprintf(outfile, "%02x", *(input+i)); } if(output != NULL) fprintf(outfile, "\n"); printf("\nHex-String (with 0x): "); for(i = 0;i < count;i++) { if(*(input+i) == '\0') break; printf("0x%02x ", *(input+i)); if(output != NULL) fprintf(outfile, "0x%02x ", *(input+i)); } if(output != NULL) fprintf(outfile, "\n"); printf("\nHex-String (with 0x, reversed): "); for(i = count-1;i >= 0;i--) { if(*(input+i) == '\0') break; printf("0x%02x ", *(input+i)); if(output != NULL) fprintf(outfile, "0x%02x ", *(input+i)); } if(output != NULL) fprintf(outfile, "\n"); printf("\n"); return; } void hex_ascii(char *output) { FILE *outfile = NULL; if(output != NULL) { outfile = fopen(output, "w"); if(outfile == NULL) { fprintf(stderr, "Error opening %s for writing. Error: %s", output, strerror(errno)); exit(EXIT_FAILURE); } } int in, size = 100, count = 0; char *input = (char *) malloc(sizeof(char)*size); struct termios oldterm, newterm; tcgetattr(0,&oldterm); newterm = oldterm; newterm.c_lflag &= ~ICANON; if(input == NULL) { perror("malloc"); } memset(input, '\0', sizeof(char)*size); printf("Enter Hex-String: "); tcsetattr(0, TCSANOW, &newterm); fflush(stdin); int lastchar; while((in = fgetc(stdin))) { if((char)in == '\n') {break;} if(lastchar == '0' && ((char)in) != 'x' && ((char)in) != 'X') { *(input+count) = '0'; count++; if(size == count) { size += 100; if((input = realloc(input, sizeof(char)*size)) == NULL) { perror("realloc"); exit(EXIT_FAILURE); } memset(input+count, '\0', (sizeof(char)*size)-count); } } lastchar = in; if(((char)in) == '0' || ((char)in) == 'x' || ((char)in) == 'X') continue; *(input+count) = (char) in; count++; if(size == count) { size += 100; if((input = realloc(input, sizeof(char)*size)) == NULL) { perror("realloc"); exit(EXIT_FAILURE); } memset(input+count, '\0', (sizeof(char)*size)-count); } } if(*(input) == '\0') return; tcsetattr(0, TCSANOW, &oldterm); int byc = 0, i = 0; short *buf = (short *) malloc(2); memset(buf, 0, 2); printf("In ASCII: "); for(i = 0;i < count;i++) { if(input[i] == '\0') break; buf[byc] = input[i]; byc++; if(byc == 2) { printf("%c", htos(buf)); if(output != NULL) fprintf(outfile, "%c", htos(buf)); byc = 0; continue; } } printf("\n"); if(output != NULL) fprintf(outfile, "\n"); return; } void decimal_hex(char *output) { FILE *outfile = NULL; if(output != NULL) { outfile = fopen(output, "w"); if(outfile == NULL) { fprintf(stderr, "Error opening %s for writing. Error: %s", output, strerror(errno)); exit(EXIT_FAILURE); } } int in, size = 100, count = 0; char *input = (char *) malloc(sizeof(char)*size); struct termios oldterm, newterm; tcgetattr(0,&oldterm); newterm = oldterm; newterm.c_lflag &= ~ICANON; if(input == NULL) { perror("malloc"); } memset(input, '\0', sizeof(char)*size); printf("Enter decimal number: "); fflush(stdin); tcsetattr(0, TCSANOW, &newterm); while((in = fgetc(stdin))) { if((char)in == '\n') {break;} *(input+count) = (char) in; count++; if(size == count) { size += 100; if((input = realloc(input, sizeof(char)*size)) == NULL) { perror("realloc"); exit(EXIT_FAILURE); } memset(input+count, '\0', (sizeof(char)*size)-count); } } if(*(input) == '\0') return; tcsetattr(0, TCSANOW, &oldterm); int number = atoi(input); printf("In Hex: %#x\n", number); fprintf(outfile, "%#x\n", number); return; } void hex_decimal(char *output) { FILE *outfile = NULL; if(output != NULL) { outfile = fopen(output, "w"); if(outfile == NULL) { fprintf(stderr, "Error opening %s for writing. Error: %s", output, strerror(errno)); exit(EXIT_FAILURE); } } int in, size = 100, count = 0; char *input = (char *) malloc(sizeof(char)*size); struct termios oldterm, newterm; tcgetattr(0,&oldterm); newterm = oldterm; newterm.c_lflag &= ~ICANON; if(input == NULL) { perror("malloc"); } memset(input, '\0', sizeof(char)*size); printf("Enter Hex-String: "); tcsetattr(0, TCSANOW, &newterm); fflush(stdin); int lastchar; while((in = fgetc(stdin))) { if((char)in == '\n') {break;} if(lastchar == '0' && ((char)in) != 'x' && ((char)in) != 'X') { *(input+count) = '0'; count++; if(size == count) { size += 100; if((input = realloc(input, sizeof(char)*size)) == NULL) { perror("realloc"); exit(EXIT_FAILURE); } memset(input+count, '\0', (sizeof(char)*size)-count); } } lastchar = in; if(((char)in) == '0' || ((char)in) == 'x' || ((char)in) == 'X') continue; *(input+count) = (char) in; count++; if(size == count) { size += 100; if((input = realloc(input, sizeof(char)*size)) == NULL) { perror("realloc"); exit(EXIT_FAILURE); } memset(input+count, '\0', (sizeof(char)*size)-count); } } if(*(input) == '\0') return; tcsetattr(0, TCSANOW, &oldterm); long number; sscanf(input, "%lx", &number); printf("In decimal: %d\n", number); if(output != NULL) fprintf(outfile, "%d\n", number); return; }Download