首页
社区
课程
招聘
[原创]2015移动安全挑战赛第一二题
2015-1-25 18:24 2290

[原创]2015移动安全挑战赛第一二题

2015-1-25 18:24
2290
第一次破解安卓程序,每过一个就将其思路写下来,后来发现我真是将简单事情复杂化了。。。
第一题:
ApkTool分解APK后,找到smali里的MainActivity.smali,查看下Oncreate函数可以知道,按钮相应事件在MainActivity$1.smali内,在响应事件函数中可以看到,首先调用getTableFromPic然后调用getPwdFromPic(这两个函数都是从LOGO.PNG中使用指定的格式获取前面一定数量的数据字节,然后转为utf,由于对java的不了解,我在这上面折腾了不少的时间。),然后LOG输出(大大降低了难度),下面是LOG输出信息:
01-22 23:34:22.223: I/lil(7263): table:一乙二十丁厂七卜人入八九几儿了力乃刀又三于干亏士工土才寸下大丈与万上小口巾山千乞川亿个勺久凡及夕丸么广亡门义之尸弓己已子卫也女飞刃习叉马乡丰王井开夫天无元专云扎艺木五支厅不太犬区历尤友匹车巨牙屯比互切瓦止少日中冈贝内水见午牛手毛气升长仁什片仆化仇币仍仅斤爪反介父从今凶分乏公仓月氏勿欠风丹匀乌凤勾文六方火为斗忆订计户认心尺引丑巴孔队办以允予劝双书幻玉刊示末未击打巧正扑扒功扔去甘世古节本术可丙左厉右石布龙平灭轧东卡北占业旧帅归且旦目叶甲申叮电号田由史只央兄叼叫另叨叹四生失禾丘付仗代仙们仪白仔他斥瓜乎丛令用甩印乐
01-22 23:34:22.223: I/lil(7263): pw:义弓么丸广之
01-22 23:34:22.243: I/lil(7263): enPassword:么么么么么
table是一个预设的数组,pw是标准密码,enPassword是我们自己输入的密码加密后的结果,所以思路就是找到加密函数,然后写出逆函数,
继续往下看,调用access函数(而access函数直接调用bytesToAliSmsCode函数)将我们自己输入的密码(转为UTF-8的BYTE[])和table传入,所以关键代码肯定在这bytesToAliSmsCode里面;
查看bytesToAliSmsCode:
函数流程分析:如果Length(MyPWD)==0,则直接跳出;
否则进行下面的处理:
  for(ini i=0;i<bMyPwd.length;i++)
  {
    aa=bMyPwd[i];
    aa&=0xff;

    bb=strPicCode[aa];
    result.append(bb);
  }
函数返回result.toString();
接下来的流程:
如果result和pw(标准密码)相等则破解成功;
正确密码逆推:
获取标准密码(义弓么丸广之)每一个元素在table中的位置,然后将其由UTF-8转为ANSI即可。
MFC代码:
void test()
{
  CString str1=L"一乙二十丁厂七卜人入八九几儿了力乃刀又三于干亏士工土才寸下大丈与万上小口巾山千乞川亿个勺久凡及夕丸么广亡门义之尸弓己已子卫也女飞刃习叉马乡丰王井开夫天无元专云扎艺木五支厅不太犬区历尤友匹车巨牙屯比互切瓦止少日中冈贝内水见午牛手毛气升长仁什片仆化仇币仍仅斤爪反介父从今凶分乏公仓月氏勿欠风丹匀乌凤勾文六方火为斗忆订计户认心尺引丑巴孔队办以允予劝双书幻玉刊示末未击打巧正扑扒功扔去甘世古节本术可丙左厉右石布龙平灭轧东卡北占业旧帅归且旦目叶甲申叮电号田由史只央兄叼叫另叨叹四生失禾丘付仗代仙们仪白仔他斥瓜乎丛令用甩印乐";
  CString str2 = L"义弓么丸广之";
  CString str3;
  for (int i = 0;i<str2.GetLength();i++)
  {
    TCHAR ss = str2.GetAt(i);
    int aa = str1.Find(str2.GetAt(i));
    TRACE("%d",aa);
  }
}
执行上述代码得到的答案为:535649485054
转为UTF-8为(使用java写代码转换,其实就是查看每个元素对应的ANSI码):
java代码:
    byte[] str1={53,56,49,48,50,54};
    
    String str = new String(str1);
    System.out.print(str);
    得到的就是答案
第二题:
第一眼看这题目很简单,使用APKtool解压后,发现大部分和第一题差不多,直到调用MainActivity.securityCheck时,发现securityCheck处没代码,瞬间不知所措(从没接触过so,但毕竟在看雪上混了一段时间,听过so)。当初以为只需要随便输入一个密码满足某一触发条件就可以过关。
第一个转折:动态调试,
很显然这种情况下在win的话必须要动态调试,但是android下没od,windbg之类的,google了很久后学会了使用eclipse动态调试,但是一无所获,无法在securityCheck跟进去。
第二个转折:so文件
在看雪上看到过so文件,于是搜了相关资料,大概知道了so文件是c写的,使用的是NDK,唯一让我高兴的是可以使用IDA查看ARM反汇编代码。
第三个大转折:定位securityCheck
在so内部定位到了securityCheck流程处,发现arm汇编代码根本看不懂,于是慢慢学了arm基本指令,最不能忍受的是花了几个多小时分析了那个Startxxxx那个LOG输出,接下来卡在了
LDR     R0, [R5]
MOV     R1, R4
MOV     R2, #0
LDR     R3, [R0,#0x2A4]
MOV     R0, R5
BLX     R3
相对寻址?这种情况如果在win下有不下于十种方法去处理,但是android下无从下手。
从前面可以知道securityCheck(MainActivity,MyPwd)。
这里调用MainActivity的地址加上一个偏移的函数。静态调试不可能完成。卡在了究竟应该怎么去动态调试。
第四个转折:学会动态
搜了一下,学会了如何用IDA动态调试so文件,顺便下载了一个IDA6.5,有F5功能的,但是无论如何都不可以附加上目标进程,以为我的方法有问题,卡在了那里。
最后:
在多次尝试后,知道so添加了反调试功能。如何过掉反调试呢:
关键尝试1:在MainActivity.smali中删掉
  const-string v0, "crackme"

    invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
,发现可以动态调试,定位,反调试功能是在so中添加的。
关键尝试2:NOP掉JNI_OnLoad中的sub_17F4();函数,
发现输入wojiushidaan后有成功的提示。显然这不是正确答案。
最终尝试:NOP掉 dword_62B4(handle, 0, sub_16A4, 0);后可以动态调试,并且输入任意密码后字符会转换,尝试输入wojiushimima,发现在比较处有一个关键字符串:
aiyou,bucuoo,尝试将其输入密码框,完成破解。(这一题没有分析算法,这应该是题目设定)

后话:当我破解成功时特别兴奋,基本上是0基础,查虚拟机指令,查一些sdk工具的用法,下载一些调试工具,学到了很多知识,但是第三题卡了2天,能动态调试,过了so文件的校核,但对于修复odex玩不下去了,以后补充一些理论知识后在慢慢搞。
感觉像我这种只过了第一题和第二题的没必要写出思路来,熟悉了一些工具的使用后特别简单。这个比赛关键是看各位大牛的思路。。。

阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!

收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回