本题只做交流,没有其他意思,望管理大大不删帖
前段时间第一次接触这东西就遇到了ios的逆向题,下载题目后各种分析,楞是没读懂它的算法,知道论坛里大神多,所以上传上来分享下
下面是正文:
-------------分割线-----------------
附件来自于一CTF赛中的逆向题,flag为当用户名为ctfuser时的正确Serial值
Quiz7GUI.ipa (111.9 KB)
本题只做交流,没有其他意思,望管理大大不删帖
前段时间第一次接触这东西就遇到了ios的逆向题,下载题目后各种分析,楞是没读懂它的算法,知道论坛里大神多,所以上传上来分享下
下面是正文:
-------------分割线-----------------
附件来自于一CTF赛中的逆向题,flag为当用户名为ctfuser时的正确Serial值
Quiz7GUI.ipa (111.9 KB)
6个小时过去了,我来缓和一下尴尬的气氛
膜。哪个ctf
呃呃,这个不重要,,,,,,大神看题撒
我还太菜,所以关注这个
iOS逆向juan很多人不会关注这个的啦,毕竟做了又没人给钱23333
开黑吗我玩源氏
大神不来解一发题目。。娱乐一下么。。
唉。。看来真是这样子,本以为会出现各种骚气的逆向思路,可这都两天了,,还是没人来玩。
真是现实的向金钱看齐==
话说把这题做为入群题目之一,会不会有人来玩啊
本来是想在论坛发一系列iOS相关的ctf题,可现在看来没啥槽点
简单看了一下,校验逻辑在[ViewController checkClicked:]
里,用LLDB跟一下应该就出来了
跟这题没啥本质区别吧?
这个太明显了,他说的是算法看不懂
[ViewController checkClicked:]这个大家都能看出来,这题考的是解读逻辑校验算法,并不是简单的输出个passed就算通过,而是要根据校验算法推出当用户名为ctfuser时,serial的值应该为什么。
如果推出的Serial值是正确的话,把ctfuser和相应的Serial值填进文本框后,屏幕是会向选手显示passed,表示推出的Serial是正确的。
然后选手再把Serial值提交上去。
Serial并没有被硬编码进去,赛后据第一的战队透漏说Serial值有无数个。他们用了不到一小时就拿下了
检验算法就在那里面,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
你们看我给出的那个链接了么?
我当然知道要继续逆向;阿里那题也有个算法,两者本质是一样的。这一题的算法在:
不要看伪代码,要么静态直接看汇编,要么动态一步一步跟,算法就出来了。于我来说只是重复劳动而已,就不做这一题了
哦哦,从伪代码来说确实是相同题目
你那个算法也是无数解么? 感觉好恐怖啊。
那题我动态一步步跟的,循环了一遍,没明白算法,觉得好累,最后放弃了。。
是的我昨天看到这个代码了