From: areq Date: Tue, 5 Nov 2002 00:11:50 +0000 (+0000) Subject: - ggsniff 1.2 X-Git-Tag: RA-1_0 X-Git-Url: http://git.pld-linux.org/?p=packages%2Fdsniff.git;a=commitdiff_plain;h=a7448750c166506d653361711dd24b05d62e0b14 - ggsniff 1.2 Changed files: dsniff-gg.patch -> 1.2 --- diff --git a/dsniff-gg.patch b/dsniff-gg.patch index 1247372..2d6e4e3 100644 --- a/dsniff-gg.patch +++ b/dsniff-gg.patch @@ -1,7 +1,54 @@ +diff -urN dsniff-2.3/ChangeLog.ggsniff dsniff-2.3-gg/ChangeLog.ggsniff +--- dsniff-2.3/ChangeLog.ggsniff Thu Jan 1 01:00:00 1970 ++++ dsniff-2.3-gg/ChangeLog.ggsniff Wed Oct 30 14:49:43 2002 +@@ -0,0 +1,37 @@ ++BUGS: ++ - dsniff doesn't compile with newest libnet, use older version (1.0.x) ++ ++ ++2002.10.30 v1.2 ++ - added password sniffing (switch -w) ++ ++2002.10.22 v1.1d ++ - sometimes local user's nick was incorrectly displayed ++ - added switch -s for simple output (without IP addresses) ++ - updated man page for msgsnarf ++ - added short documentation for ggsniff ++ ++2002.09.13 v1.1c ++ - fixed silly "cut&paste" bug ++ ++2002.09.12 v1.1b ++ - fixed silly segfault in process_gg() ++ ++2002.09.11 v1.1 ++ - added printing remote GG user's IP (if available) ++ ++2002.09.03 v1.1-beta ++ - fixed segfault in process_msn() [dsniff-2.3-segfault.patch] ++ - added switch -d for debugging info ++ - added switch -p for disabling promiscous mode (useful on routers) ++[dsniff-2.3-promisc.patch] ++ - sniffer recognizes data direction ++ - different connections from single IP do not share client_info ++ - sniffing GG connections to port 443 ++ - support for extensions in new GG protocol (client version 4.9.3+) ++ ++2002.04.26 v1.01 ++ - added printing local GG user's IP ++ ++2002.03.20 v1.0 ++ - first release diff -urN dsniff-2.3/msgsnarf.8 dsniff-2.3-gg/msgsnarf.8 --- dsniff-2.3/msgsnarf.8 Sun Nov 19 07:10:50 2000 -+++ dsniff-2.3-gg/msgsnarf.8 Tue Mar 26 11:29:29 2002 -@@ -14,7 +14,7 @@ ++++ dsniff-2.3-gg/msgsnarf.8 Wed Oct 30 12:28:00 2002 +@@ -9,16 +9,24 @@ + .na + .nf + .fi +-\fBmsgsnarf\fR [\fB-i \fIinterface\fR] [[\fB-v\fR] \fIpattern [\fIexpression\fR]] ++\fBmsgsnarf\fR [\fB-d\fR] [\fB-p\fR] [\fB-s\fR] [\fB-w\fR] [\fB-i \fIinterface\fR] [[\fB-v\fR] \fIpattern [\fIexpression\fR]] + .SH DESCRIPTION .ad .fi \fBmsgsnarf\fR records selected messages from AOL Instant @@ -9,11 +56,23 @@ diff -urN dsniff-2.3/msgsnarf.8 dsniff-2.3-gg/msgsnarf.8 +Messenger, ICQ 2000, IRC, MSN Messenger, Gadu-Gadu, or Yahoo Messenger chat sessions. .SH OPTIONS ++.IP \fB-d\fR ++Debug mode (prints more information about Gadu-Gadu connections). .IP "\fB-i \fIinterface\fR" + Specify the interface to listen on. ++.IP \fB-p\fR ++Disable promiscous mode. ++.IP \fB-s\fR ++Simple output, without IP addresses. ++.IP \fB-w\fR ++Enable Gadu-Gadu password sniffing. + .IP \fB-v\fR + "Versus" mode. Invert the sense of matching, to select non-matching + messages. diff -urN dsniff-2.3/msgsnarf.c dsniff-2.3-gg/msgsnarf.c --- dsniff-2.3/msgsnarf.c Fri Dec 15 21:12:19 2000 -+++ dsniff-2.3-gg/msgsnarf.c Tue Mar 26 14:09:13 2002 -@@ -1,10 +1,13 @@ ++++ dsniff-2.3-gg/msgsnarf.c Wed Oct 30 12:36:19 2002 +@@ -1,10 +1,10 @@ /* msgsnarf.c @@ -22,34 +81,125 @@ diff -urN dsniff-2.3/msgsnarf.c dsniff-2.3-gg/msgsnarf.c Copyright (c) 1999 Dug Song - -+ -+ 2002.03.20 - support for Gadu-Gadu messages added by Ryba -+ (based on protocol description from EKG, http://dev.null.pl/ekg/) + $Id$ */ -@@ -544,6 +547,112 @@ +@@ -25,23 +25,33 @@ + #include "decode.h" + #include "version.h" + ++#define GGVERSION "1.2" ++#define TO_CLIENT 0 ++#define TO_SERVER 1 ++#define PACKED __attribute__ ((packed)) ++ + struct client_info { + char *nick; + char *peer; + char *type; + in_addr_t ip; ++ unsigned short port; ++ in_addr_t local_ip; + SLIST_ENTRY(client_info) next; + }; + + SLIST_HEAD(, client_info) client_list; + int Opt_invert = 0; + regex_t *pregex = NULL; ++int Opt_debug = 0; ++int Opt_simple = 0; ++int Opt_pass = 0; + + void + usage(void) + { +- fprintf(stderr, "Version: " VERSION "\n" +- "Usage: msgsnarf [-i interface] [[-v] pattern [expression]]\n"); ++ fprintf(stderr, "Version: " VERSION " (ggsniff " GGVERSION ")\n" ++ "Usage: msgsnarf [-d] [-p] [-s] [-w] [-i interface] [[-v] pattern [expression]]\n"); + exit(1); + } + +@@ -81,7 +91,7 @@ + }; + + int +-process_aim(struct client_info *info, u_char *data, int len) ++process_aim(struct client_info *info, u_char *data, int len, int dir) + { + struct buf *msg, *word, buf; + struct flap *flap; +@@ -215,7 +225,7 @@ + } + + int +-process_irc(struct client_info *info, u_char *data, int len) ++process_irc(struct client_info *info, u_char *data, int len, int dir) + { + struct buf *line, *word, *prefix, buf; + char *p; +@@ -336,7 +346,7 @@ + } + + int +-process_msn(struct client_info *info, u_char *data, int len) ++process_msn(struct client_info *info, u_char *data, int len, int dir) + { + struct buf *word, *line, buf; + char *p; +@@ -442,7 +452,7 @@ + }; + + int +-process_yahoo(struct client_info *info, u_char *data, int len) ++process_yahoo(struct client_info *info, u_char *data, int len, int dir) + { + struct yhoo *yhoo; + struct ymsg *ymsg; +@@ -544,11 +554,338 @@ return (len - buf_len(&buf)); } + +/* + Support for GG messages added by Ryba -+ v1.0 ++ v1.2 + + Protocol description taken from EKG (http://dev.null.pl/ekg/) + by , and others. + Thanks to all of them! + + Gadu-Gadu (http://www.gadu-gadu.pl) is a Polish communicator. -+ I believe it is most popular instant messenger in Poland. ++ I believe it is a most popular instant messenger in Poland. +*/ + ++struct remote_client_info { ++ int uin; ++ char *nick; ++ in_addr_t ip; ++ unsigned short port; ++ SLIST_ENTRY(remote_client_info) next; ++}; ++ ++SLIST_HEAD(, remote_client_info) remote_client_list; ++ ++#define GG_NETWORK "217.17.41.80" ++#define GG_NETMASK "255.255.255.248" ++unsigned int gg_network; ++unsigned int gg_netmask; ++ +#define GG_LOGIN 0x000c ++#define GG_LOGIN_EXT 0x0013 +#define GG_SEND_MSG 0x000b +#define GG_RECV_MSG 0x000a -+ ++#define GG_NOTIFY_REPLY 0x000c ++#define GG_NOTIFY 0x0010 ++ ++#define GG_STATUS_NOT_AVAIL_DESCR 0x0015 ++#define GG_STATUS_AVAIL_DESCR 0x0004 ++#define GG_STATUS_BUSY_DESCR 0x0005 ++ +struct gg_header { + int type; + int length; @@ -77,19 +227,84 @@ diff -urN dsniff-2.3/msgsnarf.c dsniff-2.3-gg/msgsnarf.c + int version; + int local_ip; + u_short local_port; -+}; ++} PACKED; ++ ++struct gg_login_ext { ++ int uin; ++ int hash; ++ int status; ++ int version; ++ int local_ip; ++ short local_port; ++ int external_ip; ++ short external_port; ++} PACKED; ++ ++struct gg_notify_reply { ++ int uin; ++ int status; ++ int remote_ip; ++ short remote_port; ++ int version; ++ short unknown1; ++} PACKED; ++ ++struct in_addr int2in_addr(u_int i) { ++ struct in_addr ia; ++ ia.s_addr = i; ++ return ia; ++} + -+int process_gg(struct client_info *info, u_char *data, int len) { ++struct remote_client_info *find_remote_client(int uin) { ++ int i; ++ struct remote_client_info *rc; ++ ++ i = 0; ++ SLIST_FOREACH(rc, &remote_client_list, next) { ++ if (rc->uin == uin) { ++ i = 1; break; ++ } ++ } ++ ++ if (i == 0) { ++ return NULL; ++ } else { ++ return rc; ++ } ++} ++ ++struct remote_client_info *add_remote_client(struct remote_client_info newrc) { ++ struct remote_client_info *rc; ++ ++ if ((rc = malloc(sizeof(*rc))) == NULL) ++ nids_params.no_mem("sniff_msgs"); ++ memset(rc, 0, sizeof(*rc)); ++ rc->uin = newrc.uin; ++ rc->ip = newrc.ip; ++ rc->port = newrc.port; ++ SLIST_INSERT_HEAD(&remote_client_list, rc, next); ++ return rc; ++} ++ ++#define GG_NICK_SIZE 45 ++#define GG_IP_SIZE 16 ++ ++int process_gg(struct client_info *info, u_char *data, int len, int dir) { + + struct buf *msg, buf; + struct gg_header *header; + struct gg_send_msg *send_msg; + struct gg_recv_msg *recv_msg; + struct gg_login *login; -+ struct in_addr addr; ++ struct gg_login_ext *login_ext; ++ struct gg_notify_reply *notify_reply; ++ struct remote_client_info *rc; ++ struct remote_client_info new_rc; + char *p; -+ char sbuff [10]; ++ char sbuff[GG_NICK_SIZE]; ++ char local_ip[GG_IP_SIZE]; + int i; ++ int count; + + buf_init(&buf, data, len); + @@ -102,53 +317,318 @@ diff -urN dsniff-2.3/msgsnarf.c dsniff-2.3-gg/msgsnarf.c + + buf_skip(msg, sizeof(*header)); + -+ if (header->type == GG_LOGIN && header->length == 22) { ++ if ((header->type == GG_LOGIN || header->type == GG_LOGIN_EXT)&& dir == TO_SERVER) { + -+ login = (struct gg_login *)buf_ptr(msg); -+ addr.s_addr = login->local_ip; -+ ++ login_ext = (struct gg_login_ext *)buf_ptr(msg); ++ ++ if (Opt_simple != 0) { ++ snprintf(sbuff, GG_NICK_SIZE, "%u", login_ext->uin); ++ } else { ++ if (info->ip == login_ext->local_ip) { ++ snprintf(sbuff, GG_NICK_SIZE, "%s/%u", inet_ntoa(int2in_addr(info->ip)), login_ext->uin); ++ } else { ++ snprintf(local_ip, GG_IP_SIZE, inet_ntoa(int2in_addr(login_ext->local_ip))); ++ snprintf(sbuff, GG_NICK_SIZE, "%s/%s/%u", inet_ntoa(int2in_addr(info->ip)), local_ip, login_ext->uin); ++ } ++ } + if (info->nick) free(info->nick); -+ snprintf(sbuff, 10, "%u", login->uin); + info->nick = strdup(sbuff); ++ ++ if (Opt_debug != 0) { ++ if (header->type == GG_LOGIN) { ++ printf("%s GG_LOGIN %s\n", timestamp(), info->nick); ++ } else { ++ printf("%s GG_LOGIN_EXT %s\n", timestamp(), info->nick); ++ } ++ } + } else + -+ if (header->type == GG_SEND_MSG) { ++ if (header->type == GG_SEND_MSG && dir == TO_SERVER) { + send_msg = (struct gg_send_msg *)buf_ptr(msg); + buf_skip(msg, sizeof(*send_msg)); + + p = buf_strdup(msg); + if (regex_match(p)) { -+ printf("%s GG %s > %u: %s\n", timestamp(), info->nick, send_msg->recipient, p); ++ rc = find_remote_client(send_msg->recipient); ++ if (rc && rc->ip != 0) { ++ snprintf(sbuff, GG_NICK_SIZE, "%s:%u/%u", inet_ntoa(int2in_addr(rc->ip)), rc->port, rc->uin); ++ } else { ++ snprintf(sbuff, GG_NICK_SIZE, "%u", send_msg->recipient); ++ } ++ printf("%s GG_SEND %s > %s: %s\n", timestamp(), info->nick, sbuff, p); + } -+ if (p) free(p); ++ free(p); + } else + -+ if (header->type == GG_RECV_MSG) { ++ if (header->type == GG_RECV_MSG && dir == TO_CLIENT) { + recv_msg = (struct gg_recv_msg *)buf_ptr(msg); + buf_skip(msg, sizeof(*recv_msg)); + + p = buf_strdup(msg); + if (regex_match(p)) { -+ printf("%s GG %s < %u: %s\n", timestamp(), info->nick, recv_msg->sender, p); ++ rc = find_remote_client(recv_msg->sender); ++ if (rc && rc->ip != 0) { ++ snprintf(sbuff, GG_NICK_SIZE, "%s:%u/%u", inet_ntoa(int2in_addr(rc->ip)), rc->port, rc->uin); ++ } else { ++ snprintf(sbuff, GG_NICK_SIZE, "%u", recv_msg->sender); ++ } ++ printf("%s GG_RECV %s < %s: %s\n", timestamp(), info->nick, sbuff, p); ++ } ++ free(p); ++ } ++ ++ if (header->type == GG_NOTIFY_REPLY && dir == TO_CLIENT) { ++ notify_reply = (struct gg_notify_reply *)buf_ptr(msg); ++ ++ if (notify_reply->status == GG_STATUS_NOT_AVAIL_DESCR || ++ notify_reply->status == GG_STATUS_AVAIL_DESCR || ++ notify_reply->status == GG_STATUS_BUSY_DESCR) { ++ count = 1; ++ } else { ++ count = header->length / sizeof(*notify_reply); ++ } ++ ++ for (i = 0; i < count; i++) { ++ rc = find_remote_client(notify_reply->uin); ++ if (rc) { ++ if (rc->ip != 0) { ++ rc->ip = notify_reply->remote_ip; ++ rc->port = notify_reply->remote_port; ++ } ++ } else { ++ new_rc.uin = notify_reply->uin; ++ new_rc.ip = notify_reply->remote_ip; ++ new_rc.port = notify_reply->remote_port; ++ rc = add_remote_client(new_rc); ++ } ++ if (Opt_debug != 0) { ++ printf("%s GG_NOTIFY_REPLY #%u [%s:%u/%u]\n", timestamp(), ++ i, inet_ntoa(int2in_addr(rc->ip)), rc->port, rc->uin); ++ } ++ buf_skip(msg, sizeof(*notify_reply)); ++ notify_reply = (struct gg_notify_reply *)buf_ptr(msg); ++ } ++ } ++ ++ if (header->type == GG_NOTIFY && dir == TO_SERVER) { ++ if (Opt_debug != 0) { ++ printf("%s GG_NOTIFY (%u)\n", timestamp(), header->length); + } -+ if (p) free(p); + } + } + + return(len - buf_len(&buf)); +} + ++char* get_value(struct buf *b, char *param, int len) { ++ char *v, *p, *l; ++ char c; ++ int i; ++ ++ v = NULL; ++ p = buf_strdup(b); ++ l = strstr(p, param); ++ while (l && l != p && l[-1] != '\n' && l[-1] != '\r' ++ && l[-1] != '&' && l[-1] != '?') { ++ l = strstr(l+1, param); ++ } ++ if (l) { ++ l += len; ++ i = strcspn(l, "&"); ++ if ((v = malloc(i + 1)) == NULL) ++ err(1, "malloc"); ++ memcpy(v, l, i); ++ v[i] = '\0'; ++ } ++ free(p); ++ return v; ++} ++ ++int process_gg_pass(struct client_info *info, u_char *data, int len, int dir) { ++ struct buf *line, *word, buf; ++ char *pass, *fmnum, *pwd, *email, *fmnumber, *fmpwd, *delete; ++ int i; ++ ++ buf_init(&buf, data, len); ++ ++ if (dir == TO_SERVER) { ++ fmnum = get_value(&buf, "FmNum=", 6); ++ fmnumber = get_value(&buf, "fmnumber=", 9); ++ pwd = get_value(&buf, "pwd=", 4); ++ ++ if (fmnum) { ++ pass = get_value(&buf, "Pass=", 5); ++ printf("GG_UIN = %s, GG_PASS = %s\n", fmnum, pass); ++ if (pass) free(pass); ++ free(fmnum); ++ } ++ if (pwd && !fmnumber) { ++ email = get_value(&buf, "email=", 6); ++ printf("GG_NEW_UIN: GG_PASS = %s, GG_EMAIL = %s\n", pwd, email); ++ if (email) free(email); ++ free(pwd); ++ } ++ if (fmnumber) { ++ fmpwd = get_value(&buf, "fmpwd=", 6); ++ delete = get_value(&buf, "delete=", 7); ++ pwd = get_value(&buf, "pwd=", 4); ++ if (delete) { ++ printf("GG_DELETE: GG_UIN = %s, GG_PASS = %s\n", fmnumber, fmpwd); ++ } else if (fmpwd) { ++ printf("GG_CHANGE: GG_UIN = %s, GG_OLDPASS = %s, GG_NEWPASS = %s\n", fmnumber, fmpwd, pwd); ++ } ++ if (fmpwd) free(fmpwd); ++ if (delete) free(delete); ++ if (pwd) free(pwd); ++ free(fmnumber); ++ } ++ } ++ ++ buf_skip(&buf, buf_len(&buf)); ++ return(len - buf_len(&buf)); ++} + void sniff_msgs(struct tcp_stream *ts, void **conn_save) { -@@ -562,6 +671,9 @@ - } + struct client_info *c; +- int (*process_msgs)(struct client_info *, u_char *, int); ++ int (*process_msgs)(struct client_info *, u_char *, int, int); + int i; + + if (ts->addr.dest >= 6660 && ts->addr.dest <= 6680) { +@@ -563,8 +900,16 @@ else if (ts->addr.dest == 1863) { process_msgs = process_msn; -+ } -+ else if (ts->addr.dest == 8074 || ts->addr.source == 8074) { -+ process_msgs = process_gg; } ++ else if (ts->addr.dest == 8074 || (ts->addr.dest == 443 && ++ (ts->addr.daddr & gg_netmask) == gg_network)) { ++ process_msgs = process_gg; ++ } ++ else if (Opt_pass != 0 && ts->addr.dest == 80 && ++ (ts->addr.daddr & gg_netmask) == gg_network) { ++ process_msgs = process_gg_pass; ++ } else return; +- ++ + switch (ts->nids_state) { + + case NIDS_JUST_EST: +@@ -573,15 +918,18 @@ + + i = 0; + SLIST_FOREACH(c, &client_list, next) { +- if (c->ip == ts->addr.saddr) { ++ if (c->ip == ts->addr.saddr && c->port == ts->addr.source) { + i = 1; break; + } + } + if (i == 0) { + if ((c = malloc(sizeof(*c))) == NULL) + nids_params.no_mem("sniff_msgs"); ++ memset(c, 0, sizeof(*c)); + c->ip = ts->addr.saddr; ++ c->port = ts->addr.source; + c->nick = strdup("unknown"); ++ c->local_ip = 0; + SLIST_INSERT_HEAD(&client_list, c, next); + } + *conn_save = (void *)c; +@@ -592,12 +940,14 @@ + + if (ts->server.count_new > 0) { + i = process_msgs(c, ts->server.data, +- ts->server.count - ts->server.offset); ++ ts->server.count - ts->server.offset, ++ TO_SERVER); + nids_discard(ts, i); + } + else if (ts->client.count_new > 0) { + i = process_msgs(c, ts->client.data, +- ts->client.count - ts->client.offset); ++ ts->client.count - ts->client.offset, ++ TO_CLIENT); + nids_discard(ts, i); + } + fflush(stdout); +@@ -608,10 +958,12 @@ + + if (ts->server.count > 0) + process_msgs(c, ts->server.data, +- ts->server.count - ts->server.offset); ++ ts->server.count - ts->server.offset, ++ TO_SERVER); + else if (ts->client.count > 0) + process_msgs(c, ts->client.data, +- ts->client.count - ts->client.offset); ++ ts->client.count - ts->client.offset, ++ TO_CLIENT); + fflush(stdout); + break; + } +@@ -627,7 +979,7 @@ + { + int c; + +- while ((c = getopt(argc, argv, "i:hv?V")) != -1) { ++ while ((c = getopt(argc, argv, "sdpwi:hv?V")) != -1) { + switch (c) { + case 'i': + nids_params.device = optarg; +@@ -635,6 +987,19 @@ + case 'v': + Opt_invert = 1; + break; ++ case 'd': ++ Opt_debug = 1; ++ break; ++ case 's': ++ Opt_simple = 1; ++ break; ++ case 'w': ++ Opt_pass = 1; ++ break; ++ case 'p': ++ // disable promiscous mode ++ nids_params.promisc = 0; ++ break; + default: + usage(); + } +@@ -653,19 +1018,35 @@ + nids_params.scan_num_hosts = 0; + nids_params.syslog = null_syslog; + ++ gg_network = inet_addr(GG_NETWORK);; ++ gg_netmask = inet_addr(GG_NETMASK); ++ + if (!nids_init()) + errx(1, "%s", nids_errbuf); + + SLIST_INIT(&client_list); ++ SLIST_INIT(&remote_client_list); + + nids_register_tcp(sniff_msgs); + ++ warnx("ggsniff " GGVERSION " enabled"); ++ + if (nids_params.pcap_filter != NULL) { + warnx("listening on %s [%s]", nids_params.device, + nids_params.pcap_filter); + } + else warnx("listening on %s", nids_params.device); + ++ if (nids_params.promisc == 0) { ++ warnx("promiscous mode disabled"); ++ } else ++ warnx("promiscous mode enabled"); ++ ++ if (Opt_pass == 0) { ++ warnx("password sniffing disabled"); ++ } else ++ warnx("password sniffing enabled"); ++ + nids_run(); + /* NOTREACHED */