-
-
[原创]2022KCTF签到WP
-
发表于: 2022-5-10 16:28 1837
-
签到-险象环生
拿到题目是一个注册程序,附件文档里有一对用户名和注册码:
1 2 | 用户名 : 461D7AD538F179EE 序列号 : 40403286341212 |
通过验证check得到success提示,要求得到KCTF对用应的注册码。
静态分析
ida打开之后主要逻辑部分F5不管用,很难看出程序逻辑,就只能尝试调试来理清逻辑。
动态调试
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 | .text: 0040154B imul ecx, eax, 3 .text: 0040154E mov dl, [ebp + edx - 108h ] .text: 00401555 mov [ebp + ecx - 1D0h ], dl .text: 0040155C lea eax, [ebp - 1D0h ] .text: 00401562 push eax ; 序列号后 4 字节 .text: 00401563 call sub_4034AD ; to interger .text: 00401568 add esp, 4 .text: 0040156B mov [ebp - 3ACh ], eax .text: 00401571 mov dword ptr [ebp - 398h ], offset loc_4015D2 .text: 0040157B mov dword ptr [ebp - 3A8h ], offset loc_401767 .text: 00401585 mov ecx, [ebp - 3A8h ] .text: 0040158B sub ecx, [ebp - 398h ] .text: 00401591 mov [ebp - 3B0h ], ecx .text: 00401597 mov edx, [ebp - 398h ] .text: 0040159D mov [ebp - 3B4h ], edx .text: 004015A3 cmp dword_413000, 0 .text: 004015AA jz short loc_4015C9 .text: 004015AC mov eax, [ebp - 3ACh ] .text: 004015B2 push eax .text: 004015B3 mov ecx, [ebp - 3B0h ] .text: 004015B9 push ecx .text: 004015BA mov edx, [ebp - 3B4h ] .text: 004015C0 push edx .text: 004015C1 call sub_4017E0 ; 此函数运行过程中生成覆盖 0x4015d2 后的代码,代码由序列号的后四个字节决定 .text: 004015C6 add esp, 0Ch |
到这里就能正常往下调试了,并且通过尝试发现注册码的后四字节必须为1212,这是用来生成代码的。之后就来到了关键的地方:
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 31 32 33 34 35 36 37 38 39 | .text: 004015D2 loc_4015D2: ; DATA XREF: .text: 00401571 ↑o .text: 004015D2 mov eax, [ebp - 39Ch ] .text: 004015D8 push eax .text: 004015D9 lea ecx, [ebp - 2BCh ] .text: 004015DF push ecx .text: 004015E0 call sub_401260 ; 通过KCTF生成注册码前 10 字节 .text: 004015E5 add esp, 8 .text: 004015E8 mov [ebp - 3B8h ], eax .text: 004015EE mov edx, [ebp - 3A0h ] .text: 004015F4 sub edx, 4 .text: 004015F7 push edx .text: 004015F8 lea eax, [ebp - 108h ] .text: 004015FE push eax .text: 004015FF lea ecx, [ebp - 30h ] .text: 00401602 push ecx .text: 00401603 call _strncpy ; 将注册码前 10 字节复制到固定地方 .text: 00401608 add esp, 0Ch .text: 0040160B push 0Ah .text: 0040160D lea edx, [ebp - 384h ] .text: 00401613 push edx .text: 00401614 mov eax, [ebp - 3B8h ] .text: 0040161A push eax .text: 0040161B call __ultoa .text: 00401620 add esp, 0Ch .text: 00401623 mov dword_413000, 0 .text: 0040162D lea ecx, [ebp - 30h ] .text: 00401630 mov [ebp - 394h ], ecx .text: 00401636 lea edx, [ebp - 384h ] .text: 0040163C mov [ebp - 390h ], edx .text: 00401642 .text: 00401642 loc_401642: ; CODE XREF: .text: 00401692 ↓j .text: 00401642 mov eax, [ebp - 390h ] .text: 00401648 mov cl, [eax] .text: 0040164A mov [ebp - 385h ], cl .text: 00401650 mov edx, [ebp - 394h ] .text: 00401656 xchg cl, [edx] .text: 00401658 jnz short loc_4016A0 .text: 0040165A cmp byte ptr [ebp - 385h ], 0 .text: 00401661 |
函数sub_401260关键逻辑:
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | int __cdecl sub_401260(char * a1, int a2) { int i; / / ecx unsigned int v3; / / eax unsigned int v4; / / eax unsigned int v5; / / eax unsigned int v6; / / eax unsigned int v7; / / eax unsigned int v8; / / eax unsigned int v9; / / eax unsigned int v10; / / eax int v11; / / edx unsigned int j; / / ecx char v14; / / al int v16[ 256 ]; / / [esp + 0h ] [ebp - 404h ] for ( i = 0 ; i < 256 ; + + i ) { v3 = (unsigned int )i >> 1 ; if ( (i & 1 ) ! = 0 ) v3 ^ = 0xEDB88320 ; if ( (v3 & 1 ) ! = 0 ) v4 = (v3 >> 1 ) ^ 0xEDB88320 ; else v4 = v3 >> 1 ; if ( (v4 & 1 ) ! = 0 ) v5 = (v4 >> 1 ) ^ 0xEDB88320 ; else v5 = v4 >> 1 ; if ( (v5 & 1 ) ! = 0 ) v6 = (v5 >> 1 ) ^ 0xEDB88320 ; else v6 = v5 >> 1 ; if ( (v6 & 1 ) ! = 0 ) v7 = (v6 >> 1 ) ^ 0xEDB88320 ; else v7 = v6 >> 1 ; if ( (v7 & 1 ) ! = 0 ) v8 = (v7 >> 1 ) ^ 0xEDB88320 ; else v8 = v7 >> 1 ; if ( (v8 & 1 ) ! = 0 ) v9 = (v8 >> 1 ) ^ 0xEDB88320 ; else v9 = v8 >> 1 ; if ( (v9 & 1 ) ! = 0 ) v10 = (v9 >> 1 ) ^ 0xEDB88320 ; else v10 = v9 >> 1 ; v16[i] = v10; } v11 = a2; for ( j = - 1 ; v11; - - v11 ) { v14 = * a1 + + ; j = v16[(unsigned __int8)(j ^ v14)] ^ (j >> 8 ); } return ~j; } |
这里得到了一串注册码,刚好10字节,先记下来1592086348
这里调试就会跳往错误逻辑,直接运行是正确的,如何判断呢?我用正确的用户名/注册码调试发现也是走向错误逻辑,所以就判断这里应该是个调试的干扰项,后面就是success和error的分支了,所以根据之前的到的1592086348
和固定的后四位1212
可以得到KCTF对应的注册码15920863481212
这其实就是个由KCTF通过异或移位运算得到的数字。
验证:
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
看原图
赞赏
雪币:
留言: