home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / sectools / dsniff / trigger.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-18  |  12.8 KB  |  577 lines

  1. /*
  2.   trigger.c
  3.  
  4.   Copyright (c) 2000 Dug Song <dugsong@monkey.org>
  5.   
  6.   $Id: trigger.c,v 1.8 2000/05/18 20:20:04 dugsong Exp $
  7. */
  8.  
  9. #include "config.h"
  10. #include <sys/types.h>
  11. #include <sys/uio.h>
  12. #include <stdlib.h>
  13. #ifdef HAVE_ERR_H
  14. #include <err.h>
  15. #endif
  16. #include <libnet.h>
  17. #include <nids.h>
  18. #include "options.h"
  19. #include "decode.h"
  20. #include "record.h"
  21. #include "tcp_raw.h"
  22. #include "trigger.h"
  23.  
  24. #define SERVICES_FILE    "dsniff.services"
  25.  
  26. struct trigger {
  27.     int num;
  28.     struct decode *decode;
  29. };
  30.  
  31. static struct trigger    ip_triggers[32];
  32. static struct trigger    udp_triggers[512];
  33. static struct trigger    tcp_triggers[512];
  34. static struct trigger    rpc_triggers[32];
  35.  
  36. static u_int        ip_cnt = 0;
  37. static u_int        udp_cnt = 0;
  38. static u_int        tcp_cnt = 0;
  39. static u_int        rpc_cnt = 0;
  40.  
  41. static int
  42. trigger_compare(const void *a, const void *b)
  43. {
  44.     struct trigger *p, *q;
  45.  
  46.     q = (struct trigger *)a;
  47.     p = (struct trigger *)b;
  48.     
  49.     if (p->num < q->num) {
  50.         return (-1);
  51.     }
  52.     else if (p->num > q->num) {
  53.         return (1);
  54.     }
  55.     return (0);
  56. }
  57.  
  58. int
  59. trigger_set_ip(int num, char *name)
  60. {
  61.     struct trigger *t, tr;
  62.  
  63.     tr.num = num;
  64.     
  65.     if ((tr.decode = getdecodebyname(name)) == NULL) {
  66.         warnx("trigger_set_ip: unknown decode: %s", name);
  67.         return (0);
  68.     }
  69.     t = (struct trigger *) bsearch(&tr, &ip_triggers, ip_cnt,
  70.                        sizeof(tr), trigger_compare);
  71.     if (t != NULL) {
  72.         if (Opt_debug)
  73.             warnx("trigger_set_ip: proto %d already set", num);
  74.         return (0);
  75.     }
  76.     if (ip_cnt == sizeof(ip_triggers) / sizeof(tr)) {
  77.         warnx("trigger_set_ip: ip_triggers full");
  78.         return (0);
  79.     }
  80.     ip_triggers[ip_cnt++] = tr;
  81.     
  82.     qsort(&ip_triggers, ip_cnt, sizeof(tr), trigger_compare);
  83.     
  84.     if (Opt_debug)
  85.         warnx("trigger_set_ip: proto %d -> %s", num, name);
  86.     
  87.     return (1);
  88. }
  89.  
  90. int
  91. trigger_set_udp(int num, char *name)
  92. {
  93.     struct trigger *t, tr;
  94.     
  95.     tr.num = num;
  96.     
  97.     if ((tr.decode = getdecodebyname(name)) == NULL) {
  98.         warnx("trigger_set_udp: unknown decode: %s", name);
  99.         return (0);
  100.     }
  101.     t = (struct trigger *) bsearch(&tr, &udp_triggers, udp_cnt,
  102.                        sizeof(tr), trigger_compare);
  103.     if (t != NULL) {
  104.         if (Opt_debug)
  105.             warnx("trigger_set_udp: port %d already set", num);
  106.         return (0);
  107.     }
  108.     if (udp_cnt == sizeof(udp_triggers) / sizeof(tr)) {
  109.         warnx("trigger_set_udp: udp_triggers full");
  110.         return (0);
  111.     }
  112.     udp_triggers[udp_cnt++] = tr;
  113.     
  114.     qsort(&udp_triggers, udp_cnt, sizeof(tr), trigger_compare);
  115.     
  116.     if (Opt_debug)
  117.         warnx("trigger_set_udp: port %d -> %s", num, name);
  118.  
  119.     return (1);
  120. }
  121.  
  122. int
  123. trigger_set_tcp(int num, char *name)
  124. {
  125.     struct trigger *t, tr;
  126.     
  127.     tr.num = num;
  128.     
  129.     if ((tr.decode = getdecodebyname(name)) == NULL) {
  130.         warnx("trigger_set_tcp: unknown decode: %s", name);
  131.         return (0);
  132.     }
  133.     t = (struct trigger *) bsearch(&tr, &tcp_triggers, tcp_cnt,
  134.                        sizeof(tr), trigger_compare);
  135.     if (t != NULL) {
  136.         if (Opt_debug)
  137.             warnx("trigger_set_tcp: port %d already set", num);
  138.         return (0);
  139.     }
  140.     if (tcp_cnt == sizeof(tcp_triggers) / sizeof(tr)) {
  141.         warnx("trigger_set_tcp: tcp_triggers full");
  142.         return (0);
  143.     }
  144.     tcp_triggers[tcp_cnt++] = tr;
  145.     
  146.     qsort(&tcp_triggers, tcp_cnt, sizeof(tr), trigger_compare);
  147.     
  148.     if (Opt_debug)
  149.         warnx("trigger_set_tcp: port %d -> %s", num, name);
  150.     
  151.     return (1);
  152. }
  153.  
  154. int
  155. trigger_set_rpc(int num, char *name)
  156. {
  157.     struct trigger *t, tr;
  158.  
  159.     tr.num = num;
  160.     
  161.     if ((tr.decode = getdecodebyname(name)) == NULL) {
  162.         warnx("trigger_set_tcp: unknown decode: %s", name);
  163.         return (0);
  164.     }
  165.     t = (struct trigger *) bsearch(&tr, &rpc_triggers, rpc_cnt,
  166.                        sizeof(tr), trigger_compare);
  167.     if (t != NULL) {
  168.         if (Opt_debug)
  169.             warnx("trigger_set_rpc: RPC program %d already set",
  170.                   num);
  171.         return (0);
  172.     }
  173.     if (rpc_cnt == sizeof(rpc_triggers) / sizeof(tr)) {
  174.         warnx("trigger_set_rpc: rpc_triggers full");
  175.         return (0);
  176.     }
  177.     rpc_triggers[rpc_cnt++] = tr;
  178.     
  179.     qsort(&rpc_triggers, rpc_cnt, sizeof(tr), trigger_compare);
  180.     
  181.     if (Opt_debug)
  182.         warnx("trigger_set_rpc: program %d -> %s", num, name);
  183.     
  184.     return (1);
  185. }
  186.  
  187. void
  188. trigger_dump(void)
  189. {
  190.     FILE *f;
  191.     int i;
  192.  
  193.     if ((f = fopen(SERVICES_FILE, "w")) == NULL) {
  194.         warn("trigger_dump: couldn't open " SERVICES_FILE);
  195.         return;
  196.     }
  197.     fprintf(f, "# $Id: trigger.c,v 1.8 2000/05/18 20:20:04 dugsong Exp $\n"
  198.         "#\n# Network services, dsniff style\n#\n");
  199.     
  200.     for (i = 0; i < ip_cnt; i++) {
  201.         fprintf(f, "%s\t\t%d/ip\n", ip_triggers[i].decode->dc_name,
  202.             ip_triggers[i].num);
  203.     }
  204.     for (i = 0; i < udp_cnt; i++) {
  205.         fprintf(f, "%s\t\t%d/udp\n", udp_triggers[i].decode->dc_name,
  206.             udp_triggers[i].num);
  207.     }
  208.     for (i = 0; i < tcp_cnt; i++) {
  209.         fprintf(f, "%s\t\t%d/tcp\n", tcp_triggers[i].decode->dc_name,
  210.             tcp_triggers[i].num);
  211.     }
  212.     for (i = 0; i < rpc_cnt; i++) {
  213.         fprintf(f, "%s\t\t%d/rpc\n", rpc_triggers[i].decode->dc_name,
  214.             rpc_triggers[i].num);
  215.     }
  216.     fclose(f);
  217. }
  218.     
  219. void
  220. trigger_ip(struct ip *ip)
  221. {
  222.     struct trigger *t, tr;
  223.     u_char *buf;
  224.     int len;
  225.  
  226.     tr.num = ip->ip_p;
  227.     
  228.     t = (struct trigger *) bsearch(&tr, &ip_triggers, ip_cnt,
  229.                        sizeof(tr), trigger_compare);
  230.     if (t == NULL)
  231.         return;
  232.     
  233.     buf = (u_char *)ip + (ip->ip_hl * 4);
  234.     len = ntohs(ip->ip_len) - (ip->ip_hl * 4);
  235.     
  236.     if (Opt_debug)
  237.         warnx("trigger_ip: decoding proto %d as %s",
  238.               tr.num, t->decode->dc_name);
  239.     
  240.     if ((len = t->decode->dc_func(buf, len)) > 0) {
  241.         record(ip->ip_src.s_addr, ip->ip_dst.s_addr, ip->ip_p,
  242.                0, 0, t->decode->dc_name, Buf, len);
  243.     }        
  244. }
  245.  
  246. /* libnids needs a nids_register_udp()... */
  247. void
  248. trigger_udp(struct ip *ip)
  249. {
  250.     struct trigger *t, tr;
  251.     struct udphdr *udp;
  252.     u_char *buf;
  253.     int len, ip_hl = ip->ip_hl * 4;
  254.     
  255.     len = ntohs(ip->ip_len) - ip_hl;
  256.     
  257.     if (ip->ip_p != IPPROTO_UDP || len < sizeof(*udp))
  258.         return;
  259.  
  260.     buf = (u_char *)ip + ip_hl;
  261.     udp = (struct udphdr *)buf;
  262.     
  263.     if (len != ntohs(udp->uh_ulen))
  264.         return;
  265.     
  266.     tr.num = ntohs(udp->uh_dport);
  267.     
  268.     t = (struct trigger *) bsearch(&tr, &udp_triggers, udp_cnt,
  269.                        sizeof(tr), trigger_compare);
  270.     if (t == NULL) {
  271.         tr.num = 0 - (int) ntohs(udp->uh_sport);
  272.         t = (struct trigger *) bsearch(&tr, &udp_triggers, udp_cnt,
  273.                            sizeof(tr), trigger_compare);
  274.         if (t == NULL)
  275.             return;
  276.     }
  277.     buf += sizeof(*udp);
  278.     len -= sizeof(*udp);
  279.  
  280.     if (Opt_debug)
  281.         warnx("trigger_udp: decoding port %d as %s",
  282.               tr.num, t->decode->dc_name);
  283.     
  284.     if ((len = t->decode->dc_func(buf, len)) > 0) {
  285.         record(ip->ip_src.s_addr, ip->ip_dst.s_addr, IPPROTO_UDP,
  286.                ntohs(udp->uh_sport), ntohs(udp->uh_dport),
  287.                t->decode->dc_name, Buf, len);
  288.     }
  289. }
  290.  
  291. static void
  292. trigger_tcp_half(struct tuple4 *addr, struct half_stream *hs,
  293.          struct trigger *t)
  294. {
  295.     u_char *buf;
  296.     int len;
  297.     
  298.     buf = hs->data;
  299.     len = hs->count - hs->offset;
  300.     
  301.     if (hs->bufsize > len)
  302.         buf[len] = '\0';
  303.  
  304.     if (Opt_debug)
  305.         warnx("trigger_tcp: decoding port %d as %s",
  306.               addr->dest, t->decode->dc_name);
  307.     
  308.     if ((len = t->decode->dc_func(buf, len)) > 0) {
  309.         record(addr->saddr, addr->daddr, IPPROTO_TCP,
  310.                addr->source, addr->dest, t->decode->dc_name, Buf, len);
  311.     }
  312.     hs->collect = 0;
  313. }
  314.  
  315. void
  316. trigger_tcp(struct tcp_stream *ts, void **conn_save)
  317. {
  318.     struct trigger *ct, *st, tr;
  319.     
  320.     tr.num = ts->addr.dest;
  321.     ct = (struct trigger *) bsearch(&tr, &tcp_triggers, tcp_cnt,
  322.                     sizeof(tr), trigger_compare);
  323.     
  324.     tr.num = 0 - (int) ts->addr.dest;
  325.     st = (struct trigger *) bsearch(&tr, &tcp_triggers, tcp_cnt,
  326.                     sizeof(tr), trigger_compare);
  327.     
  328.     switch (ts->nids_state) {
  329.  
  330.     case NIDS_JUST_EST:
  331.         if (ct != NULL) {
  332.             ts->server.collect = 1;
  333.         }
  334.         if (st != NULL) {
  335.             ts->client.collect = 1;
  336.         }
  337.         break;
  338.  
  339.     case NIDS_DATA:
  340.         if (ct != NULL && ts->server.count_new) {
  341.             if (ts->server.count - ts->server.offset >=
  342.                 Opt_snaplen) {
  343.                 trigger_tcp_half(&ts->addr, &ts->server, ct);
  344.             }
  345.             else nids_discard(ts, 0);
  346.         }
  347.         else if (st != NULL && ts->client.count_new) {
  348.             if (ts->client.count - ts->client.offset >=
  349.                 Opt_snaplen) {
  350.                 trigger_tcp_half(&ts->addr, &ts->client, st);
  351.             }
  352.             else nids_discard(ts, 0);
  353.         }
  354.         break;
  355.         
  356.     default:
  357.         if (ct != NULL && ts->server.count > 0) {
  358.             trigger_tcp_half(&ts->addr, &ts->server, ct);
  359.         }
  360.         if (st != NULL && ts->client.count > 0) {
  361.             trigger_tcp_half(&ts->addr, &ts->client, st);
  362.         }
  363.         break;
  364.     }
  365. }
  366.  
  367. void
  368. trigger_tcp_raw(struct ip *ip)
  369. {
  370.     struct trigger *t, tr;
  371.     struct tcphdr *tcp;
  372.     struct iovec *iov;
  373.     int len, ip_hl = ip->ip_hl * 4;
  374.     
  375.     len = ntohs(ip->ip_len) - ip_hl;
  376.  
  377.     if (ip->ip_p != IPPROTO_TCP || len < sizeof(*tcp))
  378.         return;
  379.  
  380.     tcp = (struct tcphdr *)((u_char *)ip + ip_hl);
  381.     
  382.     tr.num = ntohs(tcp->th_dport);
  383.     
  384.     t = (struct trigger *) bsearch(&tr, &tcp_triggers, tcp_cnt,
  385.                        sizeof(tr), trigger_compare);
  386.     if (t == NULL) {
  387.         tr.num = 0 - (int) ntohs(tcp->th_sport);
  388.         t = (struct trigger *) bsearch(&tr, &tcp_triggers, tcp_cnt,
  389.                            sizeof(tr), trigger_compare);
  390.         if (t == NULL)
  391.             return;
  392.     }
  393.     if ((iov = tcp_raw_input(ip, tcp, len)) == NULL)
  394.         return;
  395.     
  396.     if (Opt_debug)
  397.         warnx("trigger_tcp_raw: decoding port %d as %s",
  398.               tr.num, t->decode->dc_name);
  399.     
  400.     if ((len = t->decode->dc_func(iov->iov_base, iov->iov_len)) > 0) {
  401.         record(ip->ip_src.s_addr, ip->ip_dst.s_addr, IPPROTO_TCP,
  402.                ntohs(tcp->th_sport), ntohs(tcp->th_dport),
  403.                t->decode->dc_name, Buf, len);
  404.     }
  405.     free(iov->iov_base);
  406.     free(iov);
  407. }
  408.  
  409. static void
  410. trigger_tcp_raw_callback(u_long src, u_long dst,
  411.              u_short sport, u_short dport,
  412.              u_char *buf, int len)
  413. {
  414.     struct trigger *t, tr;
  415.  
  416.     tr.num = dport;
  417.  
  418.     t = (struct trigger *) bsearch(&tr, &tcp_triggers, tcp_cnt,
  419.                        sizeof(tr), trigger_compare);
  420.     if (t == NULL)
  421.         return;
  422.  
  423.     if (Opt_debug)
  424.         warnx("trigger_tcp_raw_timeout: decoding port %d as %s",
  425.               tr.num, t->decode->dc_name);
  426.  
  427.     if ((len = t->decode->dc_func(buf, len)) > 0) {
  428.         record(src, dst, IPPROTO_TCP, sport, dport,
  429.                t->decode->dc_name, Buf, len);
  430.     }
  431. }
  432.  
  433. void
  434. trigger_tcp_raw_timeout(int signal)
  435. {
  436.     tcp_raw_timeout(TRIGGER_TCP_RAW_TIMEOUT, trigger_tcp_raw_callback);
  437.     alarm(TRIGGER_TCP_RAW_TIMEOUT);
  438. }
  439.  
  440. void
  441. trigger_rpc(int program, int proto, int port)
  442. {
  443.     struct trigger *t, tr;
  444.  
  445.     tr.num = program;
  446.  
  447.     t = (struct trigger *) bsearch(&tr, &rpc_triggers, rpc_cnt,
  448.                        sizeof(tr), trigger_compare);
  449.     if (t == NULL)
  450.         return;
  451.  
  452.     if (proto == IPPROTO_UDP) {
  453.         trigger_set_udp(port, t->decode->dc_name);
  454.     }
  455.     else if (proto == IPPROTO_TCP) {
  456.         trigger_set_tcp(port, t->decode->dc_name);
  457.     }
  458. }
  459.     
  460. static void
  461. trigger_init_default(void)
  462. {
  463.     trigger_set_ip(89,    "ospf");
  464.     
  465.     trigger_set_udp(111,    "portmap");
  466.     trigger_set_udp(-111,    "portmap");
  467.     trigger_set_udp(161,    "snmp");
  468.     trigger_set_udp(417,    "mmxp");
  469.     trigger_set_udp(2417,    "mmxp");
  470.     trigger_set_udp(520,    "rip");
  471.     trigger_set_udp(2001,    "sniffer");
  472.     trigger_set_udp(4000,    "icq");
  473.  
  474.     trigger_set_tcp(21,    "ftp");
  475.     trigger_set_tcp(23,    "telnet");
  476.     trigger_set_tcp(80,    "http");
  477.     trigger_set_tcp(98,    "http");
  478.     trigger_set_tcp(3128,    "http");
  479.     trigger_set_tcp(8080,    "http");
  480.     trigger_set_tcp(106,    "poppass");
  481.     trigger_set_tcp(109,    "pop");
  482.     trigger_set_tcp(110,    "pop");
  483.     trigger_set_tcp(111,    "portmap");
  484.     trigger_set_tcp(-111,    "portmap");
  485.     trigger_set_tcp(119,    "nntp");
  486.     trigger_set_tcp(139,    "smb");
  487.     trigger_set_tcp(143,    "imap");
  488.     trigger_set_tcp(220,    "imap");
  489.     trigger_set_tcp(389,    "ldap");
  490.     trigger_set_tcp(417,    "mmxp");
  491.     trigger_set_tcp(2417,    "mmxp");
  492.     trigger_set_tcp(513,    "rlogin");
  493.     trigger_set_tcp(514,    "rlogin");
  494.     trigger_set_tcp(1080,    "socks");
  495.     trigger_set_tcp(1494,    "citrix");
  496.     trigger_set_tcp(1521,    "oracle");
  497.     trigger_set_tcp(1526,    "oracle");
  498.     trigger_set_tcp(2401,    "cvs");
  499.     trigger_set_tcp(4444,    "napster");
  500.     trigger_set_tcp(5555,    "napster");
  501.     trigger_set_tcp(6666,    "napster");
  502.     trigger_set_tcp(7777,    "napster");
  503.     trigger_set_tcp(8888,    "napster");
  504.     trigger_set_tcp(5190,    "aim");
  505.     trigger_set_tcp(9898,    "aim");
  506.     trigger_set_tcp(5432,    "postgresql");
  507.     trigger_set_tcp(5631,    "pcanywhere");
  508.     trigger_set_tcp(65301,    "pcanywhere");
  509.     trigger_set_tcp(6000,    "x11");
  510.     trigger_set_tcp(6001,    "x11");
  511.     trigger_set_tcp(6002,    "x11");
  512.     trigger_set_tcp(6003,    "x11");
  513.     trigger_set_tcp(6004,    "x11");
  514.     trigger_set_tcp(6005,    "x11");
  515.     trigger_set_tcp(6667,    "irc");
  516.     trigger_set_tcp(6668,    "irc");
  517.     trigger_set_tcp(6669,    "irc");
  518.  
  519.     trigger_set_rpc(100005,    "mountd");
  520.     trigger_set_rpc(100009,    "yppasswd");
  521. }
  522.  
  523. void
  524. trigger_init(char *services)
  525. {
  526.     FILE *f;
  527.     char *name, *port, *proto, line[1024];
  528.     int num;
  529.  
  530.     ip_cnt = 0;
  531.     udp_cnt = 0;
  532.     tcp_cnt = 0;
  533.     rpc_cnt = 0;
  534.     
  535.     memset((char *)&ip_triggers, 0, sizeof(ip_triggers));
  536.     memset((char *)&udp_triggers, 0, sizeof(udp_triggers));
  537.     memset((char *)&tcp_triggers, 0, sizeof(tcp_triggers));
  538.     memset((char *)&rpc_triggers, 0, sizeof(rpc_triggers));
  539.  
  540.     if (services == NULL) {
  541.         trigger_init_default();
  542.         return;
  543.     }
  544.     if ((f = fopen(services, "r")) == NULL)
  545.         errx(1, "trigger_init: couldn't open %s", services);
  546.     
  547.     while (fgets(line, sizeof(line), f) != NULL) {
  548.         if (line[0] == '#' || line[0] == '\n')
  549.             continue;
  550.         
  551.         name = strtok(line, " \t");
  552.         port = strtok(NULL, " \t/");
  553.         proto = strtok(NULL, " \t#\n");
  554.  
  555.         if (!name || !port || !proto)
  556.             continue;
  557.  
  558.         if ((num = atoi(port)) == 0)
  559.             continue;
  560.  
  561.         if (strcasecmp(proto, "ip") == 0) {
  562.             trigger_set_ip(num, name);
  563.         }
  564.         else if (strcasecmp(proto, "udp") == 0) {
  565.             trigger_set_udp(num, name);
  566.         }
  567.         else if (strcasecmp(proto, "tcp") == 0) {
  568.             trigger_set_tcp(num, name);
  569.         }
  570.         else if (strcasecmp(proto, "rpc") == 0) {
  571.             trigger_set_rpc(num, name);
  572.         }
  573.     }
  574.     fclose(f);
  575. }
  576.  
  577.