二进制文件静态分析漏洞挖掘技术-BinAbsInspector

前言

关于如何对源代码进行静态分析漏洞挖掘的工具和教程还是比较多的,至于二进制文件就比较少。去年科恩实验室发了一个开源的针对二进制文件的漏洞扫描工具BinAbsInspector,所以前一段时间也就简单看了一下。我这里会先总结一下《WYSINWYX:What You See Is Not What You eXecute》这篇论文,这篇论文非常经典,BinAbsInspector也是参考它实现的,然后再简单分析一下代码。这篇blog真的非常难写,花了很多时间感觉也不是写的很好,因为这一块的知识比较欠缺也不好学。

论文导读

论文感觉写的有点晦涩,本来其实用大白话说还是比较好理解的,乱七八糟的公式和符号一堆看的头疼,我就尽量提炼一下。

我们首先想分析二进制程序比分析源代码难在什么地方?二进制文件里面全是汇编代码,没有源代码中的变量,因此不好分析。所以第一步就是从汇编代码中恢复出抽象变量(ALoc),通过{区域,长度,起始地址}的三元组来表示。这里“区域”可以有:堆,栈,全局等几种。抽象变量会有一个可能的抽象值(AbsVal)的集合(KSet)。从ALoc到KSet的映射组成了AbsEnv(Abstract environment)。

这里用论文中的例子:

ppmDdeS.png

对于这样一个程序,ALoc如下:

ppmDsWn.png
(FormalGuard和LocalGuard表示边界)

在指令L1, 8和指令14处的KSet如下所示:

ppmDNsf.png

语法:
(2[1, 9], ⊥)代表数值集{1, 3, 5, 7, 9}以及地址集{(Global, 1), (Global, 3), … , (Global, 9)}
(⊥, 8[-48, -40])代表地址集{(AR_main, -48), (AR_main, -40)}

KSet是如何计算的呢?下图是具体的算法,其中R1和R2是两个大小相同的寄存器,c、c1和c2是显式整数常量,≤和≥表示有符号比较:

ppmDtQP.png

比如R1 = R2 + c,假设R2的KSet是(4, 4[4, 12]),c=12,那么R1的KSet就是(16, 4[16, 24])。这个计算的过程在论文中叫做抽象转换器(AbstractTransformer)。

对于单个函数且不存在间接跳转的情况,算法如下:

ppmDwdg.png

简单来说就是按照CFG的顺序一直算,算到不动点为止。

接下来就开始考虑存在间接跳转的情况(非上下文敏感)。这个时候需要在调用、结束调用、进入和退出节点之间添加边。例如P的起始地址分别为A,B,在C处调用P,就需要添加三条边:C到A(call→enter);B到C的下一条指令(exit→end call);C到C的下一条指令(call→end call)。

我们再用下面这个程序作为例子:

ppmD0oQ.png

对于这样一个程序,ALoc如下:

ppmDDij.png

1.call→enter

算法如下图所示(把调用方的实参复制到被调用方的形参):

ppmDrJs.png

例如在进入initArray时,此时的KSet如下图所示:

ppmDcQ0.png

(区域的顺序为Global, AR_main, AR_initArray)

2.exit→end call/call→end call

算法如下图所示(进行一个合并操作):

ppmDyzq.png

最终非上下文敏感的过程间的Propagate函数如下图所示,第一个参数从Node n修改成了n到succ的边。

ppmDgyV.png

非上下文敏感的精度肯定是远远不如上下文敏感的,那在考虑上下文敏感的情况下如何计算呢?论文中用的是callstring的方法。例如考虑下面这样一个程序:

main—yyy—aaa/bbb—ccc

main函数在0xY处调用yyy函数,yyy函数根据不同的条件会在0xA处调用aaa函数或者0xB处调用bbb函数,aaa函数和bbb函数分别在0xAC处和0xBC处调用ccc函数。

此时就用两个callstring:[0, 0xY, 0xA]和[0, 0xY, 0xB]来表示ccc函数被调用时不同的上下文。

之后论文还谈到了ASI算法(Aggregate Structure Identification),ASI算法是将每一个结构体当成一个给定长度的一系列字节集,依据内存访问方式分解。回到我们最开始的图中的程序,ASI算法恢复出的结构体如下图所示(这个应该还是比较好理解)。和前面的算法结合迭代,得到更精确的AbsEnv。

ppmDUL8.png

BinAbsInspector

先参考一下github上的技术细节:https://github.com/KeenSecurityLab/BinAbsInspector/wiki/Technical-Details

前面已经说了这是一个ghidra的插件,ghidra的中间语言是pcode,通过varnode概括寄存器或内存位置,pcode对varnode进行操作,varnode由:地址空间、偏移量、大小组成,是不是听起来非常熟悉?BinAbsInspector里面的ALoc就是把varnode包装了一下,基本可以理解成一个东西,所以其实已经简化了一些工作量了。而AbsEnv就是一个hashmap,把ALoc和KSet关联起来。

先简单过一下每个class的大致功能:

CallGraph.java: 调用图
CFG.java: CFG
ConstraintSolver.java: 通过Z3进行约束求解(感觉作用不是很大,本来也可以disable掉)
GraphBase.java: 提供对图进行操作的函数
InterSolver.java: 过程间分析
Worklist.java: 保存需要处理的CFG
region目录:表示不同的”区域”,例如Heap.java表示Heap,其中boolean类型的valid表示Heap空间是否有效
funcs目录:对C库函数和std函数调用的处理,比如调用free之类释放内存的函数时就需要把Heap空间的valid设为false,而调用malloc之类分配内存的函数时就需要把Heap空间的valid设为true,以检测UAF等漏洞
Context.java: 基于callstring实现上下文敏感的分析
有两个Stack用来存储context,active和pending。从popContext函数中可以看出只有当active stack处理完了才处理pending stack。整个程序运行的流程是从mainLoop中开始的,一个context中的worklist空了之后就调用popContext函数取下一个context。
还是考虑前面解读论文时举的例子:
main—yyy—aaa/bbb—ccc
mainLoop中context一共会switch 10次:(1)main调用yyy,(2)yyy调用aaa,(3)aaa调用ccc,(4)ccc返回,(5)aaa返回,(6)yyy调用bbb,(7)bbb调用ccc,(8)ccc返回,(9)bbb返回,(10)yyy返回。
首先是在initContext函数中将入口点地址插入worklist,正常情况下visit完一条指令将下一条指令加入worklist,除此之外还有处理RETURN指令的时候会将调用点的地址加入worklist;处理CALL指令的时候会将call指令所在的地址加入worklist(这两个一样);处理分支指令时将两个分支的地址加入worklist
ContextTransitionTable.java: 使用Address到callstring数组组成的TreeSet的HashMap,在call/return指令中维护context的转换关系
TaintMap.java: 使用taintSourceToIdMap进行污点跟踪。taintSourceToIdMap是一个source到integer的map,source由callSite,context和function组成

接下来简单解释一下漏洞具体时怎么检测的,一共有两个地方,PcodeVisitor.java对pcode进行visit的时候,以及visit之后(checkers目录)。
visit时(我们看几个比较关键的):

1.visit_LOAD(visit_STORE类似)
1.1: 检查是否存在空指针解引用漏洞
1.2: 对于input1对应的KSet中的AbsVal
1.2.1: region为heap,调用checkUseAfterFree函数检查UAF,如果heap的valid为false,则证明存在UAF漏洞(读取已经被释放的内存)
1.2.2: region为heap或者local,调用checkHeapOutOfBound函数或者checkStackOutOfBound函数检查OOB
1.2.2.1: checkHeapOutOfBound: 如果AbsVal的offset为负或者大于region的size,则证明存在越界漏洞(越界读取)
1.2.2.2: checkStackOutOfBound: 类似
1.3: 设置output的KSet

2.visit_CALL
2.1: 对于external函数(基本是一些C库函数)调用invokeExternal函数去调用env/funcs/externalfuncs中的实现
2.2: 对于std函数调用invokeStd函数去调用env/funcs/stdfuncs中的实现
2.3: 在调用invokeExternal函数或者invokeStd函数之前调用checkExternalCallParameters函数检查函数的参数,是否有MemoryCorruption类的漏洞
2.4: 调用adjustLocalAbsVal函数更新AbsVal
2.5: 新建context,将新context加入worklist,将当前callSite和context放入ContextTransitionTable,将新context或当前context加入active stack或pending stack

3.visit_RETURN
3.1: 设置context的exitvalue(在return时的AbsEnv)
3.2: 根据ContextTransitionTable取出所有callstring,根据不同的callstring获取对应的context并将callsite加入到worklist
还是前面的例子,当处理到ccc中的return指令时,此时的callstring如果是[0, 0xY, 0xA]将0xAC加入到worklist;此时的callstring如果是[0, 0xY, 0xB]将0xBC加入到worklist

4.visit_INT_ADD/visit_INT_LEFT/visit_INT_MULT
这三个指令进行污点跟踪,输入源来自scanf/sscanf/fscanf/fgets/fgetc/rand/recv就表示可能会发生整数溢出,其他算数指令基本上都是对input的KSet进行相应的计算并给output

visit后:

以CWE78为例:对于system/popen/execl/execlp函数(下面以system函数为例),获取toAddress(system函数地址)和fromAddress(BL system指令的地址)和对应的函数callee和caller,调用checkFunctionParameters函数,checkFunctionParameters函数中对于caller的每一个context的每一个函数参数,如果:1.kSet为null并被污点标记;2.kSet不为null,其中存在AbsVal,包含此AbsVal的AbsEnv中的kSet被污点标记。则说明存在命令注入漏洞

总结

