网址如下

http://challenge.onebox.so.com/DeveloperZhaopin/question?tag=crack#nav-wrap



公开答题时间是

答题时间为4月23日-4月30日,将于5月15日公布结果。

目前我主要做的方向是

无线攻防


里面一共有三道题


等答题时间过了以后,我会在博客更新一下研究结果,还请朋友指正。


关于答案:

第一题

本题主要是需要集成一个 openssl,然后找到java层和c层对于des的openssl对应的函数。
主要工作如下:
1 openssl 从https://github.com/eighthave/openssl-android 下载openssl源码
 修改其编译文件,能够生成静态库 libssl.a 和 libcrypto.a 这两个静态库
2 找到java层和c层对应的openssl减密函数
 int Encrypt( unsigned char * inbuf , unsigned char * * outbuf , int inlen , unsigned char * key, unsigned char * iv ,int enc)
{
   BIO *bio, *mbio, *cbio;
   unsigned char *dst;
   int outlen;

   mbio = BIO_new( BIO_s_mem( ) );
   cbio = BIO_new( BIO_f_cipher( ) );
   BIO_set_cipher( cbio , EVP_des_ecb( ) , key , iv , enc );

   bio = BIO_push( cbio , mbio );
   BIO_write( bio , inbuf , inlen );
   BIO_flush( bio );

   outlen = BIO_get_mem_data( mbio , (unsigned char **) & dst );
   * outbuf = ( unsigned char * ) malloc( outlen );
   memcpy( * outbuf , dst , outlen );
   BIO_free_all( bio );

   return outlen;
}

关键就是上面这个函数,写成自己的so
3 用apktool工具反编译测试apk,将so放进去,然后稍微修改一点smali源码,
 点击的时候调用jni函数
4  由于我是用ubuntu环境下开发,所以apktool的反编译的时候aapt在解析程序
  图标的时候失败,我就随便换了个图标,没有认为这是试题的一部分。



第二题:

本题主要是考查重打包的能力。
主要工作
1 修改AndroidManifest.xml文件,修改程序包名,以及application和主lunch的activity的名称,同时修改smali文件中的包名。

2 插入一个 com.qihoo.crack.StubApplication.MainActivity activity 做为
 android.intent.action.MAIN 主activity,因为木有想着修改so,其实感觉
 修改so可能更为方便,所以就将原先的 com.qihoo.test.MainActivity 做为一个非MAIN的activity,让插入的 StubApplication.MainActivity 来启动test.MainActivity,然后自己finish。当然程序名称也进行了修改了

3 关于 provider,直接使用 StubApplication.MainActivity 来进行provider的使用,然后将返回的奇虎Test 通过静态变量给 test.MainActivity 感觉更为方便。

4  木有动so,是因为题目要求的包名要远远大于 com.qihoo.test 这个包名,并且so中的写法估计是
char *packagename = "com.qihoo.test";
没有留出多余的字节让修改,当然可以通过更改整个elf文件的结构,比如.symstrtb 这些字段突破限制,但感觉不在本题讨论范畴,故未这样尝试



第三题:

比较惭愧,虽然有思路,但是木有做出来,这个就不让献丑了。

附件是内存dump出来的  so库文件,通过 android gdb_server 配合着调试指令集都能对的上

但是由于看汇编代码的内力还不足,所以暂时没有看出来其注册代码生成的算法。

关于暴力破解

这个思路很多,但是感觉对于  62的8次方的破解量,估计应该用分布式的计算才好。用字典的话

基本上不靠谱,又不是猜用户密码。


后来补充的思路:

主要分两个方向来进行破解:
1  分析so破解,后来又下载的新的so利用linux加载so的时候对于 段表部分不敏感的特点修改了一下段表的个数和每个段表的长度。
  造成ida加载的时候会报错,这个很好修改,基本上到段表的偏移,计算一下大小和对其就解决修改了
  然后用ida打开后,发现这个so里面关于核心代码都经过加密了。但是apk中又能够执行,这点感觉比较奇怪。于是用gdb配合 android gdb_server进行动态调试(由于没有正版的ida,所以只能用gdb一条一条的调试,这也是后来看不下去汇编代码的一个原因吧),发现实际上
的指令和ida中对应的指令内容不同。而实际指令是arm标准指令,这个so肯定在加载的时候做了一些处理,初步估计是利用工具修改了其入口地址,让动态链接器在加载的时候调用的第一个函数的地址不是这个so上正常逻辑的地址,而这个地址又将数据填充到正常逻辑的函数地址上,造成了从ida看的指令和内存中的指令不同
  但是就破解来说,我不用关心这个指令变换,只是需要知道在内存中运行的地址上的指令是我想要的即可,因为本身这个例子没有反ptrace,所以就编写了一个 memdump工具,通过maps将这个so给dump出来,然后再用ida打开,发现的确是有效的arm指令,当然直接从内存中dump出来的so是少 .symtab .symstrtab这些段的,我又自己编写了一个小工具将dump出来的数据同原来的so结合一下,形成了附件中能够被ida顺利读取的so,请见附件libqihooout.so 这个so

   接下来的工作就是通过静态分析 libqihooout.so然后配合动态调试来找到这个so的算法,但是这个时候出现了问题:

1  我以前做嵌入式的时候用过arm汇编,但是由于时间比较长了,对arm汇编的阅读对我造成了破解障碍。
2  工具由于用gdb + android gdb-server 来调试,gdb没有图形界面,看寄存器的值 都需要用 info reg 这些命令,
   效率很低。
这个是我一天多研究的结果,综上,造成了这次破解的放弃。

2  暴力破解
由于上面有两个软肋,我第二天的时候就想采用暴力破解的方式。
首先评估了一下计算量   (26+26+10)^8 大概是 5.345972853×10大概 50多万亿次的计算量。由于是注册码,我没有想用字典的方式。
所以只能采用分布式的计算了。
这个需要服务器,我没有具体实现,只是说一下思路
对于这个简单的计算任务,自己可以编写一套服务器的代码,然后将这个计算任务分成一个可接收的最小单位量,比如1千万次,这样的话总的计算量就有500多万份了
然后利用不同的终端来进行连接,服务器分配计算因子,当终端在计算完成服务器分配的计算因子后提交结果,服务器保存结果,然后下次再进行分配。靠多个终端协同来完成这样的暴力破解。后来这个想法我发现也不是一两天能够完成的,要编写服务器端和客户端两部分的代码。并且也没有那么多机器,也就放弃了。
以上是我关于第三题的研究过程。