2009/10/17

tcpdump 到 sniffer , 這果然是個邪惡的工具.

昨天本來是在練習網路封包的抓取,判斷並使用網路分析器....目前流行的有兩套 for windows版的,幾乎念資工的都會遇到,用這個來瞭解網路.當然CCNA也會用到.
目前比較有名的是 wireshark 這套 opensource 的軟體
(他其實就是以前的etherreal,只是作者換公司沒辦法帶走這個商標)
http://www.wireshark.org/ 
網路上有很多教學文章,可以參考這裡
另外一套是 packetyzer 這套也是opensource
http://sourceforge.net/projects/packetyzer/
但兩套都是以 winpcap 來開發的,差別只是UI及內容的解析能力而已.
http://www.winpcap.org/
但其實我還是不太清楚,winpcap 和 libpcap 的關係,我猜可能是有人把他改寫成windows的lib巴!
libpcap 這個 lib 也是 opensource
http://sourceforge.net/projects/libpcap/
然後其實在 linux 下也有一套 tcpdump 文字介面的探測器,一般用法如下:

* man tcpdump 的語法部份
SYNOPSIS
tcpdump [ -AdDeflLnNOpqRStuUvxX ] [ -c count ]
[ -C file_size ] [ -F file ]
[ -i interface ] [ -m module ] [ -M secret ]
[ -r file ] [ -s snaplen ] [ -T type ] [ -w file ]
[ -W filecount ]
[ -E spi@ipaddr algo:secret,... ]
[ -y datalinktype ] [ -Z user ]
[ expression ]
* 大陸的中文翻譯 http://fanqiang.chinaunix.net/a1/b5/20010924/1000011342_b.html
* 簡單易懂,底下用了幾個參數說明如下
# -s 0 封包抓完成,預設沒有抓完全
# -i eth1 指令網卡抓取
# -nn 不要作 dns 反解,加快顯示速度
# port 1863 指的是 expreesion 中對於 tcp port 1863 msn port 的擷取
* example 範例如下:
[root@linux ]# tcpdump -i eth1 -s 0 -nn port 1863
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
20:35:56.701302 IP 140.117.69.174.49265 > 64.4.16.40.1863: . ack 4099310568 win 251
20:35:57.535320 IP 140.117.74.59.2137 > 207.46.124.54.1863: P 2422497404:2422497564(160) ack 2763176839 win 65535
20:35:57.623174 IP 140.117.69.174.49265 > 64.4.16.40.1863: . ack 496 win 256
* 更進一步的用法,把他用 -w 參數寫入檔案
# -X 會把 ascii 及 hex 兩個同時列出來
# tcpdump -i eth1 -s 0 -nn -X -w temp.msn.txt port 1863
* 如果需要可以在 expression 加入 host 192.168.1.254 之類的過濾
# tcpdump -i eth1 -s 0 -nn -X -w temp.msn.txt port 1863 and host 192.168.1.254


* 後來想說找找看有沒有可以看起來更有趣的東西,例如直接抓出msn的內容之類的....於是就找到下面的 perl 程式碼. msn sniffer use perl
* 來源 http://www.757.org/~joat/wiki/index.php/Perl_-_MSN_IM_Sniffer 原始站台好像掛了,連google都找不到.
使用說明:
To capture live traffic from device eth0 run:
msndump.pl -i eth0

To capture from tcpdump traffic.pcap file run:
msndump.pl -r traffic.pcap
* 程式碼備份..純備份.
#!/usr/bin/perl -w
# quick dirty msn sniffer
# http://miscname.com/
# $Id: msndump.pl,v 1.3 2004/11/17 10:00:33 meh Exp $

# you need Net::Pcap and Net::Packet
# use cpan or get manually
# http://search.cpan.org/CPAN/authors/id/A/AT/ATRAK/NetPacket-0.04.tar.gz
# http://search.cpan.org/CPAN/authors/id/K/KC/KCARNUT/Net-Pcap-0.05.tar.gz

my $lowuid='1001';
my $lowgid='1001';

my $filter = 'tcp and port 1863';

