首页
社区
课程
招聘
[原创]看雪.京东 2018CTF 第十三题 NeuralCrackme WriteUp
2018-7-12 00:09 2317

[原创]看雪.京东 2018CTF 第十三题 NeuralCrackme WriteUp

2018-7-12 00:09
2317
1.浮点运算的题目。
0000000000403880      | 57                    | push rdi                                     | rdi:"%lf"
0000000000403881      | 56                    | push rsi                                     | rsi:"9.998681"
0000000000403882      | 53                    | push rbx                                     | rbx:"Congratuur KEY:"
0000000000403883      | 48:81EC A0010000      | sub rsp,1A0                                  |
000000000040388A      | E8 71E6FFFF           | call nncrackme.401F00                        |
000000000040388F      | 48:8DB424 90000000    | lea rsi,qword ptr ss:[rsp+90]                |
0000000000403897      | 31C0                  | xor eax,eax                                  |
0000000000403899      | B9 20000000           | mov ecx,20                                   | 20:' '
000000000040389E      | 48:89F7               | mov rdi,rsi                                  | rdi:"%lf", rsi:"9.998681"
00000000004038A1      | C64424 24 00          | mov byte ptr ss:[rsp+24],0                   |
00000000004038A6      | F348:AB               | rep stosq                                    |
00000000004038A9      | C64424 34 00          | mov byte ptr ss:[rsp+34],0                   |
00000000004038AE      | 48:8D5C24 70          | lea rbx,qword ptr ss:[rsp+70]                |
00000000004038B3      | 48:C74424 50 00000000 | mov qword ptr ss:[rsp+50],0                  |
00000000004038BC      | 48:C74424 58 00000000 | mov qword ptr ss:[rsp+58],0                  |
00000000004038C5      | 48:C74424 60 00000000 | mov qword ptr ss:[rsp+60],0                  |
00000000004038CE      | 48:C74424 68 00000000 | mov qword ptr ss:[rsp+68],0                  |
00000000004038D7      | 48:C74424 40 00000000 | mov qword ptr ss:[rsp+40],0                  |
00000000004038E0      | C707 00000000         | mov dword ptr ds:[rdi],0                     | rdi:"%lf"
00000000004038E6      | C74424 20 00000000    | mov dword ptr ss:[rsp+20],0                  |
00000000004038EE      | C74424 30 00000000    | mov dword ptr ss:[rsp+30],0                  |
00000000004038F6      | 48:C74424 70 00000000 | mov qword ptr ss:[rsp+70],0                  |
00000000004038FF      | 48:C74424 78 00000000 | mov qword ptr ss:[rsp+78],0                  |
0000000000403908      | 48:C78424 80000000 00 | mov qword ptr ss:[rsp+80],0                  |
0000000000403914      | 48:C78424 88000000 00 | mov qword ptr ss:[rsp+88],0                  |
0000000000403920      | E8 6BDEFFFF           | call nncrackme.401790                        |
0000000000403925      | B9 FC000000           | mov ecx,FC                                   |
000000000040392A      | E8 21E3FFFF           | call nncrackme.401C50                        |
000000000040392F      | 48:8D0D CA530000      | lea rcx,qword ptr ds:[408D00]                |
0000000000403936      | 31C0                  | xor eax,eax                                  |
0000000000403938      | 0F1F8400 00000000     | nop dword ptr ds:[rax+rax],eax               |
0000000000403940      | 0FB61401              | movzx edx,byte ptr ds:[rcx+rax]              |
0000000000403944      | 83F2 19               | xor edx,19                                   |
0000000000403947      | 29C2                  | sub edx,eax                                  |
0000000000403949      | 881403                | mov byte ptr ds:[rbx+rax],dl                 | rbx+rax*1:"ur KEY:"
000000000040394C      | 48:83C0 01            | add rax,1                                    |
0000000000403950      | 48:83F8 10            | cmp rax,10                                   |
0000000000403954      | 75 EA                 | jne nncrackme.403940                         |
0000000000403956      | 48:8D7C24 30          | lea rdi,qword ptr ss:[rsp+30]                |
000000000040395B      | 48:89D9               | mov rcx,rbx                                  | rbx:"Congratuur KEY:"
000000000040395E      | E8 75FDFFFF           | call <JMP.&printf>                           |
0000000000403963      | 0FB605 06540000       | movzx eax,byte ptr ds:[408D70]               |
000000000040396A      | 48:89F2               | mov rdx,rsi                                  | rsi:"9.998681"
000000000040396D      | 48:89F9               | mov rcx,rdi                                  | rdi:"%lf"
0000000000403970      | 83F0 25               | xor eax,25                                   |
0000000000403973      | 884424 30             | mov byte ptr ss:[rsp+30],al                  |
0000000000403977      | 0FB605 F3530000       | movzx eax,byte ptr ds:[408D71]               |
000000000040397E      | 83F0 25               | xor eax,25                                   |
0000000000403981      | 83E8 01               | sub eax,1                                    |
0000000000403984      | 884424 31             | mov byte ptr ss:[rsp+31],al                  |
0000000000403988      | E8 3BFDFFFF           | call <JMP.&scanf>                            |
000000000040398D      | 48:89F2               | mov rdx,rsi                                  | rsi:"9.998681"
0000000000403990      | 8B0A                  | mov ecx,dword ptr ds:[rdx]                   |
0000000000403992      | 48:83C2 04            | add rdx,4                                    |
0000000000403996      | 8D81 FFFEFEFE         | lea eax,qword ptr ds:[rcx-1010101]           |
000000000040399C      | F7D1                  | not ecx                                      |
000000000040399E      | 21C8                  | and eax,ecx                                  |
00000000004039A0      | 25 80808080           | and eax,80808080                             |
00000000004039A5      | 74 E9                 | je nncrackme.403990                          |
00000000004039A7      | 89C1                  | mov ecx,eax                                  |
00000000004039A9      | C1E9 10               | shr ecx,10                                   |
00000000004039AC      | A9 80800000           | test eax,8080                                |
00000000004039B1      | 0F44C1                | cmove eax,ecx                                |
00000000004039B4      | 48:8D4A 02            | lea rcx,qword ptr ds:[rdx+2]                 |
00000000004039B8      | 48:0F44D1             | cmove rdx,rcx                                |
00000000004039BC      | 89C1                  | mov ecx,eax                                  |
00000000004039BE      | 00C1                  | add cl,al                                    |
00000000004039C0      | 48:83DA 03            | sbb rdx,3                                    |
00000000004039C4      | 48:29F2               | sub rdx,rsi                                  | rsi:"9.998681"
00000000004039C7      | 48:83FA 0A            | cmp rdx,A                                    | 比较输入字符个数  要求10个字符
00000000004039CB      | 74 3E                 | je nncrackme.403A0B                          |
00000000004039CD      | 48:8D0D 3C530000      | lea rcx,qword ptr ds:[408D10]                |
00000000004039D4      | 31C0                  | xor eax,eax                                  |
00000000004039D6      | 662E:0F1F8400 0000000 | nop word ptr cs:[rax+rax],ax                 |
00000000004039E0      | 0FB61401              | movzx edx,byte ptr ds:[rcx+rax]              |
00000000004039E4      | 83F2 0F               | xor edx,F                                    |
00000000004039E7      | 29C2                  | sub edx,eax                                  |
00000000004039E9      | 881403                | mov byte ptr ds:[rbx+rax],dl                 | rbx+rax*1:"ur KEY:"
00000000004039EC      | 48:83C0 01            | add rax,1                                    |
00000000004039F0      | 48:83F8 10            | cmp rax,10                                   |
00000000004039F4      | 75 EA                 | jne nncrackme.4039E0                         |
00000000004039F6      | 48:89D9               | mov rcx,rbx                                  | rbx:"Congratuur KEY:"
00000000004039F9      | E8 DAFCFFFF           | call <JMP.&printf>                           |
00000000004039FE      | 31C0                  | xor eax,eax                                  |
0000000000403A00      | 48:81C4 A0010000      | add rsp,1A0                                  |
0000000000403A07      | 5B                    | pop rbx                                      | rbx:"Congratuur KEY:"
0000000000403A08      | 5E                    | pop rsi                                      | rsi:"9.998681"
0000000000403A09      | 5F                    | pop rdi                                      | rdi:"%lf"
0000000000403A0A      | C3                    | ret                                          |
0000000000403A0B      | 48:8D5424 20          | lea rdx,qword ptr ss:[rsp+20]                |
0000000000403A10      | 41:B8 0A000000        | mov r8d,A                                    | A:'\n'
0000000000403A16      | 48:89F1               | mov rcx,rsi                                  | rsi:"9.998681"
0000000000403A19      | E8 C2E2FFFF           | call <nncrackme.is_key_ok>                   | 检查输入字符的组成是否是由0-9 A-F组成
0000000000403A1E      | 83F8 05               | cmp eax,5                                    |
0000000000403A21      | 74 25                 | je nncrackme.403A48                          |
0000000000403A23      | 48:8D0D F6520000      | lea rcx,qword ptr ds:[408D20]                |
0000000000403A2A      | 31C0                  | xor eax,eax                                  |
0000000000403A2C      | 0F1F40 00             | nop dword ptr ds:[rax],eax                   |
0000000000403A30      | 0FB61401              | movzx edx,byte ptr ds:[rcx+rax]              |
0000000000403A34      | 83F2 21               | xor edx,21                                   |
0000000000403A37      | 29C2                  | sub edx,eax                                  |
0000000000403A39      | 881403                | mov byte ptr ds:[rbx+rax],dl                 | rbx+rax*1:"ur KEY:"
0000000000403A3C      | 48:83C0 01            | add rax,1                                    |
0000000000403A40      | 48:83F8 10            | cmp rax,10                                   |
0000000000403A44      | 75 EA                 | jne nncrackme.403A30                         |
0000000000403A46      | EB AE                 | jmp nncrackme.4039F6                         |
0000000000403A48      | 0FB64424 20           | movzx eax,byte ptr ss:[rsp+20]               |
0000000000403A4D      | 48:8D5424 40          | lea rdx,qword ptr ss:[rsp+40]                |
0000000000403A52      | 48:8D4C24 50          | lea rcx,qword ptr ss:[rsp+50]                |
0000000000403A57      | 884424 56             | mov byte ptr ss:[rsp+56],al                  |
0000000000403A5B      | 0FB64424 21           | movzx eax,byte ptr ss:[rsp+21]               |
0000000000403A60      | 884424 57             | mov byte ptr ss:[rsp+57],al                  |
0000000000403A64      | 0FB64424 22           | movzx eax,byte ptr ss:[rsp+22]               |
0000000000403A69      | F2:0F104424 50        | movsd xmm0,qword ptr ss:[rsp+50]             |
0000000000403A6F      | F2:0F114424 60        | movsd qword ptr ss:[rsp+60],xmm0             |
0000000000403A75      | 884424 5D             | mov byte ptr ss:[rsp+5D],al                  |
0000000000403A79      | 0FB64424 23           | movzx eax,byte ptr ss:[rsp+23]               |
0000000000403A7E      | 884424 5E             | mov byte ptr ss:[rsp+5E],al                  |
0000000000403A82      | 0FB64424 24           | movzx eax,byte ptr ss:[rsp+24]               |
0000000000403A87      | 884424 5F             | mov byte ptr ss:[rsp+5F],al                  |
0000000000403A8B      | F2:0F104424 58        | movsd xmm0,qword ptr ss:[rsp+58]             |
0000000000403A91      | F2:0F114424 68        | movsd qword ptr ss:[rsp+68],xmm0             |
0000000000403A97      | E8 44DBFFFF           | call <nncrackme.maybe_add>                   |
0000000000403A9C      | 0FB605 CF520000       | movzx eax,byte ptr ds:[408D72]               |
0000000000403AA3      | 48:89FA               | mov rdx,rdi                                  | rdi:"%lf"
0000000000403AA6      | 48:89F1               | mov rcx,rsi                                  | rsi:"9.998681"
0000000000403AA9      | F2:0F104424 40        | movsd xmm0,qword ptr ss:[rsp+40]             |
0000000000403AAF      | 66:0F28D0             | movapd xmm2,xmm0                             |
0000000000403AB3      | 6649:0F7EC0           | movq r8,xmm0                                 |
0000000000403AB8      | 83F0 12               | xor eax,12                                   |
0000000000403ABB      | 884424 30             | mov byte ptr ss:[rsp+30],al                  |
0000000000403ABF      | 0FB605 AD520000       | movzx eax,byte ptr ds:[408D73]               |
0000000000403AC6      | 83F0 12               | xor eax,12                                   |
0000000000403AC9      | 83E8 01               | sub eax,1                                    |
0000000000403ACC      | 884424 31             | mov byte ptr ss:[rsp+31],al                  |
0000000000403AD0      | 0FB605 9D520000       | movzx eax,byte ptr ds:[408D74]               |
0000000000403AD7      | 83F0 12               | xor eax,12                                   |
0000000000403ADA      | 83E8 02               | sub eax,2                                    |
0000000000403ADD      | 884424 32             | mov byte ptr ss:[rsp+32],al                  |
0000000000403AE1      | E8 D2FBFFFF           | call <JMP.&sprintf>                          |
0000000000403AE6      | 80BC24 91000000 2E    | cmp byte ptr ss:[rsp+91],2E                  | 2E:'.'
0000000000403AEE      | 74 24                 | je nncrackme.403B14                          |
0000000000403AF0      | 48:8D0D 49520000      | lea rcx,qword ptr ds:[408D40]                |
0000000000403AF7      | 31C0                  | xor eax,eax                                  |
0000000000403AF9      | 0FB61401              | movzx edx,byte ptr ds:[rcx+rax]              |
0000000000403AFD      | 83F2 3F               | xor edx,3F                                   |
0000000000403B00      | 29C2                  | sub edx,eax                                  |
0000000000403B02      | 881403                | mov byte ptr ds:[rbx+rax],dl                 | rbx+rax*1:"ur KEY:"
0000000000403B05      | 48:83C0 01            | add rax,1                                    |
0000000000403B09      | 48:83F8 10            | cmp rax,10                                   |
0000000000403B0D      | 75 EA                 | jne nncrackme.403AF9                         |
0000000000403B0F      | E9 E2FEFFFF           | jmp nncrackme.4039F6                         |
0000000000403B14      | 0FBE8424 90000000     | movsx eax,byte ptr ss:[rsp+90]               |
0000000000403B1C      | 66:0FEFC0             | pxor xmm0,xmm0                               |
0000000000403B20      | 66:0FEFD2             | pxor xmm2,xmm2                               |
0000000000403B24      | 66:0FEFC9             | pxor xmm1,xmm1                               |
0000000000403B28      | 83E8 30               | sub eax,30                                   |
0000000000403B2B      | F2:0F2AC0             | cvtsi2sd xmm0,eax                            |
0000000000403B2F      | 0FBE8424 92000000     | movsx eax,byte ptr ss:[rsp+92]               |
0000000000403B37      | F2:0F59C0             | mulsd xmm0,xmm0                              |
0000000000403B3B      | 83E8 30               | sub eax,30                                   |
0000000000403B3E      | F2:0F2AD0             | cvtsi2sd xmm2,eax                            |
0000000000403B42      | 0FBE8424 93000000     | movsx eax,byte ptr ss:[rsp+93]               |
0000000000403B4A      | F2:0F59D2             | mulsd xmm2,xmm2                              |
0000000000403B4E      | 83E8 30               | sub eax,30                                   |
0000000000403B51      | F2:0F2AC8             | cvtsi2sd xmm1,eax                            |
0000000000403B55      | F2:0F59C9             | mulsd xmm1,xmm1                              |
0000000000403B59      | F2:0F58C2             | addsd xmm0,xmm2                              |
0000000000403B5D      | F2:0F58C1             | addsd xmm0,xmm1                              |
0000000000403B61      | E8 FAF7FFFF           | call <nncrackme.maybe_sqrt>                  | (szBuf[0]-'0')*(szBuf[0]-'0')*+(szBuf[2]-'2')*(szBuf[2]-'0')*+(szBuf[3]-'0')*(szBuf[3]-'0')*
0000000000403B66      | 66:0F2E05 02550000    | ucomisd xmm0,qword ptr ds:[409070]           | [409070]=15.5
0000000000403B6E      | 76 53                 | jbe nncrackme.403BC3                         | xmm0小于15.5跳到错误
0000000000403B70      | F64424 22 0F          | test byte ptr ss:[rsp+22],F                  | 测试输入的第6个字符是否为0
0000000000403B75      | 75 4C                 | jne nncrackme.403BC3                         |
0000000000403B77      | F2:0F100D 11550000    | movsd xmm1,qword ptr ds:[409090]             |
0000000000403B7F      | 31C0                  | xor eax,eax                                  |
0000000000403B81      | F2:0F104424 60        | movsd xmm0,qword ptr ss:[rsp+60]             |
0000000000403B87      | F2:0F584424 68        | addsd xmm0,qword ptr ss:[rsp+68]             |
0000000000403B8D      | F2:0F5C4424 40        | subsd xmm0,qword ptr ss:[rsp+40]             |
0000000000403B93      | 66:0F5405 E5540000    | andpd xmm0,xmmword ptr ds:[409080]           |
0000000000403B9B      | 66:0F2EC8             | ucomisd xmm1,xmm0                            |
0000000000403B9F      | 76 24                 | jbe nncrackme.403BC5                         |
0000000000403BA1      | 48:8D0D A8510000      | lea rcx,qword ptr ds:[408D50]                |
0000000000403BA8      | 0FB61401              | movzx edx,byte ptr ds:[rcx+rax]              |
0000000000403BAC      | 83F2 47               | xor edx,47                                   |
0000000000403BAF      | 29C2                  | sub edx,eax                                  |
0000000000403BB1      | 881403                | mov byte ptr ds:[rbx+rax],dl                 | rbx+rax*1:"ur KEY:"
0000000000403BB4      | 48:83C0 01            | add rax,1                                    |
0000000000403BB8      | 48:83F8 10            | cmp rax,10                                   |
0000000000403BBC      | 75 EA                 | jne nncrackme.403BA8                         |
0000000000403BBE      | E9 33FEFFFF           | jmp nncrackme.4039F6                         |
0000000000403BC3      | 31C0                  | xor eax,eax                                  |
0000000000403BC5      | 48:8D0D 94510000      | lea rcx,qword ptr ds:[408D60]                |
0000000000403BCC      | 0FB61401              | movzx edx,byte ptr ds:[rcx+rax]              |
0000000000403BD0      | 83F2 37               | xor edx,37                                   |
0000000000403BD3      | 29C2                  | sub edx,eax                                  |
0000000000403BD5      | 881403                | mov byte ptr ds:[rbx+rax],dl                 | rbx+rax*1:"ur KEY:"
0000000000403BD8      | 48:83C0 01            | add rax,1                                    |
0000000000403BDC      | 48:83F8 10            | cmp rax,10                                   |
0000000000403BE0      | 75 EA                 | jne nncrackme.403BCC                         |
0000000000403BE2      | E9 0FFEFFFF           | jmp nncrackme.4039F6                         |


