天网防火墙的配置文件加密方法——兼谈RC6算法 (www.team509.com)
2005-06-24 13:22
513 查看
author: doublelee
date: 2005-6-1
天网防火墙2.50版,用Borland C编译,规则配置文件是加密的。为了绕开其监控,必须能够读写其规则配置文件并重新启动之。
本文主要说说怎样读写其配置文件,顺便谈谈RC6的基本情况,作为备忘。
author: doublelee
date: 2005-6-1
天网防火墙2.50版,用Borland C编译,规则配置文件是加密的。为了绕开其监控,必须能够读写其规则配置文件并重新启动之。
本文主要说说怎样读写其配置文件,顺便谈谈RC6的基本情况,作为备忘。
说实话这个软件真还算比较绿色了,连个dll文件都没有,就那么几个exe,就能拦截几乎所有本地网络数据包了。但是正因为这样也就缺少了必要的保护,作为普通进程,典型缺点就是进程可以轻松被杀掉。
其实跟踪过程不外乎那么几招。扔进IDA找到关键字AppRule.dat或config.ini,顺藤摸瓜就是了。虽然Borland C的传参数方式比较令人不爽,不压栈,不过看在天网是个没有壳的程序,少了很多麻烦,也就不追究了吧。
反汇编出来居然有RC6::TRC6这样的符号信息。工作马上变的没有难度了,找来RC6的源码对照阅读,很快就可以理清思路。天网防火墙内置的加密算法果然是标准的RC6。用的512bit密钥,分组长度128bit,ECB模式。密钥是"TENYKS"。
全贴太多了,这里就只贴密钥初始化部分的反汇编代码(来自RuleWize.exe)这一段对应后面的setkey函数
.text:00408284 ; 圹圹圹圹圹圹圹?S U B R O U T I N E 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹?
.text:00408284
.text:00408284 ; Attributes: bp-based frame
.text:00408284
.text:00408284 ; __fastcall Rc6::TRC6::CalculateSubKeys(void)
.text:00408284 public @Rc6@TRC6@CalculateSubKeys$qqrv
.text:00408284 @Rc6@TRC6@CalculateSubKeys$qqrv proc near ; DATA XREF: .text:0040823Co
.text:00408284
.text:00408284 m_l_table = dword ptr -58h
.text:00408284 m_b = dword ptr -18h
.text:00408284 m_a = dword ptr -14h
.text:00408284 m_k = dword ptr -10h
.text:00408284 m_j = dword ptr -0Ch
.text:00408284 m_i = dword ptr -8
.text:00408284 l_key = dword ptr -4
.text:00408284
.text:00408284 push ebp
.text:00408285 mov ebp, esp
.text:00408287 add esp, 0FFFFFFA8h
.text:0040828A mov [ebp+l_key], eax
.text:0040828D mov eax, [ebp+l_key]
.text:00408290 mov ecx, [eax+10h]
.text:00408293 lea edx, [ebp+m_l_table]
.text:00408296 mov eax, [ebp+l_key]
.text:00408299 mov eax, [eax+14h]
.text:0040829C call @System@Move$qqrpxvpvi ; System::Move(void *,void *,int)
.text:004082A1 mov eax, [ebp+l_key]
.text:004082A4 mov dword ptr [eax+30h], 0B7E15163h
.text:004082AB mov [ebp+m_i], 1
.text:004082B2
.text:004082B2 loc_4082B2: ; CODE XREF: Rc6::TRC6::CalculateSubKeys(void)+4Ej
.text:004082B2 mov eax, [ebp+l_key]
.text:004082B5 mov edx, [ebp+m_i]
.text:004082B8 mov eax, [eax+edx*4+2Ch]
.text:004082BC add eax, 9E3779B9h
.text:004082C1 mov edx, [ebp+l_key]
.text:004082C4 mov ecx, [ebp+m_i]
.text:004082C7 mov [edx+ecx*4+30h], eax
.text:004082CB inc [ebp+m_i]
.text:004082CE cmp [ebp+m_i], 2Ch
.text:004082D2 jnz short loc_4082B2
.text:004082D4 xor eax, eax
.text:004082D6 mov [ebp+m_i], eax
.text:004082D9 xor eax, eax
.text:004082DB mov [ebp+m_j], eax
.text:004082DE xor eax, eax
.text:004082E0 mov [ebp+m_a], eax
.text:004082E3 xor eax, eax
.text:004082E5 mov [ebp+m_b], eax
.text:004082E8 mov [ebp+m_k], 1
.text:004082EF
.text:004082EF loc_4082EF: ; CODE XREF: Rc6::TRC6::CalculateSubKeys(void)+E6j
.text:004082EF mov eax, [ebp+l_key]
.text:004082F2 mov edx, [ebp+m_i]
.text:004082F5 mov eax, [eax+edx*4+30h] ; eax=l_key[i];
.text:004082F9 add eax, [ebp+m_a]
.text:004082FC add eax, [ebp+m_b]
.text:004082FF mov edx, 3
.text:00408304 call m_rotl_eax_edx
.text:00408309 mov [ebp+m_a], eax
.text:0040830C mov eax, [ebp+l_key]
.text:0040830F mov edx, [ebp+m_i]
.text:00408312 mov ecx, [ebp+m_a]
.text:00408315 mov [eax+edx*4+30h], ecx ; l_key[i]=a;
.text:00408319 mov edx, [ebp+m_a]
.text:0040831C add edx, [ebp+m_b]
.text:0040831F mov eax, [ebp+m_j]
.text:00408322 mov eax, [ebp+eax*4+m_l_table]
.text:00408326 add eax, [ebp+m_a]
.text:00408329 add eax, [ebp+m_b]
.text:0040832C call m_rotl_eax_edx
.text:00408331 mov [ebp+m_b], eax ; b=rotl()
.text:00408334 mov eax, [ebp+m_j]
.text:00408337 mov edx, [ebp+m_b]
.text:0040833A mov [ebp+eax*4+m_l_table], edx ; l[j]=b;
.text:0040833E mov eax, [ebp+m_i]
.text:00408341 inc eax
.text:00408342 mov ecx, 2Ch
.text:00408347 cdq
.text:00408348 idiv ecx ; i=(i+1)%44;
.text:0040834A mov [ebp+m_i], edx
.text:0040834D mov eax, [ebp+m_j]
.text:00408350 inc eax
.text:00408351 and eax, 8000000Fh
.text:00408356 jns short loc_40835D
.text:00408358 dec eax
.text:00408359 or eax, 0FFFFFFF0h
.text:0040835C inc eax
.text:0040835D
.text:0040835D loc_40835D: ; CODE XREF: Rc6::TRC6::CalculateSubKeys(void)+D2j
.text:0040835D mov [ebp+m_j], eax
.text:00408360 inc [ebp+m_k]
.text:00408363 cmp [ebp+m_k], 85h
.text:0040836A jnz short loc_4082EF
.text:0040836C mov esp, ebp
.text:0040836E pop ebp
.text:0040836F retn
.text:0040836F @Rc6@TRC6@CalculateSubKeys$qqrv endp
.text:0040836F
RC6到处可以下载到,c的asm的单片机加速版的perl的。不过某些for Delphi的居然还收费,真不嫌丢人。我是在http://fp.gladman.plus.com/cryptography_technology/aesr2/下载了一份并在其基础上修改的。
在模拟其加密的过程中遇到了一点小麻烦,B. R. Gladman 为AES测试写的RC6版本固定密钥长度为256bit,我跟踪了半天才发现这一点,改成了512。其他没有问题。把"aes_defs.h"这个头文件掐掉。边角作点修修补补,就完成了。另外看的出Gladman为了竞选AES作了些优化,也许能使速度快一点。
下面分析无程序破解其密文的可能性。
首先使用的加密模式是ECB,微小的明文改动导致密文仅一个分组的改动。很容易经选择明文攻击判断出其分组长度,进而推断可能的加密算法。这一点在动手砍软件之前我是初步判断过的。
其次虽然密钥用了512bit的,但是初始化用的密钥是固定的!而且居然用仅仅6个字节的"TENYKS",这里有遭受暴力破解的可能性。
总体来说,天网的配置文件加密虽然用了不错的算法,可惜只是一层窗户纸,一捅就破。主要弱点在于固定密钥并且太短。不过话说回来即使弄的再复杂一点也没有什么用。
RC6的简单描述:
RC6是Ron Rivest设计的系列加密算法之一,从RC5改进而来,与RC4完全不同的一点是,RC5和RC6都属于分组加密算法,并且由于曾经参加过AES选拔赛,都是设计为可以调整密钥和分组的长度的。虽然最后落选,不过也算是当今比较优秀的加密算法之一了。
分析RC6的汇编代码有以下几个要点:
1,异或少,移位多,初始化key的过程在一个132次的循环内进行了2次左移,第一次移位的位数固定为3位。加密或解密代码中有四次的左移。通常这个移位表现为一个call。
2,初始化函数中有常数0xb7e15163和0x9e3779b9。
3,加密过程中维护着一个44个元素的整型表,即共176bytes(代码中的l_key)。
最后贴代码
RC6(set_key(const u1byte in_key[], const u4byte key_len))是我改动过的函数,贴出来,其他没改动就不贴了。
/////////////////////////////////////////////////////////////////////////////////////////
// rc6.c
// ...
#define KEYLEN 64*8 //512 bit key length only, eg, 64 bytes.
// initialise the key schedule from the user supplied key
// void RC6(set_key(const u1byte in_key[], const u4byte key_len, const enum dir_flag f))
void RC6(set_key(const u1byte in_key[], const u4byte key_len))
{
u4byte l[KEYLEN/32], i, j, k, a, b, t;
u1byte * pl = (u1byte*)l;
RC6(l_key)[0] = 0xb7e15163;
for(k = 1; k < 44; ++k)
RC6(l_key)[k] = RC6(l_key)[k - 1] + 0x9e3779b9;
// for(k = 0; k < key_len / 32; ++k)
// l[k] = u4byte_in(in_key + 4 * k);
for(k = 0; k < KEYLEN/8 ; ++k)
pl[k] = in_key[ k%key_len ];
t = (KEYLEN / 32) - 1; // t = (key_len / 32);
a = b = i = j = 0;
for(k = 0; k < 132; ++k)
{
a = rotl(RC6(l_key)[i] + a + b, 3);
b += a;
b = rotl(l[j] + b, b);
RC6(l_key)[i] = a; l[j] = b;
i = (i == 43 ? 0 : i + 1); // i = (i + 1) % 44;
j = (j == t ? 0 : j + 1); // j = (j + 1) % t;
}
return;
}
/////////////////////////////////////////////////////////////////////////////////////////
// main.c
#include "rc6.h"
#include
int main(int argc, char *argv[])
{
char f[16];
FILE *fdat, *ftxt;
fdat=fopen("AppRule.dat", "rb");
if(!fdat)
return 0;
ftxt=fopen("AppRule.txt", "wb");
if(!ftxt)
return 0;
RC6(set_key)("TENYKS", 6);
while(fread(f, 1, 16, fdat))
{
RC6(decrypt)(f, f);
fwrite(f, 1, 16, ftxt);
}
fclose(fdat);
fclose(ftxt);
return 1;
// RC6(encrypt)(f, f); 加密
// RC6(decrypt)(f, f); 解密
}
date: 2005-6-1
天网防火墙2.50版,用Borland C编译,规则配置文件是加密的。为了绕开其监控,必须能够读写其规则配置文件并重新启动之。
本文主要说说怎样读写其配置文件,顺便谈谈RC6的基本情况,作为备忘。
author: doublelee
date: 2005-6-1
天网防火墙2.50版,用Borland C编译,规则配置文件是加密的。为了绕开其监控,必须能够读写其规则配置文件并重新启动之。
本文主要说说怎样读写其配置文件,顺便谈谈RC6的基本情况,作为备忘。
说实话这个软件真还算比较绿色了,连个dll文件都没有,就那么几个exe,就能拦截几乎所有本地网络数据包了。但是正因为这样也就缺少了必要的保护,作为普通进程,典型缺点就是进程可以轻松被杀掉。
其实跟踪过程不外乎那么几招。扔进IDA找到关键字AppRule.dat或config.ini,顺藤摸瓜就是了。虽然Borland C的传参数方式比较令人不爽,不压栈,不过看在天网是个没有壳的程序,少了很多麻烦,也就不追究了吧。
反汇编出来居然有RC6::TRC6这样的符号信息。工作马上变的没有难度了,找来RC6的源码对照阅读,很快就可以理清思路。天网防火墙内置的加密算法果然是标准的RC6。用的512bit密钥,分组长度128bit,ECB模式。密钥是"TENYKS"。
全贴太多了,这里就只贴密钥初始化部分的反汇编代码(来自RuleWize.exe)这一段对应后面的setkey函数
.text:00408284 ; 圹圹圹圹圹圹圹?S U B R O U T I N E 圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹?
.text:00408284
.text:00408284 ; Attributes: bp-based frame
.text:00408284
.text:00408284 ; __fastcall Rc6::TRC6::CalculateSubKeys(void)
.text:00408284 public @Rc6@TRC6@CalculateSubKeys$qqrv
.text:00408284 @Rc6@TRC6@CalculateSubKeys$qqrv proc near ; DATA XREF: .text:0040823Co
.text:00408284
.text:00408284 m_l_table = dword ptr -58h
.text:00408284 m_b = dword ptr -18h
.text:00408284 m_a = dword ptr -14h
.text:00408284 m_k = dword ptr -10h
.text:00408284 m_j = dword ptr -0Ch
.text:00408284 m_i = dword ptr -8
.text:00408284 l_key = dword ptr -4
.text:00408284
.text:00408284 push ebp
.text:00408285 mov ebp, esp
.text:00408287 add esp, 0FFFFFFA8h
.text:0040828A mov [ebp+l_key], eax
.text:0040828D mov eax, [ebp+l_key]
.text:00408290 mov ecx, [eax+10h]
.text:00408293 lea edx, [ebp+m_l_table]
.text:00408296 mov eax, [ebp+l_key]
.text:00408299 mov eax, [eax+14h]
.text:0040829C call @System@Move$qqrpxvpvi ; System::Move(void *,void *,int)
.text:004082A1 mov eax, [ebp+l_key]
.text:004082A4 mov dword ptr [eax+30h], 0B7E15163h
.text:004082AB mov [ebp+m_i], 1
.text:004082B2
.text:004082B2 loc_4082B2: ; CODE XREF: Rc6::TRC6::CalculateSubKeys(void)+4Ej
.text:004082B2 mov eax, [ebp+l_key]
.text:004082B5 mov edx, [ebp+m_i]
.text:004082B8 mov eax, [eax+edx*4+2Ch]
.text:004082BC add eax, 9E3779B9h
.text:004082C1 mov edx, [ebp+l_key]
.text:004082C4 mov ecx, [ebp+m_i]
.text:004082C7 mov [edx+ecx*4+30h], eax
.text:004082CB inc [ebp+m_i]
.text:004082CE cmp [ebp+m_i], 2Ch
.text:004082D2 jnz short loc_4082B2
.text:004082D4 xor eax, eax
.text:004082D6 mov [ebp+m_i], eax
.text:004082D9 xor eax, eax
.text:004082DB mov [ebp+m_j], eax
.text:004082DE xor eax, eax
.text:004082E0 mov [ebp+m_a], eax
.text:004082E3 xor eax, eax
.text:004082E5 mov [ebp+m_b], eax
.text:004082E8 mov [ebp+m_k], 1
.text:004082EF
.text:004082EF loc_4082EF: ; CODE XREF: Rc6::TRC6::CalculateSubKeys(void)+E6j
.text:004082EF mov eax, [ebp+l_key]
.text:004082F2 mov edx, [ebp+m_i]
.text:004082F5 mov eax, [eax+edx*4+30h] ; eax=l_key[i];
.text:004082F9 add eax, [ebp+m_a]
.text:004082FC add eax, [ebp+m_b]
.text:004082FF mov edx, 3
.text:00408304 call m_rotl_eax_edx
.text:00408309 mov [ebp+m_a], eax
.text:0040830C mov eax, [ebp+l_key]
.text:0040830F mov edx, [ebp+m_i]
.text:00408312 mov ecx, [ebp+m_a]
.text:00408315 mov [eax+edx*4+30h], ecx ; l_key[i]=a;
.text:00408319 mov edx, [ebp+m_a]
.text:0040831C add edx, [ebp+m_b]
.text:0040831F mov eax, [ebp+m_j]
.text:00408322 mov eax, [ebp+eax*4+m_l_table]
.text:00408326 add eax, [ebp+m_a]
.text:00408329 add eax, [ebp+m_b]
.text:0040832C call m_rotl_eax_edx
.text:00408331 mov [ebp+m_b], eax ; b=rotl()
.text:00408334 mov eax, [ebp+m_j]
.text:00408337 mov edx, [ebp+m_b]
.text:0040833A mov [ebp+eax*4+m_l_table], edx ; l[j]=b;
.text:0040833E mov eax, [ebp+m_i]
.text:00408341 inc eax
.text:00408342 mov ecx, 2Ch
.text:00408347 cdq
.text:00408348 idiv ecx ; i=(i+1)%44;
.text:0040834A mov [ebp+m_i], edx
.text:0040834D mov eax, [ebp+m_j]
.text:00408350 inc eax
.text:00408351 and eax, 8000000Fh
.text:00408356 jns short loc_40835D
.text:00408358 dec eax
.text:00408359 or eax, 0FFFFFFF0h
.text:0040835C inc eax
.text:0040835D
.text:0040835D loc_40835D: ; CODE XREF: Rc6::TRC6::CalculateSubKeys(void)+D2j
.text:0040835D mov [ebp+m_j], eax
.text:00408360 inc [ebp+m_k]
.text:00408363 cmp [ebp+m_k], 85h
.text:0040836A jnz short loc_4082EF
.text:0040836C mov esp, ebp
.text:0040836E pop ebp
.text:0040836F retn
.text:0040836F @Rc6@TRC6@CalculateSubKeys$qqrv endp
.text:0040836F
RC6到处可以下载到,c的asm的单片机加速版的perl的。不过某些for Delphi的居然还收费,真不嫌丢人。我是在http://fp.gladman.plus.com/cryptography_technology/aesr2/下载了一份并在其基础上修改的。
在模拟其加密的过程中遇到了一点小麻烦,B. R. Gladman 为AES测试写的RC6版本固定密钥长度为256bit,我跟踪了半天才发现这一点,改成了512。其他没有问题。把"aes_defs.h"这个头文件掐掉。边角作点修修补补,就完成了。另外看的出Gladman为了竞选AES作了些优化,也许能使速度快一点。
下面分析无程序破解其密文的可能性。
首先使用的加密模式是ECB,微小的明文改动导致密文仅一个分组的改动。很容易经选择明文攻击判断出其分组长度,进而推断可能的加密算法。这一点在动手砍软件之前我是初步判断过的。
其次虽然密钥用了512bit的,但是初始化用的密钥是固定的!而且居然用仅仅6个字节的"TENYKS",这里有遭受暴力破解的可能性。
总体来说,天网的配置文件加密虽然用了不错的算法,可惜只是一层窗户纸,一捅就破。主要弱点在于固定密钥并且太短。不过话说回来即使弄的再复杂一点也没有什么用。
RC6的简单描述:
RC6是Ron Rivest设计的系列加密算法之一,从RC5改进而来,与RC4完全不同的一点是,RC5和RC6都属于分组加密算法,并且由于曾经参加过AES选拔赛,都是设计为可以调整密钥和分组的长度的。虽然最后落选,不过也算是当今比较优秀的加密算法之一了。
分析RC6的汇编代码有以下几个要点:
1,异或少,移位多,初始化key的过程在一个132次的循环内进行了2次左移,第一次移位的位数固定为3位。加密或解密代码中有四次的左移。通常这个移位表现为一个call。
2,初始化函数中有常数0xb7e15163和0x9e3779b9。
3,加密过程中维护着一个44个元素的整型表,即共176bytes(代码中的l_key)。
最后贴代码
RC6(set_key(const u1byte in_key[], const u4byte key_len))是我改动过的函数,贴出来,其他没改动就不贴了。
/////////////////////////////////////////////////////////////////////////////////////////
// rc6.c
// ...
#define KEYLEN 64*8 //512 bit key length only, eg, 64 bytes.
// initialise the key schedule from the user supplied key
// void RC6(set_key(const u1byte in_key[], const u4byte key_len, const enum dir_flag f))
void RC6(set_key(const u1byte in_key[], const u4byte key_len))
{
u4byte l[KEYLEN/32], i, j, k, a, b, t;
u1byte * pl = (u1byte*)l;
RC6(l_key)[0] = 0xb7e15163;
for(k = 1; k < 44; ++k)
RC6(l_key)[k] = RC6(l_key)[k - 1] + 0x9e3779b9;
// for(k = 0; k < key_len / 32; ++k)
// l[k] = u4byte_in(in_key + 4 * k);
for(k = 0; k < KEYLEN/8 ; ++k)
pl[k] = in_key[ k%key_len ];
t = (KEYLEN / 32) - 1; // t = (key_len / 32);
a = b = i = j = 0;
for(k = 0; k < 132; ++k)
{
a = rotl(RC6(l_key)[i] + a + b, 3);
b += a;
b = rotl(l[j] + b, b);
RC6(l_key)[i] = a; l[j] = b;
i = (i == 43 ? 0 : i + 1); // i = (i + 1) % 44;
j = (j == t ? 0 : j + 1); // j = (j + 1) % t;
}
return;
}
/////////////////////////////////////////////////////////////////////////////////////////
// main.c
#include "rc6.h"
#include
int main(int argc, char *argv[])
{
char f[16];
FILE *fdat, *ftxt;
fdat=fopen("AppRule.dat", "rb");
if(!fdat)
return 0;
ftxt=fopen("AppRule.txt", "wb");
if(!ftxt)
return 0;
RC6(set_key)("TENYKS", 6);
while(fread(f, 1, 16, fdat))
{
RC6(decrypt)(f, f);
fwrite(f, 1, 16, ftxt);
}
fclose(fdat);
fclose(ftxt);
return 1;
// RC6(encrypt)(f, f); 加密
// RC6(decrypt)(f, f); 解密
}
相关文章推荐
- 解决Enterprise Library - January 2006不能加密配置文件的方法(转)
- PHP加密方法-用Zend Encoder加密PHP文件和PHP 优化配置(PHP文件加密)
- 加密配置文件(App.Config和Web.config)中connectionStrings通用方法
- C#为配置文件加密的实现方法
- .Net配置文件读取及修改方法封装(未加密)
- spring配置文件加密方法示例
- 解决Enterprise Library - January 2006不能加密配置文件的方法
- Spring Cloud Config RSA简介及使用RSA加密配置文件的方法
- C#为配置文件加密的实现方法
- ssh中数据库配置文件加密方法
- 加密配置文件(App.Config和Web.config)中connectionStrings通用方法
- ASP.NET 2.0 中一种新的方法实现对配置文件的加密
- 加密网站配置文件中的信息
- Hibernate配置文件加密解决方案
- 300.33通过读取配置文件方式来使用反射完成实例对象调用方法
- MyEclipse中web开发修改类文件和配置文件不重启服务器的方法
- Spring加载Properties配置文件的加密解密处理
- 【环境配置】Fedora samba服务器环境搭建及无法查看文件的解决方法
- 服务调用RMI远程方法调用示例【基于Spring配置文件】
- MySQL连接配置文件密码加密及其在多种连接池上的应用