本文最后更新于:2023年6月22日 上午
之前阅读掘金小册时一直没实战,这里就补一下
tcpdump
参考网站: 博客园
默认情况下tcpdump抓第一个网卡上的数据包
监听特定网卡使用-i参数
监听特定本机和特定ip的通信使用host参数:
| tcpdump host 111.111.11.11
|
监听来源/目标地址通信:
| tcpdump src host 111.111.11.11 tcpdump dst host 111.111.11.11
|
监听特定端口:
可以指定tcp/udp
监听特定主机之间的通信(需要有权限)
| tcpdump ip host 210.27.48.1 and 210.27.48.2
|
稍微详细点的例子
| tcpdump tcp -i eth1 -t -s 0 -c 100 and dst port ! 22 and src net 192.168.1.0/24 -w ./target.cap
|
(1)tcp: ip icmp arp rarp 和
tcp、udp、icmp这些选项等都要放到第一个参数的位置,用来过滤数据报的类型
(2)-i eth1 : 只抓经过接口eth1的包 (3)-t : 不显示时间戳 (4)-s 0 :
抓取数据包时默认抓取长度为68字节。加上-S 0 后可以抓到完整的数据包 (5)-c
100 : 只抓取100个数据包 (6)dst port ! 22 : 不抓取目标端口是22的数据包
(7)src net 192.168.1.0/24 : 数据包的源网络地址为192.168.1.0/24 (8)-w
./target.cap : 保存成cap文件,方便用ethereal(即wireshark)分析
strace
参考网站: 博客园
strace用来跟踪进程执行时的系统调用以及所接收的信号,如:
| strace cat /dev/null execve("/usr/bin/cat", ["cat", "/dev/null"], 0x7ffc3650b2a8 /* 80 vars */) = 0 brk(NULL) = 0x560885cd5000 arch_prctl(0x3001 /* ARCH_??? */, 0x7ffd61de71d0) = -1 EINVAL (无效的参数) mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8cb41e5000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (没有那个文件或目录) openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=132945, ...}, AT_EMPTY_PATH) = 0 mmap(NULL, 132945, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8cb41c4000 close(3) = 0
|
每一行都是一个系统调用
strace的参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| -c 统计每一系统调用的所执行的时间,次数和出错的次数等. -d 输出strace关于标准错误的调试信息. -f 跟踪由fork调用所产生的子进程. -ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号. -F 尝试跟踪vfork调用.在-f时,vfork不被跟踪. -r 打印出相对时间关于,,每一个系统调用. -t 在输出中的每一行前加上时间信息. -e trace=set 只跟踪指定的系统 调用.例如:-e trace=open,close,rean,write表示只跟踪这四个系统调用.默认的为set=all. -e trace=file 只跟踪有关文件操作的系统调用. -e trace=process 只跟踪有关进程控制的系统调用. -e trace=network 跟踪与网络有关的所有系统调用. -e strace=signal 跟踪所有与系统信号有关的 系统调用 -e trace=ipc 跟踪所有与进程通讯有关的系统调用 -o filename 将strace的输出写入文件filename -p pid 跟踪指定的进程pid. -u username 以username 的UID和GID执行被跟踪的命令
|
这个佬的博客写的很详细,案例也不错,建议看看。
strace给我的感觉是如果不加参数过滤一些信息,给出的信息实在太多了。
如在我的电脑上strace -o 1.txt pkill goldendict
,strace就给出了3287行的信息。。。如果加上参数-e
trace=process,那么就只有4行:
| execve("/usr/bin/pkill", ["pkill", "goldendict"], 0x7ffc17024708 /* 83 vars */) = 0 kill(340891, SIGTERM) = 0 exit_group(0) = ? +++ exited with 0 +++
|
我后来又试了试了,sudo strace -e trace=close -f -d -uheeler -o 1.txt pkill goldendict
,发现kill这个goldendict的调用的close是真多
😃
packetdrill
安装:github
| cd gtests/net/packetdrill sudo apt-get install -y bison flex
|
为避免 offload 机制对包大小的影响,修改 netdev.c 注释掉
set_device_offload_flags 函数所有内容
修改 Makefile,去掉第一行的末尾的 -static 执行 make 命令编译
可以在目录下尝试packetdrill是否正常生成 加入环境变量:
加入你的路径即可。之后任意打开一个命令行。packetdrill
查看是否成功
由于packetdrill需要sudo权限,因此需要更改/.zshrc
(我用的zsh解释器),在里面加入
| alias sudo='sudo env PATH="$PATH"'
|
之后保存, source /.zshrc
即可
packetdrill实际上方便了程序员以确定的时间安排系统调用。他可以执行系统调用函数、把数据包注入到内核协议栈,并且支持py、shell,
来看一个张师傅给出的简单的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 //在第0秒创建一个socket +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 +0 bind(3, ..., ...) = 0 +0 listen(3, 1) = 0
//TCP three-way handshake +0 < S 0:0(0) win 4000 <mss 1000> //<表示输入数据包 +0 > S. 0:0(0) ack 1 <...> //>表示预期协议栈响应的包 +.1 < . 1:1(0) ack 1 win 1000
+0 accept(3, ..., ...) = 4 +0 write(4, ..., 10) = 10 +0 > P. 1:11(10) ack 1 +.1 < . 1:1(0) ack 6 win 1000
|
上述代码可以通过tcpdump抓到8080端口的包
packetdrill实际上是通过创建一个虚拟网卡来模拟协议的执行。
其他内容建议参考: developpaper