网络上有使用strings过滤tcpdump的代码, 缺点是不能同时现实客户端ip
sudo tcpdump -i eth0 -s 0 -l -w - dst port 3306 | strings | perl -e '
while(<>) { chomp; next if /^[^ ]+[ ]*$/;
if(/^(SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER)/i) {
if (defined $q) { print "$q/n"; }
$q=$_;
} else {
$_ =~ s/^[ /t]+//; $q.=" $_";
}
}'
改进下(因不使用pcap来处理原始包, 无法识别包分界问题, 想到tcpdump每次抓一个包的方法)
因为在sql语句组成字符上还有遗漏, 还需要晚上. 不过基本能工作
while [ true ];do sudo tcpdump -c 1 -s 0 -l -w - dst port 3306 2>/dev/null|perl -e 'BEGIN{$/=""; $/="";}
read STDIN, $_, 16384; $ips="";
if(/^.{66}(.{8})/) { @ip=unpack('C8', $1); $ips=sprintf("%d.%d.%d.%d->%d.%d.%d.%d",$ip[0],$ip[1],$ip[2],$ip[3],$ip[4],$ip[5],$ip[6],$ip[7]); }
if($_ =~/(SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER)/i) { printf("/n%s:", $ips);}
while ($_ =~ /([/s/w=/*,)/(]+)/gi) { print $& if(length($&) > 5);} ' ;done