Wireshark解析自定义加密协议.docx 您所在的位置:网站首页 加密算法介绍ppt Wireshark解析自定义加密协议.docx

Wireshark解析自定义加密协议.docx

2023-04-01 21:26| 来源: 网络整理| 查看: 265

Wireshark解析自定义加密协议.docx

《Wireshark解析自定义加密协议.docx》由会员分享,可在线阅读,更多相关《Wireshark解析自定义加密协议.docx(13页珍藏版)》请在冰豆网上搜索。

Wireshark解析自定义加密协议.docx

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 实验室设备网 版权所有