1
mirror of https://github.com/rapid7/metasploit-payloads synced 2024-12-02 20:36:40 +01:00

Implement pymet osx rg memread and memwrite

This commit is contained in:
Spencer McIntyre 2017-06-15 10:56:47 -04:00
parent 31f65cf365
commit e0c26186c1

View File

@ -14,6 +14,7 @@ import time
try:
import ctypes
import ctypes.util
has_ctypes = True
has_windll = hasattr(ctypes, 'windll')
except ImportError:
@ -69,10 +70,10 @@ else:
unicode = lambda x: (x.decode('UTF-8') if isinstance(x, bytes) else x)
if has_ctypes:
size_t = getattr(ctypes, 'c_uint' + str(ctypes.sizeof(ctypes.c_void_p) * 8))
#
# Windows Structures
#
size_t = getattr(ctypes, 'c_uint' + str(ctypes.sizeof(ctypes.c_void_p) * 8))
class EVENTLOGRECORD(ctypes.Structure):
_fields_ = [("Length", ctypes.c_uint32),
("Reserved", ctypes.c_uint32),
@ -1770,6 +1771,33 @@ def _linux_memwrite(address, data):
raise RuntimeError('operation failed')
return size
def _osx_memread(address, size):
libc = ctypes.CDLL(ctypes.util.find_library('c'))
task = libc.mach_task_self()
libc.mach_vm_read.argtypes = [ctypes.c_uint32, size_t, size_t, ctypes.POINTER(ctypes.c_void_p), ctypes.POINTER(ctypes.c_uint32)]
libc.mach_vm_read.restype = ctypes.c_uint32
pointer = ctypes.c_void_p()
out_size = ctypes.c_uint32()
result = libc.mach_vm_read(task, address, size, ctypes.byref(pointer), ctypes.byref(out_size))
if result == 1: # KERN_INVALID_ADDRESS
raise RuntimeError('invalid address')
elif result == 2: # KERN_PROTECTION_FAILURE
raise RuntimeError('invalid permissions')
if result != 0 or size != out_size.value:
raise RuntimeError('operation failed')
buff = ctypes.cast(pointer, ctypes.POINTER(ctypes.c_byte * out_size.value))
return ctarray_to_bytes(buff.contents)
def _osx_memwrite(address, data):
libc = ctypes.CDLL(ctypes.util.find_library('c'))
task = libc.mach_task_self()
libc.mach_vm_write.argtypes = [ctypes.c_uint32, size_t, ctypes.c_void_p, ctypes.c_uint32]
libc.mach_vm_write.restype = ctypes.c_uint32
buff = bytes_to_ctarray(data)
if libc.mach_vm_write(task, address, buff, len(buff)) != 0:
raise RuntimeError('operation failed')
return len(buff)
def _win_format_message(source, msg_id):
EN_US = 0
msg_flags = 0
@ -1907,12 +1935,14 @@ def stdapi_railgun_api_multi(request, response):
response += tlv_pack(TLV_TYPE_RAILGUN_MULTI_GROUP, group_result)
return ERROR_SUCCESS, response
@register_function_if(sys.platform.startswith('linux') or has_windll)
@register_function_if(sys.platform == 'darwin' or sys.platform.startswith('linux') or has_windll)
def stdapi_railgun_memread(request, response):
address = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_ADDRESS)['value']
length = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_LENGTH)['value']
debug_print('[*] railgun reading ' + str(length) + ' bytes from 0x' + hex(address))
if sys.platform.startswith('linux'):
if sys.platform.startswith('darwin'):
result = _osx_memread(address, length)
elif sys.platform.startswith('linux'):
result = _linux_memread(address, length)
elif has_windll:
result = _win_memread(address, length)
@ -1923,13 +1953,15 @@ def stdapi_railgun_memread(request, response):
response += tlv_pack(TLV_TYPE_RAILGUN_MEM_DATA, result)
return ERROR_SUCCESS, response
@register_function_if(sys.platform.startswith('linux') or has_windll)
@register_function_if(sys.platform == 'darwin' or sys.platform.startswith('linux') or has_windll)
def stdapi_railgun_memwrite(request, response):
address = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_ADDRESS)['value']
data = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_DATA)['value']
length = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_LENGTH)['value']
debug_print('[*] railgun writing ' + str(len(data)) + ' bytes to 0x' + hex(address))
if sys.platform.startswith('linux'):
if sys.platform.startswith('darwin'):
result = _osx_memwrite(address, data)
elif sys.platform.startswith('linux'):
result = _linux_memwrite(address, data)
elif has_windll:
result = _win_memwrite(address, data)