Date: Wed, 12 Apr 2000 17:30:46 +0200 From: Graham Wheeler <gram@cequrux.com> To: hackers@FreeBSD.ORG Subject: Determining traffic on a socket - solution and security question Message-ID: <38F496A6.1DE73643@cequrux.com> References: <53045.955453206@axl.ops.uunet.co.za> <38F31395.68EFE3EF@cequrux.com> <38F44460.391BD4B9@cequrux.com> <38F46F1C.1115AEDE@cequrux.com>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------7FACD920DB1E44CD02E708A0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit I have attached my final program which works on both FreeBSD 2.x and FreeBSD 3.x (I don't have a FreeBSD 4.x box to test this on yet). On FreeBSD 2.x one must be root to run this (to read /dev/kmem), but on FreeBSD 3.x any user can run this. I would argue that this is a potential security vulnerability. Some clever user may be able to exploit this for some protocols to determine the lengths of usernames and passwords (admittedly this is unlikely to work with telnet unless in line mode). The sysctl calls that extract things like TCP control blocks should require privileged access (although the downside of this is that programs like netstat would have to be setuid). -- Dr Graham Wheeler E-mail: gram@cequrux.com Director, Research and Development WWW: http://www.cequrux.com CEQURUX Technologies Phone: +27(21)423-6065 Firewalls/VPN Specialists Fax: +27(21)424-3656 --------------7FACD920DB1E44CD02E708A0 Content-Type: text/plain; charset=us-ascii; name="showtraf.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="showtraf.c" #include <stdio.h> #include <fcntl.h> #include <kvm.h> #include <nlist.h> #include <sys/types.h> #include <sys/socket.h> #if (__FreeBSD__ > 2) #include <sys/socketvar.h> #endif #include <net/route.h> #include <netinet/in.h> #include <netinet/in_pcb.h> #include <netinet/in_systm.h> #include <netinet/ip.h> #include <netinet/tcp.h> #define TCPSTATES #include <netinet/tcp_fsm.h> #define TCPTIMERS #include <netinet/tcp_timer.h> #include <netinet/tcp_var.h> #if (__FreeBSD__ > 2) #include <sys/sysctl.h> #include <netinet/in_pcb.h> #endif //---------------------------------------------------------------- void Display(struct inpcb *inpcb, struct tcpcb *tcpcb) { if (tcpcb->t_state >= TCPS_ESTABLISHED && tcpcb->t_state < TCP_NSTATES) { printf("%17s:%-5d ", inet_ntoa(inpcb->inp_laddr.s_addr), ntohs(inpcb->inp_lport)); printf("%17s:%-5d ", inet_ntoa(inpcb->inp_faddr.s_addr), ntohs(inpcb->inp_fport)); printf("[%10s] tx: %10lu rx: %10lu\n", tcpstates[tcpcb->t_state], (u_long)tcpcb->snd_nxt - (u_long)tcpcb->iss, (u_long)tcpcb->rcv_nxt - (u_long)tcpcb->irs); } } #if (__FreeBSD__ <= 2) struct nlist nml[] = { #define N_TCB 0 { "_tcb" }, 0 }; void Process_IP_CB(kvm_t *kmem, struct inpcb *inpcb) { struct tcpcb tcpcb; if (kvm_read(kmem, (long)inpcb->inp_ppcb, (char*)&tcpcb, sizeof(tcpcb))>0) Display(inpcb, &tcpcb); } void Process_IP_CBs(kvm_t *kvm) { struct inpcb in_pcb; long off = nml[N_TCB].n_value; if (kvm_read(kvm, off, (char *) &in_pcb, sizeof (struct inpcb))>0) { long prev = off; while (in_pcb.inp_list.le_next != (struct inpcb *)off) { long next = (long)in_pcb.inp_list.le_next; if (kvm_read(kvm, next, (char*)&in_pcb, sizeof(struct inpcb)) < 0 || (long)in_pcb.inp_list.le_prev != prev) // lost sync break; Process_IP_CB(kvm, &in_pcb); prev = next; } } } #endif main(int argc, char **argv) { #if (__FreeBSD__ > 2) int len = 0; if (sysctlbyname("net.inet.tcp.pcblist", 0, &len, 0, 0)<0) perror("sysctlbyname"); else { char *buf = (char*)malloc(len); if (buf == 0) perror("malloc"); else if (sysctlbyname("net.inet.tcp.pcblist", buf, &len, 0, 0)<0) perror("sysctlbyname"); else { struct xinpgen *xig, *oxig; oxig = xig = (struct xinpgen*)buf; for (xig = (struct xinpgen*)(((char*)xig)+xig->xig_len) ; xig->xig_len > sizeof(struct xinpgen); xig = (struct xinpgen*)(((char*)xig)+xig->xig_len)) { struct tcpcb *tcpcb = & ((struct xtcpcb*)xig)->xt_tp; struct inpcb *inpcb = & ((struct xtcpcb*)xig)->xt_inp; if (inpcb->inp_gencnt <= oxig->xig_gen) Display(inpcb, tcpcb); } } if (buf) free(buf); } #else kvm_t *kvm = kvm_open(0,0,0,0,0); if (kvm) { if (kvm_nlist(kvm, nml) < 0) perror("kvm_nlist"); else { Process_IP_CBs(kvm); kvm_close(kvm); } } else perror("kvm_open"); #endif } --------------7FACD920DB1E44CD02E708A0-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?38F496A6.1DE73643>