目录
前文
前几天在php-JA3 TLS握手指纹实践中,通过转发流量提取ja3指纹。方案是可行的,但为了不影响性能和稳定性,实际在部署时,我是单独给了一个端口处理,如 demo https://bjun.tech:9763/demo/ja3/ja3.php。后续在思考和了解tcpdump的原理后,我开始新的尝试。
tcpdump 原理
简单的说,tcpdump 是 Linux 系统中非常有用的网络工具,运行在用户态,本质上是通过调用 libpcap 库的各种 api 来实现数据包的抓取功能。
通过上图,我们可以很直观的看到,数据包到达网卡后,经过数据包过滤器(BPF)筛选后,拷贝至用户态的 tcpdump 程序,以供 tcpdump 工具进行后续的处理工作,输出或保存到 pcap 文件
正因为数据是拷贝的,tcpdump的抓包是不会影响其他程序的正常运行(不考虑性能)。
思路和选择
-
获取tcdump抓包内容
- 关于tcpdump数据输出有许多种命令选项,如 -xv= ,不过我最后选择的是 -w - ,看中的是不输出文件,直接输出二进制文件到标准输出。直觉告诉我它会更快点,并且不用再去关心输出文件的处理问题。
- php 获取程序输出有多个方法,不过有实时读取的就2个,popen()和proc_open(),只需要单向读取,所以选择前者。
-
处理成需要的数据
tcpdump 标准输出的内容和输出到文件内容是一致的,主要是文件头,后续的每个包内容都会有抓包包头和对应内容。而抓包的内容在我们的项目中就是以太帧的数据部分。
per-packet header 16 , mac frame header 14 ,ip header 20,tcp header ?
其中的 tcp body data 起始位置,则按过滤规则从tcp header 偏移字段再取一次即可。
规则:
tcp[tcp[12]/16*4]=22
-
传递给web
在跨进程数据传输,我直接用的是workerman-GlobalData,不过捏在测试中发现了问题。
- 抓包的延迟
在之前wkm_ja3中,数据是通过转发的,在时间线上是存在必然的前后关系的,先算出ja3,再到web部分。
而在ja3_tcpdump中,先后关系不是必然,大部分情况下还是抓包数据的输出慢于web的响应。如果继续使用原来的思路,会有一定问题,而我的解决方法是魔改了workerman-GlobalData,效果类似redis中list的blpop。
- 原代码
$t = microtime(1);
while (!($global->__isset($remote_port_key)) && microtime(1)-$t <1 ){
usleep(10000);
};
问题是,$global->__isset命令触发很多次,具体取决于usleep,并且始终还是有延迟。
- 优化后
$global->watch($remote_port_key,1);
其效果就是,当watch后,在限定时间内该值被修改,立刻返回,超时则返回空。仅一次查询。
具体可以查看DataShareClinet.php 和 DataShareServer.php
demo
php ja3er with tcpdump
浏览器返回none,可以通过chrome://net-internals/#sockets 关闭socket重新触发握手。
源码
项目 Xxx-Bin/php-ja3,具体可见 ja3_tcpdump.php
关于tshark
在本地调试时,用的就是tshark,tshark相比tcpdump,有分析功能。利用分析工具,可以通过以下命令直接获得处理过的内容。好处是不用处理二进制数据,只要过滤掉ja3_full不需要信息,更加方便。缺点是,该模式和 -w - 选项冲突,结果就是必然的会输出额外的临时文件。
"C:\Program Files\Wireshark\tshark.exe" -i 9 -f "tcp port 443 and (tcp[tcp[12]/16*4]=22 and (tcp[tcp[12]/16*4+5]=1) and (tcp[tcp[12]/16*4+9]=3) and (tcp[tcp[12]/16*4+1]=3))" -n -l -T fields -e "tls.handshake.ja3_full" -e "ip.src" -e "tcp.srcport" -e "ip.dst" -e "tcp.dstport" -q
771,43690-4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,19018-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-2570-21,19018-29-23-24,0 127.0.0.1 55234 127.0.0.100 443
后话
利用tcpdump转包相比之前共用端口的流量转化在可靠性上会稍微好些,前者在机制上就决定了程序挂掉了也不影响数据传输,而后者,挂掉了就都挂掉了。当然性能如何还需要再进行测试,这就是另外的课题了。
参考
Linux 网络分析必备技能:tcpdump 实战详解
TCPDUMP 手册页
MAN PAGE OF PCAP-SAVEFILE