tcpdump:如何获取可重复输出?


13

我正在尝试解决设备上只有tcpdump可用的问题。我想使用tcpdump过滤Web流量,仅显示包含某些字符串的流量。

我执行以下操作:

tcpdump -nei eth0 -X | grep "something interesting"

输出是具有16字节pr行的hexview。由于数据显示在多行中,因此我无法grep此数据。

tcpdump是否可以在一行上显示捕获的数据?这将使使用grep查找有趣的数据包成为可能。


1
好,我现在无法测试,但是如果您有多行,则可以| tr -d'\ n'或grep -C 3前后可获得一些代码
barlop 2014年

@barlop,grep -C可以正常工作,但是不可靠,因为我永远不知道标题的行数,而且看不到匹配项下方的行。tr命令将所有输出转换为1行,因此它有点过多。
狗吃猫世界

以下不是grep,但tcpdump可以通过十六进制匹配字符串,而十六进制本质上是grep,无需任何正则表达式。您可以指定一个偏移量。我将其记入文件中(用windump完成,但我只是tcpdump的Windows版本,所以假定tcpdump)tcpdump -nXr zfile“ tcp [32:4] = 0x47455420”
barlop 2014年

tcpdump -nei eth0 -X | grep --line-buffered "something interesting"出于不加区分的原因,我的有效工作答案已被删除。
sjas

Answers:


11

对于像您这样无法使用的人ngrep,以下是如何awk使tcpdump数据包内容的输出可复制的方法。

首先,提供的一些示例输出tcpdump -x,以介绍前面的任务:

$ tcpdump -xr dump.pcap 2>/dev/null
12:04:59.590664 IP 10.17.14.93.51009 > 239.194.1.9.51009: UDP, length 370
        0x0000:  4500 018e 0000 4000 fa11 7625 0a11 0e5d
        0x0010:  efc2 0109 c741 c741 017a 6f28 1120 2020
        0x0020:  3337 3030 3039 3031 3835 3635 3430 3130
...

这是复制和粘贴awk脚本,您可以将输出通过管道传递到

awk '{ if (match($0, /^[0-9]/, _)) { printf (NR == 1 ? "%s " : "\n%s "), $0; fflush() } else { sub(/^\s+0x[0-9a-z]+:\s+/, " "); gsub(" ", ""); printf "%s", $0 } } END { print ""; fflush() }'

为了获得以下可输出的结果

12:04:59.590664 IP 10.17.14.93.51009 > 239.194.1.9.51009: UDP, length 370 4500018e00004000fa1176250a...
12:04:59.590798 IP 10.17.14.113.51011 > 239.194.1.11.51011: UDP, length 370 4500018e00004000fa11760f...
...

以下是上述脚本的注释版本:

awk '
{
    # if this is a header line
    if (match($0, /^[0-9]/, _)) 
    {
        # print the header, but:

        # except for the first line,
        # we need to insert a newline,
        # as the preceding data lines
        # have been stripped of theirs

        # we also append a space to
        # separate header info from the
        # data that will get appended
        printf (NR == 1 ? "%s " : "\n%s "), $0
        # enforce line-buffering
        fflush()
    }
    # otherwise it is a data line
    else 
    {
        # remove the data address
        sub(/^\s+0x[0-9a-z]+:\s+/, " ");
        # remove all spaces
        gsub(" ", "");
        # print w/o newline
        printf "%s", $0 
    }
}
END
{
    # print final newline, as
    # the preceding data lines
    # have been stripped of theirs
    print ""
    # enforce line-buffering
    fflush()
}'

2

tcpdump联机帮助页:

-A      Print each packet (minus its link level header) in ASCII.  Handy
        for capturing web pages.

确保您还使用该-s 0选项来确保显示整个数据包。


谢谢,但是数据仍然以多行显示-网页中包含换行符的任何位置。我在将标头(和其余数据)与grepped输出关联时遇到问题。
狗吃猫世界

我刚刚意识到为什么将该工具称为awk 病房
狗吃猫世界

1

您可能需要看一下ngrep命令:

ngrep -W single -d eth0 'regex to match' 'port 80'

哪里:

  • -W single 指定单行格式
  • regex to match 表示仅转储包含某些字符串的数据包。
  • 'port 80' 是一个pcap过滤器,仅嗅探来自或进入端口80的数据包

1
想使用ngrep,但是没有这样的工具-它是一种设备...
狗吃猫的世界

ngrep很棒。我正在寻找几个小时,哪个主机正在向我的主机生成HTTP通信。用单个sudo ngrep“ GET ..”在几分钟内找到了答案。
Bartosz Bilicki

0

您的输出为十六进制的原因是该-X标志。尝试:

tcpdump -ni eth1 | grep something_interesting

您将直接将可读输出转储到cli。


是的,但是将不包含数据包的内容。
拉尔夫弗里德尔

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.