-
-
[原创]KCTF Q3 第十三题:大圣归来
-
发表于: 2019-9-24 04:59 4192
-
用OD在MessageBoxA下断,跟到校验代码。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 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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | int __cdecl sub_407F30( HWND hDlg) { CHAR *v1; // edi signed int v2; // esi signed int v3; // eax const CHAR *v4; // eax const char *v5; // eax CHAR *v6; // ecx char v7; // al const CHAR *v8; // eax _BYTE *v9; // ecx char v10; // al char v11; // al _BYTE *v12; // ecx char v13; // al CHAR *v14; // ecx char pe; // [esp-40h] [ebp-3D8h] char *v17; // [esp-3Ch] [ebp-3D4h] int v18; // [esp-38h] [ebp-3D0h] int v19; // [esp-34h] [ebp-3CCh] char un; // [esp-30h] [ebp-3C8h] char *v21; // [esp-2Ch] [ebp-3C4h] int v22; // [esp-28h] [ebp-3C0h] int v23; // [esp-24h] [ebp-3BCh] int kx; // [esp-20h] [ebp-3B8h] char *v25; // [esp-1Ch] [ebp-3B4h] int v26; // [esp-18h] [ebp-3B0h] int v27; // [esp-14h] [ebp-3ACh] char *input; // [esp-10h] [ebp-3A8h] char *v29; // [esp-Ch] [ebp-3A4h] const CHAR *v30; // [esp-8h] [ebp-3A0h] void (__thiscall *v31)( void *); // [esp-4h] [ebp-39Ch] char v32; // [esp+13h] [ebp-385h] char v33; // [esp+14h] [ebp-384h] LPCSTR v34; // [esp+18h] [ebp-380h] int v35; // [esp+1Ch] [ebp-37Ch] int v36; // [esp+20h] [ebp-378h] char v37; // [esp+24h] [ebp-374h] int v38; // [esp+28h] [ebp-370h] unsigned int v39; // [esp+2Ch] [ebp-36Ch] int v40; // [esp+30h] [ebp-368h] char v41; // [esp+34h] [ebp-364h] int v42; // [esp+38h] [ebp-360h] int v43; // [esp+3Ch] [ebp-35Ch] int v44; // [esp+40h] [ebp-358h] char v45; // [esp+44h] [ebp-354h] const char *v46; // [esp+48h] [ebp-350h] unsigned int v47; // [esp+4Ch] [ebp-34Ch] char v48; // [esp+54h] [ebp-344h] LPCSTR lpText; // [esp+58h] [ebp-340h] int nIDDlgItem; // [esp+64h] [ebp-334h] int v51; // [esp+68h] [ebp-330h] int v52; // [esp+6Ch] [ebp-32Ch] char *v53; // [esp+70h] [ebp-328h] char *v54; // [esp+74h] [ebp-324h] int *v55; // [esp+78h] [ebp-320h] char **v56; // [esp+7Ch] [ebp-31Ch] int v57[3]; // [esp+80h] [ebp-318h] CHAR String; // [esp+8Ch] [ebp-30Ch] char v59; // [esp+8Dh] [ebp-30Bh] char v60; // [esp+18Ch] [ebp-20Ch] char v61; // [esp+28Ch] [ebp-10Ch] __int16 v62; // [esp+389h] [ebp-Fh] char v63; // [esp+38Bh] [ebp-Dh] int v64; // [esp+394h] [ebp-4h] String = 0; memset (&v59, 0, 0x2FCu); v62 = 0; v63 = 0; nIDDlgItem = 1005; v51 = 1000; v52 = 1001; v1 = &String; v2 = 0; while ( 1 ) { v3 = GetDlgItemTextA(hDlg, *( int *)(( char *)&nIDDlgItem + v2 * 4), v1, 255); v57[v2] = v3; if ( v3 < 1 || v3 > 100 ) return 0; ++v2; v1 += 256; if ( v2 >= 3 ) { `eh vector constructor iterator'(&v45, 0x10u, 2, sub_408360, sub_40B410); v64 = 0; v33 = v32; newstring(&v33, 0); strcpy (&v33, &String, strlen (&String)); v37 = v32; LOBYTE(v64) = 1; newstring(&v37, 0); strcpy (&v37, &v60, strlen (&v60)); LOBYTE(v64) = 2; v41 = v32; newstring(&v41, 0); strcpy (&v41, aKxctf19q3, strlen (aKxctf19q3)); LOBYTE(v64) = 3; if ( !check1(&v61, ( int )&v45, ( int )&v48) ) // 以KXCTFXXXX分割字符串并判断长度,第一部分长度需大于等于4,第二部分长度需大于等于8 { v4 = lpText; if ( !lpText ) v4 = ( const CHAR *)&unk_419144; v31 = 0; v30 = aBadCode; goto LABEL_15; } v5 = v46; if ( !v46 ) v5 = ( const char *)&unk_419144; if ( ! strcmp (&v37, 0, v39, v5, v47) ) // 前8位是否为username { v56 = &input; LOBYTE(input) = v48; newstring(&input, 0); substr_0(&input, &v48, 0, 0xFFFFFFFF); v55 = &kx; LOBYTE(v64) = 4; strmove(&kx, &v41); // KXCTF19Q3 v53 = &un; LOBYTE(v64) = 5; strmove(&un, &v37); // username v54 = &pe; LOBYTE(v64) = 6; strmove(&pe, &v33); // PEDIY_CTF2019_Q3_完璧归赵_Crackme_Readyu_ LOBYTE(v64) = 3; if ( !check2(( int )hDlg, pe, v17, v18, v19, un, v21, v22, v23, kx, v25, v26, v27, ( char )input, v29, ( int )v30) ) { v8 = v34; if ( !v34 ) v8 = ( const CHAR *)&unk_419144; MessageBoxA(hDlg, v8, aBadCheck, 0); if ( v42 ) { v9 = (_BYTE *)(v42 - 1); v10 = *(_BYTE *)(v42 - 1); if ( v10 && v10 != -1 ) *v9 = v10 - 1; else sub_40DF24(v9); } v42 = 0; v43 = 0; v44 = 0; if ( v38 ) { v11 = *(_BYTE *)(v38 - 1); v12 = (_BYTE *)(v38 - 1); if ( v11 && v11 != -1 ) *v12 = v11 - 1; else sub_40DF24(v12); } v38 = 0; v39 = 0; v40 = 0; if ( v34 ) { v13 = *(v34 - 1); v14 = ( CHAR *)(v34 - 1); if ( v13 && v13 != -1 ) *v14 = v13 - 1; else sub_40DF24(v14); } v34 = 0; v35 = 0; v36 = 0; v64 = -1; goto LABEL_41; } success(hDlg); LOBYTE(v64) = 2; newstring(&v41, 1); LOBYTE(v64) = 1; newstring(&v37, 1); if ( v34 ) { v6 = ( CHAR *)(v34 - 1); v7 = *(v34 - 1); if ( v7 && v7 != -1 ) *v6 = v7 - 1; else sub_40DF24(v6); } v31 = sub_40B410; v30 = ( const CHAR *)2; v29 = ( char *)16; v34 = 0; v35 = 0; v36 = 0; v64 = -1; input = &v45; } else { v4 = v46; if ( !v46 ) v4 = ( const CHAR *)&unk_419144; v31 = 0; v30 = aBadName; LABEL_15: MessageBoxA(hDlg, v4, v30, ( UINT )v31); LOBYTE(v64) = 2; newstring(&v41, 1); LOBYTE(v64) = 1; newstring(&v37, 1); LOBYTE(v64) = 0; newstring(&v33, 1); v64 = -1; LABEL_41: v31 = sub_40B410; v30 = ( const CHAR *)2; v29 = ( char *)16; input = &v45; } `eh vector destructor iterator'(input, (unsigned int )v29, ( int )v30, v31); return 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 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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | int __cdecl sub_407F30( HWND hDlg) { CHAR *v1; // edi signed int v2; // esi signed int v3; // eax const CHAR *v4; // eax const char *v5; // eax CHAR *v6; // ecx char v7; // al const CHAR *v8; // eax _BYTE *v9; // ecx char v10; // al char v11; // al _BYTE *v12; // ecx char v13; // al CHAR *v14; // ecx char pe; // [esp-40h] [ebp-3D8h] char *v17; // [esp-3Ch] [ebp-3D4h] int v18; // [esp-38h] [ebp-3D0h] int v19; // [esp-34h] [ebp-3CCh] char un; // [esp-30h] [ebp-3C8h] char *v21; // [esp-2Ch] [ebp-3C4h] int v22; // [esp-28h] [ebp-3C0h] int v23; // [esp-24h] [ebp-3BCh] int kx; // [esp-20h] [ebp-3B8h] char *v25; // [esp-1Ch] [ebp-3B4h] int v26; // [esp-18h] [ebp-3B0h] int v27; // [esp-14h] [ebp-3ACh] char *input; // [esp-10h] [ebp-3A8h] char *v29; // [esp-Ch] [ebp-3A4h] const CHAR *v30; // [esp-8h] [ebp-3A0h] void (__thiscall *v31)( void *); // [esp-4h] [ebp-39Ch] char v32; // [esp+13h] [ebp-385h] char v33; // [esp+14h] [ebp-384h] LPCSTR v34; // [esp+18h] [ebp-380h] int v35; // [esp+1Ch] [ebp-37Ch] int v36; // [esp+20h] [ebp-378h] char v37; // [esp+24h] [ebp-374h] int v38; // [esp+28h] [ebp-370h] unsigned int v39; // [esp+2Ch] [ebp-36Ch] int v40; // [esp+30h] [ebp-368h] char v41; // [esp+34h] [ebp-364h] int v42; // [esp+38h] [ebp-360h] int v43; // [esp+3Ch] [ebp-35Ch] int v44; // [esp+40h] [ebp-358h] char v45; // [esp+44h] [ebp-354h] const char *v46; // [esp+48h] [ebp-350h] unsigned int v47; // [esp+4Ch] [ebp-34Ch] char v48; // [esp+54h] [ebp-344h] LPCSTR lpText; // [esp+58h] [ebp-340h] int nIDDlgItem; // [esp+64h] [ebp-334h] int v51; // [esp+68h] [ebp-330h] int v52; // [esp+6Ch] [ebp-32Ch] char *v53; // [esp+70h] [ebp-328h] char *v54; // [esp+74h] [ebp-324h] int *v55; // [esp+78h] [ebp-320h] char **v56; // [esp+7Ch] [ebp-31Ch] int v57[3]; // [esp+80h] [ebp-318h] CHAR String; // [esp+8Ch] [ebp-30Ch] char v59; // [esp+8Dh] [ebp-30Bh] char v60; // [esp+18Ch] [ebp-20Ch] char v61; // [esp+28Ch] [ebp-10Ch] __int16 v62; // [esp+389h] [ebp-Fh] char v63; // [esp+38Bh] [ebp-Dh] int v64; // [esp+394h] [ebp-4h] String = 0; memset (&v59, 0, 0x2FCu); v62 = 0; v63 = 0; nIDDlgItem = 1005; v51 = 1000; v52 = 1001; v1 = &String; v2 = 0; while ( 1 ) { v3 = GetDlgItemTextA(hDlg, *( int *)(( char *)&nIDDlgItem + v2 * 4), v1, 255); v57[v2] = v3; if ( v3 < 1 || v3 > 100 ) return 0; ++v2; v1 += 256; if ( v2 >= 3 ) { `eh vector constructor iterator'(&v45, 0x10u, 2, sub_408360, sub_40B410); v64 = 0; v33 = v32; newstring(&v33, 0); strcpy (&v33, &String, strlen (&String)); v37 = v32; LOBYTE(v64) = 1; newstring(&v37, 0); strcpy (&v37, &v60, strlen (&v60)); LOBYTE(v64) = 2; v41 = v32; newstring(&v41, 0); strcpy (&v41, aKxctf19q3, strlen (aKxctf19q3)); LOBYTE(v64) = 3; if ( !check1(&v61, ( int )&v45, ( int )&v48) ) // 以KXCTFXXXX分割字符串并判断长度,第一部分长度需大于等于4,第二部分长度需大于等于8 { v4 = lpText; if ( !lpText ) v4 = ( const CHAR *)&unk_419144; v31 = 0; v30 = aBadCode; goto LABEL_15; } v5 = v46; if ( !v46 ) v5 = ( const char *)&unk_419144; if ( ! strcmp (&v37, 0, v39, v5, v47) ) // 前8位是否为username { v56 = &input; LOBYTE(input) = v48; newstring(&input, 0); substr_0(&input, &v48, 0, 0xFFFFFFFF); v55 = &kx; LOBYTE(v64) = 4; strmove(&kx, &v41); // KXCTF19Q3 v53 = &un; LOBYTE(v64) = 5; strmove(&un, &v37); // username v54 = &pe; LOBYTE(v64) = 6; strmove(&pe, &v33); // PEDIY_CTF2019_Q3_完璧归赵_Crackme_Readyu_ LOBYTE(v64) = 3; if ( !check2(( int )hDlg, pe, v17, v18, v19, un, v21, v22, v23, kx, v25, v26, v27, ( char )input, v29, ( int )v30) ) { v8 = v34; if ( !v34 ) v8 = ( const CHAR *)&unk_419144; MessageBoxA(hDlg, v8, aBadCheck, 0); if ( v42 ) { v9 = (_BYTE *)(v42 - 1); v10 = *(_BYTE *)(v42 - 1); if ( v10 && v10 != -1 ) *v9 = v10 - 1; else sub_40DF24(v9); } v42 = 0; v43 = 0; v44 = 0; if ( v38 ) { v11 = *(_BYTE *)(v38 - 1); v12 = (_BYTE *)(v38 - 1); if ( v11 && v11 != -1 ) *v12 = v11 - 1; else sub_40DF24(v12); } v38 = 0; v39 = 0; v40 = 0; if ( v34 ) { v13 = *(v34 - 1); v14 = ( CHAR *)(v34 - 1); if ( v13 && v13 != -1 ) *v14 = v13 - 1; else sub_40DF24(v14); } v34 = 0; v35 = 0; v36 = 0; v64 = -1; goto LABEL_41; } success(hDlg); LOBYTE(v64) = 2; newstring(&v41, 1); LOBYTE(v64) = 1; newstring(&v37, 1); if ( v34 ) { v6 = ( CHAR *)(v34 - 1); v7 = *(v34 - 1); if ( v7 && v7 != -1 ) *v6 = v7 - 1; else sub_40DF24(v6); } v31 = sub_40B410; v30 = ( const CHAR *)2; v29 = ( char *)16; v34 = 0; v35 = 0; v36 = 0; v64 = -1; input = &v45; } else { v4 = v46; if ( !v46 ) v4 = ( const CHAR *)&unk_419144; v31 = 0; v30 = aBadName; LABEL_15: MessageBoxA(hDlg, v4, v30, ( UINT )v31); LOBYTE(v64) = 2; newstring(&v41, 1); LOBYTE(v64) = 1; newstring(&v37, 1); LOBYTE(v64) = 0; newstring(&v33, 1); v64 = -1; LABEL_41: v31 = sub_40B410; v30 = ( const CHAR *)2; v29 = ( char *)16; input = &v45; } `eh vector destructor iterator'(input, (unsigned int )v29, ( int )v30, v31); return 0; } } } |
主要是计算一些字符串的hash作为大数,用LUC算法解密两次被KXCTFXXXX分割的第二部分input转成的大数,比较结果是否为0xC4B73CB0DD1D750C69E1755B06BBAFFFF44D2600
总结一下就是
1 2 3 4 5 6 | N = 0x3FBDAD083DBC11A52FA2AF1A0829C522C1492907F1B9523A17B7A8E65679BB01 message = 0x9071232E6B170092668255303E5D824F2879AD56 + inputnum message2 = LUCdecrypt(message, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B5843544631395133 ,N) message2 + = 0x249BA36000029BBE97499C03DB5A9001F6B734EC (LUCdecrypt(message2,N,N) + 0x6DC844C73B34D6E6B8DE48DA64EF92AB2B11F461 ) % N = = 0xC4B73CB0DD1D750C69E1755B06BBAFFFF44D2600 / / (LUCdecrypt(message2,N,N) % N = = 0x56EEF7E9A1E89E25B1032C80A1CC1D54C93B319F |
1 2 3 4 5 6 | N = 0x3FBDAD083DBC11A52FA2AF1A0829C522C1492907F1B9523A17B7A8E65679BB01 message = 0x9071232E6B170092668255303E5D824F2879AD56 + inputnum message2 = LUCdecrypt(message, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B5843544631395133 ,N) message2 + = 0x249BA36000029BBE97499C03DB5A9001F6B734EC (LUCdecrypt(message2,N,N) + 0x6DC844C73B34D6E6B8DE48DA64EF92AB2B11F461 ) % N = = 0xC4B73CB0DD1D750C69E1755B06BBAFFFF44D2600 / / (LUCdecrypt(message2,N,N) % N = = 0x56EEF7E9A1E89E25B1032C80A1CC1D54C93B319F |
怎么得到0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B5843544631395133的?
1 2 3 4 5 6 7 8 9 10 11 12 13 | LUC( v206, // input+... v207, big_Nadd1, v209, big_Index, // 第一轮为:hash+KXCTF19Q3 // 第二轮为:~hash v211, big_Ncp, v213, ( int *)v214, //U ( int *)v215, //V ( int *)v216); |
1 2 3 4 5 6 7 8 9 10 11 12 13 | LUC( v206, // input+... v207, big_Nadd1, v209, big_Index, // 第一轮为:hash+KXCTF19Q3 // 第二轮为:~hash v211, big_Ncp, v213, ( int *)v214, //U ( int *)v215, //V ( int *)v216); |
第一次解密,CM是将其分成两步来算的,第一步取得Lucas序列第 hash+KXCTF19Q3项的值,第二轮取第~hash项的值。
之后将第二轮的U,V值做72次快速递推,换算到项数上就是 ~hash * 2 ^ 0x72 =
~hash * 0x1000000000000000000。
然后再进行一次递推
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 | v169 = big_mul(( int )&v263, ( int *)v234, ( int *)&v235); LOBYTE(v362) = 122; v170 = ( int *)big_mul(( int )&v258, ( int *)&v243, ( int *)v239); // v243=(input+...)^2-4 LOBYTE(v362) = 123; v171 = big_mul(( int )&v256, v170, ( int *)&v240); LOBYTE(v362) = 124; v172 = ( int *)big_add(( int )&v246, v171, v169); LOBYTE(v362) = 125; v173 = ( int *)big_mod(( int )&v237, v172, big_hash64); LOBYTE(v362) = 126; big_cpy(( int *)&v251, v173); LOBYTE(v362) = 125; free (&v237); LOBYTE(v362) = 124; free (&v246); LOBYTE(v362) = 123; free (&v256); LOBYTE(v362) = 122; free (&v258); LOBYTE(v362) = 18; free (&v263); big_num = ( char *)&v215; strmove_0(( int *)&v215, big_hash64); big_shr1(( int *)&v251); v174 = ( int *)big_add(( int )&v237, ( int )&v251, ( int )&v271); // username |
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 | v169 = big_mul(( int )&v263, ( int *)v234, ( int *)&v235); LOBYTE(v362) = 122; v170 = ( int *)big_mul(( int )&v258, ( int *)&v243, ( int *)v239); // v243=(input+...)^2-4 LOBYTE(v362) = 123; v171 = big_mul(( int )&v256, v170, ( int *)&v240); LOBYTE(v362) = 124; v172 = ( int *)big_add(( int )&v246, v171, v169); LOBYTE(v362) = 125; v173 = ( int *)big_mod(( int )&v237, v172, big_hash64); LOBYTE(v362) = 126; big_cpy(( int *)&v251, v173); LOBYTE(v362) = 125; free (&v237); LOBYTE(v362) = 124; free (&v246); LOBYTE(v362) = 123; free (&v256); LOBYTE(v362) = 122; free (&v258); LOBYTE(v362) = 18; free (&v263); big_num = ( char *)&v215; strmove_0(( int *)&v215, big_hash64); big_shr1(( int *)&v251); v174 = ( int *)big_add(( int )&v237, ( int )&v251, ( int )&v271); // username |
精简一下
message2=((v243*v239*v240+v234*235 mod 0x3FBDAD083DBC11A52FA2AF1A0829C522C1492907F1B9523A17B7A8E65679BB01
)>>1)+ 0x249BA36000029BBE97499C03DB5A9001F6B734EC //username
message2=((v243*v239*v240+v234*235 mod 0x3FBDAD083DBC11A52FA2AF1A0829C522C1492907F1B9523A17B7A8E65679BB01
)>>1)+ 0x249BA36000029BBE97499C03DB5A9001F6B734EC //username
再加上一条性质

将第二轮的项数和第一轮的项数相加(hash是20字节的),就得到
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B5843544631395133了。
之后,用LUC算法把0x56EEF7E9A1E89E25B1032C80A1CC1D54C93B319F
加密回去就行,具体步骤如下:
1.分解N(N=0x3FBDAD083DBC11A52FA2AF1A0829C522C1492907F1B9523A17B7A8E65679BB01)
最后于 2019-9-25 19:51
被梦游枪手编辑
,原因:
赞赏
他的文章
赞赏
雪币:
留言: