点击图片,观看解题分析视频
出题团队简介
第十题《生命的馈赠》出题方:【GRAFFINDOR】战队。
赛题设计思路
题目设计说明:防守有两部分,程序代码混淆和数学保护。
一
混淆
1、代码乱序处理
定义:定义了一个结构体管理每行代码,结构体如下。
struct CodeLineToExpand
{
OrderType m_Type;//原来代码的类型
Param1;
Param2;
OldAddr; //原来代码的地址
OldAddrToJmpOrCall;//原来代码中要跳转的目标地址
OldIndexValue;
NewSize;//已经加入了远相对jmp后的大小
NewAddr;
NewAddrToJmpOrCall;
RamdomValue;//随机值
NewCode;//新的代码
}CTE[nCodeLines];
int MapNewToOld[nCodeLines];//存储新的Line和旧的Line之间的对应关系
int CodeLineOldAddrBegin;//原来代码地址的开始
int CodeLineOldAddrEnd;//原来代码地址的结束(不包含本地址)
步骤:
(1)将某一行代码nCodeLines的原始信息填入CTE数组。
计算出nCodeLines,填好CTE数组的每个元素的m_Type、Param1、Param2、OldAddr、OldAddrToJmpOrCall、OldIndexValue。
(2)对CTE每个元素赋予随机值,以该随即值的从小到大顺序重新组合代码。
计算出随机值填入RamdomValue,然后以此排序,排序后的结果放入MapNewToOld数组。
MapNewToOld数组按照索引顺序(NewIndex)来放置OldValue的值,顺序为从小到大。
(3)某行代码新地址的计算方法(CTE: NewAddr)
遍历MapNewToOld数组,除去第0个,每个元素对应的CodeLineToExpand结构体的NewAddr都为前面的元素CodeLineToExpand结构体的NewAddr+NewSize。
(4) 新CodeLine中的远相对跳转中相对地址的计算方法
遍历CTE数组,找它下一个元素的NewAddr配合自己的NewAddr进行计算。
(5)新的jmpcall目标地址的计算方法(假设源代码仅为代码,不做它用,且代码为Jmp或者Call)
相对跳转的修正:若原来代码要跳转的地址not in [CodeLineOldAddrBegin,
CodeLineOldAddrEnd]中,则用NewAddr和OldAddrToJmpOrCall进行修正;反之,寻找原来代码跳转地址对应的CodeLineToExpand,用NewAddr和原来代码跳转地址对应的CodeLineToExpand中的NewAddr进行修正。
绝对跳转的修正:若原来代码要跳转的地址not in [CodeLineOldAddrBegin,
CodeLineOldAddrEnd]中,则不需要修正;反之,寻找原来代码跳转地址对应的CodeLineToExpand,原来代码跳转地址对应的CodeLineToExpand中的NewAddr进行修正。
2、初步替换jmp指令
按长度分为9种。
// 第一种 长度:6
push Addr
ret
// 第二种 长度:0x1C
push eax
mov eax,Addr
push eax
mov [esp-4],eax
mov eax,[esp+4]
mov [esp],eax
mov eax,[esp-4]
mov [esp+4],eax
pop eax
ret
// 第三种1 长度:0xC
mov dword ptr[esp-4],Addr
jmp[esp - 4]
// 第三种2 长度:C
mov dword ptr[esp-4],Addr
sub esp,4
ret
// 第四种 长度:0x2D
push eax
mov dword ptr[esp-4],Addr
mov eax,[esp-4]
mov [esp-8],eax
sub esp,4
mov eax,[esp+4]
mov [esp],eax
mov eax,[esp-4]
mov [esp+4],eax
mov eax,[esp]
add esp,8 //add esp,4
jmp [esp-4] //ret
// 第五种 长度:0x34
push Addr
push eax
mov eax,Addr
mov eax,[esp]
//
push eax
mov eax,Addr
push eax
mov [esp-4],eax
mov eax,[esp+4]
mov [esp],eax
mov eax,[esp-4]
mov [esp+4],eax
pop eax
//
add esp,4
pop eax
add esp,4
jmp [esp-4]
// 第六种(4+5) 长度:0x86
push Addr
push eax
mov eax,Addr
push eax
mov dword ptr [esp-4],Addr
mov eax,[esp-4]
mov [esp-8],eax
sub esp,4
mov eax,[esp+4]
mov [esp],eax
mov eax,[esp-4]
mov [esp+4],eax
mov eax,[esp]
add esp,8 //add esp,4
mov eax,[esp]
push eax
mov eax,Addr
push eax
mov [esp-4],eax
mov eax,[esp+4]
push eax
mov dword ptr[esp-4],Addr
mov eax,[esp-4]
mov [esp-8],eax
sub esp,4
mov eax,[esp+4]
mov [esp],eax
mov eax,[esp-4]
mov [esp+4],eax
mov eax,[esp]
add esp,8 //add esp,4
mov [esp],eax
mov eax,[esp-4]
mov [esp+4],eax
pop eax
add esp,4
pop eax
add esp,4
jmp [esp-4]
// 第7种 长度:0x59
push Addr
push 0x7FFA08AC
jmp [esp]
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
push ebp
mov ebp,esp
add esp,-34
push ebx
push ecx
push eax
push esi
push edi
lea edi,[ebp-34h]
mov ecx,D
mov eax,0x0CCCCCCCC
rep stos dword ptr [edi]
mov [ebp-4],ecx
mov eax,[ebp+8]
mov edx,dword ptr [esp+4]
mov ecx,dword ptr [esp+8]
mov dword ptr [ebp-30h],1
mov edx,dword ptr [ebp-30h]
mov dword ptr [ebp-34h],edx
mov ecx,[ebp-4h]
pop edi
pop esi
pop eax
pop ecx
pop ebx
leave
ret
// 第8种 长度:0x42
pushfd
push eax
mov eax, 4
mul eax
lea eax, [4 * eax]
mov[esp - 4], eax
mov eax, 4
shl eax, 4
sub eax, 4
sub[esp - 4], eax
mov eax, [esp - 4]
sub eax, 4
mov[esp - 4], eax
pop eax
jne $ + 0x13
call $+5
add dword ptr [esp],0x13
mov eax,[esp+4]
mov [esp-4],eax
popfd
add esp,4
mov dword ptr[esp - 4], Addr
sub esp, 4
ret
// 第9种(7+8) 长度:0x99
// 第10种 长度:0x46
pushfd
push eax
xor eax,Addr
xor eax,64
test eax,eax
//
push eax
mov eax,Addr
push eax
mov [esp-4],eax
mov eax,[esp+4]
mov [esp],eax
mov eax,[esp-4]
mov [esp+4],eax
pop eax
add esp,4
//
xor eax,64
xor eax,[esp]
push eax
add esp,8
popfd
sub esp,8
pop eax
pop [esp-4]
jmp [esp-C]
7FFBDD3B pushfd + retn
7FFAF6DF popfd + retn
addr
eax
fd
3、通过计算得出jmp的目标地址
有8种计算方式,以长度区分。
// 第1种 长度:0x2d
pushfdn
push eaxn
push $1n
add dword ptr[esp], $2n
shl dword ptr[esp], $3n
xor dword ptr[esp], $4n
add dword ptr[esp], $5n
xchg eax,[esp]n
xchg eax,[esp+8]n
xchg eax,[esp]n
popfdn
pop eaxn
ret
// 第2种 长度:0x31
push eaxn
mov eax, $1n
lea eax, [eax + $2]n
push eaxn
mov[esp - 4], eaxn
mov eax, [esp + 4]n
mov[esp], eaxn
mov eax, dword ptr[esp - 4]n
pushfdn
shl eax, $3n
add eax, $4n
xor eax, $5n
popfdn
mov[esp + 4], eaxn
pop eaxn
ret
// 第3种 长度:0x2f
pushfdn
pushfdn
add esp,8n
mov dword ptr[esp - 4], $1n
shl dword ptr[esp - 4], $2n
add dword ptr[esp - 4], $3n
xor dword ptr[esp - 4], $4n
add dword ptr[esp - 4], $5n
sub esp, 8n
popfdn
ret
// 第4种 长度:0x65
pushfdn
push eaxn
mov dword ptr[esp - 4], $1n
mov eax, [esp - 4]n
mov[esp - 8], eaxn
sub esp, 4n
shl dword ptr[esp - 4], $2n
mov eax, [esp + 4]n
add dword ptr[esp - 4], $3n
mov dword ptr[esp], eaxn
mov eax, [esp - 4]n
mov[esp + 4], eaxn
mov eax, [esp]n
mov [esp-8],eaxn
add dword ptr[esp + 4], $4n
xor dword ptr[esp + 4], $5n
mov eax,[esp+4]n
mov [esp-8],eaxn
lea esp, [esp + 8]n
popfdn
lea esp,[esp-4]n
mov eax,[esp-4]n
mov [esp],eaxn
mov eax,[esp-8]n
ret
// 第5种 长度:0x5d
pushfdn
push $1n
push eaxn
mov eax, $2n
mov eax, [esp]n
shl dword ptr[esp + 4], $2n
push eaxn
mov eax, 1n
push eaxn
mov[esp - 4], eaxn
mov eax, [esp + 4]n
mov[esp], eaxn
mov eax, [esp - 4]n
mov[esp + 4], eaxn
pop eaxn
xor dword ptr[esp + 8], $3n
add esp, 4n
mov eax, $4n
add eax, $5n
add dword ptr[esp + 4], eaxn
pop eaxn
add esp,4n
popfdn
lea esp,[esp-4]n
mov eax,[esp-4]n
mov [esp],eaxn
mov eax,[esp-8]n
ret
// 第6种 长度:0x82
push $1n
push eaxn
mov eax, edin
push eaxn
pushfdn
pushfdn
pushfdn
add esp, 0chn
mov dword ptr[esp - 4], $3n
mov eax, [esp - 4]n
mov[esp - 8], eaxn
sub esp, 4n
mov eax, [esp + 4]n
mov[esp], eaxn
mov eax, [esp - 4]n
mov[esp + 4], eaxn
mov eax, [esp]n
add esp, 8n
mov eax, [esp]n
xor eax, [esp]n
mov eax, [esp + 4]n
add eax, $2n
xor eax, $3n
mov[esp + 4], eaxn
push eaxn
mov eax, $4n
push eaxn
mov[esp - 4], eaxn
mov eax, [esp + 4]n
mov[esp], eaxn
mov eax, [esp - 4]n
mov[esp + 4], eaxn
pop eaxn
add esp, 4n
pop eaxn
shl dword ptr[esp], $4n
add dword ptr[esp], $5n
sub esp,14hn
popfdn
lea esp,[esp + 10h]n
ret
// 第7种 长度:0x98
push $1n
push eaxn
mov eax, $4n
push eaxn
mov[esp - 4], eaxn
mov eax, [esp + 4]n
mov[esp], eaxn
mov eax, [esp - 4]n
mov[esp + 4], eaxn
pop eaxn
lea esp, [esp + 4]n
nopn
nopn
nopn
nopn
nopn
nopn
nopn
nopn
nopn
nopn
nopn
nopn
nopn
push ebpn
mov ebp, espn
lea esp, [esp - 34h]n
pushfdn
push ebxn
push ecxn
push eaxn
push esin
push edin
push edxn
lea edi, [ebp - 34h]n
mov ecx, 0xDn
mov eax, 0x0CCCCCCCCn
rep stos dword ptr[edi]n
mov[ebp - 4], ecxn
mov eax, [ebp + 8]n
mov eax, ebpn
mov edx, dword ptr[esp + 4]n
mov ecx, [eax + 4]n
add ecx, $2n
xchg ecx, edxn
mov ecx, dword ptr[esp + 8]n
mov dword ptr[ebp - 30h], 1n
add edx, $3n
shl edx, $4n
mov ecx, edxn
mov edx, dword ptr[ebp - 30h]n
xor ecx, $5n
lea ebx, [eax + 4]n
mov dword ptr[ebp - 34h], edxn
mov [ebx], ecxn
mov ecx, [ebp - 4h]n
pop edxn
pop edin
pop esin
pop eaxn
pop ecxn
pop ebxn
popfdn
leaven
ret
// 第8种 长度:0xaf
pushfdn
push $1n
push eaxn
push edxn
mov eax, 4n
mul eaxn
lea eax, [4 * eax]n
mov[esp - 4], eaxn
mov eax, 4n
shl eax, 4n
sub eax, 4n
sub[esp - 4], eaxn
mov eax, [esp - 4]n
sub eax, 4n
mov[esp - 4], eaxn
pop edxn
pop eaxn
nopn
nopn
nopn
nopn
nopn
nopn
nopn
nopn
nopn
nopn
nopn
nopn
nopn
push ebpn
mov ebp, espn
add esp, -34hn
push edxn
push ebxn
push ecxn
push eaxn
push esin
push edin
lea edi, [ebp - 34h]n
mov ecx, 0xDn
mov eax, 0xCCCCCCCCn
rep stos dword ptr[edi]n
mov[ebp - 4], ecxn
mov eax, [ebp + 8]n
mov edx, dword ptr[esp + 4]n
mov ecx, dword ptr[ebp + 4]n
test edx, 3n
lea ebx, [ebp + 8]n
mov dword ptr[ebp - 30h], 1n
mov edx, ecxn
xor edx, $2n
shl edx, $3n
mov eax, edxn
mov edx, dword ptr[ebp - 30h]n
mov dword ptr[ebp - 34h], edxn
cmp dword ptr[ebp - 34h], 0n
add eax, $4n
add eax, $5n
4、替换后的代码进行拆分成块
拆分的方法和步骤0一致,相当于做二次处理。
5、为了降低拆分后代码的规律性,引入了无效的代码片段
四种片段,随机填充。
1、长度 58
push ebp
mov ebp, esp
lea esp, [esp - 34h]
push ecx
push edx
push ebx
push esi
push edi
pushfd
mov edi, fs: [30h]
lea edi, [edi + 8h]
mov edi, [edi]
lea ebx, [ebp]
mov ecx, edi
xchg edx, [ebp]
add ecx, 3ch
mov ecx,[ecx]
add edi, ecx
call $ + 5
pop ecx
lea edi,[edi + 74h]
lea ecx,[ecx + 29h]
sub ebp, 4
mov[ebp], edx
lea ebx,[ebp]
mov[ebx + 4], ecx
cmp edi, 12h
je $ - 55h
popfd
pop edi
pop esi
pop ebx
pop edx
pop ecx
leave
ret
nop
nop
nop
nop
nop
nop
nop
2、长度 21
push ebp
mov ebp,esp
sub esp,-34h
pushad
mov edi,fs:[30h]
lea edi,[edi+8h]
mov edi,[edi]
mov eax,edi
lea eax,[4*eax]
push eax
pop edi
popad
leave
3、长度 21
mov edi,edi
push ebp
mov ebp,esp
lea esp,[esp-22h]
mov dword ptr [ebp-4h],ecx
mov dword ptr [ebp-8h],ecx
mov dword ptr [ebp-ch],ecx
mov dword ptr [ebp-1ch],ecx
mov esp,ebp
pop ebp
jmp $+8
nop
nop
nop
4、长度 42
call $ +0x2E
mov eax, eax
call $ +0xB
mov eax, eax
lea esp, [esp + 12]
lea esp, [esp + 10h]
mov eax, eax
mov eax, eax
call $ +0x24
mov eax, eax
mov eax, eax
call $ +0x14
mov eax, eax
lea esp, [esp - 4]
call $ -0xD
mov eax, eax
mov eax, eax
call $ -0x30
mov eax, eax
lea esp, [esp + 8h]
5、长度 42
call $ +0x2E
mov eax, eax
call $ +0x37
mov eax, eax
lea esp, [esp + 12]
lea esp, [esp + 10h]
mov eax, eax
mov eax, eax
call $ +0x24
mov eax, eax
mov eax, eax
call $ +0x14
mov eax, eax
lea esp, [esp - 4]
call $ -0xD
mov eax, eax
mov eax, eax
call $ -0x30
mov eax, eax
lea esp, [esp + 8h]
二
数学保护
数学公式(逆运算):((format(Serial) ^2 mod P) * A + B) mod P) ^2 mod P = MD5(name)
参数:
验证:
(((S^2 Mod P) * A + B) Mod P) ^2 Mod P = N 满足该式子则成功。
破解思路:
1、把无效的代码片段替换为空,去除垃圾代码,保留有效代码。
2、去除拆分后成块的代码中的jmp,将代码块整合成有序代码。
3、通过trace找出最终跳转地址的计算模板,然后通过文本处理计算出地址进行替换。
4、处理乱序:通过trace跟踪出执行乱序的代码,截获原始地址进行处理。
赛题解析
lea esp, dword ptr ss:[esp+0x14]
lea esp, dword ptr ss:[esp+0x8]
0043D6E1 51 push ecx
0043D6E2 E8 82FAFDFF call 0041D169 ; 获取serial
0043D6E7 68 80B57D1F push 0x1F7DB580 ; 这里能看到name/serial
0043D6EC 89DB mov ebx, ebx
0043D6EE 50 push eax
0043D6EF 89E4 mov esp, esp
0043D6F1 B8 1D000000 mov eax, 0x1D
0043D6F6 90 nop
00466750 5D pop ebp
00466751 83F8 20 cmp eax, 0x20 ; 比较长度
00466754 9C pushfd
004DD1DE C785 00FFFFFF 7>mov dword ptr ss:[ebp-0x100], 0x10325476 ;md5初始化
0019FD38 01 23 45 67 89 AB CD EF FE DC BA 98 76 54 32 10 #Eg壂惋簶vT2
0019FDC4 F4 D5 16 EF CE 55 11 93 B6 6E E1 68 26 51 5A 4F 粽镂U摱n醜&QZO
004C4F17 E8 8840F7FF call 00438FA4 ; 验证call,ecx = name, edx = serial
004C4F1C 68 66757D1C push 0x1C7D7566 ; 这里验证完毕, al = 1 成功, al = 0 失败
004C4F21 50 push eax
0049BFAE B8 F8414000 mov eax, 004041F8 ; ASCII "验证正确n"
0049BFB3 9C pushfd
0049BFB4 89E4 mov esp, esp
0049BFB6 9C pushfd
0049BFB7 89DB mov ebx, ebx
004CA73A 8D6424 08 lea esp, dword ptr ss:[esp+0x8]
004CA73E ^ 0F85 BE38FAFF jnz 0046E002 ; 爆破点,jmp,验证成功
004CA744 68 BAEB7025 push 0x2570EBBA
call 438fa4
004318D5 81EC 28010000 sub esp, 0x128
0043E967 8D6424 14 lea esp, dword ptr ss:[esp+0x14]
0043E96B E8 A3B90900 call 004DA313 ; 似乎是 string to bignum
0043E970 9C pushfd
004C0B29 89C0 mov eax, eax
004C0B2B 8D6424 14 lea esp, dword ptr ss:[esp+0x14]
004C0B2F E8 D059F9FF call Mul ; 这里似乎是 pow2
004C0B34 9C pushfd
EEA43B9D52515B49838AFAA50490DA0B * EEA43B9D52515B49838AFAA50490DA0B = DE75C834F482A299391D073F5D424CAB9AA9FE2AAE920EE2228766F45E16BC79
0019FDA4 79 BC 16 5E F4 66 87 22 E2 0E 92 AE 2A FE A9 9A y?^鬴??挳*?
0019FDB4 AB 4C 42 5D 3F 07 1D 39 99 A2 82 F4 34 C8 75 DE 獿B]?9櫌傯4萿?
00444D59 67:E8 21020100 call <modN>
00444D5F 50 push eax ; 返回1
0019FDA4 C3 E1 2D 54 FD 5A A8 FC 4F DC D5 D1 6D D8 04 93 冕-T齔O苷裮??
0019FDB4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
DE75C834F482A299391D073F5D424CAB9AA9FE2AAE920EE2228766F45E16BC79 - 9304D86DD1D5DC4FFCA85AFD542DE1C3 =
DE75C834F482A299391D073F5D424CAB07A525BCDCBC329225DF0BF709E8DAB
factor(0xDE75C834F482A299391D073F5D424CAB07A525BCDCBC329225DF0BF709E8DAB6)
fac: factoring 100621555269000733341031010157969998386759504095520400047147427430100793612982
fac: using pretesting plan: normal
fac: no tune info: using qs/gnfs crossover of 95 digits
starting SIQS on c72: 146405049556078485019294860272741026808150808686274920697977580425648851
==== sieving in progress (1 thread): 16656 relations needed ====
==== Press ctrl-c to abort and save state ====
SIQS elapsed time = 0.6650 seconds.
Total factoring time = 0.6730 seconds
P39 = 340282366920938463463374607424628147107
P33 = 430245771712568276625619760299793
ans = 1
其中P33太小,P39 = FFFFFFFFFFFFFFFFFFFFFFFE566B43A3。
DE75C834F482A299391D073F5D424CAB9AA9FE2AAE920EE2228766F45E16BC79 Mod FFFFFFFFFFFFFFFFFFFFFFFE566B43A3 = 9304D86DD1D5DC4FFCA85AFD542DE1C3
6805A57D5B006445AC1B0675EB188435 * 9304D86DD1D5DC4FFCA85AFD542DE1C3 = 3BBD360EF483631109E77CAB8B604BE7252D7537F13655FA919F38844130495F
3BBD360EF483631109E77CAB8B604BE768906BBC53C8BB20F644044205801BE2
3BBD360EF483631109E77CAB8B604BE768906BBC53C8BB20F644044205801BE2 - 3BBD360EF483631109E77CAB8B604BE7252D7537F13655FA919F38844130495F =
4362F6846292652664A4CBBDC44FD283
00473134 E8 471EFEFF call <modN>
00473139 50 push eax
24938628338F43651192F4F03FD24328 * 24938628338F43651192F4F03FD24328 = 0539D2BEA6F99DC5F4B8C6AAD5DCBB1F9927D007969D817073CB54BFEF3DF640
0019FD10 40 F6 3D EF BF 54 CB 73 70 81 9D 96 07 D0 27 99 @?锟T藄p仢???
0019FD20 1F BB DC D5 AA C6 B8 F4 C5 9D F9 A6 BE D2 39 05 卉摘聘襞濝?
0019FD10 F4 D5 16 EF CE 55 11 93 B6 6E E1 68 26 51 5A 4F 粽镂U摱n醜&QZO
待评选(1):【最受欢迎战队奖】
长按二维码立即投票!
【最受欢迎战队奖】
【最受欢迎战队奖】
评选对象:
2021 KCTF秋季赛 参赛战队(包含防守方所有战队+攻击方前20名战队)
评选方式:
登陆看雪账号,在本帖为喜欢的战队投票,每个账号可投1票。
投票时间:
12月15日 14:00 ~12月22日 14:00
奖品:
【最受欢迎战队奖】得票第一名:可获得「HUAWEI WATCH GT2 华为手表」
待评选(2):【新思路奖】
长按二维码立即投票!
【新思路奖】
【新思路奖】
评选对象:
2021 KCTF秋季赛 参赛防守方战队
评选方式:
1、会员投票(占比50%):在KCTF答题页面投票,只有提交答案的选手才可投票。【快使用你们的特权~】
2、看雪KCTF专家评审团投票(占比50%):评审团成员投票,每人一票。
投票时间:
比赛开始,直到比赛结束后一周。(12月22日12:00关闭投票通道)
奖品:
【新思路奖】得票第一名:可获得「HUAWEI WATCH GT2 华为手表」
基于区块链、人工智能、大数据、云计算等前沿技术探索,以科技构建生态新基建。经过实际业务验证,围绕三大核心产品系列——业务增长系列、业务生产系列、业务基建系列,覆盖保险经营中的产品设计、精准营销、核保核赔、服务与运营管理等关键环节,打造高效、安全、可靠的技术产品与解决方案,助力保险生态及更多金融、电商、在线教育、融媒体等行业客户实现数字化升级。
往期解析
1、看雪·众安 2021 KCTF 秋季赛 | 第二题设计思路及解析
2、看雪·众安 2021 KCTF 秋季赛 | 第三题设计思路及解析
3、看雪·众安 2021 KCTF 秋季赛 | 第四题设计思路及解析
4、看雪·众安 2021 KCTF 秋季赛 | 第五题设计思路及解析
5、看雪·众安 2021 KCTF 秋季赛 | 第六题设计思路及解析
6、看雪·众安 2021 KCTF 秋季赛 | 第七题设计思路及解析
7、看雪·众安 2021 KCTF 秋季赛 | 第八题设计思路及解析
8、看雪·众安 2021 KCTF 秋季赛 | 第九题设计思路及解析
球分享
球点赞
球在看
原文始发于微信公众号(看雪学苑):看雪·众安 2021 KCTF 秋季赛 | 第十题设计思路及解析