Wireshark BPF 捕获过滤器
Wireshark 中,如果要过滤出所有的 POST 或者是 GET 请求,我们可以用显示过滤器里的 method
过滤。但是如果流量过大的话,涌入的数据包会填满缓冲区,过滤也需要消耗大量的 CPU 资源。
Capture Filter
Capture filter is not a display filter
Capture filters (like tcp port 80
) are not to be confused with display filters (like tcp.port == 80
). The former are much more limited and are used to reduce the size of a raw packet capture. The latter are used to hide some packets from the packet list.
Capture filters are set before starting a packet capture and cannot be modified during the capture. Display filters on the other hand do not have this limitation and you can change them on the fly.
https://wiki.wireshark.org/CaptureFilters
捕获过滤器可以在从网卡接收数据的阶段就进行过滤,大大优化抓包性能。
但是需要我们生成一个 BPF 格式的过滤规则,主要是基于二进制与偏移的。
生成器
https://www.wireshark.org/tools/string-cf.html
https://www.wireshark.org/docs/wsug_html_chunked/ChCapCaptureFilterSection.html
这里为了性能和批量生成,使用 C++ 重构了代码。
https://github.com/sfc9982/wireshark-bpf-capfilter
auto stringToBpf(std::string str, int offset) -> std::string {
std::vector<unsigned char> bytes = utf8Convert(str);
std::string snippet = "";
int slicelen;
std::string hexbytes;
std::string conj = "";
std::string offstr;
while (bytes.size() > 0) {
if (bytes.size() >= 4) {
slicelen = 4;
}
else if (bytes.size() >= 2) {
slicelen = 2;
}
else {
slicelen = 1;
}
auto slicebytes = std::vector<unsigned char>(bytes.begin(), bytes.begin() + slicelen);
bytes.erase(bytes.begin(), bytes.begin() + slicelen);
hexbytes = "";
for (auto i: slicebytes) {
char buf[3];
sprintf(buf, "%02x", i);
hexbytes += buf;
}
if (offset) {
offstr = " + " + std::to_string(offset);
}
else {
offstr = "";
}
snippet += conj + "tcp[((tcp[12:1] & 0xf0) >> 2)" + offstr + ":" + std::to_string(slicelen) + "] = 0x" + hexbytes;
conj = " && ";
offset += slicelen;
}
return snippet;
}
TODO
- 支持 UTF-8 字符
- 交互模式
Also see
- https://www.middlewareinventory.com/blog/tcpdump-capture-http-get-post-requests-apache-weblogic-websphere/