Sniffing Network Traffic in Python
Sniffing Network Traffic in Python
Rapid development
Easy data structure use
Fewer LoC per tool
Easy to manipulate strings
http://www.python.org/
Marrying Python and Sniffing
Librares in C
Often SWIGged, exported to Python
pcap, dnet, nids
Modules
pypcap/pcappy pcap for python
dpkt packet deconstruction library
libdnet packet construction library (has python
bindings in the distribution)
Kernel
IP stack
Userland
Kernel
Libnids IP stack
IP stack
libnids Basics
Initialize
nids_init()
Register callbacks
nids_register_tcp()
nids_regster_ip()
nids_regiser_udp()
Run!
nids_run()
React
nids_kill_tcp()
nids_run()
TCP?
State exist? Create state or reuse state
Append data
Process based on state in callback
UDP or IP?
Use handler, pass packet in
You process in callback
Code Example (Python)
import nids
<handleTcpStream>
def main():
nids.param("scan_num_hosts", 0)
if not nids.init():
print "error -", nids.errbuf()
sys.exit(1)
nids.register_tcp(handleTcpStream)
try: nids.run() # loop forever
except KeyboardInterrupt:
sys.exit(1)
Code Example (Python) cont
def handleTcpStream(tcp):
if tcp.nids_state == nids.NIDS_JUST_EST:
if dport in (80, 8000, 8080):
tcp.client.collect = 1
tcp.server.collect = 1
elif tcp.nids_state == nids.NIDS_DATA:
tcp.discard(0)
elif tcp.nids_state in end_states:
print "addr:", tcp.addr
# may be binary
print "To server:, tcp.server.data
print "To client:, tcp.client.data
Code Example (C)
int main(int argv, char *argv[])
{
if (nids_init() == 0)
err(1, error, %s, nids_errbuf);
nids_register_tcp(handleTcp);
nids_run();
exit(0);
}
Code Example (C), cont
int handleTcp(struct tcp_stream *tcp)
{
switch (tcp->nids_state) {
case NIDS_JUST_EST:
if ((tcp->addr.dest == 80) ||
(tcp->addr.dest == 8000) ||
(tcp->addr.dest == 8080) {
tcp.server.collect = 1;
tcp.client.collect = 1;
}
break;
case NIDS_DATA:
nids_discard(tcp, 0);
break;
case NIDS_CLOSE:
case NIDS_RESET:
case NIDS_TIMED_OUT:
printf(((%s, %d), (%s, %d))\n, inet_ntoa(tcp->saddr), tcp.srce,
inet_ntoa(tcp->daddr), tcp.dest);
printf(%s\n, tcp->server.data);
printf(%s\n, tcp->client.data);
break;
}
} About the same LoC, until we start string manipulation
VersionDetect
Small python tool
Reports on headers
Fully passive
Support for: SSH (client, server), WWW
(client, server), and SMTP clients
Motivation: coordinate data collection with
TCP stack fingerprinting
63.236.16.161 SymbianOS 6048 (on Nokia 7650?) www 80/tcp
63.236.16.161: 80: Microsoft-IIS/6.0
VersionDetect Output
192.168.1.7: 22: SSH-2.0-OpenSSH_3.5
192.168.1.101:http: Mozilla/5.0 (X11; U; OpenBSD i386; en-
US; rv:1.5a) Gecko/20031030 Mozilla Firebird/0.6.1
168.75.65.85: 80: Microsoft-IIS/5.0
165.1.76.60: 80: Netscape-Enterprise/3.6 SP2
168.75.65.69: 80: Microsoft-IIS/5.0
168.75.65.87: 80: Microsoft-IIS/5.0
69.28.159.7: 80: ZEDO 3G
198.65.148.234: 80: Apache/1.3.29 (Unix) PHP/4.3.3
216.150.209.231: 80: Apache/1.3.31 (Unix)
212.187.153.30: 80: Apache/1.3.31 (Unix)
212.187.153.37: 80: Apache/1.3.31 (Unix)
212.187.153.32: 80: thttpd/2.25b 29dec2003
64.209.232.207: 80: Apache/1.3.27 (Unix)
mod_perl/1.27
216.239.39.99: 80: CAFE/1.0
http-graph
Small, passive python tool
Examines HTTP request header:
GET /blog/styles-site.css HTTP/1.1
Host: www.jackcheng.com
User-Agent: Mozilla/5.0 (X11; U; OpenBSD i386; en-US;
rv:1.5a) Gecko/20031030 Mozilla Firebird/0.6.1Accept:
text/css,*/*;q=0.1
Referer:
http://www.jackcheng.com/blog/archives/2004/12/ipod_rumo
rs.html
http-graph
Directed graph history of browsing
Reconstructs graph from referrer and URL
in the header:
Referrer Request
Rewriting
string.replace(req, GET HTTP/1.0, , 1)
More Fun!
Privacy invasion
Snarf mail
Log conversations
IRC, AIM, etc
Steal files
FTP, P2P apps, HTTP downloads
Disrupt sessions
tcp.kill()