分享
 
 
 

透视RPCDCOM第二个接口漏洞(2)

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

Windows DCOM漏洞分析

有了上面的基础知识,我们可以来看一下Windows的DCOM漏洞究竟是怎么产生的。对于远程调用一个对象的接口,一般来说我们使用CoCreateInstanceEx这个API函数,这个函数有一个COSERVERINFO*pServerInfo的参数,这是一个结构,在其中的LPWSTR pwszName域我们填入远

程主机的主机名或IP地址。这样就可以创建某个对象的接口的实例。除了CoCreateInstanceEx之外,系统还提供了另外一个名叫CoGetlnstance FromFile的API来进行同样的操作。CoGetlnstance FromFile除了完成CoCreateInstanceEx所做的工作之外,还从一个指定的文件里面读出内容。然后按照文件内容对接口进行初始化。

这些都是在系统提供的COM API上所做的事情,而COM API首先发送RPC包来调用远程系统的IRemoteActivation接口来激活指定对象。对于Windows 2000以前的操作系统,直接绑定到IRemoteActivation接口就行了,而Windows2000以及后来的系统,都要首先绑定到ISystemActivato,这个接口上面 ,然后才会调用系统的IRemoteActivation接口。注意,这些接口并不是某个COM对象导出的接口,而是RPC上的DCOM接口。IRemoteActivation这个接口只有一个名为RemoteActivation的函数,它的作用就是激活某个指定对象的指定接口,函数原型如下:

其中包含众多的参数,大多数都是用于指定对象以及接口特征的。目前所公布的两个漏洞都是服务端的RemoteAchvaton函数的内部实现造成的,其中pwszObjectName这个参数就是CoGetInstanceFromFile函数所传入的文件名参数,由于对UNC文件名进行解析的时候对长度检查不够,所以造成了一个堆栈溢出和一个堆溢出。

下面我们就来分别看一下这两个漏洞。

1.MS03-026堆栈溢出漏洞分析

最早LSD所发现的就是这个漏洞,微软在MSO3-026安全公告里面指出这是一个堆栈缓冲区溢出漏洞,其后flashsky分析出了这个漏洞的触发原理。

首先当我们调用CoGetInstanceFromfile函数时,OLECHAR*szName参数可以指定一个UNC路径表示的文件名,即\\主机名\\共享名\\文件名"的形式,这个调用就会首先发送到远程主机的ISystemActivator接口上,然后ISysbmAtivator再调用把UNC路径表示的文件名字符串作为IRemoteActivation接口的RemoteActivation函数的pwszObjectName参数来传入。当其中主机名字符串的长度超过0x20的字节的时候会造成系统RPC进程溢出,可以覆盖函数的返回地址或着异常处理指针。

想要触发溢出的话,就不能简单的通过给CoGetInstanceFromFile函数传递超长文件名,因为CoGetInstanceFromFile首先要检查该函数是否可以在本地进行访问,如果不能的话,就不会向远程主机发送RPC包了。而Windows对主机名的长度是有限制的,因此我们也无法设置一台主机的主机名超过0x20个字节,所以就只能通过手工构造RPC数据包的办法来触发溢出。对于包的结构,flashsky发布的Exploit给出了一个通过调用ISystemActivator接口传入长字符串的包,其中除了要改变UNC文件名中的主机名长度之外,还要设置几处结构的长度。但是这个包还会触发一个RPC的DoS的漏洞,所以有时候调试的时候多发几次这个包(UNC路径不超长的)也会把RPC服务给当掉。其实我们直接调用IRemoteActivation接口就行了,包的长度小了很多,其中的结构长度也少很多。这里给出一个用于测试的小程序,就是直接给IRemoteActivation接口的RemoteActivation函数传入超长字符串:

这个程序非常简单,它的作用就是发送指定长度的字符串到远程主机,默认长度是0x28字节的长主机名。这时候远程主机会报错误,如果这时我们在远程主机上面运行了调试软件,就会发现出错的位置是在下面我们提到的地址。

通过反汇编C.入WTNNT\System32\下面的rpcss.dll文件我们就可以发现其中的秘密。

从反汇编后的代码可以看出,这是一个非常典型的堆栈缓冲区溢出,而且没有长度限制,通过调试,察看fs:0指向的异常处理指针的位置可以发现,在从主机名字符串偏移为0x600的位置是异常处理指针,此时我们就可以很容易的使用如下字符串来覆盖异常处理指针:

|AAAAAAAAA...|jmp

8|jmp ebx|NOPNOPNOP...shellcode...|

这样当GetPathForServer函数返回的时候会返回到0x41414141,因为这个地址是一个非法地址,所以就会触发异常,从而跳到异常处理指针+4的位置执行,也就是我们用系统中存在的jmp ebx或call ebx地址来覆盖的位置,这时ebx寄存器指向前面的jmp8,用这个指令来跳过后面的jmp ebx地址,从而执行到shelIcode当中。

具体的攻击代码就不现赘述了,网上有许多可以用的代码,惟一的区别就在于jmp ebx地址的通用性和shellcode的不同。当然,也有一些程序是通过覆盖返回地址来实现的,这样通用性就比较差了。

