一道ctf中的逆向题

本题只做交流,没有其他意思,望管理大大不删帖:blush:

前段时间第一次接触这东西就遇到了ios的逆向题,下载题目后各种分析,楞是没读懂它的算法,知道论坛里大神多,所以上传上来分享下:blush:

下面是正文:
-------------分割线-----------------
附件来自于一CTF赛中的逆向题,flag为当用户名为ctfuser时的正确Serial值

Quiz7GUI.ipa (111.9 KB)

1 个赞

6个小时过去了,我来缓和一下尴尬的气氛:neutral_face:

膜。哪个ctf

呃呃,这个不重要,,,,,,大神看题撒:wink:

我还太菜,所以关注这个:joy:

iOS逆向juan很多人不会关注这个的啦,毕竟做了又没人给钱23333

开黑吗我玩源氏

大神不来解一发题目。。娱乐一下么。。

:pensive:唉。。看来真是这样子,本以为会出现各种骚气的逆向思路,可这都两天了,,还是没人来玩。
真是现实的向金钱看齐==

话说把这题做为入群题目之一,会不会有人来玩啊:pensive:
本来是想在论坛发一系列iOS相关的ctf题,可现在看来没啥槽点

简单看了一下,校验逻辑在[ViewController checkClicked:]里,用LLDB跟一下应该就出来了

跟这题没啥本质区别吧?

这个太明显了,他说的是算法看不懂

[ViewController checkClicked:]这个大家都能看出来,这题考的是解读逻辑校验算法,并不是简单的输出个passed就算通过,而是要根据校验算法推出当用户名为ctfuser时,serial的值应该为什么。
如果推出的Serial值是正确的话,把ctfuser和相应的Serial值填进文本框后,屏幕是会向选手显示passed,表示推出的Serial是正确的。
然后选手再把Serial值提交上去。

1 个赞

Serial并没有被硬编码进去,赛后据第一的战队透漏说Serial值有无数个。他们用了不到一小时就拿下了:pensive:

检验算法就在那里面,F5一下看看

这是我比赛那天的f5结果,,最后没读懂这个算法

--------分割线-----------


void -[ViewController checkClicked:](void * self, void * _cmd, void * arg2) {
    r7 = sp + 0xc;
    asm{ vst1.64    {d8, d9, d10, d11}, [r4:0x80]! };
    asm{ vst1.64    {d12, d13, d14, d15}, [r4:0x80] };
    sp = (sp - 0x40 & !0xf) - 0xa0;
    r5 = self;
    var_AC = ___stack_chk_guard;
    var_1C = *___stack_chk_guard;
    var_7C = [arg2 retain];
    r4 = r5->_started;
    _Unwind_SjLj_Register();
    if (r4 != 0x0) {
        [r5 appendlog:"already checking...\n"];
    }
    else {
        
        r5->_started = 0x1;
        var_B0 = *0x5990;
        var_B4 = @selector(appendlog:);
        var_A8 = r5;
        [r5 appendlog:("/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics" | 0x0) + 0x31a6];
        r0 = objc_loadWeak(*0x5994 + var_A8);
        var_A0 = @selector(text);
        r0 = [r0 text];
        r7 = r7;
        var_78 = [r0 retain];
        CFStringGetCString(var_78, sp + 0x2c, 0x9, 0x600);
        r0 = CFStringGetLength(var_78);
        
        r2 = 0x0;
        do {
            r0 = *(r2 + sp + 0x2c);
            0x6 << 0x10 | sub_3bfe(r0);
            r2 = r2 + 0x1;
            asm{ vadd.f64   d8, d16, d8 };
        } while (r2 < 0x9);
        
        
        r0 = objc_loadWeak(*0x5998 + var_A8);
        r0 = objc_msgSend(r0, var_A0);
        r7 = r7;
        var_74 = [r0 retain];
        CFStringGetCString(var_74, sp + 0x7c, 0x11, 0x600);
        
        
        r2 = 0x0;
        r1 = 0x0;
        do {
            var_A0 = r1;
            var_9C = r2;
            r0 = *(r2 + sp + 0x7c);
            if ((r2 & 0x2) == 0x0) {
                asm{ uxtb       r0, r0 };
                var_A4 = sub_3d44(r0);
                r0 = *(0x1 + var_9C + sp + 0x7c);
                r0 = sub_3d44(r0);
                r2 = var_9C;
                r0 = r0 + var_A4;
            }
            else {
                asm{ uxtb       r0, r0 };
                var_A4 = sub_3d44(r0);
                r0 = *(0x1 + var_9C + sp + 0x7c);
                r0 = sub_3d44(r0);
                r2 = var_9C;
                r0 = var_A4 - r0;
            }
            *(r2 + sp + 0x7c) = r0;
            asm{ uxtb       r0, r0 };
            r0 = sub_3bf4(r0);
            r2 = var_9C;
            r1 = *((SAR(r2, 0x1)) + sp + 0x20);
            if ((r0 ^ r1) <= 0xf) {
                r1 = var_A0 + 0x18e8e;
            }
            else {
                r1 = var_A0 + (r1 - *(r2 + sp + 0x7c) & 0xf);
            }
            r2 = r2 + 0x2;
        } while (r2 < 0x10);
        if (r1 == 0xae5e9) {
            [var_A8 appendboldlog:"passed.\n"];
        }
        //
        else {
            if (r1 == 0xc7470) {
                objc_msgSend(var_A8, var_B4);
            }
        }
        *(var_A8 + var_B0) = 0x0;
        [var_74 release];
        [var_78 release];
    }
    [var_7C release];
    _Unwind_SjLj_Unregister();
    if (*var_AC == var_1C) {
        r4 = sp + 0xa0;
    }
    if (CPU_FLAGS & E) {
        asm{ vld1.64    {d8, d9, d10, d11}, [r4:0x80]! };
    }
    if (CPU_FLAGS & E) {
        asm{ vld1.64    {d12, d13, d14, d15}, [r4:0x80] };
    }
    if (CPU_FLAGS & E) {
        r4 = r7 - 0x18;
    }
    if (CPU_FLAGS & E) {
        sp = r4;
    }
    if (CPU_FLAGS & E) {
        return;
    }
    __stack_chk_fail();
    return;
}

@NavilleZhang @xiaossv

你们看我给出的那个链接了么?

我当然知道要继续逆向;阿里那题也有个算法,两者本质是一样的。这一题的算法在:

不要看伪代码,要么静态直接看汇编,要么动态一步一步跟,算法就出来了。于我来说只是重复劳动而已,就不做这一题了

哦哦,从伪代码来说确实是相同题目:+1:

你那个算法也是无数解么? 感觉好恐怖啊。
那题我动态一步步跟的,循环了一遍,没明白算法,觉得好累,最后放弃了。。

是的我昨天看到这个代码了