over 4 years ago

基本上就是重新把檢查的部份實作出來,這個用 IDA decompile 的結果,加上有給 0x66666667 這個提示,看似很複雜的乘法和位運算其實是 /10 的意思。把每個檢查的條件式分開來看,會發現函式中第一個回圈所有條件判斷和賦值只跟第0,1,2,3,4,5,7,10,11位(padding後)有關,直接搜的時間是可以接受的。
最後第二個迴圈比對20位原本key與函式生成的20位key,由於如果第一個迴圈檢查通過,則函式生成的20位key即為正確的key,所以直接把剩下位數還沒搜的key直接丟去跑,抓出函式生成的20位key即為flag。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define LOBYTE(x) ((char*)&x)[0]
#define BYTE1(x) ((char*)&x)[1]
#define BYTE2(x) ((char*)&x)[2]
#define BYTE3(x) ((char*)&x)[3]
#define _BYTE char
#define _WORD short

char key[20] = {0x00};

char sub_401000(char* a1,char* a2,char* a3){
    int v4; // edi@1
    signed int v5; // ecx@1
    char v6; // ST20_1@1
    signed int v7; // ST18_4@1
    signed int v8; // ecx@1
    char v9; // al@1
    signed int v10; // ecx@1
    signed int v11; // ebx@1
    signed int v12; // edx@1
    char result; // al@1

    v4 = a1[1];
    v5 = v4 * a2[1];
    v6 = v5 % 10;
    v7 = v5 / 10 + a2[1] * a1[0];
    v8 = v4 * a2[0];
    v9 = v8 % 10;
    a3[2] = v9;
    v10 = v8 / 10 + *(_BYTE *)a2 * a1[0];
    a3[3] = v6;
    v11 = v7 % 10 + v9;
    a3[2] = v11 % 10;
    v12 = (v11 / 10 + v10 % 10 + (signed int)(char)(v7 / 10)) / 10;
    a3[1] = v11 / 10 + v10 % 10 + v7 / 10 - 10 * v12;
    result = v12 + ((unsigned int)v12 >> 31) + v10 / 10;
    a3[0] = result;
    return result;
}