其实分析完一遍就知道,如果你是想拿着这个去扫然后就报一堆CVE走上人生巅峰可以说是不可能的。比较现实的还是自己编写规则查找相似漏洞捡漏的玩法,对于开源软件有codeql为代表的工具;对于二进制文件也可以借助IDA等反编译工具提供的脚本。不过相信看到漏洞挖掘完全自动化的那一天不会太远。

cisco设备CDP协议漏洞分析与挖掘

简介

去年还在研究挖洞的时候注意到了cisco设备的CVE-2020-3119漏洞,其实也是搞研究时间长了的一种直觉,觉得这个攻击面还可以再挖一挖,最终也是fuzz出一个DOS的洞CVE-2022-20625,也算还好吧,就简单分享一下。
注意:这篇笔记写于2021年4月向cisco报告漏洞之后,现在一些环境配置步骤等等可能已经发生变化。

环境搭建

固件提取有两种方法:一是搭建好环境之后ssh拷贝出固件;二是用How to mount a qcow2 disk image这里面的方法挂载qcow2文件,得到bin文件之后解压得到固件。我看参考的博客里面说第二种方法可以,但是我没有成功,我是用的第一种方法。

这里我们通过GNS3去仿真。我的环境是这样的:windows物理机上运行了VMware,在VMware里运行了GNS3 VM,在GNS3 VM里通过qemu运行交换机。然后VMware还运行了一个ubuntu虚拟机,在ubuntu虚拟机里面可以telnet到交换机和执行其他操作。建议windows物理机内存>=16G。

下载GNS3-2.2.19-all-in-one-regular.exe然后直接双击安装。勾选GNS3 WebClient和GNS3 VM。

GNS3 VM类型选择VMware Workstation。

因为要去下载虚拟机所以需要等待一段时间,也可以手动从gns的网站上下载。

安装完成启动之后选择Run appliances in a virtual machine。

其他全部默认即可,这里记得把CPU和RAM改大一点,因为运行交换机至少都需要8G。然后就会在vmware中打开GNS3 VM。

这个时候你看见GNS3 VM是绿色的说明就成功了。如果不是绿色的说明还有问题。

然后去gns3的网站上下载NX-OSv 9000的appliance。

点击File-Import appliance导入我们下载的appliance。