# no modify below
use Getopt::Std;
use Net::Pcap;
use NetPacket::IP;
use NetPacket::Ethernet qw (:strip);
use Fcntl;
$|=1;
my $flags |= O_NONBLOCK;

my %opts;
getopt("wicr",\%opts);
if ( (!($opts{i})) && (!($opts{r})) ) {
print "[ msndump - miscname.com ]\n Usage:\n\t-i rl0 || -r file.pcap\n\t-c X - capture X packets\n\t-w freshIMz.txt\n\n";
exit;
}

if ((!$opts{r}) && ($> != '0')) {
die ("you need uid 0\n");
}

# main loop
my $exitvar = '0';
while ($exitvar == '0') {

# create pcap
my $pcap = &cap_pkt;
if (!($pcap)) {
die ("cant capture\n");
}

# drop privs
my $GID="$lowgid";
my $UID="$lowuid";
my $EGID="$lowgid $lowgid";

# -w if set
if ($opts{w}) {
open (FILEOUT,">$opts{w}") || die ("cant open $opts{w} ($!)\n");
fcntl(FILEOUT, F_SETFL, $flags) or die ("couldn't set nonblock for $opts{w} ($!)\n");
}

# capture loop
if (($opts{c}) && ($opts{c} =~ /(\d+)/)) {
print "stopping after $1 packets\n";
Net::Pcap::loop($pcap, $1, \&proc_pkt, 0);
$exitvar = '1';
} else {
Net::Pcap::loop($pcap, -1, \&proc_pkt, 0);
my %stats;
Net::Pcap::stats($pcap, \%stats);
print "saw $stats{ps_recv} packets, dropped $stats{ps_drop}\n";
}

# free it
print "cleaning up\n";
Net::Pcap::close($pcap);
# close fh
if ($opts{w}) {
print "wrote $opts{w}.\n";
close FILEOUT;
}
}

# sub procs below
sub cap_pkt {

my ($pcap,$dev,$err,$mask,$net,$filter2);
my $snaplen = 14096; # seen some big im's :(
my $promisc = 1; # promisc of course
my $timeout = 0; # timeout

# file.pcap?
if ($opts{r}) {
print "reading from '$opts{r}'\n";
$pcap = Net::Pcap::open_offline($opts{r}, \$err);
if (!($pcap)) {
die("error opening $opts{r} ($err)\n");
}
} else {

# set dev from cmdline
$dev = $opts{i};
print "dumping on '$opts{i}'\n";

# get netmask for filter
if ((Net::Pcap::lookupnet($dev, \$net, \$mask, \$err)) == -1 ) {
die ("Net::Pcap::lookupnet failed ($err)\n");
}

# open it
$pcap = Net::Pcap::open_live($dev, $snaplen, $promisc, $timeout, \$err);
if (!($pcap)) {
die ("can't create packet fd ($err)\n");
}
}

# sanity check
if (!($pcap)) {
die ("sanity check failed - \$pcap null\n");
} elsif (!($mask)) {
$mask = '0'; # for open_offline
}

# make filter struct
if (Net::Pcap::compile($pcap, \$filter2, $filter, 1, $mask) != '0') {
die ("broken filter ($filter)\n");
}
# apply
Net::Pcap::setfilter($pcap, $filter2);

return $pcap;
}

