improved local interface selection when exploiting
This commit is contained in:
parent
d2203b2220
commit
b3322b2541
|
@ -292,7 +292,7 @@ class RdpExploiter(HostExploiter):
|
|||
LOG.info("Trying RDP logging into victim %r with user %s and password '%s'",
|
||||
host, self._config.psexec_user, password)
|
||||
|
||||
LOG.info("RDP logged in to %r", host)
|
||||
LOG.info("RDP connected to %r", host)
|
||||
|
||||
client_factory = CMDClientFactory(self._config.psexec_user, password, "", command)
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import os
|
||||
import sys
|
||||
import socket
|
||||
import struct
|
||||
import ntpath
|
||||
import pprint
|
||||
import logging
|
||||
|
@ -8,7 +11,7 @@ import monkeyfs
|
|||
from difflib import get_close_matches
|
||||
from network import local_ips
|
||||
from transport import HTTPServer
|
||||
from network.info import get_free_tcp_port
|
||||
from network.info import get_free_tcp_port, get_routes
|
||||
from network.firewall import app as firewall
|
||||
from impacket.dcerpc.v5 import transport, srvs
|
||||
from impacket.dcerpc.v5.dcom.wmi import DCERPCSessionError
|
||||
|
@ -369,7 +372,7 @@ class HTTPTools(object):
|
|||
local_port = get_free_tcp_port()
|
||||
|
||||
if not local_ip:
|
||||
local_ip = get_close_matches(host.ip_addr, local_ips())[0]
|
||||
local_ip = get_interface_to_target(host.ip_addr)
|
||||
|
||||
if not firewall.listen_allowed():
|
||||
return None, None
|
||||
|
@ -381,6 +384,39 @@ class HTTPTools(object):
|
|||
return "http://%s:%s/%s" % (local_ip, local_port, urllib.quote(os.path.basename(src_path))), httpd
|
||||
|
||||
|
||||
def get_interface_to_target(dst):
|
||||
if sys.platform == "win32":
|
||||
try:
|
||||
import dnet
|
||||
intf = dnet.intf()
|
||||
inte = intf.get_dst(dnet.addr(dst))
|
||||
return str(inte['addr']).split("/")[0]
|
||||
except ImportError:
|
||||
# dnet lib is not installed
|
||||
return get_close_matches(dst, local_ips())[0]
|
||||
else:
|
||||
# based on scapy implementation
|
||||
|
||||
def atol(x):
|
||||
ip = socket.inet_aton(x)
|
||||
return struct.unpack("!I", ip)[0]
|
||||
|
||||
routes = get_routes()
|
||||
dst = atol(dst)
|
||||
pathes = []
|
||||
for d, m, gw, i, a in routes:
|
||||
aa = atol(a)
|
||||
if aa == dst:
|
||||
pathes.append((0xffffffffL, ("lo", a, "0.0.0.0")))
|
||||
if (dst & m) == (d & m):
|
||||
pathes.append((m, (i, a, gw)))
|
||||
if not pathes:
|
||||
return None
|
||||
pathes.sort()
|
||||
ret = pathes[-1][1]
|
||||
return ret[1]
|
||||
|
||||
|
||||
def get_target_monkey(host):
|
||||
from control import ControlClient
|
||||
import platform
|
||||
|
|
|
@ -30,9 +30,11 @@ if sys.platform == "win32":
|
|||
network_adapters.append((add["addr"], add["netmask"]))
|
||||
return network_adapters
|
||||
|
||||
else:
|
||||
import fcntl
|
||||
def get_routes():
|
||||
raise NotImplementedError()
|
||||
|
||||
else:
|
||||
from fcntl import ioctl
|
||||
|
||||
def get_host_subnets(only_ips=False):
|
||||
"""Get the list of Linux network adapters."""
|
||||
|
@ -46,7 +48,7 @@ else:
|
|||
offset2 = 32
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
names = array.array('B', '\0' * max_bytes)
|
||||
outbytes = struct.unpack('iL', fcntl.ioctl(
|
||||
outbytes = struct.unpack('iL', ioctl(
|
||||
sock.fileno(),
|
||||
0x8912,
|
||||
struct.pack('iL', max_bytes, names.buffer_info()[0])))[0]
|
||||
|
@ -54,13 +56,13 @@ else:
|
|||
for n_cnt in xrange(0, outbytes, offset2)]
|
||||
network_adapters = []
|
||||
for adapter_name in adapter_names:
|
||||
ip_address = socket.inet_ntoa(fcntl.ioctl(
|
||||
ip_address = socket.inet_ntoa(ioctl(
|
||||
sock.fileno(),
|
||||
0x8915,
|
||||
struct.pack('256s', adapter_name))[20:24])
|
||||
if ip_address.startswith('127'):
|
||||
continue
|
||||
subnet_mask = socket.inet_ntoa(fcntl.ioctl(
|
||||
subnet_mask = socket.inet_ntoa(ioctl(
|
||||
sock.fileno(),
|
||||
0x891b,
|
||||
struct.pack('256s', adapter_name))[20:24])
|
||||
|
@ -72,10 +74,56 @@ else:
|
|||
|
||||
return network_adapters
|
||||
|
||||
|
||||
def local_ips():
|
||||
return get_host_subnets(only_ips=True)
|
||||
|
||||
def get_routes(): # based on scapy implementation for route parsing
|
||||
LOOPBACK_NAME = "lo"
|
||||
SIOCGIFADDR = 0x8915 # get PA address
|
||||
SIOCGIFNETMASK = 0x891b # get network PA mask
|
||||
RTF_UP = 0x0001 # Route usable
|
||||
RTF_REJECT = 0x0200
|
||||
|
||||
try:
|
||||
f = open("/proc/net/route", "r")
|
||||
except IOError:
|
||||
return []
|
||||
routes = []
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
ifreq = ioctl(s, SIOCGIFADDR, struct.pack("16s16x", LOOPBACK_NAME))
|
||||
addrfamily = struct.unpack("h", ifreq[16:18])[0]
|
||||
if addrfamily == socket.AF_INET:
|
||||
ifreq2 = ioctl(s, SIOCGIFNETMASK, struct.pack("16s16x", LOOPBACK_NAME))
|
||||
msk = socket.ntohl(struct.unpack("I", ifreq2[20:24])[0])
|
||||
dst = socket.ntohl(struct.unpack("I", ifreq[20:24])[0]) & msk
|
||||
ifaddr = socket.inet_ntoa(ifreq[20:24])
|
||||
routes.append((dst, msk, "0.0.0.0", LOOPBACK_NAME, ifaddr))
|
||||
|
||||
for l in f.readlines()[1:]:
|
||||
iff, dst, gw, flags, x, x, x, msk, x, x, x = l.split()
|
||||
flags = int(flags, 16)
|
||||
if flags & RTF_UP == 0:
|
||||
continue
|
||||
if flags & RTF_REJECT:
|
||||
continue
|
||||
try:
|
||||
ifreq = ioctl(s, SIOCGIFADDR, struct.pack("16s16x", iff))
|
||||
except IOError: # interface is present in routing tables but does not have any assigned IP
|
||||
ifaddr = "0.0.0.0"
|
||||
else:
|
||||
addrfamily = struct.unpack("h", ifreq[16:18])[0]
|
||||
if addrfamily == socket.AF_INET:
|
||||
ifaddr = socket.inet_ntoa(ifreq[20:24])
|
||||
else:
|
||||
continue
|
||||
routes.append((socket.htonl(long(dst, 16)) & 0xffffffffL,
|
||||
socket.htonl(long(msk, 16)) & 0xffffffffL,
|
||||
socket.inet_ntoa(struct.pack("I", long(gw, 16))),
|
||||
iff, ifaddr))
|
||||
|
||||
f.close()
|
||||
return routes
|
||||
|
||||
|
||||
def get_free_tcp_port(min_range=1000, max_range=65535):
|
||||
start_range = min(1, min_range)
|
||||
|
|
|
@ -32,7 +32,11 @@ Windows:
|
|||
type > C:\Python27\Lib\site-packages\zope\__init__.py
|
||||
7. Download and extract UPX binary to [source-path]\monkey\chaos_monkey\bin\upx.exe:
|
||||
http://upx.sourceforge.net/download/upx391w.zip
|
||||
8. Run [source-path]\monkey\chaos_monkey\build_windows.bat to build, output is in dist\monkey.exe
|
||||
8. (Optional) For some exploits to work better, install 'dnet' python library. You'll need to compile it for your OS
|
||||
or use a precompiled setup that can be found at:
|
||||
32bit: https://github.com/Kondziowy/scapy_win64/raw/master/win32/dnet-1.12.win32-py2.7.exe
|
||||
64bit: https://github.com/Kondziowy/scapy_win64/raw/master/win64/dnet-1.12.win-amd64-py2.7.exe
|
||||
9. Run [source-path]\monkey\chaos_monkey\build_windows.bat to build, output is in dist\monkey.exe
|
||||
|
||||
Linux (Tested on Ubuntu 12.04):
|
||||
1. Run:
|
||||
|
|
Loading…
Reference in New Issue