发新话题
打印

[转载]一个比较另类的ECC stuff

[转载]一个比较另类的ECC stuff

文章作者:divinomas

这个crackme是tkm2004年的strainer,用ECC保护的。虽然ECC大家玩得比较熟了,不过这个东东的保护方法还是有点意思。
用PEiD查壳并脱壳,unpack不是目的,算法才是关键。unpack后载入ida,用miracl的sig,或

http://www.secretashell.com/cryptocrk/tutorials/miracl.calls.zip这里的方法识别miracl库函数,检查序列号的流程一目了然。
1.获取name,sn1,sn2

代码:
Un_FSG__:0040194Cloc_40194C: Un_FSG__:0040194Cpush50h Un_FSG__:0040194Epushoffsetname Un_FSG__:00401953push2 Un_FSG__:00401955pushedi Un_FSG__:00401956callGetDlgItemText;name>=4 Un_FSG__:0040195Bmovesi,eax Un_FSG__:0040195Dpush50h Un_FSG__:0040195Fpushoffsetsn1 Un_FSG__:00401964push3 Un_FSG__:00401966pushedi Un_FSG__:00401967callGetDlgItemText;sn1>=4 Un_FSG__:0040196Cmovebx,eax Un_FSG__:0040196Epush50h Un_FSG__:00401970pushoffsetsn2 Un_FSG__:00401975push4 Un_FSG__:00401977pushedi Un_FSG__:00401978callGetDlgItemText;sn2>=1


2.检查序列号
1)椭圆曲线E(a,b,p)、点(pt1,pt2,pt3,pt4,pt5)初始化

代码:
Un_FSG__:0040149Ccallepoint_init Un_FSG__:004014A1movedi,eax Un_FSG__:004014A3mov[esp+1F8h+var_1F8],0 Un_FSG__:004014AAcall_mirvar Un_FSG__:004014AFmov[ebp+pt2_x],eax Un_FSG__:004014B5callepoint_init Un_FSG__:004014BAmov[esp+1F8h+var_1F8],0 Un_FSG__:004014C1mov[ebp+pt2],eax Un_FSG__:004014C7call_mirvar Un_FSG__:004014CCmov[ebp+big_t],eax Un_FSG__:004014D2callepoint_init Un_FSG__:004014D7mov[ebp+pt3],eax Un_FSG__:004014DDcallepoint_init Un_FSG__:004014E2mov[ebp+pt4],eax Un_FSG__:004014E8callepoint_init Un_FSG__:004014EDmovdwordptr[esi+220h],10h Un_FSG__:004014F7mov[ebp+pt5],eax ... Un_FSG__:00401512movebx,[ebp+a] Un_FSG__:00401518pushoffseta416d656e657369;"416D656E65736961" Un_FSG__:0040151Dpushebx Un_FSG__:0040151Ecall_cinstr Un_FSG__:00401523popeax Un_FSG__:00401524popedx Un_FSG__:00401525moveax,[ebp+b] Un_FSG__:0040152Bpushoffseta1b35b7093fee5a;"1B35B7093FEE5AE601A" Un_FSG__:00401530pusheax Un_FSG__:00401531call_cinstr Un_FSG__:00401536popebx Un_FSG__:00401537popesi Un_FSG__:00401538movesi,[ebp+p] Un_FSG__:0040153EpushoffsetaFffffffdffffff;"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF" Un_FSG__:00401543pushesi Un_FSG__:00401544call_cinstr Un_FSG__:00401549popeax Un_FSG__:0040154Apopedx Un_FSG__:0040154Bmovedx,[ebp+pt1_x] Un_FSG__:00401551pushoffseta71263a72c2fdfb;"71263A72C2FDFB8FE851182B408210A4" Un_FSG__:00401556pushedx Un_FSG__:00401557call_cinstr Un_FSG__:0040155Cmoveax,[ebp+pt2_x] Un_FSG__:00401562popecx Un_FSG__:00401563popebx Un_FSG__:00401564pushoffseta2c052124bdd94e;"2C052124BDD94E5645E99B01DCECA28D" Un_FSG__:00401569pusheax Un_FSG__:0040156Acall_cinstr Un_FSG__:0040156Fmoveax,[ebp+p] Un_FSG__:00401575push1 Un_FSG__:00401577pusheax Un_FSG__:00401578moveax,[ebp+b] Un_FSG__:0040157Epusheax Un_FSG__:0040157Fmoveax,[ebp+a] Un_FSG__:00401585pusheax Un_FSG__:00401586call_ecurve_init Un_FSG__:0040158Bmoveax,[ebp+pt1_x] Un_FSG__:00401591addesp,20h Un_FSG__:00401594pushedi;pt1 Un_FSG__:00401595push0 Un_FSG__:00401597pusheax Un_FSG__:00401598moveax,[ebp+pt1_x] Un_FSG__:0040159Epusheax Un_FSG__:0040159Fcall_epoint_set Un_FSG__:004015A4movecx,[ebp+pt2_x] Un_FSG__:004015AAmoveax,[ebp+pt2] Un_FSG__:004015B0movebx,[ebp+pt2_x] Un_FSG__:004015B6pusheax Un_FSG__:004015B7push1 Un_FSG__:004015B9pushebx Un_FSG__:004015BApushecx Un_FSG__:004015BBcall_epoint_set