2.MS03-039堆溢出漏洞分析

除了LSD发现的这个堆栈溢出之外,IRemoteActivation接口还存在另外一个溢出漏洞。eEye在LSD公布第一个RPC漏洞之后不久就发现了这个漏洞虽然也是在IRemoteActivation接口在处下UNC文件名时出现的问题,但是它并不是堆栈溢出,而是一个堆溢出,这样就大大的增加了利用漏洞的难度。

当把UNC路径表示的文件名,即"\\主机名\共享名\文件名"中的共享名和文件名指定为超长字符串的时候会触发这个堆溢出漏洞。我们首先来看一个这个溢出是怎样发生的。

同样的在GetPathForServer函数中,当拷贝完了主机名之后,会对主机名作一下判断。

也就是判断主机名是本主机名或是"localhost"或"127.0.0.1"其中之一的时候才会继续后面的操作,所以我们要想触发堆溢出,必须把主机名设为以上字符串中的一个。后面的操作就是分配一块内存,然后使用lstrcatW函数把文件名拷贝进去。

大家可以看到,这里由于没有判断IstrcatW的长度,所以会造成堆溢出。虽然溢出本身没有什么限制,但是由于堆溢出的特殊性,所以利用起来相当困难。这也就是目前所公布的针对RPC DCOM2漏洞的攻击程序都不是非常通用的原因。

首先我们来看一下这个堆溢出为什么可以被利用。我们知道,由于Windows使用双向链表进行堆的管理,所以动态分配的内存块之间都是不连续的。当分配一块内存的时候,会在固定大小的内存之后多分配出几个字节用于存放链表指针,这样当下一次再分配或者释放内存的时候就会用到这些指针。比较特殊的是,无论是分配还是释放,都会把其中一个指针的地址写到另一个指针中去。这就是堆溢出可以利用的原因了,因为溢出的时候,我们可以把堆后面的管理结构覆盖掉,这样我们就可以有控制地把任意4个字节的内容写到任意地址当中去,示例如下图所示。

RPC的堆溢出也是这样,在共享和文件名偏移为0x230的地方可以覆盖到堆的管理结构,会把0x234开始的4个字节的内容写到0x230所包含的地址的地方。根据目前堆溢出的利用理论,一般都是把可以定位shellcode的地址写入顶层异常处理指针中去。顶层异常处理指针就是系统的SetUnhandledExceptionFilter函数来设置的一个二级指针的位置,当发生异常时,首先会调用这个指针所包含的地址的代码,然后才会逐步进入程序中的异常处理代码。所以只要我们把顶层异常处理指针位置写人shellcode或者能够定位sheUcode的地址,这样当后面发生异常的时候就可以跳到shellcode当中去执行了。

虽然理论上比较简单,可是想要写出通用的攻击程序却是非常困难,因为首先顶层异常处理指针在不同语言、不同SP补丁。不同版本的Widows系统当中都是不固定的,甚至打过不同的补丁,都会造成这个地址的改变,这样就不可能对所有的系统使用统一的地址。这还只是攻击程序不能通用的原因之一。另外,想找到通用的定位shellcode的地址的方法也绝非易事,一种思路就是通过使用大量NOP+shellcode的方法来把返回地址尽量放在中间,这样可以达到一定的成功率。另一种思路,就是像普通堆栈溢出一样使用一个固定的跳转地址来定位shellcode。根据immunitysec的DAVE的研究成果,当进入顶层异常处理代码的时候,ebp+0x74和edp+0x74的位置存放着可以shellcode的地址。这样我们可以在内存当中寻找包含[ebp+0x74或者jmp [ebp+0x74这样指令的地址,用这个地址来覆盖顶层异常处理指针,同样可以返回到shellcode当中。幸运的是,在中英文版的Widows2000系统中都可以找到这样的地址。

当然困难还不仅仅是这些,由于溢出发生在线程默认堆中,所以堆的链表结构被破坏了,因此我们所能使用的shellcodc受到了极大的限制。这是因为shellcode要使用系统API函数,而系统API函数一般都要使用线程默认堆来分配内存,所以一旦默认堆被破坏,系统API函数就无法成功调用了。目前解决这一问题的办法就是在shellcode中首先使用HeapCreate函数来创建一个堆,然后用这个堆的地址来替换掉TEB结构当中的默认堆地址。但是这样使用winsock函数仍然会出现问颧,因为winsock函数会使用一些特殊机制来得到线程默认堆地址,所以目前的攻击程序都只能使用不带网络连接功能的shellcode。

解决了以上难题之后,我们就可以来看看如何构造超长字符串来利用这个溢出漏洞了:

|NOPNOPNOP....sheUcode|NOPNOPNOP...jmp back||顶层异常处理地址|call[ebp+0x74]|

这样用顶层异常处理地址和call[ebp+O074]地址覆盖掉堆内存后面的链表指针之后,当释放这块内存或着再次分配内存的时候,就会把call[ebp+0x74]地址写入

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有