Wireshark解析HTTP GET方法不会解析URI里Query字符串里的参数(通常由GET方式提交form数据),本文介绍用lua编写一个简单的协议解析器,让这些参数解析出来,并显示在wireshark协议解析窗口里。
首先编写以下解析器lua脚本(用文本编辑器编辑即可),取文件名为my_http_querystring_decoder.lua:
-- Decode param=value from query string of http request uri (http.request.uri) -- Author: Huang Qiangxiong ([email protected]) -- change log: -- 2010-07-01 -- Just can play. ------------------------------------------------------------------------------------------------ do local querystring_decoder_proto = Proto("my_http_querystring_decoder", "Decoded HTTP URI Query String [HQX's plugins]") ---- url decode (from www.lua.org guide) function unescape (s) s = string.gsub(s, "+", " ") s = string.gsub(s, "%%(%x%x)", function (h) return string.char(tonumber(h, 16)) end) return s end ---- convert string to hex string function string2hex (s) local hex = ""; for i=1, #s, 1 do hex = hex .. string.format("%x", s:byte(i)) end return hex end local f_http_uri = Field.new("http.request.uri") ---- my dissector function querystring_decoder_proto.dissector(tvb, pinfo, tree) local http_uri = f_http_uri() -- ignore packages without "http.request.uri" if not http_uri then return end -- begin build my tree local content = http_uri.value local idx = content:find("?") if not idx then return end -- not include query string, so stop parsing local tab = ByteArray.new(string2hex(content)):tvb("Decoded HTTP URI Query String") local tab_range = tab() -- add proto item to tree local subtree = tree:add(querystring_decoder_proto, tab_range) -- add raw data to tree subtree:add(tab_range, "[HTTP Request URI] (" .. tab_range:len() .. " bytes)"):add(tab_range, content) -- add param value pair to tree local pairs_tree = subtree:add(tab_range, "[Decoded Query String]") local si = 1 local ei = idx local count = 0 while ei do si = ei + 1 ei = string.find(content, "&", si) local xlen = (ei and (ei - si)) or (content:len() - si + 1) if xlen > 0 then pairs_tree:add(tab(si-1, xlen), unescape(content:sub(si, si+xlen-1))) count = count + 1 end end pairs_tree:append_text(" (" .. count .. ")") end -- register this dissector register_postdissector(querystring_decoder_proto) end
然后修改wireshark安装目录下的init.lua文件:
(1)把disable_lua = true; do return end;这行注释掉:在前面加“--”
(2)然后在init.lua文件最后面加一句:dofile("my_http_querystring_decoder.lua")
OK大功告成,打开HTTP抓包,若其请求中URI带QueryString,则界面如下:
可以看到,在协议解析树上新增了Decoded HTTP URI Query String ... 节点。看该节点下[HTTP Request URI]为原始HTTP Request URI,[Decoded Query String]下为解开后的一个个参数(经过url decode)。而且在wireshark的“Packet Bytes”窗口里新增了一个“Decoded HTTP URI Query String”的数据tab,专门显示HTTP URI内容,用于显示参数在URL里的原始形式。
另外,如果要解析HTTP Body部分的参数(用POST方法提交form数据),请参考《用Wireshark lua编写的协议解析器查看Content-Type为application/x-www-form-urlencoded的HTTP抓包》(http://blog.csdn.net/jasonhwang/archive/2010/04/25/5525700.aspx)。
注:wireshark版本为1.3.4
2015年更新:
-- Decode param=value from query string of http request uri (http.request.uri) -- Author: Huang Qiangxiong ([email protected]) -- change log: -- 2010-07-01 -- Just can play. ------------------------------------------------------------------------------------------------ do local querystring_decoder_proto = Proto("my_http_querystring_decoder", "Decoded HTTP URI Query String [HQX's plugins]") ---- url decode (from www.lua.org guide) function unescape (s) s = string.gsub(s, "+", " ") s = string.gsub(s, "%%(%x%x)", function (h) return string.char(tonumber(h, 16)) end) return s end ---- convert string to hex string function string2hex (s) local hex = ""; for i=1, #s, 1 do hex = hex .. string.format("%x", s:byte(i)) end return hex end local f_http_uri = Field.new("http.request.uri") ---- my dissector function querystring_decoder_proto.dissector(tvb, pinfo, tree) local http_uri = f_http_uri() -- ignore packages without "http.request.uri" if not http_uri then return end -- begin build my tree local content = http_uri.value local idx = content:find("?") if not idx then return end -- not include query string, so stop parsing local tab = ByteArray.new(string2hex(content)):tvb("Decoded HTTP URI Query String") local tab_range = tab() -- add proto item to tree local subtree = tree:add(querystring_decoder_proto, tab_range) -- add raw data to tree subtree:add(tab_range, "[HTTP Request URI] (" .. tab_range:len() .. " bytes)"):add(tab_range, content) -- add param value pair to tree local pairs_tree = subtree:add(tab_range, "[Decoded Query String]") local si = 1 local ei = idx local count = 0 while ei do si = ei + 1 ei = string.find(content, "&", si) local xlen = (ei and (ei - si)) or (content:len() - si + 1) if xlen > 0 then --pairs_tree:add(tab(si-1, xlen), unescape(content:sub(si, si+xlen-1))) pairs_tree:add(tab(si-1, xlen), unescape(content:sub(si, si+xlen-1):gsub("=", " = ", 1))) count = count + 1 end end pairs_tree:append_text(" (" .. count .. ")") end -- register this dissector register_postdissector(querystring_decoder_proto) end