• 启用github博客

    日期:2016-06-04 | 分类:随笔杂谈

    开始使用github写博客:http://riusksk.github.io,配合Markdown+Hexo写文章感觉很方便,简洁的页面效果也是挺赞的,而且用github也更符合一个IT男的“情趣”。

    博客大巴确实不适合写技术博客,也没有人气,用户体验也差,基本连发个博文都成问题(需要等几天的审核),让人很难有兴致继续更新下去,而且以前的发的图片有些已经莫名其妙地丢失了。更可恨的是,blogbus居然不允许导出博客了。

  • 生日礼物

    日期:2016-05-14 | 分类:随笔杂谈

    昨天晚上收到妹子的生日礼物,是时候重回战场了!

  • 更新下博客

    日期:2016-03-27 | 分类:随笔杂谈

    好久没更新了,发一帖证明还活着。

    很少更新的主要原因是:

    1、变懒了,没了写博客的感觉;

    2、博客大巴用户体验确实不好,发帖还得审核,不能直接发出,一审核有时就是一星期之后,即使发了,外面的人也很难即时看到;

    3、博客大巴已经把搬博客的功能去掉了,无法将以前的日志导出,想转移到阿里云服务器都不方便,毕竟写了这么多年的博客,还是希望能够把它留存着。

    总之一句话:博客大巴变质了……

  • 原始的漏洞分析文章参见:“ANALYSIS AND EXPLOITATION OF A LINUX KERNEL VULNERABILITY (CVE-2016-0728)”
    http://perception-point.io/2016/01/14/analysis-and-exploitation-of-a-linux-kernel-vulnerability-cve-2016-0728/
     
    此次漏洞的问题出现在linux密钥管理keyrings上,在创建新会话去覆盖旧会话时,没有对旧数据进行清理,导致内存泄露(引用计数refcount),通过整数溢出refcount为0,导致keyring对象释放,再使用IPC发送消息,用与keyring对象大小相等的内存块去填充free的对象空间,修改已释放的keyring对象中的revoke函数指针,使其指向用户空间的自定义函数,通过它来执行commit_creds(prepare_kernel_cred(0)),就相当于执行shellcode,从而实现Root提权。
     
    整个利用过程如下:
    内存泄露 =》 整数溢出 =》Use After Free =》 篡改函数指针指向shellcode=》实现提权
     
    cve_2016_0728
  • https://bugzilla.redhat.com/show_bug.cgi?id=1294425

  • vim开发环境设置

    日期:2015-11-22 | 分类:编程窥探

    以前习惯用sublime text 阅读/写代码,主要还是因为它的界面风格、代码高亮,个人比较喜欢,但是在平常经常是直接拖文件到sublime text导致开了好多个窗口,而且还在Finder里面先找到文件再去,有时觉得又有些不方便。

    平时开电脑,命令行是肯定也开着的,在命令行下自然是习惯用vim来写代码,因此这次直接给vim设置了下开发环境,把文件浏览器、代码函数显示、自动补全、函数提醒等多个实用功能都添加上去,感觉还不错。

    直接上图,下面是windows上的一份代码,只是用来查看效果的。

  • 泄露的 driver-macos-master 项目是一个Mac OS X Rootkit 病毒,从源码看,它可能就是当年红极一时的病毒“OSX.Crisis”,因为两者之间连一些函数名都一模一样(比如关键函数hide_proc、hide_kext_osarray,甚至连废弃的hide_kext_leopard也有),逻辑也基本相同。更为牛逼之处的是,Crisis是在2012年爆发的,而该份代码在2009就已完工,想想之间的差距吧,这也再一次证明Hacking Team的技术实力有多强大。
     
     
    【源码分析】
     
    下面分析下该 OSX rootkit 技术内幕:
     
    1、先从入口函数 mchook_start 开始分析,主要就是注册字符设备,然后在文件系统上创建设备节点,常规的驱动入口行为。
     
     
    对应的字符设备转换表如下:
     
     
    主IOCTL回调函数就下面3个,其中cdev_open和cdev_close为空,整个处理逻辑都包含在cdev_ioctl函数中:
     
     
    2、关键看下cdev_ioctl 回调函数,里面包括各种潜伏隐藏的行为。在mchook.h文件头中就定义了一些cdev_ioctl中调用到的函数,从函数名上基本可以推测出该rootkit包含文件隐藏、进程隐藏、内核模块隐藏等功能。
     
     
    3、进程隐藏:在mac osx上,每个进程的上下文都保存在proc结构中,而在allproc链表中就保存着所有进程proc结构的指针,通过allproc链表移除相应进程的proc结构可隐藏正在运行的进程,下面是关于隐藏进程的代码,位于hide_proc函数中(还有另一个未被调用到的函数hide_proc_l,也是用于实现相同功能),它相应进程从进程链表和进程Hash表里都移除掉。之前笔者在分析 rubilyn osx rootkit 时,发现它就没有从Hash表里移除进程相关信息,导致可通过“ps -p pid ”命令查找到进程。
     
     
    4、内核模块隐藏:早期针对leopard系统的内核模块隐藏是调用 hide_kext_leopard 函数,现在已经不再使用,它只是简单地遍历kmod_info 内核模块链表结构,找到相匹配的模块名,然后将从它链表中踢除,这样当执行kextstat命令时就查看不到隐藏的内核模块,但这种方法现在无效。
     
     
    为了支持多个系统版本,后来重写了个 hide_kext_osarray 函数。在“雪豹”苹果系统之后,有个叫sLoadedKexts 的 IOKit OSArray类引用到内核模块列表,不过它并没有导出符号,只要能够找到它,那么就可以对sLoadedKexts 数组进行修改,以达到隐藏内核模块的目的。
     
    庆幸的是,OSKext::lookupKextWithLoadTag 函数里面引用到sLoadKexts(源码参见:http://www.opensource.apple.com/source/xnu/xnu-2782.1.97/libkern/c++/OSKext.cpp),通过它可以定位到sLoadKexts地址。
     
     
    它对应的内核模块位于/System/Library/Extensions/System.kext/PlugIns/LibKern.kext/LibKern,不过当用IDA加载分析时,发现它只有导入表的函数信息,并无实际函数,包括PlugIns目录下的其它驱动也是大多如此。进一步分析,发现这些驱动其实都链接到/System/Library/Kernels/kernel里面,可以发现OSKext::lookupKextWithLoadTag函数对应的符号名为__ZN6OSKext21lookupKextWithLoadTagEj。
     
     
    通过该符号即可找到OSKext::lookupKextWithLoadTag函数,然后开始搜索机器 E8,即CALL指令,从上面的源码看,调用的第一个函数是IORecursiveLockLock,然后跳过call指令(共5字节)进入下一条指令。
     
     
    再根据32位/64位系统进行区分,对于32位比较简单,call下一条指令就包含有sLoadedKexts地址,下图就是32位系统Snow Leopard 10.6.8的OSKext::lookupKextWithLoadTag函数,由于笔者缺乏该环境,因此图片是从网上扣来的:
     
     
    但对于64位系统会相对繁琐一些,它先找到机器码 48 8B,即mov指令,获取第2个操作数的实际内存地址,即为sLoadKexts,不过笔者在最新版10.10.4上发现必须是在第2个 48 8B才有效,因此该份rookit只适用于低版本的 64位Leopard系统
     
     
     
    定位到sLoadedKext这个OSArray数组之后, sLoadedKext[OFFT_KEXT_COUNT] =  sLoadedKext[0x14] = 元素个数,即已加载的内核模块个数。接着找到最后一个kext模块的kmod_info结构信息,判断该内核模块是否为com.apple.mdworker,若是则将递减模块数量,进而隐藏kext模块,所以实际要隐藏哪个模块就得去更改com.apple.mdworker为相应的模块名。
     
     
    5、文件隐藏:为了对列出文件的相应系统函数进行挂钩,我们需要先对finder和ls所使用的函数进行进程跟踪,在mac上已经用Dtrace代替ktrace,在finder上主要是使用getdirentriesattr函数,而ls主要是使用getdirentries64,下面是用Dtrace分别对finder和ls的进程跟踪情况:
     
     
    下面是查看finder进程2841的调用函数,其中的getdirentriesattr在最新版10.10.4上未发现被调用,以下测试是之前在10.9系统上测试的,但是在10.10.4中getdirentriesattr函数依然在syscall.h中被定义着。
     
    riusksk@macosx:/usr/include/sys$ sudo dtrace -s ~/Reverse\ engineering/Dtrace/calltrace.d -p 2841 | grep getdir
     
    dtrace: script '/Users/riusksk/Reverse engineering/Dtrace/calltrace.d' matched 573227 probes
     
      2 1078881          getdirentriesattr:entry 
      2 1363229         getdirentriesattr:return =1
    ……
     
    下面是ls命令(64位系统)调用的函数:
     
     
    因此,我们若想在finder和ls中隐藏文件,只要对这两个函数 getdirentriesattr 和 getdirentries64 (32位的为getdirentries)进行挂钩处理即可。在系统调用函数表中,主要是由sysent结构数组构成,每个sysent结构中都包括参数个数sy_narg,执行函数sy_call 这些重要数据。sysent结构如下:
     
     
    为了实现对上述系统函数的挂钩,通过修改相应函数sysent结构的sy_call来进行偷梁换柱,关于各系统函数的调用号和宏名均可在 /usr/include/sys/syscall.h中找到:
     
     
    回头看源码,发现该rootkit也是对上面这3个函数进行hook:
     
     
    看下其中的hook_getdirentiries64函数,其它类似,主要还是移除指定文件的dirent结构,其中dirent结构原型如下:
     
     
    先调用原始函数,获取真实的文件信息(源码中的direntry对应的其实是dirent结构,在新版版本中这两个结构是独立存在的了):
     
     
    然后遍历文件链表,找到相匹配的文件名,然后用后一个dirent文件结构覆盖当前找到的dirent文件结构,这样就相当于指定的文件结构信息从链表中移除,从而实现文件隐藏的目的。
     
     
    10、官方另外在testuint目录下放有用于测试的rootkit的工具kextControl.c 和 solveKernel.c。
     
     
    【总结】
        
         实际测试时,由于没有合法签名,导致驱动也无法被正常加载,因此未能作实际测试。
     
    15/7/17 下午2:23:27.921 com.apple.kextd[44]: ERROR: invalid signature for com.revenge.kext.machooker, will not load
     
    此次泄露的OSX rootkit 相对还是比较常规的技术,毕竟是2009的源码了,年代久远,但在最新OSX 10.10上稍作修改,应该还是可以用的。
  • 在此次泄露的Flash 0Day的利用代码都包含针对Mac OSX 64位系统的利用,以往在网上看到的大多是windows平台32/64位的利用代码,很少有Mac版的flash利用代码曝光,刚好可以借机分析学习下军用级武器的写法。

     

    【源码分析】

     

    下面以第1HackingTeam泄露的CVE-2015-5119Flash 0day 漏洞中的利用代码为例:

     

    1、内在中暴力搜索Mach-o文件头magic标记0xfeedfacf(类似搜索windows平台下的PEMZ标记),它代表64位程序的意思,也是MacOS X上可执行文件的开头。

     


     

    可以用otool或者MachOView查看Mach-o可执行文件格式:

     


     

    2、在Mach-o文件头之后是加载命令(LoadCommand)区域,接下来程序搜索用于映射文件中的段到进程内存空间的LC_SEGMENT_64加载命令,遍历每个被加载的段,找到包含段标记为S_SYMBOL_STUBS(代表包含符号信息) S_ATTR_PURE_INSTRUCTIONS (代表包含机器码)的段,然后获取段地址Address、偏移量OffsetSizeStubs SizeStubs数量以及Indirect Sym Index(间接符号表索引值)。

     


     


     


     

    3、找到_LINKEDIT 段,从中获取相应的虚拟地址和文件偏移,然后互减得到两者之间的偏移量。

     


     

    4、获取LC_SYMTAB加载命令的相关信息,该命令用于指定文件所使用的符号表,找到后分别获取符号表偏移量、符号数、字符串表偏移量、字符串表大小

     


     


     

    5、获取LC_DYSYMTAB加载命令的相关信息,该命令用于指定动态链接库所使用的符号表,找到后获取间接符号表偏移量

     


     


     

    6、将前面获取的符号表地址、间接符号表地址和字符串表地址分别加上第3步获取的偏移量

     



     

    7、从前面获取的3个值,去字符串表中索引mprotect函数,找到其对应的内存地址,以利用它去真正的shellcode部分赋予可执行权限(这部分与Windows平台上的代码基本一致),以绕过DEP的保护。

     


     

    8、前面都是为执行接下来x64 shellcode代码而作的准备,由于vfork所创建的子进程与父进程共享数据,因此可用于检测是否位于沙盒中,若在沙盒中vfrok会执行失效,进而退出执行。

     


     

    9、通过为syscall指定调用号来调用execve函数,以执行"/Applications/Calulator.app/Contents/MacOS/Calculator”打开计算器,然后再调用exit退出子进程。

     


     

    10、设置返回值为int atom类型,左移3位是为了对最后3 bits 清零,因为它代表着atom类型,再加6是为了设置为int atom类型,因为shellcode相当于自定义函数,它是用于替换payloadJIT函数去执行的,最后弹出栈数据,以维持栈平衡。

     


     



     

    【总结】

     

           此次的Mac OSX 64位平台的利用,主要还是先根据Maco-o文件头标记找到flash模块,然后去索引符号表、间接符号表和字符串表,进而找到mprotect函数的地址,将shellcode内存块设置为可执行权限。真正用于弹出计算器的shellcode代码相对比较简单,向syscall传递调用号来执行execve函数,进而打开指定的程序文件Calculator,实现最终的任意代码执行。

     

  • 周末大清早起来,就看到知道创宇在微博上说,Hacking Team又泄露新的Flash 0Day,在当前最新实测可用。于是笔者下载了一份利用代码,经测试确实在最新版上可利用,目前Adobe官方未发布补丁。此次泄露的0day并没有在泄露的工具库里面,而是在邮件附件中被发现的。
     
     
    【利用代码分析】
     
    1、这次的漏洞主要出现在AS3 "opaqueBackground” 属性上,它主要用于设置背景颜色。首先创建_ar Array数组,然后用vector.对象填充。
     


     
    2、接着创建TextLine对象,然后设置它的opaqueBackground属性,再自定义valueOf函数,这个函数是触发漏洞的关键,跟前几个flash漏洞类似。
     
     
    3、设置opaqueBackground属性,将_mc(MyClass类型)赋予opaqueBackground,由于数据类型不同,AVM会进行类型转换,此时自定义的valueOf2就会被调用。
     


     
    4、调用recreateTextLine函数重建TextLine,导致原分配的TextLine对象内存被释放,但程序依然保留着对它的引用,所以漏洞也是个UAF漏洞。接着重新设置_ar[i].length的长度值(_vLen 大于原始长度值 ),会导致重新分配内存,从而占用已释放的内存,此时里面都是vector.对象。最后返回_vLen+8的值给_ar[_cnt].opaqueBackground,如果利用成功,它刚好会去篡改某个vector.对象的长度值为106。
     
     
    5、找到被篡改了长度的vector对象,由于其长度值被更改,再用这个被改的vector去覆盖下一个vector长度为0x40000000,允许读取到更大内存空间的数据,从而获取需要调用的函数地址,绕过ASLR保护。根据不同的系统平台,选择不同的shellcode代码执行,这些跟前2个flash 漏洞的利用模板基本一致。
     
     
    6、内存搜索的方式也是采用搜索“MZ”PE头这种暴力方式,再去解析PE文件格式,从导入表中的找到kernel32.dll库,再从其函数名列表里找到VirtualProtect函数,进而找到对应的函数地址进行调用。
     
     
    7、看下ShellWin32.Exec函数,通过内存搜索找到VirtualProtect函数地址,将包含执行calc的shellcode设置为可执行权限,以此绕过DEP保护,并用指向shellcode的指针替换payload对应的JIT函数指针,当调用Payload.call 时则执行的正是shellcode。
     

    【防范方案】

    Adobe官方刚刚已经发布安全公告,对应的CVE号为:CVE-2015-5122,并称12号将发布安全补丁,相当于北京时间周一早上。TSRC建议大家在官方发布补丁前,先禁用Flash插件。


    【总结】
     
         此次漏洞主要是AS3 opaqueBackground 属性导致的UAF漏洞,依然是valueOf导致的漏洞,此次Hacking Team 曝光的3个漏洞均是valueOf问题,用的基本是同一套利用模板,并且支持多个平台环境,都是采用vector exploit技术去实现信息泄露,从而绕过ASLR,再调用virtualProtect去赋予shellcode可执行权限,以此绕过DEP保护。可以预见未来将会有很多flash exploit 采用类似技术,甚至可能在一些恶意样本中找到Hacking Team的Flash利用模板,未来的利用代码将会更加工程化,通用化。
     
  • 泄露的core-android-audiocapture一款Android平台下基于DBI Hook框架的语音窃取工具,可窃取当前国内外流行的即时聊天工具,比如wechat、whatsapp、skype等等。
     
    【源码分析】
     
    1、搜索 mediaserver 进程,然后注入libt.so,并将窃取的语音文件dump到指定目录。
     
     
    2、查看libt.c源码,其动态链接库的构造函数为my_init,这里参数和返回值都必须为空。
     
     
    3、检测当前的Android系统是否为4.x版本,然后分不同的子版本进行处理。
     
     
    4、比如对于Android 4.0版本,会指定mStramType和mname的偏移量,不同系统版本对应的偏移量不同,同时也定义一些将被hook的函数,这些Hook_coverage_x是定义在hijack_func/hooker.h中,对应的函数名在注释代码中已经写得很清楚,主要是Hook Android系统的audio接口提供库libaudiofinger.so里的函数,以用于实现录音(RecordThread)和放音(PlaybackThread)功能。
     
     
     
     
    5、以Hook回调函数recordTrack_getNextBuffer3_h为例分析下它的修改行为,该函数定义在hijack_func/hooker_thumb.c中,原getNextBuffer获取的缓冲区主要是用于存放录音数据,而录音的开始、停止动作的相关函数也是被hook掉。在recordTrack_getNextBuffer3_h函数中先调用原始函数,得到返回后的结果,然后获取帧大小、采样率、帧数以及原始的AudioBufferProvider::Buffer地址。
     
     
    6、创建指定格式的文件名,将语音数据dump出来写入到前面创建的文件:
     
     
     
    7、录音Hook的日志记录如下,其它hook动作类似,此处就不一一分析。
     
     
    8、生成的dump文件,会再调用decode.py去转换成wav语音文件
     
     
     
    【结语】
     

     
         网上有人说这工具会去解密微信的语音格式,其实它根本没有做这方面的处理,也没必要,因为它Hook的Android系统的Audio库,当你使用一些即时聊天工具进行语音对话时,就会触发放音的函数,此时语音数据早就可以拿到,而decoder.py只是作一些wav的格式化处理,使得dump出来的文件能够转换成可播放的wav文件。在decoder目录下的一些聊天工具目录,只不过是Hacking Team成员在作一些测试而已。