5 stasi的本机测试
测试环境:
硬件环境:p42.0G+256M(DDR 400)
系统环境: WIN2000+SP4
软件环境:MASM6.exe编译
5.1 测试对象: Asprotect1.0
5.1.1测试代码
.586
.MODEL FLAT,STDCALL
; ------------------------------------------------------
; Poorly coded brute forcer for Asprotect 1.0/1.11
; by Amenesia//TKM!
; ------------------------------------------------------
include BruteAspro10.inc
.DATA
;..User friendly :).........................
solution db "Seed =",0
notf db "- Nop -",0
hexstring db "0123456789ABCDEF",0
result db "00000000",0
;..Brute-forcer............................
CurrentSeed dd 00000000h
MinSeed dd 0398BBB73h
MaxSeed dd 0FFFFFFFFh
;..N........................................
HighMod dd 0EB1D4EADh
.CODE
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
BruteForcer:
mov eax, [MinSeed]
BruteForcer_loop:
push eax
mov [CurrentSeed], eax
call RandInt
or eax, 0C0000000h
push eax
call RandInt
or eax, 0C0000000h
pop ebx
mul ebx
sub edx, [HighMod]
cmp edx, 2
jbe SeedF
pop eax
inc eax
cmp eax, [MaxSeed]
je SeedNotF
jmp BruteForcer_loop
SeedF:
pop eax
mov edi, (offset result+7)
Hex2ascii:
mov ebx, eax
and ebx, 0Fh
mov bl, [offset hexstring + ebx]
mov [edi], bl
sub edi, 1
shr eax, 4
cmp eax, 0
jne Hex2ascii
call MessageBoxA,0,offset result,offset solution,0
ret
SeedNotF:
call MessageBoxA,0,offset notf,offset solution,0
ret
rand proc near
mov ecx, [CurrentSeed]
imul ecx, 343FDh
add ecx, 269EC3h
mov [CurrentSeed], ecx
mov eax, ecx
shr eax, 10h
and eax, 7FFFh
retn
rand endp
RandInt proc near
mov edi, 60
mov ecx, [CurrentSeed]
highbyte:
imul ecx, 343FDh
add ecx, 269EC3h
dec edi
jnz highbyte
mov [CurrentSeed], ecx
xor esi, esi
mov edi, 4
build_int:
call rand
shl esi, 8
add esi, eax
dec edi
jnz build_int
mov eax, esi
retn
RandInt endp
end BruteForcer
ends
5.1.2 测试结果
用时:3.12秒
D= l8F1EGKSQWCw9Et5klCpkm9/TIQFw0xOxibd+bQNndzGYoIX
4PmHXcdZtN3VWRQfuYS/cLeEf0i+kG3Cd7kaqKCkBO3xiAFgZMf
vW8D+bov+AfjDICITq5/Lhex7PykLGtUNnH8LSsmIDSWqldwX3Q
9o8U4HcJSjSJIfS4bumc=
5.2 测试对象:Asprotect1.1c
5.2.1测试代码:
.586
.MODEL FLAT,STDCALL
; ------------------------------------------------------
; Poorly coded brute forcer for Asprotect 1.11c
; by Amenesia//TKM!
; ------------------------------------------------------
include BruteAspro111c.inc
.DATA
;..User friendly :).........................
solution db "_rand() =",0
notf db "- Nop -",0
hexstring db "0123456789ABCDEF",0
result db "00000000",0
;..Brute-forcer............................
CurrentSeed dd 00000000h
MinSeed dd 00000000h
MaxSeed dd 00007FFFh
;..N........................................
Mod_p1 dd 0C7D6E57Ah
Mod_p2 dd 00D1C3A97h
Mod_p3 dd 052618FB4h
Mod_p4 dd 097A6E4D1h
.CODE
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
BruteForcer:
mov eax, [MinSeed]
BruteForcer_loop:
push eax
mov [CurrentSeed], eax
call RandInt
mov ebx, eax
or eax, 0C0000000h
mov ebp, eax
mov edx, [Mod_p1]
mov eax, [Mod_p2]
cmp ebp, edx
jb nextseed
div ebp
mov esi, eax
mov edi, edx
big_mul:
mov eax, ebx
mul esi
mov ecx, edx
add edx, eax
adc ecx, 0
cmp edi, ecx
jb too_big
ja sub_big
cmp [Mod_p3], edx
jb too_big
ja sub_big
cmp [Mod_p4], eax
jb too_big
jae sub_big
too_big:
dec esi
;add edi, ebp
;jmp big_mul
sub ecx, ebp
sub_big:
push [Mod_p4]
push [Mod_p3]
sub [Mod_p4], eax
sbb [Mod_p3], edx
sbb edi, ecx
mov eax, [Mod_p3]
mov edx, edi
pop [Mod_p3]
pop [Mod_p4]
div ebp
mov ebp, edx
mov edi ,eax
mul ebx
cmp edx, ebp
jb nocarry
dec edi
nocarry:
or edi, 0C0000000h
and esi, 0FFFFFFFEh
and edi, 0FFFFFFFEh
cmp esi, edi
je SeedF
nextseed:
pop eax
inc eax
cmp eax,[MaxSeed ]
je SeedNotF
jmp BruteForcer_loop
SeedF:
pop eax
call RandInt
mov edi, (offset result+7)
Hex2ascii:
mov ebx, eax
and ebx, 0Fh
mov bl, [offset hexstring + ebx]
mov [edi], bl
sub edi, 1
shr eax, 4
cmp eax, 0
jne Hex2ascii
call MessageBoxA,0,offset result,offset solution ,0
ret
SeedNotF:
call MessageBoxA,0,offset notf ,offset solution,0
ret
rand proc near
mov eax, [CurrentSeed]
and eax, 7FFFh
retn
rand endp
RandInt proc near
xor esi, esi
mov edi, 4
build_int:
call rand
shl esi, 8
add esi, eax
dec edi
jnz build_int
mov eax, esi
retn
RandInt endp
end BruteForcer
ends
5.2.2 测试结果
用时:0.98秒
D = HV/nbSNxR14Tvhm4bHRVey+U+qdbHQk8Q+BPfBrY
qZYMa14KmBhtGX4flkK+gVoGGX23485UMFwdxMMux5Aw
DtEsU+ZTzlQmvNX5zEuDRVg/1jZJGc7NIBltCVy+sOt+
iVqzBnopoHPQHrNGzDkr/615Ch40ns4iIWp3i7PbRs
6 译者(stasi)的话
作为一个算法爱好者,对blowfish前辈从exetool转来的<<How break RSA-1024 ?>>文章也甚是有兴趣,所以翻译过来大家研究。
我主要是想说说自己对这次攻破算法保护的看法:
以前常说RSA的安全性就依赖于大数的分解,通过密钥数位的增加就能在一定程度上使得算法是很安全的,这是在数学领域正确,但从这篇文章来看,把算法保护运用到软件设计上又是由很多需要注意的地方了。Asprotect 1.0/1.1/1.11c的算法被攻破,其主要原因就是Seed的估计不足造成的。我们来看一下Asprotect 1.0/1.1/1.11c在选取大素数p和q时所用的代码:
unsigned long _rand() //基本数的生成
{
Seed *= 214013;
Seed += 2531011;
return( ((Seed >> 16) & 0x7FFF) );
}
unsigned long RandInt() //整数随机数的生成
{
for(i=0;i<4;i++) { rval = ((rval << 8) +_ rand()); }
return(rval);
}
Seed = ( time() + ThreadId()) xor TickCount(); //seed的计算公式
for(ri=0;ri<16;ri++) { BigNumber1[ri] = RandInt(); }
BigNumber1[ri] = BigNumber1[ri] xor C0000000h;
P= nextPrime(BigNumber1);
for(ri=0;ri<16;ri++) { BigNumber2[ri] = RandInt(); }
BigNumber2[ri] = BigNumber2[ri] xor C0000000h;
Q= nextPrime(BigNumber2);
主要关注( time() + ThreadId()) xor TickCount(),看似有了( time() + ThreadId()),结果似乎是一个随机的数值,但由于( time() + ThreadId()) xor TickCount()在计算的时候有计算机自行完成,且计算的函数取值固定,就导致 GetTickCount and time()在计算随机数的时候基本是保持在time()值左右,意外的导致了计算所的到的数值并不是一个很随机的数,用老罗的话就是“伪随机数”,它是在一个数值段内的一个随机数,而大素数p和q就是通过这个数值计算得到的,这就大大限制了大素数p和q选取可能,使得穷举成为了可能。我们都知道一旦大素数p和q被知道之后,RSA就毫无保护意义可言,通过p和q计算就能得到得到私钥d,然后把密文分组得到的数值,计算他的d次方,并与n取模就是原始数据了。
本人万分感慨原作者对加密算法的理解,并不是冒然尝试分解n的值,而是仔细分析了算法的本质要素,找到了RSA-1024算法和软件Asprotect 1.0/1.1/1.11c两者相结合的弱点。这也揭示了数学意义上的随机数和软件编程上的随机数的区别,这也许也将在以后对其他算法攻破有很大的指导意义。
7 译者(stasi)对算法的改进想法:
但就RSA-1024本身而言,不是什么问题,并不需要怀疑它的强度问题,因为在其他数据保护方面,要知道产生大素数的函数并不时很简单的事!我所想到的改进方法,供大家研究:
1)Asprotect 如果还想使用RSA-1024算法的话,只要注意对产生大素数的随机种子数的选取就可以了,不使用time(),而是尝试利用其他的随机数,例如磁盘文件大小,文件建立时间等随机数,混沌或分形理论。
2)即使使用time()函数也要将随机池放大,覆盖有一定大范围的数据段,使穷举变得困难。
3)把算法验证放在网络上,使得攻破者不能得到大素数p和q的生成方法,要知道无畏的穷举并不是一个理想的办法:)
stasi
2005.4.13 上海
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课