整体代码就这么多。
要求我们输入的是一个由0-9 A-Z 组成的10个字符的字符串。
长度计算和判断:
000000000040398D      | 48:89F2               | mov rdx,rsi                                  | rsi:"9.998681"
0000000000403990      | 8B0A                  | mov ecx,dword ptr ds:[rdx]                   |
0000000000403992      | 48:83C2 04            | add rdx,4                                    |
0000000000403996      | 8D81 FFFEFEFE         | lea eax,qword ptr ds:[rcx-1010101]           |
000000000040399C      | F7D1                  | not ecx                                      |
000000000040399E      | 21C8                  | and eax,ecx                                  |
00000000004039A0      | 25 80808080           | and eax,80808080                             |
00000000004039A5      | 74 E9                 | je nncrackme.403990                          |
00000000004039A7      | 89C1                  | mov ecx,eax                                  |
00000000004039A9      | C1E9 10               | shr ecx,10                                   |
00000000004039AC      | A9 80800000           | test eax,8080                                |
00000000004039B1      | 0F44C1                | cmove eax,ecx                                |
00000000004039B4      | 48:8D4A 02            | lea rcx,qword ptr ds:[rdx+2]                 |
00000000004039B8      | 48:0F44D1             | cmove rdx,rcx                                |
00000000004039BC      | 89C1                  | mov ecx,eax                                  |
00000000004039BE      | 00C1                  | add cl,al                                    |
00000000004039C0      | 48:83DA 03            | sbb rdx,3                                    |
00000000004039C4      | 48:29F2               | sub rdx,rsi                                  | rsi:"9.998681"
00000000004039C7      | 48:83FA 0A            | cmp rdx,A                                    | 比较输入字符个数  要求10个字符
不满足条件,则直接往下执行,解密输出字符串key len error.
再往下检查字符:
0000000000403A0B      | 48:8D5424 20          | lea rdx,qword ptr ss:[rsp+20]                |
0000000000403A10      | 41:B8 0A000000        | mov r8d,A                                    | A:'\n'
0000000000403A16      | 48:89F1               | mov rcx,rsi                                  | rsi:"9.998681"
0000000000403A19      | E8 C2E2FFFF           | call <nncrackme.is_key_ok>                   | 检查输入字符的组成是否是由0-9 A-F组成
必须是0-9 A-Z相关字符组成,否则失败显示key char error