其中E的参数为:
a:416D656E65736961
b:1B35B7093FEE5AE601A
p:FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF
pt1的x坐标为:71263A72C2FDFB8FE851182B408210A4
pt2的x坐标为:2C052124BDD94E5645E99B01DCECA28D
2)sn1,sn2转变为大数,并变形

代码:
Un_FSG__:004015C0movesi,[ebp+big_sn1] Un_FSG__:004015C6addesp,18h Un_FSG__:004015C9movsxebx,ds:Serial_sign Un_FSG__:004015D0pushoffsetsn1 Un_FSG__:004015D5subebx,30h Un_FSG__:004015D8pushesi Un_FSG__:004015D9leaesi,[ebp+var_1A8] Un_FSG__:004015DFcall_cinstr Un_FSG__:004015E4popeax Un_FSG__:004015E5popedx Un_FSG__:004015E6moveax,[ebp+big_sn2] Un_FSG__:004015ECpushoffsetsn2 Un_FSG__:004015F1pusheax Un_FSG__:004015F2call_cinstr


其中sn1的第一个byte是正负标志位,剩下的部分转化为大数

代码:
Un_FSG__:004015F7moveax,[ebp+big_t] Un_FSG__:004015FDpusheax Un_FSG__:004015FEmoveax,[ebp+p] Un_FSG__:00401604pusheax Un_FSG__:00401605moveax,[ebp+big_sn1] Un_FSG__:0040160Bpush1 Un_FSG__:0040160Dpusheax Un_FSG__:0040160Ecall_powmod Un_FSG__:00401613moveax,[ebp+big_t] Un_FSG__:00401619addesp,20h Un_FSG__:0040161Cmovedx,[ebp+pt3] Un_FSG__:00401622pushedx Un_FSG__:00401623pushebx Un_FSG__:00401624xorebx,ebx Un_FSG__:00401626pusheax Un_FSG__:00401627moveax,[ebp+big_t] Un_FSG__:0040162Dpusheax Un_FSG__:0040162Ecall_epoint_set


pt3的x坐标为big_sn1%p
3)计算name的sha值,并变形

代码:
Un_FSG__:00401636call_shs_init Un_FSG__:0040163Bmoval,ds:name Un_FSG__:00401640addesp,10h Un_FSG__:00401643testal,al Un_FSG__:00401645jzshortloc_401661 Un_FSG__:00401647 Un_FSG__:00401647loc_401647:;CODEXREF:_check+27Fj Un_FSG__:00401647movsxecx,al Un_FSG__:0040164Apushedx Un_FSG__:0040164Bincebx Un_FSG__:0040164Cpushedx Un_FSG__:0040164Dpushecx Un_FSG__:0040164Epushesi Un_FSG__:0040164Fcall_shs_process Un_FSG__:00401654moval,ds:name[ebx] Un_FSG__:0040165Aaddesp,10h Un_FSG__:0040165Dtestal,al Un_FSG__:0040165Fjnzshortloc_401647 Un_FSG__:00401661 Un_FSG__:00401661loc_401661:;CODEXREF:_check+265j Un_FSG__:00401661pushebx Un_FSG__:00401662pushebx Un_FSG__:00401663leaebx,[ebp+var_38] Un_FSG__:00401666pushebx Un_FSG__:00401667pushesi Un_FSG__:00401668call_shs_hash Un_FSG__:0040166Dmovedx,[ebp+big_hName] Un_FSG__:00401673addesp,0Ch Un_FSG__:00401676pushedx Un_FSG__:00401677pushebx Un_FSG__:00401678push14h Un_FSG__:0040167Acall_bytes_to_big Un_FSG__:0040167Fmoveax,[ebp+big_hName] Un_FSG__:00401685pusheax Un_FSG__:00401686moveax,[ebp+p2];FFFFFFFE000000006FAFED9C3353F08D Un_FSG__:0040168Cpusheax Un_FSG__:0040168Dmoveax,[ebp+big_hName] Un_FSG__:00401693push3 Un_FSG__:00401695pusheax Un_FSG__:00401696call_powmod


