好记性不如铅笔头

编程, 网络通讯

使用wireshark和LUA脚本对报文进行筛选保存

最近需要对wireshark抓到的报文进行二次筛选和分析,为了提高工作效率,还是使用lua脚本来扩展wireshark的功能,主要做法为将符合条件的报文找出来,然后重新保存到单独的pcap文件中,这里笔记一下简单的思路和部分工具代码。

简单起见,我们可以在lua脚本启动时创建一个pcap文件,也可以在发现符合条件的报文时创建一个文件,为了减少复杂度,这里pcap文件保存为IP层报文。参考代码如下:

--当前日期 当前时间
local curr_time = os.date("%Y%m%d_%H_%M_%S")
local raw_file = nil
local raw_file_name = "cap_files/"..curr_time..".pcap"

local function create_new_pcap_file()
	if(raw_file ~= nil) then
		return nil
	end

	Dir.make("cap_files")
	raw_file = io.open(raw_file_name, "wb")

-- pcap 文件头部Global Header 共 24 Byte
	local global_pcap_header = {
		0xD4, 0xC3, 0xB2, 0xA1,  -- Magic 4Byte
		0x02, 0x00,              -- Major 2Byte
		0x04, 0x00,              -- Minor 2Byte
		0x00, 0x00, 0x00, 0x00,   -- ThisZone 4Byte
		0x00, 0x00, 0x00, 0x00,   -- SigFigs 4Byte
		0x00, 0x00, 0x04, 0x00,   -- SnapLen 4Byte  ffff 0000
		0x65, 0x00, 0x00, 0x00    -- LinkType 4Byte 目前只保存IP层的报文(101)
	}
	raw_file:write( string.char( table.unpack(global_pcap_header) ) )
	raw_file:flush()
end

当我们发现符合筛选条件的报文时,把报文附加到pcap文件尾巴上:

-- B1 B2 B3 B4
local function B4(value)  return value % 256   end
local function B3(value)  return B4(value/256) end
local function B2(value)  return B3(value/256) end
local function B1(value)  return B2(value/256) end

local function write_pkt_to_pcap_file(pinfo, tvb)
	-- create_new_pcap_file()
	local cap_sec = math.floor(pinfo.abs_ts)
	local cap_msec = math.floor( (pinfo.abs_ts - cap_sec) * 1000000 )
	local ip_packet_len = pinfo.len - pkt_ip_offset

	local packet_pcap_header = {
		B4(cap_sec),  B3(cap_sec),  B2(cap_sec),  B1(cap_sec),   -- Timestamp 被捕获时间的高位 单位是seconds
		B4(cap_msec), B3(cap_msec), B2(cap_msec), B1(cap_msec),  -- Timestamp 被捕获时间的低位 单位是microseconds
		B4(ip_packet_len), B3(ip_packet_len), B2(ip_packet_len), B1(ip_packet_len),  -- Caplen
		B4(ip_packet_len), B3(ip_packet_len), B2(ip_packet_len), B1(ip_packet_len)   -- Len
	}
	raw_file:write( string.char( table.unpack(packet_pcap_header) ) )

	raw_file:write( tvb:raw(pkt_ip_offset) )
	raw_file:flush()
end

当整个报文序列分析结束后,我们可以关闭报文IO句柄:

-- 关闭文件句柄,考虑到一般都是实时抓取,强制退出,一般都不会有调用机会。
local function close_pcap_file()
	if(raw_file ~= nil) then
		raw_file:flush()
		raw_file:close()
		raw_file = nil
	end
end

发表评论

11 − 4 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据