Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Windows Memory Search support using regex #686

Merged

Conversation

sjanusz-r7
Copy link
Contributor

@sjanusz-r7 sjanusz-r7 commented Nov 28, 2023

This PR adds in the ability to search Windows process memory for needles. These needles are searched for using regex, provided by the tiny-regex-c library. This library has been modified to match an arbitrary length of bytes (null-bytes included). This was necessary so that we do not treat null-bytes as the end of a string/buffer, and continue trying to match the regular expression.

Example Usage

I went through the following steps:

  1. Compile the project using Visual Studio in a Windows 10 x64 VM as an x64 project in Debug mode.
  2. Mount the Framework data directory into the VM as a share with write permissions.
  3. On the VM, execute: cp -rf ./output/* /z/meterpreter && ~/Desktop/met.exe to copy the debug dll files to Framework. met.exe is a symlink to a Framework-generated Meterpreter payload.
  4. In Framework, setg MeterpreterDebugBuild true
  5. Get a session
  6. sessions -i -1
  7. irb

Now we can define our memory search function that we will use for testing:

require 'rex/post/meterpreter/extensions/stdapi/tlv'
require 'rex/post/meterpreter/extensions/stdapi/command_ids'
require 'rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/memory'

def mem_search(pid, needles, min_search_len = 5, match_len = 255)
  stdapi = ::Rex::Post::Meterpreter::Extensions::Stdapi
  request = ::Rex::Post::Meterpreter::Packet.create_request(stdapi::COMMAND_ID_STDAPI_SYS_PROCESS_MEMORY_SEARCH)

  request.add_tlv(stdapi::TLV_TYPE_PID, pid)

  needles.each do | needle |
    request.add_tlv(stdapi::TLV_TYPE_MEMORY_SEARCH_NEEDLE, needle)
  end
  request.add_tlv(stdapi::TLV_TYPE_MEMORY_SEARCH_MATCH_LEN, match_len)  
  request.add_tlv(::Rex::Post::Meterpreter::TLV_TYPE_UINT, min_search_len)

  self.send_request(request)
end

Then we can use regex to search for needles:

response = mem_search(pid, ['my_needle.*'], 5, 255)
response.tlvs[2].tlvs[0].value

When searching for multiple needles, call:

response = mem_search(pid, ['needle_one', "some_needle"], 5, 255)

The changes in the tiny-regex-c library allow us to match null-bytes as well, meaning we can match wide characters:

wide_needle = "e\x00x\x00a\x00m\x00p\x00l\x00e\x00.*"
response = mem_search(pid, [wide_needle], 5, 255)

To make sure the command is stable, you can run the following in irb for a single needle:

100.times { response = mem_search(10840, ['some_needle'], 5, 255) }

or with multiple needles:

100.times { response = mem_search(10840, ['needle_one', 'needle_two.*', 'needle_three'], 5, 255) }

This should result in no memory usage increases for Meterpreter and the session should remain stable.

Debugging

When wanting to debug the new re.c file, we can first:

#include <windows.h>

This will also typedef CHAR which initially conflicted with the enum CHAR; this has been renamed to CHAR_RE.
Then define a buffer, format it using sprintf and call OutputDebugStringA, mimicking what dprintf was doing.

char buffer[1024];
unsigned long long example_llu = 42;
sprintf(buffer, "Example output: %llu", example_llu);
OutputDebugStringA(buffer);

You will need to use the DebugView program to view debug logs.

Dr. Memory

I also ran the generated executable with Dr. Memory using drmemory -- ~/Desktop/met.exe:

Dr. Memory version 2.6.19621 build 0 built on Sep 23 2023 02:25:01
Windows version: WinVer=105;Rel=2009;Build=19045;Edition=Professional
Dr. Memory results for pid 5632: "met.exe"
Application cmdline: "./met.exe"
Recorded 124 suppression(s) from default C:\Users\win10\scoop\apps\drmemory\current\bin64\suppress-default.txt
ERROR: Failed to find "main" for limiting memory dump

WARNING: application is missing line number information.

Error #1: UNINITIALIZED READ: reading register eax
# 0 WS2_32.dll!WSALookupServiceNextW   +0x23f1   (0x00007ffa23ffded1 <WS2_32.dll+0xded1>)
# 1 WS2_32.dll!WSALookupServiceNextW   +0x2ffd   (0x00007ffa23ffeade <WS2_32.dll+0xeade>)
# 2 WS2_32.dll!WSAStartup              +0x33c    (0x00007ffa23ffee4d <WS2_32.dll+0xee4d>)
# 3 met.exe!?                          +0x0      (0x000000014000411b <met.exe+0x411b>)
# 4 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:00.609 in thread 10020
Note: instruction: cmp    %eax %r12d

Error #2: UNINITIALIZED READ: reading register eflags
# 0 WS2_32.dll!WSALookupServiceNextW   +0x240f   (0x00007ffa23ffdeef <WS2_32.dll+0xdeef>)
# 1 WS2_32.dll!WSALookupServiceNextW   +0x2ffd   (0x00007ffa23ffeade <WS2_32.dll+0xeade>)
# 2 WS2_32.dll!WSAStartup              +0x33c    (0x00007ffa23ffee4d <WS2_32.dll+0xee4d>)
# 3 met.exe!?                          +0x0      (0x000000014000411b <met.exe+0x411b>)
# 4 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:00.609 in thread 10020
Note: instruction: cmovo  %r13 -> %rax

Error #3: UNINITIALIZED READ: reading 0x000000000014fbc0-0x000000000014fbc4 4 byte(s) within 0x000000000014fbc0-0x000000000014fbc8
# 0 replace_memset                      [D:\a\drmemory\drmemory\drmemory\replace.c:194]
# 1 WS2_32.dll!WSALookupServiceNextW   +0x2448   (0x00007ffa23ffdf29 <WS2_32.dll+0xdf29>)
# 2 WS2_32.dll!WSALookupServiceNextW   +0x2ffd   (0x00007ffa23ffeade <WS2_32.dll+0xeade>)
# 3 WS2_32.dll!WSAStartup              +0x33c    (0x00007ffa23ffee4d <WS2_32.dll+0xee4d>)
# 4 met.exe!?                          +0x0      (0x000000014000411b <met.exe+0x411b>)
# 5 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:00.656 in thread 10020
Note: instruction: cmp    0x30(%rsp) $0x0000000000000003

Error #4: UNINITIALIZED READ: reading 0x000000000014fb9c-0x000000000014fba0 4 byte(s) within 0x000000000014fb88-0x000000000014fba0
# 0 system call NtDeviceIoControlFile AFD_RECV_INFO
# 1 MSWSOCK.dll!NSPStartup                                       +0x55d    (0x00007ffa2240c5fe <MSWSOCK.dll+0xc5fe>)
# 2 WS2_32.dll!recv                                              +0xc0     (0x00007ffa24001e51 <WS2_32.dll+0x11e51>)
# 3 met.exe!?                                                    +0x0      (0x0000000140004179 <met.exe+0x4179>)
# 4 met.exe!?                                                    +0x0      (0x000000014000400a <met.exe+0x400a>)
# 5 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:01.000 in thread 10020

Error #5: UNINITIALIZED READ: reading 0x000000000014fc7c-0x000000000014fc80 4 byte(s) within 0x000000000014fc78-0x000000000014fc88
# 0 system call NtDeviceIoControlFile AFD_RECV_INFO.BufferArray
# 1 MSWSOCK.dll!NSPStartup                                                   +0x55d    (0x00007ffa2240c5fe <MSWSOCK.dll+0xc5fe>)
# 2 WS2_32.dll!recv                                                          +0xc0     (0x00007ffa24001e51 <WS2_32.dll+0x11e51>)
# 3 met.exe!?                                                                +0x0      (0x0000000140004179 <met.exe+0x4179>)
# 4 met.exe!?                                                                +0x0      (0x000000014000400a <met.exe+0x400a>)
# 5 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:01.000 in thread 10020

Error #6: UNINITIALIZED READ: reading 0x000000000014fb84-0x000000000014fb88 4 byte(s) within 0x000000000014fb70-0x000000000014fb88
# 0 system call NtDeviceIoControlFile AFD_RECV_INFO
# 1 MSWSOCK.dll!NSPStartup                                       +0x55d    (0x00007ffa2240c5fe <MSWSOCK.dll+0xc5fe>)
# 2 WS2_32.dll!recv                                              +0xc0     (0x00007ffa24001e51 <WS2_32.dll+0x11e51>)
# 3 met.exe!?                                                    +0x0      (0x00000001400041b3 <met.exe+0x41b3>)
# 4 met.exe!?                                                    +0x0      (0x000000014000400a <met.exe+0x400a>)
# 5 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:01.125 in thread 10020

Error #7: UNINITIALIZED READ: reading 0x000000000014fc64-0x000000000014fc68 4 byte(s) within 0x000000000014fc60-0x000000000014fc70
# 0 system call NtDeviceIoControlFile AFD_RECV_INFO.BufferArray
# 1 MSWSOCK.dll!NSPStartup                                                   +0x55d    (0x00007ffa2240c5fe <MSWSOCK.dll+0xc5fe>)
# 2 WS2_32.dll!recv                                                          +0xc0     (0x00007ffa24001e51 <WS2_32.dll+0x11e51>)
# 3 met.exe!?                                                                +0x0      (0x00000001400041b3 <met.exe+0x41b3>)
# 4 met.exe!?                                                                +0x0      (0x000000014000400a <met.exe+0x400a>)
# 5 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:01.125 in thread 10020

Error #8: UNINITIALIZED READ: reading register rsi
# 0 met.exe!?                        +0x0      (0x00000001400041b9 <met.exe+0x41b9>)
# 1 met.exe!?                        +0x0      (0x000000014000400a <met.exe+0x400a>)
# 2 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:01.140 in thread 10020
Note: instruction: test   %rsi %rsi

Error #9: UNINITIALIZED READ: reading 0x000000000014f3e0-0x000000000014f3e1 1 byte(s)
# 0 <not in a module>   (0x0000000001047196)
# 1 met.exe!?                        +0x0      (0x000000014000400a <met.exe+0x400a>)
# 2 met.exe!?                        +0x0      (0x000000014000400a <met.exe+0x400a>)
# 3 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:02.780 in thread 10020
Note: instruction: cmp    (%rax,%rcx) $0x00

Error #10: UNINITIALIZED READ: reading register eflags
# 0 <not in a module>   (0x000000000103d447)
# 1 met.exe!?                        +0x0      (0x000000014000400a <met.exe+0x400a>)
# 2 met.exe!?                        +0x0      (0x000000014000400a <met.exe+0x400a>)
# 3 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:02.937 in thread 10020
Note: instruction: jz     $0x000000000103d431

Error #11: UNINITIALIZED READ: reading 0x000000000013f5dc-0x000000000013f5e0 4 byte(s) within 0x000000000013f5c8-0x000000000013f5e0
# 0 system call NtDeviceIoControlFile AFD_RECV_INFO
# 1 MSWSOCK.dll!NSPStartup                                       +0x55d    (0x00007ffa2240c5fe <MSWSOCK.dll+0xc5fe>)
# 2 WS2_32.dll!recv                                              +0xc0     (0x00007ffa24001e51 <WS2_32.dll+0x11e51>)
# 3 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:04.108 in thread 10020

Error #12: UNINITIALIZED READ: reading 0x000000000013f6bc-0x000000000013f6c0 4 byte(s) within 0x000000000013f6b8-0x000000000013f6c8
# 0 system call NtDeviceIoControlFile AFD_RECV_INFO.BufferArray
# 1 MSWSOCK.dll!NSPStartup                                                   +0x55d    (0x00007ffa2240c5fe <MSWSOCK.dll+0xc5fe>)
# 2 WS2_32.dll!recv                                                          +0xc0     (0x00007ffa24001e51 <WS2_32.dll+0x11e51>)
# 3 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:04.108 in thread 10020

Error #13: UNINITIALIZED READ: reading 0x0000000001bbfc84-0x0000000001bbfc88 4 byte(s) within 0x0000000001bbfc70-0x0000000001bbfc88
# 0 system call NtDeviceIoControlFile AFD_SEND_INFO
# 1 MSWSOCK.dll!?                                                +0x0      (0x00007ffa224093bf <MSWSOCK.dll+0x93bf>)
# 2 WS2_32.dll!send                                              +0x16a    (0x00007ffa23ff248b <WS2_32.dll+0x248b>)
# 3 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:08.357 in thread 6604

Error #14: UNINITIALIZED READ: reading 0x0000000001bbfd4c-0x0000000001bbfd50 4 byte(s) within 0x0000000001bbfd48-0x0000000001bbfd58
# 0 system call NtDeviceIoControlFile AFD_SEND_INFO.BufferArray
# 1 MSWSOCK.dll!?                                                            +0x0      (0x00007ffa224093bf <MSWSOCK.dll+0x93bf>)
# 2 WS2_32.dll!send                                                          +0x16a    (0x00007ffa23ff248b <WS2_32.dll+0x248b>)
# 3 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:08.373 in thread 6604

Error #15: UNADDRESSABLE ACCESS beyond heap bounds: reading 0x00000000009baed5-0x00000000009baed8 3 byte(s) within 0x00000000009baed0-0x00000000009baed8
# 0 <not in a module>   (0x000000000103d431)
# 1 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:28.788 in thread 12136
Note: next higher malloc: 0x00000000009baf00-0x00000000009bb3a8
Note: refers to 0 byte(s) beyond last valid byte in prior malloc
Note: prev lower malloc:  0x00000000009baea0-0x00000000009baed5
Note: instruction: mov    (%rax) -> %rdx

Error #16: UNADDRESSABLE ACCESS beyond heap bounds: reading 0x00000000009baed5-0x00000000009baed8 3 byte(s) within 0x00000000009baed0-0x00000000009baed8
# 0 <not in a module>   (0x000000000103d449)
# 1 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:28.788 in thread 12136
Note: next higher malloc: 0x00000000009baf00-0x00000000009bb3a8
Note: refers to 0 byte(s) beyond last valid byte in prior malloc
Note: prev lower malloc:  0x00000000009baea0-0x00000000009baed5
Note: instruction: mov    0xfffffff8(%rax) -> %rdx

Error #17: UNADDRESSABLE ACCESS beyond heap bounds: reading 0x00000000009ccef0-0x00000000009ccf00 16 byte(s) within 0x00000000009ccee0-0x00000000009ccf00
# 0 <not in a module>   (0x0000000003883136)
# 1 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:31.008 in thread 13436
Note: next higher malloc: 0x00000000009ccf10-0x00000000009ccf16
Note: refers to 0 byte(s) beyond last valid byte in prior malloc
Note: prev lower malloc:  0x00000000009ccee0-0x00000000009ccef0
Note: instruction: vpcmpeqb %ymm2 (%rcx) -> %ymm1

Error #18: UNINITIALIZED READ: reading 0x0000000000a98f50-0x0000000000a98f54 4 byte(s)
# 0 IPHLPAPI.DLL!ConvertInterfaceNameToLuidW +0x464    (0x00007ffa220f58b4 <IPHLPAPI.DLL+0x58b4>)
# 1 IPHLPAPI.DLL!GetAdaptersAddresses        +0x55     (0x00007ffa220f43d6 <IPHLPAPI.DLL+0x43d6>)
# 2 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:39.504 in thread 7392
Note: instruction: cmp    (%rcx,%rax) %r12d

Error #19: UNINITIALIZED READ: reading register eax
# 0 IPHLPAPI.DLL!ConvertInterfaceNameToLuidW +0x519    (0x00007ffa220f5969 <IPHLPAPI.DLL+0x5969>)
# 1 IPHLPAPI.DLL!GetAdaptersAddresses        +0x55     (0x00007ffa220f43d6 <IPHLPAPI.DLL+0x43d6>)
# 2 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:39.723 in thread 7392
Note: instruction: cmp    %eax $0x00000100

Error #20: UNINITIALIZED READ: reading register eax
# 0 IPHLPAPI.DLL!ConvertInterfaceNameToLuidW +0x53a    (0x00007ffa220f598a <IPHLPAPI.DLL+0x598a>)
# 1 IPHLPAPI.DLL!GetAdaptersAddresses        +0x55     (0x00007ffa220f43d6 <IPHLPAPI.DLL+0x43d6>)
# 2 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:39.723 in thread 7392
Note: instruction: cmp    %eax $0x00000100

Error #21: UNINITIALIZED READ: reading 0x0000000000a98f66-0x0000000000a98f68 2 byte(s)
# 0 IPHLPAPI.DLL!ConvertInterfaceNameToLuidW +0x563    (0x00007ffa220f59b3 <IPHLPAPI.DLL+0x59b3>)
# 1 IPHLPAPI.DLL!GetAdaptersAddresses        +0x55     (0x00007ffa220f43d6 <IPHLPAPI.DLL+0x43d6>)
# 2 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:39.723 in thread 7392
Note: instruction: data16 cmp    0x16(%rcx,%rax,2) %r12w

Error #22: UNINITIALIZED READ: reading 0x0000000000a9fb16-0x0000000000a9fb18 2 byte(s)
# 0 IPHLPAPI.DLL!ConvertInterfaceNameToLuidW +0x593    (0x00007ffa220f59e3 <IPHLPAPI.DLL+0x59e3>)
# 1 IPHLPAPI.DLL!GetAdaptersAddresses        +0x55     (0x00007ffa220f43d6 <IPHLPAPI.DLL+0x43d6>)
# 2 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:40.082 in thread 7392
Note: instruction: data16 cmp    0x06(%rcx,%rax,2) %r12w

Error #23: UNINITIALIZED READ: reading 0x0000000001bbfa18-0x0000000001bbfa19 1 byte(s)
# 0 IPHLPAPI.DLL!ConvertInterfaceNameToLuidW +0x5b9    (0x00007ffa220f5a09 <IPHLPAPI.DLL+0x5a09>)
# 1 IPHLPAPI.DLL!GetAdaptersAddresses        +0x55     (0x00007ffa220f43d6 <IPHLPAPI.DLL+0x43d6>)
# 2 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:40.613 in thread 7392
Note: instruction: cmp    (%rax,%rbx) %r12l

Error #24: UNINITIALIZED READ: reading register ecx
# 0 IPHLPAPI.DLL!ConvertInterfaceNameToLuidW +0x83c    (0x00007ffa220f5c8c <IPHLPAPI.DLL+0x5c8c>)
# 1 IPHLPAPI.DLL!GetAdaptersAddresses        +0x55     (0x00007ffa220f43d6 <IPHLPAPI.DLL+0x43d6>)
# 2 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:40.676 in thread 7392
Note: instruction: cmp    %ecx $0x00000008

Error #25: UNINITIALIZED READ: reading 0x0000000000a9fd20-0x0000000000a9fd24 4 byte(s)
# 0 IPHLPAPI.DLL!ConvertInterfaceNameToLuidW +0x86a    (0x00007ffa220f5cba <IPHLPAPI.DLL+0x5cba>)
# 1 IPHLPAPI.DLL!GetAdaptersAddresses        +0x55     (0x00007ffa220f43d6 <IPHLPAPI.DLL+0x43d6>)
# 2 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:40.676 in thread 7392
Note: instruction: cmp    0x00000210(%rdi,%rax) $0x00000002

Error #26: UNINITIALIZED READ: reading 0x0000000000a9fd1c-0x0000000000a9fd20 4 byte(s)
# 0 IPHLPAPI.DLL!ConvertInterfaceNameToLuidW +0x88b    (0x00007ffa220f5cdb <IPHLPAPI.DLL+0x5cdb>)
# 1 IPHLPAPI.DLL!GetAdaptersAddresses        +0x55     (0x00007ffa220f43d6 <IPHLPAPI.DLL+0x43d6>)
# 2 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:40.691 in thread 7392
Note: instruction: cmp    0x0000020c(%rdi,%rax) $0x00000004

Error #27: UNINITIALIZED READ: reading register r8d
# 0 IPHLPAPI.DLL!ConvertInterfaceNameToLuidW +0x942    (0x00007ffa220f5d92 <IPHLPAPI.DLL+0x5d92>)
# 1 IPHLPAPI.DLL!GetAdaptersAddresses        +0x55     (0x00007ffa220f43d6 <IPHLPAPI.DLL+0x43d6>)
# 2 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:40.691 in thread 7392
Note: instruction: cmp    %r8d $0x00000005

Error #28: UNINITIALIZED READ: reading 0x00000000009d5250-0x00000000009d5258 8 byte(s)
# 0 IPHLPAPI.DLL!ConvertInterfaceNameToLuidW +0x95d    (0x00007ffa220f5dad <IPHLPAPI.DLL+0x5dad>)
# 1 IPHLPAPI.DLL!GetAdaptersAddresses        +0x55     (0x00007ffa220f43d6 <IPHLPAPI.DLL+0x43d6>)
# 2 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:40.707 in thread 7392
Note: instruction: cmp    (%r9,%rcx,8) %r10

Error #29: UNINITIALIZED READ: reading 0x00000000009df010-0x00000000009df018 8 byte(s)
# 0 IPHLPAPI.DLL!ConvertInterfaceNameToLuidW +0x97d    (0x00007ffa220f5dcd <IPHLPAPI.DLL+0x5dcd>)
# 1 IPHLPAPI.DLL!GetAdaptersAddresses        +0x55     (0x00007ffa220f43d6 <IPHLPAPI.DLL+0x43d6>)
# 2 KERNEL32.dll!BaseThreadInitThunk
Note: @0:00:40.754 in thread 7392
Note: instruction: cmp    (%r9,%rcx,8) %r10

Error #30: UNINITIALIZED READ: reading 0x00000000009deef8-0x00000000009deefc 4 byte(s)
# 0 IPHLPAPI.DLL!ConvertInterfaceNameToLuidW +0xd1b    (0x00007ffa220f616b <IPHLPAPI.DLL+0x616b>)
# 1 IPHLPAPI.DLL!GetAdaptersAddresses        +0x55     (0x00007ffa220f43d6 <IPHLPAPI.DLL+0x43d6>)
# 2 KERNEL32.dll!BaseThreadInitThunk
Note: @0:01:04.572 in thread 7392
Note: instruction: cmp    0x08(%rcx) $0x0000000e

Error #31: UNINITIALIZED READ: reading 0x00000000009df538-0x00000000009df53c 4 byte(s)
# 0 IPHLPAPI.DLL!ConvertInterfaceNameToLuidW +0xd93    (0x00007ffa220f61e3 <IPHLPAPI.DLL+0x61e3>)
# 1 IPHLPAPI.DLL!GetAdaptersAddresses        +0x55     (0x00007ffa220f43d6 <IPHLPAPI.DLL+0x43d6>)
# 2 KERNEL32.dll!BaseThreadInitThunk
Note: @0:01:04.588 in thread 7392
Note: instruction: cmp    0x08(%rcx) $0x0000000e

Error #32: UNINITIALIZED READ: reading 0x0000000000aaaad4-0x0000000000aaaad6 2 byte(s) within 0x0000000000aaaad4-0x0000000000aaaad8
# 0 IPHLPAPI.DLL!GetAdaptersAddresses +0x4ea    (0x00007ffa220f486a <IPHLPAPI.DLL+0x486a>)
# 1 KERNEL32.dll!BaseThreadInitThunk
Note: @0:01:25.459 in thread 7392
Note: instruction: cmp    0x64(%rbx) $0x00000083

This points at issues not related to the added memory search functionality and occurred before the memory search function was called.

Diagram

To help future travellers or potentially myself, below is a diagram of the memory search buffer implementation:
image

@adfoster-r7
Copy link
Contributor

Looks like there's multiple warnings/errors on the mingw build

regex_t* compiled_needle;
};

#define NEEDLES_MAX (size_t)5
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this limit enforced in Metasploit/mettle somewhere? It seems a bit arbitrary 👀

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (buffer == NULL) { dprintf("[MEM SEARCH] Could not allocate memory buffer"); result = ERROR_OUTOFMEMORY; goto done; }

// The maximum length of data that we can read into a buffer at a time from a memory region.
const size_t current_max_size = megabytes_64;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this an arbitrary value, or does it come from somewhere as a recommended value, i.e. Microsoft docs etc?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its an arbitrary value. Microsoft doesn't mention any recommended values here, and I thought 64 MB was a suitable value. I'm not opposed to reducing this value 🚀

@sjanusz-r7 sjanusz-r7 force-pushed the add-windows-memory-search-support branch from e3dc185 to 92d04de Compare December 11, 2023 14:06
@sjanusz-r7 sjanusz-r7 marked this pull request as ready for review December 11, 2023 14:34
static HMODULE hKernel32 = NULL;
static HMODULE hNTDLL = NULL;

static GETPROCADDRESS fGetProcAddress = NULL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do these need to be global statics? I think the windows dispatcher is threaded for process handling, so I wonder if this approach would introduce quirks versus just using local variables on the stack 👀

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sync'd up with @sjanusz-r7 and this pattern is from:

static PCLOSECLIPBOARD pCloseClipboard = NULL;
static PCLOSEHANDLE pCloseHandle = NULL;
static PCREATEFILEA pCreateFileA = NULL;
static PDRAGQUERYFILEA pDragQueryFileA = NULL;
static PEMPTYCLIPBOARD pEmptyClipboard = NULL;
static PENUMCLIPBOARDFORMATS pEnumClipboardFormats = NULL;
static PGETCLIPBOARDDATA pGetClipboardData = NULL;
static PGETFILESIZEEX pGetFileSizeEx = NULL;
static PGLOBALALLOC pGlobalAlloc = NULL;
static PGLOBALFREE pGlobalFree = NULL;
static PGLOBALLOCK pGlobalLock = NULL;
static PGLOBALUNLOCK pGlobalUnlock = NULL;
static POPENCLIPBOARD pOpenClipboard = NULL;
static PSETCLIPBOARDDATA pSetClipboardData = NULL;

@adfoster-r7 adfoster-r7 merged commit 2430d20 into rapid7:master Jan 4, 2024
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants