MENU

Catalog

    bugku Reverse bingo

    December 12, 2020 • Read: 1207 • Reverse

    听说BugKu上线了,从昨天下午做到了今天下午,正好一天时间,最后是做了87题,实在是做不动了,冲分就暂时告一段落,前面的题目还是比较水的。这里讲解一下花了我大概一个小时才做出来的题目,bingo
    ranklist.png
    题目是一个解锁包,解压得到一张图片。
    bingo.png
    刚开始的时候没看分类,以为是MISC题,然后找了半天隐写内容,都没做找到,但是这个文件这么大,肯定是有问题。
    然后又仔细找了一下,结果发现了这样一段内容,
    图片截图.png
    看上去内容好像是EXE程序中才会有的,于是看了一下分类,好家伙,原来是re题。
    百度了一下png文件尾
    PNG (png),   
    文件头:89504E47  文件尾:AE 42 60 82
    搜索 AE 42 60 82
    mz.png
    这不就是熟悉的MZ文件头吗,用010 Editor提取出这一段内容。
    并重命名为bingo.exe
    error.png
    结果报错了,随便找了一个exe文件,比对文件内容是否确实,发生少了PE文件头标识。
    PE缺失.png
    补上这一段内容。
    ok.png
    数据补上后直接打开运行,发现可以显示黑框,但是运行后直接退出,于是打开IDA分析一下
    ida.png
    ida打开后似乎认不出来文件的其他内容,动态调试后发现这一段内容会出现异常的情况。

    pusha
    mov     ecx, 3E000h
    mov     ebx, 1000h
    mov     ebx, 400000h
    add     ebx, edx
    xor     byte ptr [ebx], 22h
    inc     ebx
    popa
    jmp     loc_408BE0

    原因是edx的内容也是400xxxh,相加之后到了800xxx,超出了范围。
    这里不知道是作者预期还是怎么的,反正应该是这个解密函数出现了问题。
    但是看到这里应该就是一个xor解密(xor 0x22),所以直接在外部解密吧。

    #define MAXKEY 5000
    #define MAXFILE 1000
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int main()
    {
        char xor_key[MAXKEY], file_dir[MAXFILE];
        char* buf;
        //printf("xor key: ");
        //scanf("%s", xor_key);
        xor_key[0] = 0x22;
        xor_key[1] = 0;
        printf("file: ");
        scanf("%s", file_dir);
        FILE* fp = fopen(file_dir, "rb");
        strcat(file_dir, ".xor");
        FILE* fpw = fopen(file_dir, "wb+");
        if (fp && fpw)
        {
            fseek(fp, 0, SEEK_END);
            size_t size = ftell(fp);
            fseek(fp, 0, SEEK_SET);
            buf = new char[size];
            fread(buf, sizeof(char), size, fp);
            for (size_t i = 0, keySize = strlen(xor_key); i < size; i++)
                buf[i] ^= xor_key[i % keySize];
            fwrite(buf, sizeof(char), size, fpw);
        }
        if (fp) fclose(fp);
        if (fpw) fclose(fpw);
        return 0;
    }

    解密文件后,得到文件bingo.exe.xor,观察文件信息,发现实际上只有.text段进行了异或加密,其他内容都没有加密。
    从文件中大量的0x22内容也可以看出来(因为0x00 ^ 0x22 = 0x22)
    cmp.png
    从0xCC就可以知道,应该是解密对了,因为0xCC对应的是INT3断点,也就是当段未初始化的时候,vs debug模式下会赋值的内容。vs中的烫烫烫也是这么来的。
    替换.text段的内容。
    替换后.png
    替换后得到的exe程序,直接运行当然还是不可以的,但是可以放到ida中解析各个函数了。
    但是没有任何的符号信息,难以阅读。所以我还是打算调整程序让其可以正常运行。

    打开ida后,定位到start处
    patch.png
    直接用Keypatch(ida插件)进行修改,让其直接跳到程序真正的入口点(jmp sub_408BE0)。
    patch.png
    修改后进行保存
    canrun.png
    发现程序以及可以成功运行。
    重新载入后发现,接下来发现程序的符号信息就有了。
    main.png
    可以看出,程序对输入内容进行加密后与程序中off_443DC0(zaciWjV!Xm[_XSqeThmegndq)进行比对。
    encode.png
    这里的加密方法就是对你输入值(c)进行平方,然后再加上一个参数(b),最后解出来a。
    满足关系式: a^2 + b^2 = c^2。
    本来以为直接解密就好了,没想到这里还有一个函数_strrev(v6);
    他的作用是把字符串信息倒置,所以最后显示的顺序也会变换。

    由于这里sqrt还有个精度问题,我这里就不进行逆运算了,也就是
    c = sqrt(a^2 + b^2)
    直接编写程序爆破c的内容。

    解密程序

    #include <cstdio>
    #include <algorithm>
    #include <string.h>
    using namespace std;
    
    int main()
    {
        char s[] = "zaciWjV!Xm[_XSqeThmegndq";
        char e[] = "                        ";
        char* v6 = (char*)operator new(strlen(s) + 1);
        memset(v6, 0, strlen(s) + 1);
    
        for (int i = 0; i < strlen(s); i++)
        {
            v6[i] = 'a' + i;
            _strrev(v6);
        }
        for (int i = 0; i < strlen(s); i++) e[v6[i] - 'a'] = s[i];
        printf("%s\n", v6);
        printf("%s\n", e);
        int a2 = 0x34;
        for (int i = 0; i < strlen(s); ++i)
        {
            for (char t = 1; t < 0xFF; t++)
            {
                int v2 = (signed __int64)pow((double)a2, 2.0);
                signed int v3 = (unsigned __int64)(signed __int64)pow((double)t, 2.0);
                v3 -= v2;
                v6[i] = (signed __int64)(sqrt((double)v3) + 0.5);
                if (v6[i] == e[i])
                {
                    printf("%c", t);
                    break;
                }
            }
            --a2;
        }
        return 0;
    }

    运行后可以得到:
    flag.png

    flag{woc_6p_tql_moshifu},看到这个flag之后还是觉得挺开心的。

    Last Modified: March 23, 2021
    Archives QR Code
    QR Code for this page
    Tipping QR Code
    Leave a Comment

    2 Comments
    1. Sapphire Sapphire

      大哥求教皇家马德里flag.png里面到底怎么弄

      1. Sapphire Sapphire

        @Sapphire已经搞出来了 谢谢