再往下:
0000000000403A97      | E8 44DBFFFF           | call <nncrackme.maybe_add>                   |
这个函数函数挺复杂的,跟了几次,但是没有还原他。
函数参数在rcx中:


进函数之前,栈中情况:
60fcf0 key1  60fcf8 key2

60fD00 key1  60fD08 key2


此题答案:F13FE02140
这里作为我们的输入。 在函数之前的代码中,会把key分成两部分,前4位key1(F13E),后6位key2( E02140 )
其实这两部分是一个double数值的16进制的高位部分。
此函数执行完成之后,会把一个和(double(key1)+double(key2))放在栈中,之后会通过sprintf(szBuf,"%lf",r8) 打印出来
0000000000403AA9      | F2:0F104424 40        | movsd xmm0,qword ptr ss:[rsp+40]             |
0000000000403AAF      | 66:0F28D0             | movapd xmm2,xmm0                             |
0000000000403AB3      | 6649:0F7EC0           | movq r8,xmm0                                 |
0000000000403AE1      | E8 D2FBFFFF           | call <JMP.&sprintf>                          |

函数执行之后,栈中情况如上。
在函数中有一个判断:
 v14 = *(double *)(v6 + 16);
  if ( v14 <= 1.0 || v14 >= 10.0 || (v15 = *(double *)(v6 + 24), v15 <= 1.0) || v15 >= 10.0 )
  {
    *(double *)qword_40CD00 = *(double *)qword_40CD00 * *(double *)qword_40CD00;
    *(_QWORD *)v7 = 0x4024000000000000i64;
  }