int func1(){
    char *v0; // ebx@1
    int v1; // esi@1
    char v2; // ST14_1@1
    char v3; // ST10_1@1
    char v4; // ST0C_1@1
    signed int v5; // ecx@1
    char v6; // al@2
    char v7; // ch@10
    int v8; // edx@12
    signed int v9; // edi@12
    int v10; // eax@12
    signed int v12; // edx@14
    int v13; // eax@14
    int v14; // edx@14
    signed int v15; // edx@14
    char v16; // cl@14
    char v17; // al@15
    char v18; // dl@15
    int v19; // edx@17
    char v20; // bl@17
    int v21; // zf@21
    char v22; // bl@22
    char v23; // bh@24
    int v24; // edi@24
    int i; // ecx@28
    char v27; // [sp-4h] [bp-9Ch]@1
    int v28; // [sp+Ch] [bp-8Ch]@14
    int v29; // [sp+10h] [bp-88h]@34
    int v30; // [sp+14h] [bp-84h]@11
    int v31; // [sp+18h] [bp-80h]@20
    int v32; // [sp+1Ch] [bp-7Ch]@14
    int v33; // [sp+20h] [bp-78h]@31
    int v34; // [sp+24h] [bp-74h]@36
    int v35; // [sp+28h] [bp-70h]@35
    int v36; // [sp+2Ch] [bp-6Ch]@18
    int v37; // [sp+30h] [bp-68h]@13
    unsigned int v38; // [sp+34h] [bp-64h]@14
    int v39; // [sp+38h] [bp-60h]@14
    int v40; // [sp+3Ch] [bp-5Ch]@12
    char v41[4]; // [sp+40h] [bp-58h]@14
    char v45; // [sp+46h] [bp-52h]@10
    char v46; // [sp+47h] [bp-51h]@12
    char v47[16]; // [sp+48h] [bp-50h]@1
    char v48; // [sp+58h] [bp-40h]@9
    char v49; // [sp+5Ch] [bp-3Ch]@12
    short v50; // [sp+5Dh] [bp-3Bh]@12
    char v51; // [sp+5Fh] [bp-39h]@12
    int v52; // [sp+60h] [bp-38h]@12
    short v53; // [sp+64h] [bp-34h]@12
    char v54; // [sp+66h] [bp-32h]@12
    char pada[100];
    char buf[20];
    char padb[100];
    unsigned int v60; // [sp+84h] [bp-14h]@1
    char *v61; // [sp+88h] [bp-10h]@1
    int v62; // [sp+94h] [bp-4h]@1
    int v63; // [sp+98h] [bp+0h]@1

    //memcpy(v47,key,17);
    //memset(buf,-1,20);
    //
    memcpy(buf,key,20);

    v61 = &v27;
    v1 = 0;
    buf[5] = 1;
    buf[8] = 8;
    buf[12] = 0;
    buf[14] = 7;
    v62 = 0;
    /*v5 = 0;
    while ( 1 )
    {
        v6 = v47[v5];
        if ( v6 < 48 )
            break;
        if ( v6 > 57 )
            break;
        for ( ; buf[v1] != -1; ++v1 );
        buf[v1] = v6 & 0xF;
        ++v5;
        ++v1;
        if ( v5 >= 16 )
            break;
    }
    if ( v5 < 16 )
    {
        return 0;
    }

    if (!buf[0])
    {
        return 0;
    }*/

    v7 = *(int*)buf;
    v45 = *(int*)buf;

    v46 = buf[1];
    v50 = *(short*)(buf + 1);
    v51 = buf[3];
    v52 = *(int*)(buf + 4);
    v53 = *(int*)(buf + 8);
    v54 = buf[10];
    v8 = 0;
    v49 = v7;
    v9 = 11;
    v40 = 2;
    v10 = 0;

    while ( 1 )
    {
        v37 = v10;
        if ( v10 >= 2 )
            break;
        v28 = v8 + 1;
        v12 = ((int)*(char*)(buf + 4 + v8 + 3)) * buf[6];
        v13 = v12;
        LOBYTE(v13) = v12 % 10;
        //v43 = v12 % 10;
        v39 = v13;
        v14 = v12 / 10 + ((int)*(char*)(buf + 4 + v8 + 3)) * buf[4 + 1];
        v32 = v14;
        v38 = v14 / 10;
        v16 = v14 / 10;
        //v42 = v32 - v16;
        //v41[0] = v14[0] / 10;
        if ( v7 != (_BYTE)v32 - v16 || (v17 = v46, v18 = v39, v46 <= (char)v39) || (_BYTE)v38 )
        {
            return 0;
        }
        *(&v49 + v9) = (char)(v32 - v16);
        *((_BYTE *)&v50 + v9) = v18;
        v7 = v17 - v18;
        v19 = v40;
        *((_BYTE *)&v50 + v9 + 1) = v7;
        v20 = *(char*)(buf + v19);
        *(&v51 + v9) = v20;
        v9 += 4;
        v45 = v7;
        v46 = v20;
        v40 = v19 + 1;
        if ( !v7 )
        {
            return 0;
        }
        v8 = v28;
        v10 = v37 + 1;
    }

    v21 = (v7 == buf[5]);
    if ( v7 > buf[5] || (v22 = v46, v21) && v46 >= buf[6] ){
        return 0;
    }

    v23 = *(char*)(buf + v40);
    *(&v49 + v9) = v23;
    v24 = v9 + 1;

    sub_401000(buf + 5,buf + v8 + 7,v41);

    //printf("%d %d %d %d\n",v41[0],v41[1],v41[2],v41[3]);
    //printf("%d %d %d\n",v45,v22,v23);

    if ( v41[0] || v41[1] != v45 || v41[2] != v22 || v41[3] != v23)
    {
        return 0;
    }

    for(i = 0;i < 20;i++){
        printf("%d",buf[i] & 0xf);
    }
    printf("\n");

    return 1;
}

int main(){

    for(key[0] = 1;key[0] < 10;key[0]++){
        for(key[1] = 0;key[1] < 10;key[1]++){
            for(key[2] = 0;key[2] < 10;key[2]++){
                for(key[3] = 0;key[3] < 10;key[3]++){
                    for(key[4] = 0;key[4] < 10;key[4]++){
                        for(key[6] = 0;key[6] < 10;key[6]++){
                            for(key[7] = 0;key[7] < 10;key[7]++){
                                for(key[10] = 0;key[10] < 10;key[10]++){
                                    for(key[11] = 0;key[11] < 10;key[11]++){
                                        if(func1()){
                                            printf("ok\n");
                                            return 0;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    return 0;
}
← BCTF 初来乍到 Writeup ISG2014 Pwnme →