看雪·眾安 2021 KCTF 秋季賽 | 第十題設計思路及解析
此題沒有反除錯,只有一定的混淆。
對於初級參賽者,需要對抗本題的混淆。
對於中級參賽者,需要熟悉平方剩餘演算法。
對於高階參賽者,需要發現並修復CrackMe中的bug。
出題團隊在賽前釋出了一部情感短視訊,並將解題思路隱藏於其中。賽後又釋出了一部解析視訊,深入講解了破解方法。
作為第一個配短視訊的CTF賽題,此題出題思路別緻,視訊製作專業,是一個有里程碑意義的CTF賽題!
截至比賽結束,此題共計圍觀人數:1957人,攻破戰隊數:4。
分別是:金左手、中婭之戒、mininep、辣雞戰隊。從圍觀人數來看,此題吸引了不少參賽成員。特意為CTF賽題製作高水準的配套微電影還是頭一次見吧!這不,解析版的視訊也為大家奉上啦~
《生命的饋贈》出題視訊:https://www.bilibili.com/video/bv1Uh411s7u4
出題團隊簡介
第十題《生命的饋贈》出題方:【GRAFFINDOR】戰隊。
【GRAFFINDOR】戰隊成員如下:
賽題設計思路
題目設計說明:防守有兩部分,程式程式碼混淆和數學保護。
一、混淆
1、程式碼亂序處理
行與行之間加入jmp,通過jmp銜接每一行程式碼。
定義:定義了一個結構體管理每行程式碼,結構體如下。
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)新的jmp\call目標地址的計算方法(假設原始碼僅為程式碼,不做它用,且程式碼為Jmp或者Call)
相對跳轉的修正:若原來程式碼要跳轉的地址not in [CodeLineOldAddrBegin,
CodeLineOldAddrEnd]中,則用NewAddr和OldAddrToJmpOrCall進行修正;反之,尋找原來程式碼跳轉地址對應的CodeLineToExpand,用NewAddr和原來程式碼跳轉地址對應的CodeLineToExpand中的NewAddr進行修正。
絕對跳轉的修正:若原來程式碼要跳轉的地址not in [CodeLineOldAddrBegin,
CodeLineOldAddrEnd]中,則不需要修正;反之,尋找原來程式碼跳轉地址對應的CodeLineToExpand,原來程式碼跳轉地址對應的CodeLineToExpand中的NewAddr進行修正。
2、初步替換jmp指令
按長度分為9種。
// 第一種 長度:6push Addrret// 第二種 長度:0x1Cpush eaxmov eax,Addrpush eaxmov [esp-4],eaxmov eax,[esp+4]mov [esp],eaxmov eax,[esp-4]mov [esp+4],eaxpop eaxret// 第三種1 長度:0xCmov dword ptr[esp-4],Addrjmp[esp - 4] // 第三種2 長度:Cmov dword ptr[esp-4],Addrsub esp,4ret// 第四種 長度:0x2Dpush eaxmov dword ptr[esp-4],Addrmov eax,[esp-4]mov [esp-8],eaxsub esp,4mov eax,[esp+4]mov [esp],eaxmov eax,[esp-4]mov [esp+4],eaxmov eax,[esp]add esp,8 //add esp,4jmp [esp-4] //ret// 第五種 長度:0x34push Addrpush eaxmov eax,Addrmov eax,[esp]//push eaxmov eax,Addrpush eaxmov [esp-4],eaxmov eax,[esp+4]mov [esp],eaxmov eax,[esp-4]mov [esp+4],eaxpop eax//add esp,4pop eaxadd esp,4jmp [esp-4]// 第六種(4+5) 長度:0x86push Addrpush eaxmov eax,Addrpush eaxmov dword ptr [esp-4],Addrmov eax,[esp-4]mov [esp-8],eaxsub esp,4mov eax,[esp+4]mov [esp],eaxmov eax,[esp-4]mov [esp+4],eaxmov eax,[esp]add esp,8 //add esp,4mov eax,[esp]push eaxmov eax,Addrpush eaxmov [esp-4],eaxmov eax,[esp+4]push eaxmov dword ptr[esp-4],Addrmov eax,[esp-4]mov [esp-8],eaxsub esp,4mov eax,[esp+4]mov [esp],eaxmov eax,[esp-4]mov [esp+4],eaxmov eax,[esp]add esp,8 //add esp,4mov [esp],eaxmov eax,[esp-4]mov [esp+4],eaxpop eaxadd esp,4pop eaxadd esp,4jmp [esp-4]// 第7種 長度:0x59push Addrpush 0x7FFA08ACjmp [esp]nopnopnopnopnopnopnopnopnopnopnopnopnoppush ebpmov ebp,espadd esp,-34push ebxpush ecxpush eaxpush esipush edilea edi,[ebp-34h]mov ecx,Dmov eax,0x0CCCCCCCCrep stos dword ptr [edi]mov [ebp-4],ecxmov eax,[ebp+8]mov edx,dword ptr [esp+4]mov ecx,dword ptr [esp+8]mov dword ptr [ebp-30h],1mov edx,dword ptr [ebp-30h]mov dword ptr [ebp-34h],edxmov ecx,[ebp-4h]pop edipop esipop eaxpop ecxpop ebxleaveret// 第8種 長度:0x42pushfdpush eaxmov eax, 4mul eaxlea eax, [4 * eax]mov[esp - 4], eaxmov eax, 4shl eax, 4sub eax, 4sub[esp - 4], eaxmov eax, [esp - 4]sub eax, 4mov[esp - 4], eaxpop eaxjne $ + 0x13call $+5add dword ptr [esp],0x13mov eax,[esp+4]mov [esp-4],eaxpopfdadd esp,4mov dword ptr[esp - 4], Addrsub esp, 4ret// 第9種(7+8) 長度:0x99// 第10種 長度:0x46pushfdpush eaxxor eax,Addrxor eax,64test eax,eax//push eaxmov eax,Addrpush eaxmov [esp-4],eaxmov eax,[esp+4]mov [esp],eaxmov eax,[esp-4]mov [esp+4],eaxpop eaxadd esp,4//xor eax,64xor eax,[esp]push eaxadd esp,8popfdsub esp,8pop eaxpop [esp-4]jmp [esp-C]7FFBDD3B pushfd + retn7FFAF6DF popfd + retnaddreaxfd
3、通過計算得出jmp的目標地址
有8種計算方式,以長度區分。
// 第1種 長度:0x2dpushfd\npush eax\npush $1\nadd dword ptr[esp], $2\nshl dword ptr[esp], $3\nxor dword ptr[esp], $4\nadd dword ptr[esp], $5\nxchg eax,[esp]\nxchg eax,[esp+8]\nxchg eax,[esp]\npopfd\npop eax\nret // 第2種 長度:0x31push eax\nmov eax, $1\nlea eax, [eax + $2]\npush eax\nmov[esp - 4], eax\nmov eax, [esp + 4]\nmov[esp], eax\nmov eax, dword ptr[esp - 4]\npushfd\nshl eax, $3\nadd eax, $4\nxor eax, $5\npopfd\nmov[esp + 4], eax\npop eax\nret// 第3種 長度:0x2fpushfd\npushfd\nadd esp,8\nmov dword ptr[esp - 4], $1\nshl dword ptr[esp - 4], $2\nadd dword ptr[esp - 4], $3\nxor dword ptr[esp - 4], $4\nadd dword ptr[esp - 4], $5\nsub esp, 8\npopfd\nret// 第4種 長度:0x65pushfd\npush eax\nmov dword ptr[esp - 4], $1\nmov eax, [esp - 4]\nmov[esp - 8], eax\nsub esp, 4\nshl dword ptr[esp - 4], $2\nmov eax, [esp + 4]\nadd dword ptr[esp - 4], $3\nmov dword ptr[esp], eax\nmov eax, [esp - 4]\nmov[esp + 4], eax\nmov eax, [esp]\nmov [esp-8],eax\nadd dword ptr[esp + 4], $4\nxor dword ptr[esp + 4], $5\nmov eax,[esp+4]\nmov [esp-8],eax\nlea esp, [esp + 8]\npopfd\nlea esp,[esp-4]\nmov eax,[esp-4]\nmov [esp],eax\nmov eax,[esp-8]\nret// 第5種 長度:0x5dpushfd\npush $1\npush eax\nmov eax, $2\nmov eax, [esp]\nshl dword ptr[esp + 4], $2\npush eax\nmov eax, 1\npush eax\nmov[esp - 4], eax\nmov eax, [esp + 4]\nmov[esp], eax\nmov eax, [esp - 4]\nmov[esp + 4], eax\npop eax\nxor dword ptr[esp + 8], $3\nadd esp, 4\nmov eax, $4\nadd eax, $5\nadd dword ptr[esp + 4], eax\npop eax\nadd esp,4\npopfd\nlea esp,[esp-4]\nmov eax,[esp-4]\nmov [esp],eax\nmov eax,[esp-8]\nret// 第6種 長度:0x82push $1\npush eax\nmov eax, edi\npush eax\npushfd\npushfd\npushfd\nadd esp, 0ch\nmov dword ptr[esp - 4], $3\nmov eax, [esp - 4]\nmov[esp - 8], eax\nsub esp, 4\nmov eax, [esp + 4]\nmov[esp], eax\nmov eax, [esp - 4]\nmov[esp + 4], eax\nmov eax, [esp]\nadd esp, 8\nmov eax, [esp]\nxor eax, [esp]\nmov eax, [esp + 4]\nadd eax, $2\nxor eax, $3\nmov[esp + 4], eax\npush eax\nmov eax, $4\npush eax\nmov[esp - 4], eax\nmov eax, [esp + 4]\nmov[esp], eax\nmov eax, [esp - 4]\nmov[esp + 4], eax\npop eax\nadd esp, 4\npop eax\nshl dword ptr[esp], $4\nadd dword ptr[esp], $5\nsub esp,14h\npopfd\nlea esp,[esp + 10h]\nret// 第7種 長度:0x98push $1\npush eax\nmov eax, $4\npush eax\nmov[esp - 4], eax\nmov eax, [esp + 4]\nmov[esp], eax\nmov eax, [esp - 4]\nmov[esp + 4], eax\npop eax\nlea esp, [esp + 4]\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\npush ebp\nmov ebp, esp\nlea esp, [esp - 34h]\npushfd\npush ebx\npush ecx\npush eax\npush esi\npush edi\npush edx\nlea edi, [ebp - 34h]\nmov ecx, 0xD\nmov eax, 0x0CCCCCCCC\nrep stos dword ptr[edi]\nmov[ebp - 4], ecx\nmov eax, [ebp + 8]\nmov eax, ebp\nmov edx, dword ptr[esp + 4]\nmov ecx, [eax + 4]\nadd ecx, $2\nxchg ecx, edx\nmov ecx, dword ptr[esp + 8]\nmov dword ptr[ebp - 30h], 1\nadd edx, $3\nshl edx, $4\nmov ecx, edx\nmov edx, dword ptr[ebp - 30h]\nxor ecx, $5\nlea ebx, [eax + 4]\nmov dword ptr[ebp - 34h], edx\nmov [ebx], ecx\nmov ecx, [ebp - 4h]\npop edx\npop edi\npop esi\npop eax\npop ecx\npop ebx\npopfd\nleave\nret// 第8種 長度:0xafpushfd\npush $1\npush eax\npush edx\nmov eax, 4\nmul eax\nlea eax, [4 * eax]\nmov[esp - 4], eax\nmov eax, 4\nshl eax, 4\nsub eax, 4\nsub[esp - 4], eax\nmov eax, [esp - 4]\nsub eax, 4\nmov[esp - 4], eax\npop edx\npop eax\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\npush ebp\nmov ebp, esp\nadd esp, -34h\npush edx\npush ebx\npush ecx\npush eax\npush esi\npush edi\nlea edi, [ebp - 34h]\nmov ecx, 0xD\nmov eax, 0xCCCCCCCC\nrep stos dword ptr[edi]\nmov[ebp - 4], ecx\nmov eax, [ebp + 8]\nmov edx, dword ptr[esp + 4]\nmov ecx, dword ptr[ebp + 4]\ntest edx, 3\nlea ebx, [ebp + 8]\nmov dword ptr[ebp - 30h], 1\nmov edx, ecx\nxor edx, $2\nshl edx, $3\nmov eax, edx\nmov edx, dword ptr[ebp - 30h]\nmov dword ptr[ebp - 34h], edx\ncmp dword ptr[ebp - 34h], 0\nadd eax, $4\nadd eax, $5\n
4、替換後的程式碼進行拆分成塊
拆分的方法和步驟0一致,相當於做二次處理。
5、為了降低拆分後程式碼的規律性,引入了無效的程式碼片段
四種片段,隨機填充。
1、長度 58push ebpmov ebp, esplea esp, [esp - 34h]push ecxpush edxpush ebxpush esipush edipushfdmov edi, fs: [30h]lea edi, [edi + 8h]mov edi, [edi]lea ebx, [ebp]mov ecx, edixchg edx, [ebp]add ecx, 3chmov ecx,[ecx]add edi, ecxcall $ + 5pop ecxlea edi,[edi + 74h]lea ecx,[ecx + 29h]sub ebp, 4mov[ebp], edxlea ebx,[ebp]mov[ebx + 4], ecxcmp edi, 12hje $ - 55hpopfdpop edipop esipop ebxpop edxpop ecxleaveretnopnopnopnopnopnopnop 2、長度 21push ebpmov ebp,espsub esp,-34hpushadmov edi,fs:[30h]lea edi,[edi+8h]mov edi,[edi]mov eax,edilea eax,[4*eax]push eaxpop edipopadleave3、長度 21mov edi,edipush ebpmov ebp,esplea esp,[esp-22h]mov dword ptr [ebp-4h],ecxmov dword ptr [ebp-8h],ecxmov dword ptr [ebp-ch],ecxmov dword ptr [ebp-1ch],ecxmov esp,ebppop ebpjmp $+8nopnopnop4、長度 42call $ +0x2Emov eax, eaxcall $ +0xBmov eax, eaxlea esp, [esp + 12]lea esp, [esp + 10h]mov eax, eaxmov eax, eaxcall $ +0x24mov eax, eaxmov eax, eaxcall $ +0x14mov eax, eaxlea esp, [esp - 4]call $ -0xDmov eax, eaxmov eax, eaxcall $ -0x30mov eax, eaxlea esp, [esp + 8h]5、長度 42call $ +0x2Emov eax, eaxcall $ +0x37mov eax, eaxlea esp, [esp + 12]lea esp, [esp + 10h]mov eax, eaxmov eax, eaxcall $ +0x24mov eax, eaxmov eax, eaxcall $ +0x14mov eax, eaxlea esp, [esp - 4]call $ -0xDmov eax, eaxmov eax, eaxcall $ -0x30mov eax, eaxlea 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跟蹤出執行亂序的程式碼,截獲原始地址進行處理。
賽題解析
一、分析篇
程式碼被混淆了。
混淆規律:6個call之後,類似下面這樣平衡堆疊的指令下面一條,就是真實指令。
lea esp, dword ptr ss:[esp+0x14]lea esp, dword ptr ss:[esp+0x8]
二、逆向篇
輸入預設的 name/serial,記憶體訪問斷點,返回到這裡。
0043D6E1 51 push ecx0043D6E2 E8 82FAFDFF call 0041D169 ; 獲取serial0043D6E7 68 80B57D1F push 0x1F7DB580 ; 這裡能看到name/serial0043D6EC 89DB mov ebx, ebx0043D6EE 50 push eax0043D6EF 89E4 mov esp, esp0043D6F1 B8 1D000000 mov eax, 0x1D0043D6F6 90 nop
然後serial比較長度,必須是32位元組:
00466750 5D pop ebp00466751 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
猜測是md5演算法,但此時記憶體中已經出現了正確的md5值:
0019FDC4 F4 D5 16 EF CE 55 11 93 B6 6E E1 68 26 51 5A 4F 粽鏤U摱n醜&QZO
這正好是name(1A5FBFD826E1D12E)的md5值,所以,這裡應該是serial逆推回去算出來的,改一個位元組會發現驗證錯誤。
重新分析,發現這個call是關鍵:
004C4F17 E8 8840F7FF call 00438FA4 ; 驗證call,ecx = name, edx = serial004C4F1C 68 66757D1C push 0x1C7D7566 ; 這裡驗證完畢, al = 1 成功, al = 0 失敗004C4F21 50 push eax
0049BFAE B8 F8414000 mov eax, 004041F8 ; ASCII "驗證正確\n"0049BFB3 9C pushfd0049BFB4 89E4 mov esp, esp0049BFB6 9C pushfd0049BFB7 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 438fa4004318D5 81EC 28010000 sub esp, 0x128
這裡提升堆疊空間,可以直接清0堆疊,看看堆疊會出現哪些變數。
0043E967 8D6424 14 lea esp, dword ptr ss:[esp+0x14]0043E96B E8 A3B90900 call 004DA313 ; 似乎是 string to bignum0043E970 9C pushfd
004C0B29 89C0 mov eax, eax004C0B2B 8D6424 14 lea esp, dword ptr ss:[esp+0x14]004C0B2F E8 D059F9FF call Mul ; 這裡似乎是 pow2 004C0B34 9C pushfd
456504這個函式,傳入2個引數(eax, ecx) ,傳出1個引數([esp+4])。
執行完看輸出地址,這個正好是:
EEA43B9D52515B49838AFAA50490DA0B * EEA43B9D52515B49838AFAA50490DA0B = DE75C834F482A299391D073F5D424CAB9AA9FE2AAE920EE2228766F45E16BC790019FDA4 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萿?
所以上面是Mul,在Mul上面下斷點。
然後經過一個函式:
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
然後用yafu分解一下:
factor(0xDE75C834F482A299391D073F5D424CAB07A525BCDCBC329225DF0BF709E8DAB6)
fac: factoring 100621555269000733341031010157969998386759504095520400047147427430100793612982fac: using pretesting plan: normalfac: 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
factors found
P39 = 340282366920938463463374607424628147107P33 = 430245771712568276625619760299793ans = 1
其中P33太小,P39 = FFFFFFFFFFFFFFFFFFFFFFFE566B43A3。
驗證一下:
DE75C834F482A299391D073F5D424CAB9AA9FE2AAE920EE2228766F45E16BC79 Mod FFFFFFFFFFFFFFFFFFFFFFFE566B43A3 = 9304D86DD1D5DC4FFCA85AFD542DE1C3
所以上面那個函式是 Mod 0xFFFFFFFFFFFFFFFFFFFFFFFE566B43A3。
設N=FFFFFFFFFFFFFFFFFFFFFFFE566B43A3,在ModN位置下斷點,然後F9跑,然後發現Mul斷下來了。
6805A57D5B006445AC1B0675EB188435 * 9304D86DD1D5DC4FFCA85AFD542DE1C3 = 3BBD360EF483631109E77CAB8B604BE7252D7537F13655FA919F38844130495F
斷下了後,發現記憶體中值發生了變化:
3BBD360EF483631109E77CAB8B604BE768906BBC53C8BB20F644044205801BE2
跟上面乘的結果比較,發現是大了一點點:
3BBD360EF483631109E77CAB8B604BE768906BBC53C8BB20F644044205801BE2 - 3BBD360EF483631109E77CAB8B604BE7252D7537F13655FA919F38844130495F = 4362F6846292652664A4CBBDC44FD283
再跑,發現ModN斷下來了:
00473134 E8 471EFEFF call <modN>00473139 50 push eax
結果:24938628338F43651192F4F03FD24328
再跑,Mul斷下來了:
24938628338F43651192F4F03FD24328 * 24938628338F43651192F4F03FD24328 = 0539D2BEA6F99DC5F4B8C6AAD5DCBB1F9927D007969D817073CB54BFEF3DF6400019FD10 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 卉摘聘襞濝?
再跑,ModN斷下來,正好是0x4F5A512668E16EB6931155CEEF16D5F4
記憶體中結構,恰好等於 md5(name)的值:
0019FD10 F4 D5 16 EF CE 55 11 93 B6 6E E1 68 26 51 5A 4F 粽鏤U摱n醜&QZO
3、演算法篇
整理一下演算法:
設N = FFFFFFFFFFFFFFFFFFFFFFFE566B43A3
A = 6805A57D5B006445AC1B0675EB188435
B = 4362F6846292652664A4CBBDC44FD283
M = MD5(name) , 注意,記憶體中是little eddian的
S = hex(serial)
整個驗證演算法,可以用表示式來表示:
M = (((S ^ 2) Mod N) * A + B) ^ 2 Mod N
看數學表示式,實際上是 兩次平方模,然後比較name的md5。逆運算就是求平方剩餘。
平方剩餘公式是:
當 Y = X^2 Mod N ,且 N mod 4 = 3的時候
X1 = Y ^ ((N+1)/4) Mod N
平方剩餘有多解:另一解是 X2 = N - X1
所以這題其實有4解。
name: 1A5FBFD826E1D12E
serial:
EEA43B9D52515B49838AFAA50490DA0B
115BC462ADAEA4B67C75055951DA6998
41B8103BEC6C05BC8D4E37DD2DF5D1E8
BE47EFC41393FA4372B1C821287571BB
經測試,這4解都可以通過驗證。
4、音樂篇
但是,當我們使用KCTF的時候:
MD5('KCTF') = 0xA0D99FB4D5ABF597979F99A2C6B11A7A ( 記憶體中位元組碼:7A 1A B1 C6 A2 99 9F 97 97 F5 AB D5 B4 9F D9 A0 )
求出來的4解是:
2EA6060B597BA4D12D2FC0A1DF7A5FB5
D159F9F4A6845B2ED2D03F5C76F0E3EE
48538B7EADCDD321FB83E1F4D227BAD9
B7AC748152322CDE047C1E09844388CA
遺憾的是,一個都無法通過!
看了一遍又一遍《生命的饋贈》,“所有曲目我都試過了,這密碼還是打不開”
為什麼會不對呢?各種百度,谷歌,原來,平方剩餘是有條件的。
Y = X^2 Mod N,X有解的條件是 Y^ ((N-1)/2) == 1 Mod N
第一次的時候,是有平方剩餘的,所以能解出兩解。
Z1 = 0000000000000000B0D3C2D4E7B7A3BA
Z2 = 6E000A013A6DF57F8ABD86D0120C88AD
但是第二次的時候,兩組資料都沒有平方剩餘!
這就有意思了,到底哪裡出問題了呢?再看一遍視訊,發現缺了個琴音是破解的關鍵!
有沒有可能,Mod的時候,沒有模盡,使得結果多了一個N,然後取了低128bit,正好就有平方剩餘了呢?
於是,把Z1,Z2,分別
Z1 + 2^128 - N = B0D3C2D6914C6017
求兩組平方剩餘:
05A6CC68CF60E9606195E9912BBF332A
FA593397309F169F9E6A166D2AAC1079
Z2 + 2^128 - N = 6E000A013A6DF57F8ABD86D1BBA1450A
求兩組平方剩餘:
6E66D51BBB5DFD0200F5BF564A7F1052
91992AE444A202FDFF0A40A80BEC3351
驗證發現,FA593397309F169F9E6A166D2AAC1079 是唯一通過的解!
注意:【最受歡迎戰隊獎】&【新思路獎】正在火熱評選中!歡迎大家投上寶貴的一票~
待評選(一):【最受歡迎戰隊獎】
長按二維碼立即投票!【最受歡迎戰隊獎】
【最受歡迎戰隊獎】
評選物件:
2021 KCTF秋季賽 參賽戰隊(包含防守方所有戰隊+攻擊方前20名戰隊)
評選方式:
登陸看雪賬號,在本帖為喜歡的戰隊投票,每個賬號可投1票。
投票時間:
12月15日 14:00 ~12月22日 14:00
獎品:
【最受歡迎戰隊獎】得票第一名:可獲得「HUAWEI WATCH GT2 華為手錶」
待評選(二):【新思路獎】
長按二維碼立即投票!
【新思路獎】
評選物件:
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 秋季賽 | 第九題設計思路及解析
9、看雪·眾安 2021 KCTF 秋季賽 | 第十一題設計思路及解析
- End -
公眾號ID:ikanxue
官方微博:看雪安全
商務合作:wsc@kanxue.com
相關文章
- 看雪·眾安 2021 KCTF 秋季賽 | 第十一題設計思路及解析2021-12-15
- 看雪·眾安 2021 KCTF 秋季賽 | 第九題設計思路及解析2021-12-09
- 看雪·眾安 2021 KCTF 秋季賽 | 第七題設計思路及解析2021-12-03
- 看雪·眾安 2021 KCTF 秋季賽 | 第六題設計思路及解析2021-12-01
- 看雪·眾安 2021 KCTF 秋季賽 | 第五題設計思路及解析2021-11-29
- 看雪·眾安 2021 KCTF 秋季賽 | 第四題設計思路及解析2021-11-25
- 看雪·眾安 2021 KCTF 秋季賽 | 第三題設計思路及解析2021-11-22
- 看雪·深信服 2021 KCTF 春季賽 | 第十題設計思路及解析2021-05-31
- 看雪·深信服 2021 KCTF 春季賽 | 第七題設計思路及解析2021-05-25
- 看雪·深信服 2021 KCTF 春季賽 | 第八題設計思路及解析2021-05-25
- 看雪·深信服 2021 KCTF 春季賽 | 第九題設計思路及解析2021-05-28
- 看雪·深信服 2021 KCTF 春季賽 | 第六題設計思路及解析2021-05-21
- 看雪·深信服 2021 KCTF 春季賽 | 第三題設計思路及解析2021-05-14
- 看雪·深信服 2021 KCTF 春季賽 | 第四題設計思路及解析2021-05-17
- 看雪·深信服 2021 KCTF 春季賽 | 第五題設計思路及解析2021-05-17
- 看雪·深信服 2021 KCTF 春季賽 | 第二題設計思路及解析2021-05-12
- 2020 KCTF秋季賽 | 第五題設計及解題思路2020-11-30
- 2020 KCTF秋季賽 | 第二題設計及解題思路2020-11-23
- 戰局已定!排行榜新鮮出爐!看雪·眾安 2021 KCTF秋季賽圓滿收官!2021-12-17
- 今天中午12點,看雪·眾安 2021 KCTF秋季賽挑戰開啟,書寫你的傳奇故事!2021-11-15
- 看雪.紐盾 KCTF 2019 Q3 | 第十題點評及解題思路2019-10-08
- 看雪.紐盾 KCTF 2019 Q2 | 第十題點評及解題思路2019-07-05
- 2020 KCTF秋季賽 | 第一題點評及解題思路2020-11-20
- 2020 KCTF秋季賽 | 第四題點評及解題思路2020-11-24
- 看雪.紐盾 KCTF 2019 Q3 | 第十一題點評及解題思路2019-10-08
- 看雪.紐盾 KCTF 2019 Q3 | 第十二題點評及解題思路2019-10-08
- 看雪.紐盾 KCTF 2019 Q3 | 第十三題點評及解題思路2019-10-08
- 2021看雪KCTF逆向WP2021-05-21
- 看雪.紐盾 KCTF 2019 Q3 | 第四題點評及解題思路2019-09-29
- 看雪.紐盾 KCTF 2019 Q3 | 第七題點評及解題思路2019-09-30
- 看雪.紐盾 KCTF 2019 Q3 | 第一題點評及解題思路2019-09-25
- 看雪.紐盾 KCTF 2019 Q3 | 第六題點評及解題思路2019-10-08
- 看雪.紐盾 KCTF 2019 Q3 | 第八題點評及解題思路2019-10-08
- 看雪.紐盾 KCTF 2019 Q3 | 第九題點評及解題思路2019-10-08
- 看雪.紐盾 KCTF 2019 Q2 | 第七題點評及解題思路2019-07-02
- 看雪.紐盾 KCTF 2019 Q2 | 第九題點評及解題思路2019-07-04
- 看雪.紐盾 KCTF 2019 Q2 | 第六題點評及解題思路2019-07-01
- 看雪.紐盾 KCTF 2019 Q2 | 第八題點評及解題思路2019-07-03