v14即key1的值,v15即key2的值。
两个值都是大于1.0 小于10.0 .
这里格式化之后是9.998681 比我们输入的两数字之和(1.0625+8.9375=10.0) 要稍微小一点,其他输入也可能会稍微大一点,这个函数功能暂时不清楚。。。。
0000000000403AE6      | 80BC24 91000000 2E    | cmp byte ptr ss:[rsp+91],2E                  | 2E:'.'
0000000000403AEE      | 74 24                 | je nncrackme.403B14                          |
......................................................................................................................................
.....................................................................................................................................
0000000000403B14      | 0FBE8424 90000000     | movsx eax,byte ptr ss:[rsp+90]               |
0000000000403B1C      | 66:0FEFC0             | pxor xmm0,xmm0                               |
0000000000403B20      | 66:0FEFD2             | pxor xmm2,xmm2                               |
0000000000403B24      | 66:0FEFC9             | pxor xmm1,xmm1                               |
0000000000403B28      | 83E8 30               | sub eax,30                                   |
0000000000403B2B      | F2:0F2AC0             | cvtsi2sd xmm0,eax                            |
0000000000403B2F      | 0FBE8424 92000000     | movsx eax,byte ptr ss:[rsp+92]               |
0000000000403B37      | F2:0F59C0             | mulsd xmm0,xmm0                              |
0000000000403B3B      | 83E8 30               | sub eax,30                                   |
0000000000403B3E      | F2:0F2AD0             | cvtsi2sd xmm2,eax                            |
0000000000403B42      | 0FBE8424 93000000     | movsx eax,byte ptr ss:[rsp+93]               |
0000000000403B4A      | F2:0F59D2             | mulsd xmm2,xmm2                              |
0000000000403B4E      | 83E8 30               | sub eax,30                                   |
0000000000403B51      | F2:0F2AC8             | cvtsi2sd xmm1,eax                            |
0000000000403B55      | F2:0F59C9             | mulsd xmm1,xmm1                              |
0000000000403B59      | F2:0F58C2             | addsd xmm0,xmm2                              |
0000000000403B5D      | F2:0F58C1             | addsd xmm0,xmm1                              |
0000000000403B61      | E8 FAF7FFFF           | call <nncrackme.maybe_sqrt>                  | (szBuf[0]-'0')*(szBuf[0]-'0')*+(szBuf[2]-'2')*(szBuf[2]-'0')*+(szBuf[3]-'0')*(szBuf[3]-'0')*
0000000000403B66      | 66:0F2E05 02550000    | ucomisd xmm0,qword ptr ds:[409070]           | [409070]=15.5
接着是校验szBuf中的值,要求满足以下条件:
1.szBuf[1]=0x2e  第二位是小数点.
2.xmm0=((szBuf[0]-'0')*(szBuf[0]-'0')*+(szBuf[2]-'2')*(szBuf[2]-'0')*+(szBuf[3]-'0')*(szBuf[3]-'0')*)  xmm0的平方根必须大于15.5
穷举之后发现,只有当szBuf[0],[2],[3] 都是‘9’的时候才能满足条件。
3.输入的第6个字符必须是0,不然这里不满足条件
0000000000403B70      | F64424 22 0F          | test byte ptr ss:[rsp+22],F                  | 测试输入的第6个字符是否为0
4.最后1个条件:
0000000000403B77      | F2:0F100D 11550000    | movsd xmm1,qword ptr ds:[409090]             | xmm1=0.003
0000000000403B7F      | 31C0                  | xor eax,eax                                  |
0000000000403B81      | F2:0F104424 60        | movsd xmm0,qword ptr ss:[rsp+60]             | key1
0000000000403B87      | F2:0F584424 68        | addsd xmm0,qword ptr ss:[rsp+68]             | key2
0000000000403B8D      | F2:0F5C4424 40        | subsd xmm0,qword ptr ss:[rsp+40]             | [409080]=9.99868121053069   
0000000000403B93      | 66:0F5405 E5540000    | andpd xmm0,xmmword ptr ds:[409080]           | [409080]=0x7FFFFFFFFFFFFFFF
0000000000403B9B      | 66:0F2EC8             | ucomisd xmm1,xmm0                            | xmm0<xmm1
0000000000403B9F      | 76 24                 | jbe nncrackme.403BC5                         |
xmm0=key1+key2-9.99868121053069    然后16进制值与0x7fffffffffffffff与运算,结果必须比0.003小。

