-
-
[原创]2019看雪CTF 晋级赛Q3 第8题-人妒英才
-
发表于: 2019-9-25 10:30 5868
-
start有一处PEB(02:BeingDebugged)反调试,直接跳过。程序有混淆,但可以带着分析程序。
1 2 3 4 5 6 7 8 9 10 11 | k_is_9:0042F000 start proc near k_is_9:0042F000 mov byte ptr [ebp-5], 0 k_is_9:0042F004 mov eax, large fs:30h k_is_9:0042F00A mov al, [eax+2] k_is_9:0042F00D mov [ebp-5], al k_is_9:0042F010 movzx eax, byte ptr [ebp-5] k_is_9:0042F014 test eax, eax k_is_9:0042F016 k_is_9:0042F016 loc_42F016: ; CODE XREF: start:loc_42F08A↓j k_is_9:0042F016 jnz short loc_42F08A k_is_9:0042F018 jmp sub_4110FF |
程序的关键函数,根据界面提示搜索字串直接定位。 流程很明确获取输入,生成key,和目标字串进行比较检测。
1 2 3 4 5 6 7 8 9 10 11 | k_is_9:0042F000 start proc near k_is_9:0042F000 mov byte ptr [ebp-5], 0 k_is_9:0042F004 mov eax, large fs:30h k_is_9:0042F00A mov al, [eax+2] k_is_9:0042F00D mov [ebp-5], al k_is_9:0042F010 movzx eax, byte ptr [ebp-5] k_is_9:0042F014 test eax, eax k_is_9:0042F016 k_is_9:0042F016 loc_42F016: ; CODE XREF: start:loc_42F08A↓j k_is_9:0042F016 jnz short loc_42F08A k_is_9:0042F018 jmp sub_4110FF |
程序的关键函数,根据界面提示搜索字串直接定位。 流程很明确获取输入,生成key,和目标字串进行比较检测。
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 | int __usercall keyFunc@<eax>( int a1@<xmm0>) { int v1; // edx int v2; // eax int v3; // eax int v4; // ecx int v5; // eax int v6; // eax int v7; // ecx int v8; // eax int v9; // eax int v10; // ecx _DWORD *v11; // eax int v12; // eax int v13; // ecx void *v14; // edx int v16; // [esp-1Ch] [ebp-1F8h] int v17; // [esp-8h] [ebp-1E4h] void *v18; // [esp-4h] [ebp-1E0h] char v19; // [esp+0h] [ebp-1DCh] struc_String *keyString_1; // [esp+10h] [ebp-1CCh] struc_String *keyString; // [esp+14h] [ebp-1C8h] int v22; // [esp+18h] [ebp-1C4h] char goalBuf[56]; // [esp+20h] [ebp-1BCh] char v24; // [esp+58h] [ebp-184h] int v25; // [esp+60h] [ebp-17Ch] char v26; // [esp+6Ch] [ebp-170h] char v27; // [esp+7Fh] [ebp-15Dh] struc_String sting; // [esp+88h] [ebp-154h] int *v29; // [esp+ACh] [ebp-130h] int v30; // [esp+B8h] [ebp-124h] int v31; // [esp+BCh] [ebp-120h] struc_String goalString; // [esp+188h] [ebp-54h] struc_String keyStringFromInput; // [esp+1ACh] [ebp-30h] int v34; // [esp+1CCh] [ebp-10h] int v35; // [esp+1D8h] [ebp-4h] int savedregs; // [esp+1DCh] [ebp+0h] G1.x = 11; G1.y = 4; v30 = j_timesPiont((struc_Point *)a1, &G1, times); v31 = v1; G2.x = v30; G2.y = v1; sub_4113B6(( int )&keyStringFromInput, a1, byte_4252C2); v35 = 0; v2 = sub_411802(std::cout, "Ep = y^2 = x^3 + 125*x " ); v3 = std::basic_ostream< char ,std::char_traits< char >>::operator<<(v2, sub_411159); j_asmFun(v4, &v19 == &v19, v3, a1); v5 = sub_411802(std::cout, "Prime field p=127,base point G(11,4),publicK(120,41) please find private key k" ); v6 = std::basic_ostream< char ,std::char_traits< char >>::operator<<(v5, sub_411159); j_asmFun(v7, &v19 == &v19, v6, a1); v8 = sub_411802(std::cout, "input your flag:" ); v9 = std::basic_ostream< char ,std::char_traits< char >>::operator<<(v8, sub_411159); j_asmFun(v10, &v19 == &v19, v9, a1); getInput(a1, std::cin, &keyStringFromInput); // 获取输入 v29 = &v16; v22 = sub_411447(&v16, a1, &keyStringFromInput); keyString = (struc_String *)calcuKey(a1, ( int )&sting); // 根据输入生成key keyString_1 = keyString; stringCopy(&keyStringFromInput, a1, keyString); releaseString(&sting, a1); goalBuf[0] = 0x5E; //目标结果字串 goalBuf[1] = 0x26; goalBuf[2] = 0; goalBuf[3] = 0x13; goalBuf[4] = 94; goalBuf[5] = 38; goalBuf[6] = 86; goalBuf[7] = 94; goalBuf[8] = 94; goalBuf[9] = 38; goalBuf[10] = 45; goalBuf[11] = 121; goalBuf[12] = 94; goalBuf[13] = 38; goalBuf[14] = 4; goalBuf[15] = 5; goalBuf[16] = 94; goalBuf[17] = 38; goalBuf[18] = 90; goalBuf[19] = 116; goalBuf[20] = 94; goalBuf[21] = 38; goalBuf[22] = 49; goalBuf[23] = 73; goalBuf[24] = 94; goalBuf[25] = 38; goalBuf[26] = 8; goalBuf[27] = 41; goalBuf[28] = 94; goalBuf[29] = 38; goalBuf[30] = 94; goalBuf[31] = 55; goalBuf[32] = 94; goalBuf[33] = 38; goalBuf[34] = 53; goalBuf[35] = 2; goalBuf[36] = 94; goalBuf[37] = 38; goalBuf[38] = 12; goalBuf[39] = 92; goalBuf[40] = 94; goalBuf[41] = 38; goalBuf[42] = 98; goalBuf[43] = 50; goalBuf[44] = 94; goalBuf[45] = 38; goalBuf[46] = 57; goalBuf[47] = 41; goalBuf[48] = 94; goalBuf[49] = 38; goalBuf[50] = 16; goalBuf[51] = 51; goalBuf[52] = 94; goalBuf[53] = 38; goalBuf[54] = 102; goalBuf[55] = 18; v18 = j_getThis_0(( int )&v27); v11 = sub_4112C1(&v26, ( int )goalBuf, ( int )&v24); createString(&goalString, a1, *v11, v11[1], ( int )v18); if ( stringCmp(( int )&keyStringFromInput, a1, ( int )&goalString) ) // key 验证 sub_41186B( "try again" , v19); else sub_41186B( "Congratulations~~" , v19); v12 = system ( "pause" ); j_asmFun(v13, &v19 == &v19, v12, a1); v25 = 0; releaseString(&goalString, a1); v35 = -1; releaseString(&keyStringFromInput, a1); v18 = v14; v17 = v25; sub_411677(( int )&savedregs, ( int )&dword_41BC54); return j_asmFun((unsigned int )&savedregs ^ v34, 1, v17, a1); } |
分析核心的key生成函数
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 | int __usercall keyFunc@<eax>( int a1@<xmm0>) { int v1; // edx int v2; // eax int v3; // eax int v4; // ecx int v5; // eax int v6; // eax int v7; // ecx int v8; // eax int v9; // eax int v10; // ecx _DWORD *v11; // eax int v12; // eax int v13; // ecx void *v14; // edx int v16; // [esp-1Ch] [ebp-1F8h] int v17; // [esp-8h] [ebp-1E4h] void *v18; // [esp-4h] [ebp-1E0h] char v19; // [esp+0h] [ebp-1DCh] struc_String *keyString_1; // [esp+10h] [ebp-1CCh] struc_String *keyString; // [esp+14h] [ebp-1C8h] int v22; // [esp+18h] [ebp-1C4h] char goalBuf[56]; // [esp+20h] [ebp-1BCh] char v24; // [esp+58h] [ebp-184h] int v25; // [esp+60h] [ebp-17Ch] char v26; // [esp+6Ch] [ebp-170h] char v27; // [esp+7Fh] [ebp-15Dh] struc_String sting; // [esp+88h] [ebp-154h] int *v29; // [esp+ACh] [ebp-130h] int v30; // [esp+B8h] [ebp-124h] int v31; // [esp+BCh] [ebp-120h] struc_String goalString; // [esp+188h] [ebp-54h] struc_String keyStringFromInput; // [esp+1ACh] [ebp-30h] int v34; // [esp+1CCh] [ebp-10h] int v35; // [esp+1D8h] [ebp-4h] int savedregs; // [esp+1DCh] [ebp+0h] G1.x = 11; G1.y = 4; v30 = j_timesPiont((struc_Point *)a1, &G1, times); v31 = v1; G2.x = v30; G2.y = v1; sub_4113B6(( int )&keyStringFromInput, a1, byte_4252C2); v35 = 0; v2 = sub_411802(std::cout, "Ep = y^2 = x^3 + 125*x " ); v3 = std::basic_ostream< char ,std::char_traits< char >>::operator<<(v2, sub_411159); j_asmFun(v4, &v19 == &v19, v3, a1); v5 = sub_411802(std::cout, "Prime field p=127,base point G(11,4),publicK(120,41) please find private key k" ); v6 = std::basic_ostream< char ,std::char_traits< char >>::operator<<(v5, sub_411159); j_asmFun(v7, &v19 == &v19, v6, a1); v8 = sub_411802(std::cout, "input your flag:" ); v9 = std::basic_ostream< char ,std::char_traits< char >>::operator<<(v8, sub_411159); j_asmFun(v10, &v19 == &v19, v9, a1); getInput(a1, std::cin, &keyStringFromInput); // 获取输入 v29 = &v16; v22 = sub_411447(&v16, a1, &keyStringFromInput); keyString = (struc_String *)calcuKey(a1, ( int )&sting); // 根据输入生成key keyString_1 = keyString; stringCopy(&keyStringFromInput, a1, keyString); releaseString(&sting, a1); goalBuf[0] = 0x5E; //目标结果字串 goalBuf[1] = 0x26; goalBuf[2] = 0; goalBuf[3] = 0x13; goalBuf[4] = 94; goalBuf[5] = 38; goalBuf[6] = 86; goalBuf[7] = 94; goalBuf[8] = 94; goalBuf[9] = 38; goalBuf[10] = 45; goalBuf[11] = 121; goalBuf[12] = 94; goalBuf[13] = 38; goalBuf[14] = 4; goalBuf[15] = 5; goalBuf[16] = 94; goalBuf[17] = 38; goalBuf[18] = 90; goalBuf[19] = 116; goalBuf[20] = 94; goalBuf[21] = 38; goalBuf[22] = 49; goalBuf[23] = 73; goalBuf[24] = 94; goalBuf[25] = 38; goalBuf[26] = 8; goalBuf[27] = 41; goalBuf[28] = 94; goalBuf[29] = 38; goalBuf[30] = 94; goalBuf[31] = 55; goalBuf[32] = 94; goalBuf[33] = 38; goalBuf[34] = 53; goalBuf[35] = 2; goalBuf[36] = 94; goalBuf[37] = 38; goalBuf[38] = 12; goalBuf[39] = 92; goalBuf[40] = 94; goalBuf[41] = 38; goalBuf[42] = 98; goalBuf[43] = 50; goalBuf[44] = 94; goalBuf[45] = 38; goalBuf[46] = 57; goalBuf[47] = 41; goalBuf[48] = 94; goalBuf[49] = 38; goalBuf[50] = 16; goalBuf[51] = 51; goalBuf[52] = 94; goalBuf[53] = 38; goalBuf[54] = 102; goalBuf[55] = 18; v18 = j_getThis_0(( int )&v27); v11 = sub_4112C1(&v26, ( int )goalBuf, ( int )&v24); createString(&goalString, a1, *v11, v11[1], ( int )v18); if ( stringCmp(( int )&keyStringFromInput, a1, ( int )&goalString) ) // key 验证 sub_41186B( "try again" , v19); else sub_41186B( "Congratulations~~" , v19); v12 = system ( "pause" ); j_asmFun(v13, &v19 == &v19, v12, a1); v25 = 0; releaseString(&goalString, a1); v35 = -1; releaseString(&keyStringFromInput, a1); v18 = v14; v17 = v25; sub_411677(( int )&savedregs, ( int )&dword_41BC54); return j_asmFun((unsigned int )&savedregs ^ v34, 1, v17, a1); } |
生成函数的依据是椭圆曲线方程,用输入字串的每个字符和字符的index进行倍点运算。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | for ( i = 0; ; ++i ) { len = getInpuKeyLen(( int )sting, a1); // 获取key长度 if ( i >= len ) break ; index = i; oneKey = *( char *)getKeyByIndex(( int )sting, a1, i); pointPair_1 = (struc_PointPair *)timesPiontByOneKey(a1, &pointPair, index, oneKey); copyPoint_1(&pointPair_2, a1, pointPair_1); j_addZuobiao2Buf_0(a1, (struc_String *)&resultStr, pointPair_2.p1_x); j_addZuobiao2Buf_0(a1, (struc_String *)&resultStr, pointPair_2.p1_y); j_addZuobiao2Buf_0(a1, (struc_String *)&resultStr, pointPair_2.p2_x); j_addZuobiao2Buf_0(a1, (struc_String *)&resultStr, pointPair_2.p2_y); } |
运算过程如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | for ( i = 0; ; ++i ) { len = getInpuKeyLen(( int )sting, a1); // 获取key长度 if ( i >= len ) break ; index = i; oneKey = *( char *)getKeyByIndex(( int )sting, a1, i); pointPair_1 = (struc_PointPair *)timesPiontByOneKey(a1, &pointPair, index, oneKey); copyPoint_1(&pointPair_2, a1, pointPair_1); j_addZuobiao2Buf_0(a1, (struc_String *)&resultStr, pointPair_2.p1_x); j_addZuobiao2Buf_0(a1, (struc_String *)&resultStr, pointPair_2.p1_y); j_addZuobiao2Buf_0(a1, (struc_String *)&resultStr, pointPair_2.p2_x); j_addZuobiao2Buf_0(a1, (struc_String *)&resultStr, pointPair_2.p2_y); } |
运算过程如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | int __usercall timesPiontByOneKey_0@<eax>(struc_Point *a1@<xmm0>, struc_PointPair *result, int index, int onekey) { int y1AfterTimes; // edx int y2AfterTimes; // edx struc_Point p1; // [esp+100h] [ebp-20h] struc_Point p2; // [esp+110h] [ebp-10h] int v9; // [esp+11Ch] [ebp-4h] int savedregs; // [esp+120h] [ebp+0h] p2.x = j_timesPiont(a1, &G1, 17); // G1(11,4)->(0x5e,0x26) p2.y = y1AfterTimes; p1.x = index * j_timesPiont(a1, &G2, 17) % 127; // G2(14,91)->(0x56,0x5A) p1.y = onekey * y2AfterTimes % 127; copyPoint(result, ( int )a1, ( int )&p2, ( int )&p1); sub_411677(( int )&savedregs, ( int )&dword_417788); return j_asmFun((unsigned int )&savedregs ^ v9, 1, ( int )result, ( int )a1); } |
程序中有连个G点,G1(11,4),G2(14,91);根据G1,G2分别生成P1和P2两个点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | int __usercall timesPiontByOneKey_0@<eax>(struc_Point *a1@<xmm0>, struc_PointPair *result, int index, int onekey) { int y1AfterTimes; // edx int y2AfterTimes; // edx struc_Point p1; // [esp+100h] [ebp-20h] struc_Point p2; // [esp+110h] [ebp-10h] int v9; // [esp+11Ch] [ebp-4h] int savedregs; // [esp+120h] [ebp+0h] p2.x = j_timesPiont(a1, &G1, 17); // G1(11,4)->(0x5e,0x26) p2.y = y1AfterTimes; p1.x = index * j_timesPiont(a1, &G2, 17) % 127; // G2(14,91)->(0x56,0x5A) p1.y = onekey * y2AfterTimes % 127; copyPoint(result, ( int )a1, ( int )&p2, ( int )&p1); sub_411677(( int )&savedregs, ( int )&dword_417788); return j_asmFun((unsigned int )&savedregs ^ v9, 1, ( int )result, ( int )a1); } |
程序中有连个G点,G1(11,4),G2(14,91);根据G1,G2分别生成P1和P2两个点。
完成计算后分别将带你的坐标p.x,p.y保存。
[招生]科锐逆向工程师培训(2025年3月11日实地,远程教学同时开班, 第52期)!
赞赏
他的文章
赞赏
雪币:
留言: