dsniff  2.4b2
About: A collection of tools for network auditing
  Fossies Dox: dsniff-2.4b2.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

webspy.c
Go to the documentation of this file.
1 /*
2  * webspy.c
3  *
4  * Sniff a user's web session, follow it real-time in our browser.
5  *
6  * Copyright (c) 1999 Dug Song <dugsong@monkey.org>
7  *
8  * $Id: webspy.c,v 1.28 2001/03/15 08:33:05 dugsong Exp $
9  */
10 
11 #include "config.h"
12 
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <netinet/in.h>
16 #include <arpa/inet.h>
17 #include <netdb.h>
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <err.h>
24 #include <X11/Xlib.h>
25 #include <libnet.h>
26 #include <nids.h>
27 
28 #include "base64.h"
29 #include "buf.h"
30 #include "version.h"
31 
32 /* for jwz's remote.c. */
33 extern int mozilla_remote_commands (Display *, Window, char **);
35 char *progname = "webspy";
36 
37 Display *dpy;
38 char cmd[2048], *cmdtab[2];
40 libnet_t *l;
41 
42 static void
43 usage(void)
44 {
45  fprintf(stderr, "Version: " VERSION "\n"
46  "Usage: %s [-i interface] host\n", progname);
47  exit(1);
48 }
49 
50 static int
51 is_display_uri(char *uri)
52 {
53  static char *good_prefixes[] = { NULL };
54  static char *good_suffixes[] = { ".html", ".htm", "/", ".shtml",
55  ".cgi", ".asp", ".php3", ".txt",
56  ".xml", ".asc", NULL };
57  int len, slen;
58  char **pp, *p;
59 
60  /* Get URI length, without QUERY_INFO */
61  if ((p = strchr(uri, '?')) != NULL) {
62  len = p - uri;
63  }
64  else len = strlen(uri);
65 
66  for (pp = good_suffixes; *pp != NULL; pp++) {
67  if (len < (slen = strlen(*pp))) continue;
68  if (strncasecmp(&uri[len - slen], *pp, slen) == 0)
69  return (1);
70  }
71  for (pp = good_prefixes; *pp != NULL; pp++) {
72  if (len < (slen = strlen(*pp))) continue;
73  if (strncasecmp(uri, *pp, slen) == 0)
74  return (1);
75  }
76  return (0);
77 }
78 
79 /*
80  XXX - we should really be sniffing (and HTML-parsing) the returned
81  pages, not just the request URLs. this is why we don't handle
82  frames, some CGIs, banner ads, etc. correctly.
83 */
84 static int
85 process_http_request(struct tuple4 *addr, u_char *data, int len)
86 {
87  struct buf *msg, buf;
88  char *p, *req, *uri, *vhost, *auth;
89  int i;
90 
91  buf_init(&buf, data, len);
92 
93  while ((i = buf_index(&buf, "\r\n\r\n", 4)) >= 0) {
94  msg = buf_tok(&buf, NULL, i);
95  msg->base[msg->end] = '\0';
96  buf_skip(&buf, 4);
97 
98  req = strtok(buf_ptr(msg), "\r\n");
99 
100  if (strncmp(req, "GET ", 4) != 0 &&
101  strncmp(req, "POST ", 5) != 0 &&
102  strncmp(req, "CONNECT ", 8) != 0)
103  continue;
104 
105  vhost = auth = NULL;
106  uri = strchr(req, ' '); *uri++ = '\0'; strtok(uri, " ");
107 
108  if (strncmp(uri, "http://", 7) == 0) {
109  vhost = uri + 7;
110  uri = strchr(vhost, '/');
111  memmove(uri + 1, uri, strlen(uri));
112  }
113  if (!is_display_uri(uri))
114  continue;
115 
116  while ((p = strtok(NULL, "\r\n")) != NULL) {
117  if (strncasecmp(p, "Authorization: Basic ", 21) == 0) {
118  p += 21;
119  i = base64_pton(p, p, strlen(p));
120  p[i] = '\0';
121  auth = p;
122  }
123  else if (strncasecmp(p, "Host: ", 6) == 0) {
124  vhost = p + 6;
125  }
126  }
127  if (auth == NULL)
128  auth = "";
129  if (vhost == NULL)
130  vhost = libnet_addr2name4(addr->daddr, 0);
131 
132  snprintf(cmd, sizeof(cmd), "openURL(http://%s%s%s%s)",
133  auth, *auth ? "@" : "", vhost, uri);
134  fprintf(stderr, "%s\n", cmd);
135 
137  }
138  return (len - buf_len(&buf));
139 }
140 
141 static void
142 sniff_http_client(struct tcp_stream *ts, void **yoda)
143 {
144  int i;
145 
146  /* Only handle HTTP client traffic. */
147  if (ts->addr.saddr != host ||
148  (ts->addr.dest != 80 && ts->addr.dest != 3128 &&
149  ts->addr.dest != 8080))
150  return;
151 
152  switch (ts->nids_state) {
153  case NIDS_JUST_EST:
154  /* Collect data. */
155  ts->server.collect = 1;
156 
157  case NIDS_DATA:
158  if (ts->server.count_new != 0) {
159  i = process_http_request(&ts->addr, ts->server.data,
160  ts->server.count -
161  ts->server.offset);
162  nids_discard(ts, i);
163  }
164  break;
165 
166  default:
167  if (ts->server.count != 0) {
168  process_http_request(&ts->addr, ts->server.data,
169  ts->server.count -
170  ts->server.offset);
171  }
172  break;
173  }
174 }
175 
176 static void
177 null_syslog(int type, int errnum, struct ip *iph, void *data)
178 {
179 }
180 
181 int
182 main(int argc, char *argv[])
183 {
184  extern char *optarg;
185  extern int optind;
186  int c;
187  char errbuf[LIBNET_ERRBUF_SIZE];
188 
189  l = libnet_init(
190  LIBNET_RAW4, /* or LIBNET_LINK or LIBNET_RAW6 */
191  NULL, /* or device if you using LIBNET_LINK */
192  errbuf);
193 
194 
195  while ((c = getopt(argc, argv, "i:h?V")) != -1) {
196  switch (c) {
197  case 'i':
198  nids_params.device = optarg;
199  break;
200  default:
201  usage();
202  }
203  }
204  argc -= optind;
205  argv += optind;
206 
207  if (argc != 1)
208  usage();
209 
210  cmdtab[0] = cmd;
211  cmdtab[1] = NULL;
212 
213  if ((host = libnet_name2addr4(l,argv[0], 1)) == -1)
214  errx(1, "unknown host");
215 
216  if ((dpy = XOpenDisplay(NULL)) == NULL)
217  errx(1, "connection to local X server failed!");
218 
219  nids_params.scan_num_hosts = 0;
220  nids_params.syslog = null_syslog;
221 
222  if (!nids_init())
223  errx(1, "%s", nids_errbuf);
224 
225  nids_register_tcp(sniff_http_client);
226 
227  warnx("listening on %s", nids_params.device);
228 
229  nids_run();
230 
231  /* NOTREACHED */
232 
233  exit(0);
234 }
warnx
void warnx(const char *fmt,...)
Definition: err.c:89
sniff_http_client
static void sniff_http_client(struct tcp_stream *ts, void **yoda)
Definition: webspy.c:142
buf_init
void buf_init(buf_t buf, u_char *data, int len)
Definition: buf.c:24
main
int main(int argc, char *argv[])
Definition: webspy.c:182
buf::base
u_char * base
Definition: buf.h:15
buf
static u_char buf[BUFSIZ]
Definition: filenamesnarf.c:29
version.h
errbuf
char errbuf[LIBNET_ERRBUF_SIZE]
Definition: arpspoof.c:35
buf.h
process_http_request
static int process_http_request(struct tuple4 *addr, u_char *data, int len)
Definition: webspy.c:85
host
u_int32_t host
Definition: webspy.c:39
cmd
char cmd[2048]
Definition: webspy.c:38
err.h
l
libnet_t * l
Definition: webspy.c:40
VERSION
#define VERSION
Definition: version.h:1
buf
Definition: buf.h:14
base64.h
buf_tok
buf_t buf_tok(buf_t buf, void *sep, int len)
Definition: buf.c:167
buf_ptr
#define buf_ptr(b)
Definition: buf.h:31
errx
void errx(int eval, const char *fmt,...)
Definition: err.c:76
dpy
Display * dpy
Definition: webspy.c:37
mozilla_remote_commands
int mozilla_remote_commands(Display *, Window, char **)
Definition: remote.c:508
null_syslog
static void null_syslog(int type, int errnum, struct ip *iph, void *data)
Definition: webspy.c:177
base64_pton
int base64_pton(char const *src, u_char *target, size_t targsize)
Definition: base64.c:128
in_addr_t
#define in_addr_t
Definition: config.h:32
expected_mozilla_version
char * expected_mozilla_version
Definition: webspy.c:34
usage
static void usage(void)
Definition: webspy.c:43
buf_skip
#define buf_skip(b, l)
Definition: buf.h:47
buf::end
int end
Definition: buf.h:18
progname
char * progname
Definition: webspy.c:35
config.h
buf_len
#define buf_len(b)
Definition: buf.h:34
is_display_uri
static int is_display_uri(char *uri)
Definition: webspy.c:51
cmdtab
char * cmdtab[2]
Definition: webspy.c:38
buf_index
int buf_index(buf_t buf, void *ptr, int len)
Definition: buf.c:128