欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[分享]ECC替换公钥实践(下篇)

[分享]ECC替换公钥实践(下篇)

上篇总结:
上篇http://bbs.pediy.com/showthread.php?t=192180
(a) 在lm_code.h中,选定LM_SEED1.2,3, private key、public key也就固定了;
(b) 可以用lmnewgen输出lmprikey.h和lmpubkey.h查看private key和public key,高版本的SDK,缺省只输出lmprikey.h,加上-pubkey选项,可以输出lmpubkey.h;
(c) lmpubkey.h中存放的是转换过的public key,转换规律是用lmpubkey.h中的key和daemon( 比如本例中的testlmd)的ASCII代码按位做加、减或异或操作得到真正的公钥,具体如下:
0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 - (第0、2、4......26、28、30位用减法运算,比如第0位76-74=02h)
3 9 15 21 27 ^ (第3、9、15、21、27位用异或运算,例如第3位AB^74=DFh)
1 5 7 11 13 17 19 23 25 29 + (第1、5、7......23、25、29位用加法运算,例如第1位9D+65=02,注意取末两位)
0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30  <= 0~30(共31 = (1F)h位
76 9D E2 AB 3B 42 D7 6B 20 B5 46 39 ED BC A0 D1 CB 0B 5D 65 DC E5 39 63 44 80 CD 78 27 8C 17  <= pubkey in pubkey.h
74 65 73 74 6C 6D 64 74 65 73 74 6C 6D 64 74 65 73 74 6C 6D 64 74 65 73 74 6C 6D 64 74 65 73  <= testlmd
02 02 6F DF CF AF 73 DF BB C6 D2 A5 80 20 2C B4 58 7F F1 D2 78 91 D4 D6 D0 EC 60 1C B3 F1 A4  <= real pubkey(for SIGN2=)
替换公钥,就是找出lmpubkey.h中的pubkey在硬盘上是如何存储的,找到存储的位置,相应地替换成自己的lmpubkey.h中的public key就可以了。
好,我们开始下篇。
上篇我么在内存[00C93B3C~00C93B5E]处下写断点追踪出
76 9D E2 AB 3B 42 D7 6B 20 B5 46 39 ED BC A0 D1 CB 0B 5D 65 DC E5 39 63 44 80 CD 78 27 8C 17 (lmpubkey.h中的 public key)
=>
02 02 6F DF CF AF 73 DF BB C6 D2 A5 80 20 2C B4 58 7F F1 D2 78 91 D4 D6 D0 EC 60 1C B3 F1 A4 (真实的public key)
现在我么再回头看看这段内存里的public key是怎么来的
76 9D E2 AB 3B 42 D7 6B 20 B5 46 39 ED BC A0 D1 CB 0B 5D 65 DC E5 39 63 44 80 CD 78 27 8C 17
和上篇一样,在run过0041D143后,这块内存区域清零
0041D143  |.  E8 E82A0100   CALL testlmd.l_malloc                    ; \l_malloc
在此处下内存写断点,如下图所示,

按一次F9到停在0047F195,
0047F195  |.  F3:AB         REP STOS DWORD PTR ES:[EDI]
F8跳过,再按一次F9来到0047BEF4
0047BEF4   .  89448F E4     MOV DWORD PTR DS:[EDI+ECX*4-1C],EAX
看下信息窗口里的EAX,此处就是开始往[00C93B3C~00C93B5E]里写“76 9D E2 AB 3B 42 D7 6B 20 B5 46 39 ED BC A0 D1 CB 0B 5D 65 DC E5 39 63 44 80 CD 78 27 8C 17”了
EAX=ABE29D76
DS:[00C93B40]=00000000
MEMCPY.ASM:283. 

往上一步,看看EAX的值是怎么来的
0047BEF0   > \8B448E E4     MOV EAX,DWORD PTR DS:[ESI+ECX*4-1C]
EAX由[ESI+ECX*4-1C] = [00a66744]赋值而来

好了,再往回trace,看看内存[00a66744-00a66762]的赋值是怎么来的,可以看到在_l_public_key_verify的入口处,这段内存的值已经存在了,那就再看看_l_public_key_verify的调用函数的入口处。
* 这里注意下,IDA里看不到哪里调用了_l_public_key_verify,可以在OD里运行到_l_public_key_verify的入口处0041CDB0,然后按“调试”->“执行到返回”(或者按快捷键CTRL+F9),找到_l_public_key_verify调用函数。
这么一路追踪下去(得有耐心,比较耗时间,但没什么难度,如果看到这段值从某处内存拷贝过来,就再去看看那段内存值是怎么来的),最终会找到这里
004A286A  |.  FF15 F47E5200 CALL DWORD PTR DS:[l_n36_buf]            ; \testlmd.00401E60
run过004A286A后,内存[0012F184 - 0012F1A2]里的值为
76 9D E2 AB 3B 42 D7 6B 20 B5 46 39 ED BC A0 D1 CB 0B 5D 65 DC E5 39 63 44 80 CD 78 27 8C 17

我么再往回,在004A286A处按F7进去看看
run过0040326B清零
0040326B  |.  E8 E0BE0700   CALL testlmd.memset                      ; \memset
还是老办法,在内存[0012F184 - 0012F1A2]下写断点,

然后一路F9,你会看到下面的数字一个个的出现(但是不是按顺序的,第一个出现的是在.text:403C0A,往内存0012F196处写5D,最后一个出现的是.text:00412AAE,往内存0012F190处写ED)。
76 9D E2 AB 3B 42 D7 6B 20 B5 46 39 ED BC A0 D1 CB 0B 5D 65 DC E5 39 63 44 80 CD 78 27 8C 17
好,看看第一个出现的5D怎么来的。
00403C0A  |.  0305 30775200 ADD EAX,DWORD PTR DS:[527730]
00403C10  |.  8B4D 0C       MOV ECX,DWORD PTR SS:[EBP+C]
00403C13  |.  8881 AA000000 MOV BYTE PTR DS:[ECX+AA],AL

呵呵,接近成功了,看到这个固定的数了吧,[527730],里面放的是5D,回到程序还没开始运行时,看看,这个值是不是已经在那了,说明什么,这个值是直接存在硬盘上的值了。其余的也可以这么一个一个找到。
呵呵,终于找到pubkey存放的源头了,替换公钥就是把这些值一个一个的替换成自己定义的pubkey就行了。
休息一下,往下再讲除了手工替换,怎么用程序来自动替换。

上传的附件 Snap8_1.jpg
Snap8_2.jpg
Snap10.jpg
Snap11.jpg
Snap12.jpg
Snap_write_lmpubkey_1.jpg

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功