Wireshark解析自定义加密协议.docx | 您所在的位置:网站首页 › 加密算法介绍ppt › Wireshark解析自定义加密协议.docx |
Wireshark解析自定义加密协议.docx 《Wireshark解析自定义加密协议.docx》由会员分享,可在线阅读,更多相关《Wireshark解析自定义加密协议.docx(13页珍藏版)》请在冰豆网上搜索。 Wireshark解析自定义加密协议 Wireshark解析自定义加密协议 ByTerry2015年3月15日 一、概述 网上撰文写wireshark使用lua脚本解析协议的文章比较多。 笔者最近也因工作需要使用wireshark解析协议。 但因网络安全,协议的数据部分被加密了。 无法简单的使用lua脚本进行解析。 考虑到加密算法和压缩算法的复杂性,采用调用luaC库的方法,完成解密(解压)。 下面与大家分享下大致思路。 二、思路和目标 协议的大致格式如下: 协议字段 命名 协议版本(1字节) protoVersion 协议命令类型(2字节) protoCmdType 协议加密类型(1字节) protoEncrytionType 协议压缩类型(1字节) protoCompressionType 协议数据长度(4字节) protoDataLength 协议数据(protoDataLength字节) protoData : 本文仅专注于解码,为简化复杂性,暂时不考虑一个UDP/TCP包出现多个自定义数据包的情况。 Lua脚本的伪代码: localp_multi=Proto("multi","MultiProto"); localf_protoVersion=ProtoField.uint8("multi.protoVersion","Version",base.DEC) localf_protoCmdType=ProtoField.uint16("multi.protoCmdType","CmdType",base.DEC,{ [1]="CmdType_1", [2]="CmdType_2", [3]="CmdType_3", }) localf_protoEncrytionType=ProtoField.uint8( "multi.protoEncrytionType","EncrytionType",base.DEC,{ [1]="EncrytionType_1", [2]="EncrytionType_2", [3]="EncrytionType_3", }) localf_protoCompressionType=ProtoField.uint8( "multi.protoCompressionType","CompressionType",base.DEC,{ [1]="CompressionType_1", [2]="CompressionType_2", [3]="CompressionType_3", }) localf_protoDataLength=ProtoField.uint32("multi.protoDataLength","DataLength",base.DEC) p_multi.fields={f_protoVersion,f_protoCmdType,f_protoEncrytionType, f_protoCompressionType,f_protoDataLength} functionDecodeBufferFunction(protoEncrytionType,protoCompressionType,buf,pos,buf_len) localdecodeBuf=buf --TODO: Thisarticaljob returndecodeBuf end functionp_multi.dissector(buf,pkt,root) localpos=0 localbuf_len=buf: len() localt=root: add(p_multi,buf(0,buf_len)) --协议版本(1字节) t: add(f_protoVersion,buf(pos,1)) pos=pos+1 --协议命令类型(2字节) t: add(f_protoCmdType,buf(pos,2)) pos=pos+2 --协议加密类型(1字节) t: add(f_protoEncrytionType,buf(pos,1)) localprotoEncrytionType=buf(pos,1): uint() pos=pos+1 --协议压缩类型(1字节) t: add(f_protoCompressionType,buf(pos,1)) localprotoCompressionType=buf(pos,1): uint() pos=pos+1 --协议数据长度(4字节) t: add(f_protoDataLength,buf(pos,1)) localprotoDataLength=buf(pos,4): uint() pos=pos+4 --协议数据(protoDataLength字节) buf=DecodeBuffer(protoEncrytionType,protoCompressionType,buf,pos,buf_len) new_buf_len=buf: len() --TODO: addyourcode end 本文的主要任务是DecodeBufferFunction的实现。 目前的任务是把原始数据(buf) 协议头 加密数据 变成(decodeBuf) 协议头 解密数据 上图实际上就是原始buf和decodeBuf。 这里buf、decodeBuf均为Tvb("TestyVirtualBuffer").另外,为操持两个buf在偏移上的一致,decodeBuf的头部也添加了“协议头” 因而DecodeBufferFunction的任务有3个: 1.由buf转换成luac库的数据结构 2.Luac库完成解码,并返回数据 3.再由luac库的数据结构转换成decodeBuf. 当然,如果我们知道Tvb的数据结构格式,可以省去第1、3步。 三、Luac库的编写 Luac库的开发可以参考相关资料。 本文的开发需要用到LuaBinaries.可以在: 下载。 详细路径: 本文使用了lua-5.1.5_Win32_dll10_lib.zip Luac库的结构定义如下: typedefstructMyByteArray{ intsize; unsignedcharvalues[1];/*variablepart*/ }MyByteArray; : wireshark中的Tvb、ByteArray都是以0为起始索引的方式。 所以下面MyByteArray也以0为索引。 这一点和lua语言提倡的方式不一致。 本文采用vs2010生成一个win32dll的库,工程名称: decode.工程向导设置如下: 删除decode.h和decode.cpp中的,示例代码。 并在decode.h中,把导出定义改成: #ifdefDECODE_EXPORTS #defineDECODE_APIextern"C"__declspec(dllexport) #else #defineDECODE_APIextern"C"__declspec(dllimport) #endif 并引入lua-5.1.5_Win32_dll10_lib的库到本工程。 本文使用了《PrograminLua》第28章的部分示例代码。 关键源代码如下: Stdafx.h //stdafx.h: includefileforstandardsystemincludefiles, //orprojectspecificincludefilesthatareusedfrequently,but //arechangedinfrequently // #pragmaonce #include"targetver.h" #defineWIN32_LEAN_AND_MEAN//Excluderarely-usedstufffromWindowsheaders //WindowsHeaderFiles: #include
//TODO: referenceadditionalheadersyourprogramrequireshere #include"include/lua.hpp" #pragmacomment(lib,"lib/lua51") decode.h //Thefollowingifdefblockisthestandardwayofcreatingmacroswhichmakeexporting //fromaDLLsimpler.AllfileswithinthisDLLarecompiledwiththeDECODE_EXPORTS //symboldefinedonthecommandline.Thissymbolshouldnotbedefinedonanyproject //thatusesthisDLL.Thiswayanyotherprojectwhosesourcefilesincludethisfilesee //DECODE_APIfunctionsasbeingimportedfromaDLL,whereasthisDLLseessymbols //definedwiththismacroasbeingexported. #ifdefDECODE_EXPORTS #defineDECODE_APIextern"C"__declspec(dllexport) #else #defineDECODE_APIextern"C"__declspec(dllimport) #endif typedefstructMyByteArray{ intsize; unsignedcharvalues[1];/*variablepart*/ }MyByteArray; enumEncryptionType { EncryptionType_begin, EncryptionType_1=EncryptionType_begin, EncryptionType_2, EncryptionType_3, //new... EncryptionType_end=EncryptionType_3, }; enumCompressionType { CompressionType_begin, CompressionType_1=CompressionType_begin, CompressionType_2, CompressionType_3, //new... CompressionType_end=CompressionType_3, };
DECODE_APIintluaopen_decode(lua_State*L); staticintnewarray(lua_State*L); staticintsetarray(lua_State*L); staticintgetarray(lua_State*L); staticintgetsize(lua_State*L); staticintdecodearray(lua_State*L); staticMyByteArray*decryptarray(unsignedcharencryptionType,MyByteArray*myarray); staticMyByteArray*decompressarray(unsignedcharencryptionType,MyByteArray*myarray); decode.cpp //decode.cpp: DefinestheexportedfunctionsfortheDLLapplication. // #include"stdafx.h" #include"decode.h" staticconststructluaL_regdecodeLib[]={ {"new",newarray}, {"set",setarray}, {"get",getarray}, {"size",getsize}, {"decode",decodearray}, {NULL,NULL} }; intluaopen_decode(lua_State*L){ luaL_openlib(L,"decode",decodeLib,0); return1; } staticintnewarray(lua_State*L){ intn=luaL_checkint(L,1); size_tnbytes=sizeof(MyByteArray)+(n-1)*sizeof(unsignedchar); MyByteArray*a=(MyByteArray*)lua_newuserdata(L,nbytes); a->size=n; return1;/*newuserdatumisalreadyonthestack*/ } staticintsetarray(lua_State*L){ MyByteArray*a=(MyByteArray*)lua_touserdata(L,1); intindex=luaL_checkint(L,2); unsignedcharvalue=(unsignedchar)luaL_checknumber(L,3); luaL_argcheck(L,a! =NULL,1,"`array'expected"); luaL_argcheck(L,0size,2, "indexoutofrange"); a->values[index]=value; return0; } staticintgetarray(lua_State*L){ MyByteArray*a=(MyByteArray*)lua_touserdata(L,1); intindex=luaL_checkint(L,2); luaL_argcheck(L,a! =NULL,1,"'array'expected"); luaL_argcheck(L,0size,2, "indexoutofrange"); lua_pushnumber(L,a->values[index]); return1; } staticintgetsize(lua_State*L){ MyByteArray*a=(MyByteArray*)lua_touserdata(L,1); luaL_argcheck(L,a! =NULL,1,"`array'expected"); lua_pushnumber(L,a->size); return1; } staticintdecodearray(lua_State*L){ unsignedcharencryptionType=(unsignedchar)lua_touserdata(L,1); unsignedcharcompressionType=(unsignedchar)lua_touserdata(L,2); MyByteArray*a=(MyByteArray*)lua_touserdata(L,3); luaL_argcheck(L,EncryptionType_begin 2,"undefineencryptiontype"); luaL_argcheck(L,CompressionType_begin 2,"undefinecompressiontype"); luaL_argcheck(L,a! =NULL,3,"`array'expected"); MyByteArray*a1=NULL; MyByteArray*a2=NULL; if(NULL! =a){ a1=decryptarray(encryptionType,a); if(NULL! =a1){ a2=decryptarray(compressionType,a1); } } if(NULL! =a2){ lua_pushlightuserdata(L,a2); } else{ lua_pushnil(L); } return1; } ////////////////////////////////////////////////////////////////////////// staticMyByteArray*decryptarray(unsignedcharencryptionType,MyByteArray*myarray){ MyByteArray*retarray=NULL; switch(encryptionType){ caseEncryptionType_1: //TODO: break; caseEncryptionType_2: //TODO: break; caseEncryptionType_3: //TODO: break; default: break; } returnretarray; } staticMyByteArray*decompressarray(unsignedcharencryptionType,MyByteArray*myarray){ MyByteArray*retarray=NULL; switch(encryptionType){ caseCompressionType_1: //TODO: break; caseCompressionType_2: //TODO: break; caseCompressionType_3: //TODO: break; default: break; } returnretarray; } 4、调用luac库解码 Lua解析脚本的开头需要增加部分代码,以加载新开发的decode.dll库。 Path="D: \\Documents\\VisualStudio2010\\Projects\\decode\\Debug\\decode.dll" decodelib=package.loadlib(path,"luaopen_decode") ifnil~=decodelibthen decodelib() end DecodeBufferFunction的实现如下: functionDecodeBufferFunction(protoEncrytionType,protoCompressionType,buf,pos,buf_len) ifnil~=decodethen --constructMyByteArray localrawLen=buf_len-pos array=decode.new(rawLen) fori=0,rawLen-1,1do decode.set(array,i,buf(pos,1): uint()) end --decode array=decode.decode(protoEncrytionType,protoCompressionType,array) ifnil~=arraythen --constructdecodeBuftvb localdecodeLen=decode.size(array) --constructtvbthroughtwiresharkByteArray localbArray=ByteArray.new(decodeLen+pos) fori=0,pos-1,1do bArray.set_index(i,buf(i,1): uint()) end fori=0,decodeLen-1,1do bArray.set_index(pos+i,decode.get(array,i)) end --returedecodebuffer returnbArray.tvb("decodeBuf") end end returnnil end 5、总结 通过上面的介绍,提供了wireshark中解析自定义加密协议的思路和大致实现。 需要注意的是: 1.LuaBinarires的版本问题。 Wireshark采用了lua5.1和lua5.2,因此需要使用对应的LuaBinarires版本进行开发; 2.开发luac库,需要使用LuaBinarires的动态库版本。 尤其是lua5.2,如果使用静态库进行开发,wireshark在加载deco |
CopyRight 2018-2019 实验室设备网 版权所有 |