sub proc_pkt {

my($user_data, $hdr, $pkt) = @_;
my ($user,$msg);

my $ip_obj = NetPacket::IP->decode(eth_strip($pkt));
#my $ip_obj = NetPacket::IP::strip($pkt);

# check if its a message (or a p2p file transfer)
# if your reading this, include 'P2P-Dest:' in your message body to avoid sniffer ;)
if (($ip_obj->{data} !~ /MSG/m) || ($ip_obj->{data} =~ /P2P-Dest:/m)) {
;
} else {
print $ip_obj->{data};
# extract goodies
if ( (($ip_obj->{data} =~ /MSG (.*)\@(.*)/)) || (($ip_obj->{data} =~ /P4-Context: (.*)/)) ) {
$user = "$1\@$2";
}

if ($ip_obj->{data} =~ /X-MMS-IM-Format:\s.*\r(.*)/s) { #\s\w+\=\w+\;\s\w+\=\w+\;\s\w+\=\w+\;\s\w+\=\w+\;\s\w+\=\w+\;(.*)/m) {
$msg = $1;
}

# display if we have both
if (($user) || ($msg))
{
if(!$user)
{
$user = "unknown user";
}
if (!($opts{w})) {
print "\n----------------------------------------------------\n";
print "src_ip($ip_obj->{src_ip}) dst_ip($ip_obj->{dest_ip})\n";
print "TO/FROM: $user\nMESSAGE:\n$msg\n";
} else {
print FILEOUT "\n----------------------------------------------------\n";
print FILEOUT "src_ip($ip_obj->{src_ip}) dst_ip($ip_obj->{dest_ip})\n";
print FILEOUT "TO/FROM: $user\nMESSAGE: \n$msg\n\n";
}
}
}
}

#e0f

* 這程式是靠 perl CPAN 函式庫的 Net::Pcap and Net::Packet 兩個套件開發的,所以你必須要去取得這兩個函式酷並安裝上去.
# you need Net::Pcap and Net::Packet
# use cpan or get manually
# http://search.cpan.org/CPAN/authors/id/A/AT/ATRAK/NetPacket-0.04.tar.gz
# http://search.cpan.org/CPAN/authors/id/K/KC/KCARNUT/Net-Pcap-0.05.tar.gz
*but debian 安裝起來不是很方便,尤其我用的是 64bit 的os 沒有現成的 binary 檔案
只好參考這篇重新打包一個 .deb 檔案,然後安裝
http://web.suffieldacademy.org/ils/netadmin/docs/software/aimsniff/


* 但基本上這隻程式要跑在公司網路上,然後要看得到東西,你必須對你的 swtich 或是 route 作 port mirror 的動作.底下是之前對 ExtremeXOS 的筆記
* 手冊關於Mirroring 的語法說明
Mirroring

* Page.209
* Mirroring Examples

Mirroring is disabled by default. To enable mirroring in single port, the following command can be used:

enable mirroring to port
# To enable mirroring on multiple ports, use the following command:
enable mirroring to port-list loopback-port
# The port-list is a list of monitor ports which will transmit identical copies of mirrored packets. The
# loopback-port is an otherwise unused port required when mirroring to a port-list. The loopback-port is
# not available for switching user data traffic.
# To disable mirroring, use the following command:
disable mirroring

* 實作 -把全部的 vlan 塞到 port2
CoM-X450.1 # enable mirroring to port 2
* CoM-X450.2 # configure mirroring add vlan CoM
* CoM-X450.3 # configure mirroring add vlan vlan71
* CoM-X450.4 # configure mirroring add vlan vlan72
* CoM-X450.5 # configure mirroring add vlan vlan73
* CoM-X450.6 # configure mirroring add vlan vlan74
* CoM-X450.7 # configure mirroring add vlan vlan75
* CoM-X450.8 # configure mirroring add vlan vlan76
* CoM-X450.9 # configure mirroring add vlan vlan77
* CoM-X450.10 # configure mirroring add vlan vlan78
* CoM-X450.11 # show mirroring
Mirroring Mode: Standard
Mirror port: 2 is up
Number of Mirroring filters:9
Mirror Port configuration:
All ports in vlan CoM
All ports in vlan vlan71
All ports in vlan vlan72
All ports in vlan vlan73
All ports in vlan vlan74
All ports in vlan vlan75
All ports in vlan vlan76
All ports in vlan vlan77
All ports in vlan vlan78


* 本想說應該可以滿足了,但發現也有人用 java寫了一個 msn sniffer ....等等,這人看起來像是中山資管系的...XD..

* Packet Reading with libpcap 使用 C 語言與 libpcap 開發的封包擷取器,有時間再來玩!!
http://www.systhread.net/texts/200805lpcap1.php

* python 也有 pcap 的函式庫 http://pylibpcap.sourceforge.net/ 好多好多.....
張貼留言