综上,所有的条件都已列出,鉴于函数maybe_add_4015E0没有详细逆向,无法提供准确的值,用于后续运算,以上上述的条件4也不怎么好用高级语言表示。所以只能爆破。
对于一个double类型的数值来说,当一个值的浮点部分是(1.0/2**n)的倍数时,他的16进制值一般只有高位有数值,低位多为0.
比如:
3ff1000000000000 1.0625
3ff2000000000000 1.125
3ff3000000000000 1.1875
3ff4000000000000 1.25
3ff5000000000000 1.3125
3ff6000000000000 1.375
3ff7000000000000 1.4375
3ff8000000000000 1.5
3ff9000000000000 1.5625
3ffa000000000000 1.625
3ffb000000000000 1.6875
3ffc000000000000 1.75
3ffd000000000000 1.8125
3ffe000000000000 1.875
3fff000000000000 1.9375
4000000000000000 2.0
4000800000000000 2.0625
4001000000000000 2.125
4001800000000000 2.1875
4002000000000000 2.25
对于key1来说,只有4位,即要求此数只有前两个字节有值,所以其浮点部分大概是 (1.0/2**n)*m (m,n为大于0的正整数)。
1.0-10.0之间的浮点数都在0x3ff0000000000000--0x4024000000000000之间。 所以最高位只有3f,和40.
根据以上所有内容,制作出爆破脚本如下:
# -*- coding: cp936 -*-
import subprocess
import random
import time
import struct

