Find a location to potentially inject the code, in this case 0xffffff7f8c04d6e5
## This section gets the address for possible code injection in the com.vmware.kext.vmhgfs kext
#get address for the kernel extension (kext) list
p = self.addrspace.profile.get_symbol("_kmod")
kmodaddr = obj.Object("Pointer", offset = p, vm = self.addrspace)
kmod = kmodaddr.dereference_as("kmod_info")
#loop thru list to find suitable target to place the trampoline in
while kmod.is_valid():
str(kmod.name)
if str(kmod.name) == "com.vmware.kext.vmhgfs":
mh = obj.Object('mach_header_64', offset = kmod.address,vm = self.addrspace)
o = mh.obj_offset
# skip header data
o += 32
txt_data_end = 0
# loop thru segments to find __TEXT
for i in xrange(0, mh.ncmds):
seg = obj.Object('segment_command_64', offset = o, vm = self.addrspace)
if seg.cmd not in [0x26]:
for j in xrange(0, seg.nsects):
sect = obj.Object('section_64', offset = o + 0x48 + 80*(j), vm = self.addrspace)
sect_name = "".join(map(str, sect.sectname)).strip(' \t\r\n\0')
# find __text section
if seg.cmd == 0x19 and str(seg.segname) == "__TEXT" and sect_name == "__text":
print "{0:#10x} {1:#2x} {2} {3}".format(sect.addr,seg.cmd, seg.segname, sect_name)
txt_data_end = sect.addr + sect.m('size') - 50
break
if txt_data_end != 0:
break
print "The fake function will be at {0:#10x}".format(txt_data_end)
break
kmod = kmod.next
The addresses for the functions in question in the original memory sample:
Name Original Address
_mac_proc_check_get_task 0xffffff800ac8ee20
_mac_policy_list 0xffffff800aef4d28
The disassembly of the original _mac_proc_check_get_task showing the reference to _mac_policy_list:
0xffffff800ac8ee20 55 PUSH RBP
0xffffff800ac8ee21 4889e5 MOV RBP, RSP
0xffffff800ac8ee24 4157 PUSH R15
0xffffff800ac8ee26 4156 PUSH R14
0xffffff800ac8ee28 4155 PUSH R13
0xffffff800ac8ee2a 4154 PUSH R12
0xffffff800ac8ee2c 53 PUSH RBX
0xffffff800ac8ee2d 50 PUSH RAX
0xffffff800ac8ee2e 4989f6 MOV R14, RSI
0xffffff800ac8ee31 4989ff MOV R15, RDI
0xffffff800ac8ee34 488d05ed5e2600 LEA RAX, [RIP+0x265eed]
0xffffff800ac8ee3b 8b400c MOV EAX, [RAX+0xc]
The instruction in bold uses relative addressing, therefore [RIP+0x265eed] actually translates to 0xffffff800aef4d28 (current instruction address + displacement + OP size = 0xffffff800ac8ee34 + 0x265eed + 7), which is the original address of the _mac_policy_list.
Modify the LEA instruction to refer to the fake location (0xffffff7f8c04d6e5): In this case we need to modify the displacement value (0x265EED) so it points to the fake policy list. The fake displacement is calculated by reversing the operations used to calculate the _mac_policy_list (fake address - current instruction address - OP size = 0xffffff7f8c04d6e5 - 0xffffff800ac8ee34 – 7 = 0x813BE8AA).
Original Displacement Fake Displacement
0x00265EED 0x813BE8AA
Original Code Fake Code
488d05ed5e2600 488d05AAE83B81
\x48\x8d\x05 indicates that the operand size is 64 bit (0x48, REX.W), the instruction is LEA (0x8d) and using the register RIP + disp32 with RAX (0x05). The following value in bold is the displacement amount.
After we rewrite the code at the original LEA at 0xffffff800ac8ee34, the disassembly will look like the following:
0xffffff800ac8ee20 55 PUSH RBP
0xffffff800ac8ee21 4889e5 MOV RBP, RSP
0xffffff800ac8ee24 4157 PUSH R15
0xffffff800ac8ee26 4156 PUSH R14
0xffffff800ac8ee28 4155 PUSH R13
0xffffff800ac8ee2a 4154 PUSH R12
0xffffff800ac8ee2c 53 PUSH RBX
0xffffff800ac8ee2d 50 PUSH RAX
0xffffff800ac8ee2e 4989f6 MOV R14, RSI
0xffffff800ac8ee31 4989ff MOV R15, RDI
0xffffff800ac8ee34 488d05aae83b81 LEA RAX, [RIP-0x7ec41756]
0xffffff800ac8ee3b 8b400c MOV EAX, [RAX+0xc]
The reference to the mac_policy_list has been modified to point to the fake location 0xffffff7f8c04d6e5 (0xffffff800ac8ee34 + -0x7ec41756 + 7).
The output for the plugin after modifying the memory sample is as follows:
The plugin check_shadow_trustedbsd.py can be found at my GitHub repository [3].
References
[1] http://reverse.put.as/2014/03/18/teaching-rex-another-trustedbsd-trick-to-hide-from-volatility/
[2] http://ref.x86asm.net/geek.html#x0F2D
[3] https://github.com/siliconblade/volatility/blob/master/mac/check_shadow_trustedbsd.py
No comments:
Post a Comment