Closed HongThatCong closed 13 minutes ago
Hello, I fixed the structure offsets, but it is not matching well the metasploit hash for kernel32 + LoadLibraryA.
It Is accessing to the FullDllName, that should be “C:\Windows\System32\kernel32.dll” without quotes and in wide.
This python code calculates in same way the emulator does, and matches the hash with the emulator but not with metasploit:
# https://github.com/sha0coder/unsigned
from unsigned import Unsigned32 as u32
from unsigned import Unsigned64 as u64
lib = 'C\x00:\x00\\\x00W\x00i\x00n\x00d\x00o\x00w\x00s\x00\\\x00S\x00y\x00s\x00t\x00e\x00m\x003\x002\x00\\\x00k\x00e\x00r\x00n\x00e\x00l\x003\x002\x00.\x00d\x00l\x00l\x00'
api = 'LoadLibraryA\x00'
r9d = u32(0)
for al in lib:
c = ord(al)
if c >= 0x61:
c -= 0x20
r9d.ror(0x0d)
r9d.add(u32(c))
libhash = r9d
print('libhash',libhash.hex())
r9d = u32(0)
for al in api:
r9d.ror(0x0d)
r9d.add(u32(ord(al)))
r9 = u64(r9d())
r9.add(u64(libhash()))
final = hex(r9() & 0xffffffff)
print('final:',final) # 0xb47e823c
print('metasploit looks for: 0x726774c’)
I’m creating the ldr entry in this way:
…
ldr.dll_base = base;
ldr.entry_point = entry_point;
ldr.size_of_image = 0;
ldr.full_dll_name.length = full_libname.len() as u16 * 2;
ldr.full_dll_name.maximum_length = full_libname.len() as u16 * 2;
ldr.full_dll_name.buffer = space_addr + LdrDataTableEntry64::size();
ldr.base_dll_name.length = libname.len() as u16 * 2;
ldr.base_dll_name.maximum_length = libname.len() as u16 * 2;
ldr.base_dll_name.buffer = space_addr + LdrDataTableEntry64::size() + full_libname.len() as u64 * 2 + 10;
ldr.flags = 0;
ldr.load_count = 0;
ldr.tls_index = 0;
ldr.hash_links.flink = next_flink;
ldr.hash_links.blink = prev_flink;
mem.write_wide_string(space_addr + LdrDataTableEntry64::size(), &(full_libname.clone() + "\x00\x00"));
mem.write_wide_string(space_addr + LdrDataTableEntry64::size() + full_libname.len() as u64 * 2 +10, &(libname.to_string() + "\x00"));
ldr.save(space_addr, &mut emu.maps);
I have to do some window reversing to get how is the FullDllName, which is the input value of the hashing.
For now Im super busy and will continue on Sunday.
=>ldr
0x9a4 loader.exe flink:12e4 blink:6f64 base:7ff00aaa280 pe_hdr:f0 5045
0x12e4 ntdll.dll flink:1c24 blink:9a4 base:7ff000ee108 pe_hdr:e8 5045
0x1c24 kernel32.dll flink:2564 blink:12e4 base:7fefffbaa28 pe_hdr:f0 5045
0x2564 kernelbase.dll flink:2ea4 blink:1c24 base:7ff00492f30 pe_hdr:f0 5045
0x2ea4 iphlpapi.dll flink:37e4 blink:2564 base:7fefff38098 pe_hdr:f8 5045
0x37e4 ws2_32.dll flink:4124 blink:2ea4 base:7ff00311b80 pe_hdr:f0 5045
0x4124 advapi32.dll flink:4a64 blink:37e4 base:7ff003934c0 pe_hdr:100 5045
0x4a64 comctl64.dll flink:53a4 blink:4124 base:7ff007b68a8 pe_hdr:f8 5045
0x53a4 winhttp.dll flink:5ce4 blink:4a64 base:7ff0094f768 pe_hdr:f8 5045
0x5ce4 wininet.dll flink:6624 blink:53a4 base:7ff00b8aa00 pe_hdr:f0 5045
0x6624 dnsapi.dll flink:6f64 blink:5ce4 base:7ff0086a800 pe_hdr:f8 5045
0x6f64 shell32.dll flink:9a4 blink:6624 base:7ff788c0000 pe_hdr:f0 5045
=>dt
structure=>ldr_data_table_entry64
address=>0x1c24
LdrDataTableEntry64 {
in_load_order_links: ListEntry64 {
flink: 0x2564,
blink: 0x12e4,
},
in_memory_order_links: ListEntry64 {
flink: 0x2574,
blink: 0x9b4,
},
in_initialization_order_links: ListEntry64 {
flink: 0x2584,
blink: 0x1304,
},
dll_base: 0x7fefffbaa28,
entry_point: 0xf0,
size_of_image: 0x0,
full_dll_name: UnicodeString64 {
length: 0x40,
maximum_length: 0x40,
padding: 0x0,
buffer: 0x1d24,
},
base_dll_name: UnicodeString64 {
length: 0x18,
maximum_length: 0x18,
padding: 0x0,
buffer: 0x1d6e,
},
flags: 0x0,
load_count: 0x0,
tls_index: 0x0,
hash_links: ListEntry64 {
flink: 0x9a4,
blink: 0x12e4,
},
time_date_stamp: 0x0,
}
=>md
address=>0x1d24
0x1d24: 43 00 3a 00 5c 00 57 00 69 00 6e 00 64 00 6f 00 C.:.\.W.i.n.d.o.
0x1d34: 77 00 73 00 5c 00 53 00 79 00 73 00 74 00 65 00 w.s.\.S.y.s.t.e.
0x1d44: 6d 00 33 00 32 00 5c 00 6b 00 65 00 72 00 6e 00 m.3.2.\.k.e.r.n.
0x1d54: 65 00 6c 00 33 00 32 00 2e 00 64 00 6c 00 6c 00 e.l.3.2...d.l.l.
0x1d64: 00 00 00 00 00 00 00 00 00 00 6b 00 65 00 72 00 ..........k.e.r.
0x1d74: 6e 00 65 00 6c 00 33 00 32 00 2e 00 64 00 6c 00 n.e.l.3.2...d.l.
0x1d84: 6c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 l……………
It’s fixed, I’m going to publish the latest changes
~/s/scemu ❯❯❯ cargo run --release -- -f shellcodes64/metasploit.bin -6 ✘ 130 main ✱ ◼
Finished `release` profile [optimized] target(s) in 0.02s
Running `target/release/scemu -f shellcodes64/metasploit.bin -6`
use -vv to see the assembly code emulated, and -v to see the messages
loading memory maps
loading pe64: shellcodes64/metasploit.bin
shellcode detected.
----- emulation -----
** 635367 kernel32!LoadLibraryA 'ws2_32' =0x7ff00311b80
calling unimplemented ws2_32 API 0x7ff00320690 WSAStartup
WSAStartup(257, 1372936, 0, 0) (unimplemented)
calling unimplemented ws2_32 API 0x7ff00325b90 WSASocketA
WSASocketA(3, 2, 0, 0) (unimplemented)
** 3837112 ws2_32!connect family: 2 10.25.44.1:4444
invalid socket.
** 4897337 ws2_32!connect family: 2 10.25.44.1:4444
invalid socket.
** 5957562 ws2_32!connect family: 2 10.25.44.1:4444
invalid socket.
** 7017787 ws2_32!connect family: 2 10.25.44.1:4444
invalid socket.
** 8078012 ws2_32!connect family: 2 10.25.44.1:4444
invalid socket.
** 9138237 ws2_32!connect family: 2 10.25.44.1:4444
invalid socket.
^CCtrl-C detected, spawning console
--- console —
----- emulation -----
** 635367 kernel32!LoadLibraryA 'ws2_32' =0x7ff00311b80
** 1706051 ws2_32!WsaStartup
** 2776890 ws2_32!WsaSocketA
** 3837112 ws2_32!connect family: 2 10.25.44.1:4444
** 4895567 ws2_32!recv buff: 0x14f260 sz: 4
I published the fix on crates.io pypi and the 3 gits
Hi @sha0coder
Please test again with this simple metasploit x64 shellcode. And VirtualAlloc can still failed.
test.bin.gz
I use scemu/pyscemu and Speakeasy in parallel I highly appreciate the speed of scemu
Thank you very much