Wireshark远程抓包分析&自定义应用层协议解析

本文介绍了如何通过安装rpcapd程序在服务器端进行网络封包捕获,并在本地利用Wireshark进行配置,实现远程封包分析。同时,详细阐述了如何使用Lua脚本自定义应用层协议解析,以解析特定UDP端口的数据包。在实践中,可以优化捕获过滤器、显示过滤器和Lua脚本,以提高分析效率和可视化效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.操作步骤:

1.1 服务器端安装rpcapd程序
1.2 本地Wireshark安装和配置
1.3 自定义应用层协议解析

1.1 服务器端安装rpcapd程序

①安装glibc程序,C运行库

redhat/centos系列安装
sudo yum install glibc-static
debian/ubuntu系列安装
sudo apt-get install libc6-dev

下载rpcapd安装包,也可以官网下载

wget http://www.winpcap.org/install/bin/WpcapSrc_4_1_2.zip
unzip WpcapSrc_4_1_2.zip

③ 编译rpcapd

cd winpcap/wpcap/libpcap
chmod +x configure runlex.sh
CFLAGS=-static ./configure
make
cd rpcapd && make

④ 运行rpcapd

./rpcapd -n -d

⑤ 检查rpcapd运行状态

netstat -nltp|grep rpcapd
查看端口和进程是否正常,默认端口2002

1.2 本地Wireshark安装和配置

①安装wireshark程序

②配置远程捕获接口(可以此时设置捕获过滤器条件)

③查看效果

1.3 自定义应用层协议解析

①Wireshark上配置Lua脚本插件地址

②Lua脚本文件如下packet-dt.lua(解析器表部分根据自己需要监听的UDP端口更改):