我们需要有对应版本固件的fd文件和qcow2文件。这个fd文件还是可以在gns3的网站上下载(https://docs-v1.gns3.com/appliances/cisco-nxosv9k.html), qcow2文件需要到cisco的网站上下载。

成功导入之后在switches中就可以看到了。然后我们新建一个project,把它拖进去,再在End devices中选择Cloud拖进去。我们把Cloud拖进去的时候可以选择宿主机或者GNS3 VM作为Server,这里选择GNS3 VM。

然后把它们连起来,再点击绿色的三角形启动设备。

从ubuntu的虚拟机里面用GNS3界面显示的telnet命令连接上去。

等待一段时间之后会让你输入yes/skip/no配置一个什么东西,我输的是skip。然后用用户名admin,密码为空就可以登录了。

最后需要配置交换机的ip地址。我们可以看到,我们设置连接的网卡是Ethernet 1/8,对应的MAC地址是0c:05:f5:bc:de:08。

找到这个MAC地址对应的网卡给它设置ip地址。

最后把ubuntu虚拟机上的公钥放到交换机的/root/.ssh/authorized_keys就可以用ssh登录了。有时交换机会crash掉出现No autoboot or failed autoboot. falling to loader这样的提示。目前没有找到好的解决方法,只能每次都重装一遍。如果有知道怎么办的师傅还希望能告知下。

漏洞复现

这里因为参考文章中都给出了非常详细的分析所以就不再赘述。根据参考文章得到一个非常简单的POC,效果如下:

漏洞挖掘

我们可以想一下如果是我们自己去挖怎么才能去挖到这个协议里面的漏洞。如果大家去复现了这个漏洞就会发现cdpd程序crash掉之后会自动重启并显示类似于Service “xxx” (PID 5883) hasn’t caught signal 11 (core will be saved)这样的信息。

那么这里我的想法就是dumb fuzzer,基于scapy实现的cdp去发变异的数据包。很多人特别是新手挖洞可能会有顾虑,特别是这种黑盒设备的网络协议fuzz不像在PC端有AFL之类非常完善的现成工具,一会儿想怎么去做代码覆盖率一会想怎么去做crash监控,其实没有必要,先把dumb fuzzer做出来,挖不到洞再完善。我给其他厂商报过的一些溢出的洞有的也是dumb fuzzer搞出来的。并且其实我觉得cdp协议的这种情况dumb fuzzer已经足够了,因为scapy实现的cdp已经足够完善,不存在说有了代码覆盖率的fuzzer能构造出的数据包dumb fuzzer就构造不出来;至于crash监控因为这个进程crash掉之后会自动重启,并且我也不熟悉这个设备,所以其实也没什么好的办法,只能人肉时不时看一下。

这就是我搞出来的crash:

接下来为了分析crash需要提取core dump。首先我们在ubuntu虚拟机上用vsftp搭建一个ftp服务器,这个很简单具体步骤就不说了。然后在交换机上启用interface vlan:

给它设一个IP地址,在ubuntu虚拟机里面能ping到就行。

这时就可以通过ftp把core dump拷贝到我们的ubuntu虚拟机上方便进一步分析。

1
copy core://<slot #>/<PID> ftp://<FTP IP addr>/<directory>/<filename>

参考资料

1.CDPwn系列之CVE-2020-3119分析

2.CVE-2020-3119 Cisco CDP协议栈溢出漏洞分析

3.How to select and download a Cisco switch core file

4.Retrieving Core files from Cisco Nexus switching platforms

new dll hijacking scenario found by accident

Speaking of dll hijacking, many people may think it is very useless.

Some times ago, I accidentally discovered vulnerabilities in dll loading mechanism in cisco webex teams/IBM Db2/VMware ThinApp that can lead to LPE, and as far as I know, no one has ever mentioned this kind of dll hijacking scenario before.

Vendor advisories:

VMware ThinApp update addresses a DLL hijacking vulnerability
Cisco Webex Teams Client for Windows DLL Hijacking Vulnerability
Security Bulletin: IBM® Db2® could allow a local authenticated attacker to execute arbitrary code on the system, caused by DLL search order hijacking vulnerability in Microsoft Windows client. (CVE-2020-4739)

Details I posted to full disclosure mailing list:

VMware ThinApp DLL hijacking vulnerability
IBM(R) Db2(R) Windows client DLL Hijacking Vulnerability(0day)
Cisco Webex Teams Client for Windows DLL Hijacking Vulnerability

I will not repeat the details of these vulnerabilities, I will analyze the dll path processing mechanism in ntdll.dll.

In document microsoft said:

The first directory searched is the directory containing the image file used to create the calling process (for more information, see the CreateProcess function). Doing this allows private dynamic-link library (DLL) files associated with a process to be found without adding the process’s installed directory to the PATH environment variable. If a relative path is specified, the entire relative path is appended to every token in the DLL search path list. To load a module from a relative path without searching any other path, use GetFullPathName to get a nonrelative path and call LoadLibrary with the nonrelative path. For more information on the DLL search order, see Dynamic-Link Library Search Order.

So…What will happen if we provide a relative path to LoadLibrary?

Let us take following code in VMware ThinApp as example:

1
LoadLibraryExW(L"\\DummyTLS\\dummyTLS.dll", 0, 0);

The process is:KernelBase!LoadLibraryExW->ntdll!LdrpLoadDll->ntdll!LdrpPreprocessDllName:

So RtlDetermineDosPathNameType_Ustr will return 4(RtlPathTypeRooted) and LdrpGetFulPath will return C:\DummyTLS\dummyTLS.dll. You can refer to code in ReactOS:https://github.com/mirror/reactos/blob/master/reactos/lib/rtl/path.c.

So now we know Windows will treat relative path in LoadLibrary/AddDllDirectory…as the path rooted relative to the current disk designator, which is usually C:\. Since non-admin user can create directory under C:\ and write file to it, this cause LPE.

I also reported my findings to MSRC, but MSRC said this is the default behavior. I am not surprised, if the default behavior is to let developers write vulnerable code, that’s fine.

I am sharing my discovery because I haven’t seen anyone mention these and similar vulnerabilities exist in other products absolutely. At the same time, I want to remind developers should make sure that all your dlls are loaded correctly.

Some thoughts:

1.I don’t understand why Microsoft handle path this way.

2.This kind of bug would not have appeared if developers had been more careful.

3.Using relative path is dangerous and I will share some RCE/LPE vulnerabilities I found because of relative path.

4.Non-admin user can create directory under C:\ and write file to it, this is not right and it caused many LPE vulnerabilities.

macOS和iOS逆向环境搭建

最近也在慢慢开始接触一些macOS/iOS安全,首先一个难题就是环境搭建。现在的情况是我有一台mac pro 13 2020和一个iphone8,分别记录一下vmware安装macOS虚拟机和iOS越狱降级这两个在调试macOS/iOS内核之前必须做的准备工作。

vmware安装macOS虚拟机

目前主要有两种方式搭建macOS虚拟机:
1.在macOS物理机上能够使用vmware fusion/virtualbox或者vagrant搭建macOS虚拟机,说起来倒是很简单:用vmware fusion应该不会有什么坑,用virtualbox也有人把要踩的坑总结好了:Run macOS 10.15 Catalina (and other versions) in VirtualBox on macOS。用vagrant参考偏执的iOS逆向研究员:收集全版本的macOS iOS+越狱+内核调试这篇文章即可。比较麻烦的是如果用vmware fusion/virtualbox的话sb苹果是不提供完整系统镜像的,得自己找;用vagrant的话又因为大家都知道的原因你得有一个很稳的梯子下那十几个G的镜像文件。
2.在linux/windows物理机上因为版权的原因默认是没有合法的手段让你装macOS虚拟机的,最最最常见的方法就是用unlocker patch掉vmware workstation pro然后安装macOS,当然镜像还是得自己找。推荐使用这个branch的unlocker:https://github.com/BDisp/unlocker/releases,当前最新的版本是3.0.3。这个branch的unlocker据我测试应该是能直接用不会有什么坑。不过这里还是要注意一个问题,unlocker中的gettools.exe会去下载com.vmware.fusion.zip.tar并且下载速度很慢,我们可以先去把这个包下好,下载的地址是到http://softwareupdate.vmware.com/cds/vmw-desktop/fusion找你用的vmware workstation pro对应的版本即可。更改gettool.py的代码,把下载com.vmware.fusion.zip.tar的代码注释掉,用pyinstaller重新打包一个gettools.exe。以管理员权限运行win-install.cmd,在time.sleep(20)的时候把下载好的com.vmware.fusion.zip.tar拷贝进tools目录即可。

接下来就可以安装macOS了,这里我用的镜像是网上找的一个10.10.2的,如果提示你”没有足够的空间来进行安装”按照网上的方法抹掉vmware的硬盘即可:OS X Base System 上没有足够的空间来进行安装。除此之外我没有遇到任何问题。

最后就是安装VMware Tools了,gettools.exe已经下载好了darwin.iso和darwinPre15.iso,我的vmware workstation pro是15.5.1版的,应该用darwinPre15.iso。

关闭虚拟机,编辑虚拟机,设置CD/DVD,使用ISO映像为darwinPre15.iso。开启虚拟机之后会看到桌面的VMware Tools,直接安装就OK了。

很多时候如果你发现github上某个工具因为已经没有维护而不能使用的时候一个小技巧就是去看看issue或者pull request里面有没有人还在继续维护。本来最先搜到的是https://github.com/theJaxon/unlocker,因为没有维护了所以遇到一点问题,在pull request里面找到了另外有人维护的https://github.com/BDisp/unlocker。去年也是,升级了vmware workstation pro之后https://github.com/sysprogs/VirtualKD也没法用了,在issue里面找到了另外有人维护的https://github.com/4d61726b/VirtualKD-Redux。想学习MachO文件格式,https://github.com/gdbinit/MachOView早已无人维护,在issue里面找到了另外有人维护的https://github.com/mythkiven/MachOView……感谢这些编写维护开源软件的大神,不然这些问题真是让人够头疼的。

iOS越狱降级

首先肯定大家都明白越狱是个什么意思,就和你研究android安全肯定需要有一台root过的手机一样,我们也需要一台越狱的iPhone。不过越狱有四种。

完美越狱(Tethered Jailbreak)
不完美越狱(Untethered Jailbreak)
半完美越狱(Semi-tethered Jailbreak)
半不完美越狱(Semi-untethered Jailbreak)

我画了个图,你一看就明白了。tether是拴绳拴链的意思,tethered就是需要数据线连电脑,untethered就是不需要数据线连电脑。

如果你不知道你的iPhone能不能越狱,你可以到这个网站上查:https://canijailbreak.com/

一看之后你就会发现这几年出的越狱都是半不完美越狱,因为现在苹果的保护措施越来越完善,完美越狱有当然是有,但是能值很多钱,人家不会公开。这几年越狱界最大的新闻就是被称为史诗级漏洞的checkm8了,因为这个漏洞存在于BootROM中,无法通过软件更新的方式修复,所以理论上来讲只要你的iPhone在受影响的设备范围内,不管你怎么升级系统都能用这个漏洞越狱。我们直接去https://checkra.in/下载越狱程序按照上面的说明来就可以了。越狱之后该在Cydia里面装什么等等网上都有很多文章了,这里就不再说了。

接下来说说怎么降级。降级不是你想降就能降的,iOS设备上的固件恢复需要配合Apple服务器进行校验,Apple停止公开验证某个固件版本时,iOS设备就不能从高版本恢复到停止验证的版本。iOS在更新设备固件的过程中会将设备的ECID等信息以及一个一次使用的nonce发送给Apple服务器,服务器在校验通过后会返回校验结果,结果使用非对称算法加密,在没有私钥的情况下无法解密也无法伪造。但是我们可以将校验结果保存下来,之后Apple不再提供此版本校验的时候重放校验过程,实现iOS降级到不提供验证的版本。

说了一大堆可能有点晕了,我们来实际操作一下。现在Apple只会验证最新的iOS 14.0.1版本,我的iPhone8是iOS 13,因为我以前没有保存校验结果,所以理论上现在我没有任何办法将我的iPhone8降级到一个更低的版本。但是现在我可以保存14.0.1的校验结果,假设说以后我的iPhone8升级到了iOS 14.0.2,理论上我就可以通过这个保存的校验结果降级到14.0.1。

首先checkra1n越狱之后我们添加repo:halo-michale.github.io/repo/,安装插件Generator Auto Setter,默认会写入Generator值为一串0x1把nonce固定,这样也方便我们以后降级。然后我们打开爱思助手查ECID:

点击查看设备详情查硬件模型:

然后到https://tsssaver.1conan.com/把这些信息填进去点击submit,就可以下载shsh2文件了。在将来的某个时候如果想降级到这个版本我们可以使用futurerestore,在设备进入kDFU/pwnDFU模式之后用像这样的命令完成降级:

./futurerestore -t xxx.shsh2 –latest-sep –latest-baseband xxxx.ipsw

更新的iPhone和iOS操作似乎还有些不一样,以后如果需要的话再补充。

不过这还没完,苹果还有一个SEP机制(Secure Enclave Processor,安全区域处理器),如果降级的iOS系统与当前的SEP不兼容,那么降级会被禁止。iOS13范围内SEP都是兼容的,那么你只要备份过对应版本的shsh2文件,就可以在iOS13范围内降级。但是网上我看说如果你升级到iOS14,即使有iOS13的shsh2文件就会因为SEP不兼容无法降级。

所以iOS的越狱降级这些还真的挺头疼的……

最后再扯下如何入门macOS/iOS安全,经过一段时间的探索我有如下想法:

1.学http://www.newosxbook.com/index.php上的三本书,建议海淘。国内那些写macOS/iOS的书我翻了几本得出的结论是都不用买。当然就这么看肯定是非常枯燥的,所以我建议有时间就翻翻,一次也不用看太多。

2.学习各种出现的macOS/iOS漏洞,主要是project zero的。

目前我也是积极在整理这些历史漏洞:https://github.com/houjingyi233/macOS-iOS-exploit-writeup

3.从推特或者关注的大牛那里获取一些他们的研究成果然后学习。

如果遇到其它环境方面的问题我也会继续在这篇文章里面更新,2020年争取也写一些macOS/iOS漏洞研究方面的文章!

一次给爱奇艺SRC报告漏洞的经历

先给大家看看时间线吧(漏洞已经被修复):
2020-01-06:发现爱奇艺客户端某个需要用户发生交互的场景可以导致远程代码执行,报告到爱奇艺SRC
2020-01-08:发现报告被关闭,留言反馈
2020-01-09:发送邮件到71src@qiyi.com
2020-01-09:爱奇艺SRC负责人表示审核人员看错了,让我重复提交一次
2020-01-10:重新提交了漏洞
2020-02-21:通过QQ向爱奇艺SRC运营反馈这个漏洞不应该被评为中危应该是高危,对方表示会讨论
2020-03-06:再次通过QQ向爱奇艺SRC运营询问,对方表示还没有上班
2020-04-01:再次通过QQ向爱奇艺SRC运营询问,对方表示这周之内答复
2020-04-03:和爱奇艺SRC运营讨论交流,对他们的工作提出了批评和质疑,对方补发了金币和奖励

我不能理解的事情有这么几个:
1.市值上百亿美元的美股上市公司审核漏洞为何如此随意?一个能影响爱奇艺windows客户端至少几百万用户的高危漏洞能被审核人员看错直接忽略?我在漏洞下面留言没有回应,直到我发邮件询问。爱奇艺SRC的运营流程和审核人员工作的专业和态度为什么有这么严重的问题?

2.为什么我联系爱奇艺SRC运营详细说明了我认为为什么应该评高危而不是中危之后,仍然一直不给我答复,期间我不得不两次询问?

3.我和爱奇艺SRC运营沟通的过程中一直保持文明礼貌,克制自己的情绪,爱奇艺SRC运营为什么给我发送了一个微笑的表情?

4.为什么不给我道歉?是不是爱奇艺SRC觉得白帽子好欺负还是爱奇艺SRC觉得自己很牛逼不需要道歉又或者是爱奇艺SRC觉得自己什么也没有做错?

我那天在朋友圈吐槽完了之后觉得还没有发泄够,于是给71src@qiyi.com发了邮件,问了他们这几个问题,同时我也问他们爱奇艺SRC存在的意义是什么?是觉得其它公司有所以我们也要有糊弄一下就行给老板做一下样子还是真的觉得安全问题很重要?

因为我不想再理这群人,所以我邮件里面说请你们不要回复我。之后爱奇艺SRC负责人在之前拉的群里说可以给我补偿一张爱奇艺年卡激活码,当然仍然没有道歉。我不想理他,他加我QQ好友我也没通过,因为我作为一名安全研究人员已经被这家SRC侮辱到体无完肤,我很担心他对我继续进行侮辱。

我虽然穷但是我不是为了钱,我只是想讲道理。开始认定中危给了我100个积分,死皮烂脸扯了这么久补发了我100个积分,按照爱奇艺SRC上的规定相当于能换300块+300块的京东卡,我特么还真的不在乎。不是说嫌钱少,甲方做安全可能资源是有限的,钱少不是不可以理解,但是该高危为什么要评中危?我也明确承认是需要用户交互的,无意夸大漏洞危害,无交互就应该是“严重”而不是“高危”了。

前段时间一篇文章有人吐槽微博一个漏洞在微博SRC换了一条毛巾。不管是低廉的奖励,不公正的漏洞定级甚至是对安全研究人员言语上的不尊重等等种种侮辱行为我都不是第一个遭遇的,也不会是最后一个,那为什么会出这种事情?

我觉得是跟大环境有关。project zero经常因为90天内厂商没有修复漏洞就披露细节,还有前两年像sandboxescaper这样windows的0day一个接着一个发的。国内你要是敢这么玩轻则被约谈喝茶,重则涉及到的厂商直接起诉你。所以国外厂商普遍也更重视SRC建设,白帽子劳动成果能得到尊重,因为你把人家惹到了直接发0day所有人都会看你笑话。而国内厂商料定白帽子不敢披露漏洞,于是就对白帽子进行各种侮辱。

看起来好像对白帽子披露漏洞不加限制更加危险,实际上是好处大于坏处的。真正像sandboxescaper这样一心搞破坏的人几乎可以忽略不计(看他推现在也好像是被微软招安了),绝大部分白帽子厂商给了足够的金钱和尊重都不想搞出什么事情。为什么规则应该倾向白帽子还有一个原因是白帽子面对厂商是弱势群体。国内厂商之间各种报团,很多SRC漏洞评价标准都是一起制定的,经常各种开会扯淡拉关系,而白帽子之间很难形成一个类似于工会的组织维护白帽子的权益。不爽了也就只能发个帖子吐吐槽,不然还敢怎么样呢?

这几年网络安全这一行好像还挺火,一直有新人干这行,虽然时不时有白帽子和SRC扯起来但是大大小小的SRC也不愁没有人来报洞。但是国内白帽子这样的生存环境一直持续五年十年之后呢?

更新:不知道为什么爱奇艺SRC的负责人在我写这篇博客的当天就看到了然后来找我了。我不想再说这件事情了,到此为止。

给linux内核提交代码

关于如何给linux内核提交代码这个问题其实有官方的非常详细的文档,网上也有很多文章。但是这些文档要么就是太长读不下去要么就是缺乏关键步骤。因为给linux内核提交代码不是在github上pull一个request就完事了,你想想代码那么多,大家天天去pull request人家Linus Torvalds也看不过来。linux内核每个模块的代码是有不同的人负责的,我们想要提交代码需要把patch通过邮件发给对应的维护者。我第一次看如何给linux内核提交代码的官方文档的时候看了下文章长度几乎都想放弃提交了。今天刚好看到一个觉得可以提交的点,所以做一下记录,希望我写的步骤尽量简洁。

首先安装几个必要的软件:sudo apt-get install esmtp mutt vim git

vim和git就不用说了,esmtp是mstp的拓展,mutt是linux下收发邮件的程序。

在home目录下创建下面几个配置文件。

.muttrc

1
2
3
4
5
set sendmail="/usr/bin/esmtp"
set envelope_from=yes
set from="Your Name <[email protected]>"
set use_from=yes
set edit_headers=yes

.esmtprc

设置文件权限:

1
2
chmod g-rwx ~/.esmtprc
chmod o-rwx ~/.esmtprc

文件内容如下:

1
2
3
4
5
identity "[email protected]"
hostname smtp.gmail.com:587
username "[email protected]"
password "ThisIsNotARealPassWord"
starttls required

.gitconfig

文件内容如下:

1
2
3
[user]
name = Your Name
email = [email protected]

如果你用的是gmail,在“设置”->“转发和 POP/IMAP”中勾选“启用 IMAP”并保存更改。

需要注意的是这些配置文件中应该用相同的邮箱和姓名,姓名最好填自己的真实姓名,不要填一个奇奇怪怪的。然后我们把内核代码clone下来。

1
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

备份原来的文件,修改,生成patch。

1
2
3
4
5
6
7
8
SRCTREE= linux
MYFILE= drivers/net/mydriver.c

cd $SRCTREE
cp $MYFILE $MYFILE.orig
vi $MYFILE # make your change
cd ..
diff -up $SRCTREE/$MYFILE{.orig,} > /tmp/patch

git status命令查看改变了哪些文件。

git diff命令查看具体修改的内容。

git add命令将要提交的文件的信息添加到索引库中。如果再运行git diff命令就看不到之前修改的文件了。运行git status命令可以看到提示信息由Changes not staged for commit变成了Changes to be committed,文件名也由红色变成了绿色。

如果此时想放弃这次修改,可以使用git reset <file>移除已经添加到索引库中的改变。使用git commit -s -v命令提交我们的修改,此时会添加Signed-off-by:这一行。然后我们需要写清楚为什么要这么改。第一行写上”更改的子模块”+”: “+”简要描述修改的内容”。然后接下来再详细描述。

使用git show HEAD命令查看我们的commit。使用git format-patch -o /tmp/ HEAD^生成patch。

检查下有无格式错误。

看看应该发邮件给谁。

前两个maintainer是收件人,需要抄送给open list。我们最好先给自己发一封邮件再次确认一切无误。

好了,现在可以发邮件了。之后就是等待给我们回复,可能会接受我们的commit,可能会拒绝我们的commit,可能会要求我们再修改,这都很正常。接受我们的commit之后还需要等一段时间才会被加入内核代码。到时候你会还收到邮件。比如我的commit是6月19日被接受的,7月2日被加到4.14/4.19/5.1-stable tree中。

如果你用的不是gmail或者不想用mutt一些步骤可能会不太一样。建议参考下面两份官方文档。

1.FirstKernelPatch

2.Submitting patches: the essential guide to getting your code into the kernel

读《Malware Data Science》

今年一直在强迫自己有空多看点书,会慢慢分享一些读后感。

《Malware Data Science》这本书读之前我的期望比较高,虽然我没打算深入做这个方向,但是现在太多关于病毒分析的书了,写来写去都是那些东西,有这么一本从数据科学的角度讲病毒分析的书感觉很难得。但是大致读完之后,还是有点失望。满分100分只能打个60分,个人觉得属于读不读都可以的那种。

这本书一共有12章,第1章是介绍,第2章是静态分析,第3章是动态分析,可以直接跳过。下面重点说第4章到第12章。

第4章:教你怎么画图来识别攻击活动。书上举的两个例子一是把相同CC的样本连在一起,二是把含有相同图片的样本连在一起,分别用的APT1和木马样本。大概效果像下面这样。

大家都懂的,想看的话就别指望国内出翻译版了。

这种系统首先就是大名鼎鼎的virustotal的VTgraph了,virustotal官方还出了个virustotal的教程:https://storage.googleapis.com/vt-gtm-wp-media/virustotal-for-investigators.pdf

国内这样的系统还有腾讯的安图,前几天它们一篇文章中判断今年几个影响恶劣的病毒团伙背后是同一个犯罪组织:https://mp.weixin.qq.com/s/tmNYp1WHtUxYRE3aRQNUeA

当然还有360网络研究院大数据关联平台和360威胁情报中心(现更名为奇安信威胁情报中心)威胁分析平台:https://ti.360.net/blog/articles/apt-c-27-(goldmouse):-suspected-target-attack-against-the-middle-east-with-winrar-exploit/

还有微步在线等平台,就不一一列举了。

第5章:共享代码识别,这个其实是很有用的一个功能。比如为什么说VPNFilter与BlackEnergy有关,因为它们都用了相同的方式去修改RC4算法进行加密,如果在分析的时候有这样一个共享代码识别的系统,样本扔进去就跑出来识别出共享了BlackEnergy的代码,能省很多精力和时间。这样的系统目前intezer有一个。

这个是免费的,花钱可以有更多高级功能。

书上说了有这么几个方法识别二进制文件共享代码:汇编指令,字符串,IAT表,动态API调用。我估计intezer大概主要也就是汇编指令和字符串。最后基于字符串做了一个简单的命令行查询系统。

还有一个开源的IDA插件Kam1n0,是2015年IDA插件大赛的第二名:https://github.com/McGill-DMaS/Kam1n0-Community

第6章:扯了一些机器学习的概念。介绍了机器学习的步骤,特征空间和决策边界概念,模型的过拟合和欠拟合问题,和几个机器学习的算法:逻辑回归,KNN,决策树和随机森林。

第7章:扯了一些机器学习的评价指标。TP、TN、FP、FN,ROC,Precision,TPR,FPR等等。懂机器学习的话,这两章可以直接跳过。

第8章:先用是否被加密和压缩这两个指标作为特征,决策树作为算法写了一个判定恶意文件和正常文件的很简单的示例代码。然后实现了一个更接近实际用的,提取字符串作为特征,随机森林作为算法。

第9章:可视化,教你怎么画一些比较高大上的图,随便截了几张。

第10章:扯了一些深度学习的概念。神经网络原理是什么,怎么训练神经网络,最后介绍了几种神经网络:前向神经网络,卷积神经网络,自编码神经网络,生成对抗网络,循环神经网络和残差网络。懂的话也可以直接跳过。

第11章:用神经网络检测恶意HTML页面。

第12章:怎么成为一个数据科学家,随便扯扯。

数据科学用于病毒分析当然能做很多有趣的事情。但是打60分的原因是觉得翻翻还是可以,例子都太简单了,机器学习/深度学习这种玄学类的东西,举那么简单的例子基本等于没有举,真正用于实践会遇到很多问题。

其实我是买了书的,但是纸质看起来不太方便,又找了好久才找到pdf,想看看这本书又找不到pdf的话:aG91amluZ3lpMTU5。

个人博客正式上线

大二的时候开始写博客,现在觉得还是应该有一个自己的网站,希望能自己总结知识的同时帮助别人学习:)