#!d 大端,小端 @
def double_2_hex(value):
    hex_str=struct.pack('!d', value).encode('hex')
    #print hex_str
    return hex_str
    
print "test",double_2_hex(9.25)

def hex_2_double(hexStr):
    dbValue=struct.unpack('!d', hexStr.decode('hex'))[0]
    #print dbValue
    return dbValue
hex_2_double("3F1AB00000000000")


def Crate_list_key1(outStrList,valueList):
    begin=1.0
    step=1.0/2**4
    end=9.99
    i=begin
    while i<end:
        i=i+step
        hexStr=double_2_hex(i)
        zCount=(hexStr[4:]).count('0')
        nLen=len("000000000000")
        #print hexStr,i
        if zCount<nLen:
            continue
        else:
            n1=hexStr[2]+hexStr[3]+hexStr[0]+hexStr[1]
            #print hexStr,n1,i
            outStrList.append(n1.upper())
            valueList.append(i)

def Crate_list_key2(strList,valueList):
    for x1 in [0x3f,0x40]:
        for x2 in range(0,0x100):
            for x3 in range(0,0x100,0x10):
                xStr="%02X%02X%02X"%(x1,x2,x3)
                key=xStr +"0000000000"                
                value=hex_2_double(key)
                if value >0.99 and value <10.0:
                    outStr="%02X%02X%02X"%(x3,x2,x1)
                    print "xxxx",key,value,xStr,outStr
                    strList.append(outStr)
                    valueList.append(value)
  
    
def test_key(strkey):
    p = subprocess.Popen("NNCrackme.exe", stdin = subprocess.PIPE,\
    stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True)
    key=strkey+'\n'
    #print key
    outs,errs=p.communicate(bytes(key.encode("ascii")))
    if(b"Congratulation" in outs):
        print "Congratulation!!! Find it:",key
        with open("key.txt","w") as f:
            f.write(key)
        raw_input("find it!!!!")
    else:
        print key,outs,errs

key1StrList=[]
key1ValueList=[]
Crate_list_key1(key1StrList,key1ValueList)
raw_input()
key2StrList=[]
key2ValueList=[]
Crate_list_key2(key2StrList,key2ValueList)

print len(key1StrList)*len(key2StrList)
raw_input()
ixx=0
for i,v1 in enumerate(key1StrList):
    for j,v2 in enumerate(key2StrList):
        ixx+=1
        k1Value=key1ValueList[i]
        k2Value=key2ValueList[j]
        key=v1+v2
        num=k1Value+k2Value
        if num >9.299 and num <10.5:
            print "index",ixx,key,k1Value,k2Value,num
            test_key(key)
成功爆破:

结果:


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回