big_hName=sha(name)^3%p2
p2被初始化为FFFFFFFE000000006FAFED9C3353F08D
4)计算中间值

代码:
Un_FSG__:0040169Bmoveax,[ebp+pt4] Un_FSG__:004016A1addesp,1Ch Un_FSG__:004016A4pusheax Un_FSG__:004016A5moveax,[ebp+pt3] Un_FSG__:004016ABpusheax Un_FSG__:004016ACmoveax,[ebp+big_sn2] Un_FSG__:004016B2pusheax Un_FSG__:004016B3call_ecurve_mult;pt4=pt3*big_sn2 Un_FSG__:004016B8moveax,[ebp+big_hName] Un_FSG__:004016BEaddesp,0Ch Un_FSG__:004016C1pushedi Un_FSG__:004016C2pushedi Un_FSG__:004016C3pusheax Un_FSG__:004016C4call_ecurve_mult;pt1=pt1*big_hName Un_FSG__:004016C9movebx,[ebp+big_sn1] Un_FSG__:004016CFaddesp,0Ch Un_FSG__:004016D2movecx,[ebp+pt5] Un_FSG__:004016D8movesi,[ebp+pt2] Un_FSG__:004016DEpushecx Un_FSG__:004016DFpushesi Un_FSG__:004016E0pushebx Un_FSG__:004016E1call_ecurve_mult;pt5=pt2*big_sn1 Un_FSG__:004016E6popeax Un_FSG__:004016E7popedx Un_FSG__:004016E8movedx,[ebp+pt5] Un_FSG__:004016EEpushedx Un_FSG__:004016EFpushedi Un_FSG__:004016F0call_ecurve_add;pt5=pt5+pt1 Un_FSG__:004016F0;pt5=pt1*big_hName+ Un_FSG__:004016F0;pt2*big_sn1


pt4=pt3*big_sn2
pt5=pt5+pt1
=pt1*big_hName+pt2*big_sn1
5)比较
通过两处进行比较

代码:
Un_FSG__:004016F5moveax,[ebp+pt4] Un_FSG__:004016FBpopecx Un_FSG__:004016FCpopebx Un_FSG__:004016FDpusheax Un_FSG__:004016FEmoveax,[ebp+pt5] Un_FSG__:00401704pusheax Un_FSG__:00401705call_epoint_comp;pt4=t5 ... Un_FSG__:004017F5moveax,[ebp+pt5] Un_FSG__:004017FBpushedi Un_FSG__:004017FCpusheax Un_FSG__:004017FDcall_epoint_comp;pt5!=pt1


如果pt4=pt5且pt5!=pt1则通过
3.Keygen
最终只要pt3*big_sn2=pt1*big_hName+pt2*big_sn1即可通过检查
其中pt3的x坐标为big_sn1%p
big_hName是name的hash值变形得来,是不可逆的,同样pt1,pt2是给定的也做不了文章,能下手的就是pt3,sn1,sn2这几部分
不妨试试,令pt3=pt1+pt2,big_sn2=big_hName
那么方程被简化为pt2*big_hName=pt2*big_sn1
椭圆曲线作为一个阶数为n的有限群,它上面任意一点满足pt*n=indefinite(因为元素的阶是群的阶的因子)。如果椭圆曲线不好理解,可以拿模质数的乘法群来类比。indefinite相当于1。在{1,2,3,4,5,6}这几个数构成的mod7群里,群的阶(元素个数)为6,任意一个数的6次方除以7均余1也就是那个单位元。
所以只要big_sn1%n=big_hName即可
那么最终我们得到了一组同余方程
big_sn1=pt3_xmodp
big_sn1=big_hNamemodn
得到sn1
利用big_sn2=big_hName
得到sn2
当时在keygen的时候我对miracl还不熟,我自己手工解这个同余方程,大家可以用miracl实现一个更好的keygen,因为传不了附件,下面是keygen的链接
keygen

TOP

发新话题