do
    local proto = Proto("SRUDP","Stream Rapid UDP")
    --协议的各个字段
    local f_protocol = ProtoField.uint32("SRUDP.protocol","Protocol", base.DEC)
    local f_version = ProtoField.uint32("SRUDP.version","Version", base.DEC)
    local f_msgCode = ProtoField.uint32("SRUDP.msgCode","MsgCode", base.DEC)
    local f_msgType = ProtoField.string("SRUDP.msgType","MsgType", base.UTF8)
    local f_connectId = ProtoField.uint64("SRUDP.connectId","ConnectId", base.DEC)
    local f_msgSeq = ProtoField.uint32("SRUDP.msgSeq","MsgSeq", base.DEC)
    local f_streamHash = ProtoField.uint64("SRUDP.streamHash","StreamHash", base.DEC)
    local f_tsIdx = ProtoField.uint32("SRUDP.tsIdx","TsIdx", base.DEC)
    local f_piecesCount = ProtoField.uint32("SRUDP.piecesCount","PiecesCount", base.DEC)
    local f_pieceSeq = ProtoField.uint32("SRUDP.pieceSeq","PieceSeq", base.DEC)
    local f_timestamp = ProtoField.uint64("SRUDP.timestamp","Timestamp", base.DEC)
    local f_payloadEncrypt = ProtoField.uint16("SRUDP.payloadEncrypt","PayloadEncrypt", base.DEC)
    local f_payloadType = ProtoField.uint16("SRUDP.payloadType","PayloadType", base.DEC)
    local f_payloadLength = ProtoField.uint32("SRUDP.payloadLength","PayloadLength", base.DEC)
    local f_requestParams = ProtoField.string("SRUDP.requestParams","RequestParams", base.UTF8)
    local f_body = ProtoField.bytes("SRUDP.body","Body")


    --这里把DT协议的全部字段都加到proto这个变量的fields字段里
    proto.fields = {
    f_protocol,
    f_version,
    f_msgCode,
    f_msgType,
    f_connectId,
    f_msgSeq,
    f_streamHash,
    f_tsIdx,
    f_piecesCount,
    f_pieceSeq,
    f_timestamp,
    f_payloadEncrypt,
    f_payloadType,
    f_payloadLength,
    f_requestParams,
    f_body
    }
    
    local function SRUDP_dissector(buf,pkt,root)
        local buf_len = buf:len();
        --先检查报文长度,太短的不是我的协议
        if buf_len > 1388 then return false end


        --验证一下identifier这个字段是不是0x12,如果不是的话,认为不是我要解析的packet
        local v_protocol = buf(0, 4)
        local v_version = buf(4, 4)
        local v_msgCode = buf(8, 4)
        local v_msgType
        local v_code = v_msgCode:uint()
        if(v_code == 1000)
        then
            v_msgType = 'SUBSCRIBE_AND_LOGIN'
        elseif(v_code == 1001)
        then
            v_msgType = 'SUBSCRIBE_ACK'
        elseif(v_code == 1002)
        then
            v_msgType = 'UNSUBSCRIBE'
        elseif(v_code == 1100)
        then
            v_msgType = 'NOTIFY_INDEX'
        elseif(v_code == 1101)
        then
            v_msgType = 'INDEX_REQUEST'
        elseif(v_code == 1200)
        then
            v_msgType = 'BLOCK_PUSH_RESPONSE'
        elseif(v_code == 1201)
        then
            v_msgType = 'BLOCK_REQUEST'
        elseif(v_code == 1300)
        then
            v_msgType = 'HEARTBEAT_REQUEST'
        elseif(v_code == 1301)
        then
            v_msgType = 'HEARTBEAT_RESPONSE'
        else
            v_msgType = 'UNKNOWN_MSG'
        end
        
            
        local v_connectId = buf(12, 8)
        local v_msgSeq = buf(20, 4)
        local v_streamHash = buf(24, 8)
        local v_tsIdx = buf(32, 4)
        local v_piecesCount = buf(36, 4)
        local v_pieceSeq = buf(40, 4)
        local v_timestamp = buf(44, 8)
        local v_payloadEncrypt = buf(52, 2)
        local v_payloadType = buf(54, 2)
        local v_payloadLength = buf(56, 4)
        local v_requestParams;
        local v_body;
        if(buf_len<1000)
        then
            v_requestParams = buf(60, buf_len-60)
        else    
            v_body = buf(60, buf_len-60)
        end
            


        
        --现在知道是我的协议了,放心大胆添加Packet Details
        local t = root:add(proto,buf)
        --在Packet List窗格的Protocol列可以展示出协议的名称
        pkt.cols.protocol = "SRUDP"
        --这里是把对应的字段的值填写正确,只有t:add过的才会显示在Packet Details信息里. 所以在之前定义fields的时候要把所有可能出现的都写上,但是实际解析的时候,如果某些字段没出现,就不要在这里add
        t:add(f_protocol,v_protocol)
        t:add(f_version,v_version)
        t:add(f_msgCode,v_msgCode)
        t:add(f_msgType,v_msgType)
        t:add(f_connectId,v_connectId)
        t:add(f_msgSeq,v_msgSeq)
        t:add(f_streamHash,v_streamHash)
        t:add(f_tsIdx,v_tsIdx)
        t:add(f_piecesCount,v_piecesCount)
        t:add(f_pieceSeq,v_pieceSeq)
        t:add(f_timestamp,v_timestamp)
        t:add(f_payloadEncrypt,v_payloadEncrypt)
        t:add(f_payloadType,v_payloadType)
        t:add(f_payloadLength,v_payloadLength)
        if(buf_len<1000)
        then
            t:add(f_requestParams,v_requestParams)
        else    
            t:add(f_body,v_body)
        end
                                              
        return true
    end
    
    
    --这里是获取data这个解析器
    local data_dis = Dissector.get("data")
    
    --这段代码是目的Packet符合条件时,被Wireshark自动调用的,是proto的成员方法
    function proto.dissector(buf,pkt,root)
        if SRUDP_dissector(buf,pkt,root) then
        else
            --data这个dissector几乎是必不可少的;当发现不是我的协议时,就应该调用data
            data_dis:call(buf,pkt,root)
        end
    end
    
    local udp_encap_table = DissectorTable.get("udp.port")
    --因为我们的DT协议的接受端口肯定是50002,所以这里只需要添加到"udp.port"这个DissectorTable里,并且指定值为50002即可。
    udp_encap_table:add(33188, proto)
    udp_encap_table:add(8891, proto)
end

③Lua脚本文件每次更新需要重新载入Lua插件

④效果查看

⑤现在可以实时解析远程服务器的发包收包情况了,同时可以自行解析应用层协议。优化点如下:

    1)监听接口时,精细化捕获过滤器条件,这样会减少解析包的数量。
    2)精细化显示过滤器条件,更专注于自定义协议解析。如只展示srudp协议
    3)优化lua脚本,当前使用udp.port解析器表来匹配自定义解析器,需要手动配置关联监听的UDP端口号,每次都需要手动关联并重新加载Lua插件。寻找一种更方便的匹配方式。
    4)Wireshark包解析界面,展示应用层消息类型和消息序号至主界面,对发包收包分别着色展示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值