/* ** write() shellcode tool (linux x86) ** ** This utility will generate linux x86 shellcode ** that will display your custom text. ** ** NOTE: If hex code fails try convert generated asm code ** into hex. ** ** copyright (c) 2004 konewka ** www.priv8security.com */ #include #include #include #include #define RED "\033[01;31m" #define NORM "\033[00;00m" #define WRITE_CALL 04 #define EXIT_CALL 01 void usage(char *progname); void asm_code(char *str, int size); void hex_code(char *str, int size); void clear_int(int inc[], int size); int new_line = 1, do_asm = 0; void usage(char *progname) { printf("["RED"+"NORM"] write() shellcode tool -linux x86- (www.priv8security.com)\n"); printf("\nusage: %s [options] <-s string>\n", progname); printf("\t-s \tstring to use in shellcode\n"); printf("\t-a \tcreate assembler code\n"); printf("\t-n \tdo not add new line at the end\n\n"); exit(0); } void clear_int(int inc[], int size) { int i; for (i=0;i<=size;i++) inc[i] = 0; } void hex_code(char *str, int size) { int i, j, hex[3]; printf("char *shellcode = "); printf("\"\\x31\\xdb\\x31\\xc9\\x31\\xd2\\xb2\\x%02x\"\n", size); printf("\t\"\\x51"); for (i=size,j=-1;i>=0;) { hex[j++] = str[i--]; if (j >= 4) { printf("\\x68\\x%02x\\x%02x\\x%02x\\x%02x", hex[3], hex[2], hex[1], hex[0]); clear_int(hex, 3); j = 0; } } if (j) printf("\\x68\\x%02x\\x%02x\\x%02x\\x%02x", hex[3], hex[2], hex[1], hex[0]); printf("\"\n\t\"\\x89\\xe1\\x31\\xc0\\xb0\\x%02x\\xcd\\x80\\x31\\xdb\\xb0\\x%02x\"\n", WRITE_CALL, EXIT_CALL); printf("\t\"\\xcd\\x80\";\n"); printf("\nint main(void) {\n"); printf("\tint *ret;\n\n"); printf("\tret = (int *)&ret + 2;\n"); printf("\t*ret = (int)shellcode;\n}\n"); } void asm_code(char *str, int size) { int i, j, hex[3]; printf("int main(void) {\n"); printf("asm(\"\n"); printf("\txor %%ebx,%%ebx\n\txor %%ecx,%%ecx\n\txor %%edx,%%edx\n"); printf("\tmov $0x%x,%%%s\n", size, (size > 255) ? "dx" : "dl"); printf("\tpush %%ecx\n"); for (i=size,j=-1;i>=0;) { hex[j++] = str[i--]; if (j >= 4) { printf("\tpush $0x%02x%02x%02x%02x\n", hex[0], hex[1], hex[2], hex[3]); clear_int(hex, 3); j = 0; } } if (j) printf("\tpush $0x%02x%02x%02x%02x\n", hex[0], hex[1], hex[2], hex[3]); printf("\tmov %%esp,%%ecx\n"); printf("\txor %%eax,%%eax\n"); printf("\tmov $0x%02x,%%al\n", WRITE_CALL); printf("\tint $0x80\n"); printf("\txor %%ebx,%%ebx\n"); printf("\tmov $0x%02x,%%al\n", EXIT_CALL); printf("\tint $0x80\");\n"); printf("}\n"); } int main(int argc, char *argv[]) { char *string = NULL; int opt; while ((opt = getopt(argc, argv, "anhs:")) != EOF) { switch (opt) { case 'n': new_line = 0; break; case 'h': usage(argv[0]); break; case 'a': do_asm = 1; break; case 's': if (strlen(optarg) >= 4096) { printf("["RED"!"NORM"] entered string is too long\n"); return -1; } if (!(string = (char *)calloc(strlen(optarg), sizeof(char)))) { printf("["RED"!"NORM"] cannot allocate memory for buffer\n"); return -1; } strncpy(string, optarg, strlen(optarg)); break; default: break; } } if (!string) usage(argv[0]); if (strlen(string)%4) printf("["RED"!"NORM"] WARNING: string should contain 4,8,16.. characters to avoid NULLs\n"); if (new_line) strncat(string, "\n", strlen(string)); if (do_asm) asm_code(string, strlen(string)); else hex_code(string, strlen(string)); return 0; }