sha0coder/libscemu

Still have a bug in PEB walking

Closed this issue · 5 comments

Hi @sha0coder

Please test again with this simple metasploit x64 shellcode.
And VirtualAlloc can still failed.

21 Reading PEB 0x7fefff00320
22 0x3c0018: push  rsi ;0x1
23 0x3c0019: mov   rdx,[rdx+18h]
24 0x3c001d: mov   rdx,[rdx+20h]
25 0x3c0021: xor   r9,r9
26 0x3c0024: mov   rsi,[rdx+50h]
27 0x3c0028: movzx rcx,word ptr [rdx+4Ah]
28 0x3c002d: xor   rax,rax
29 0x3c0030: lodsb [rsi]
lodsb: memory read error
=>dt
structure=>PEB
address=>0x7fefff00320
thread 'main' panicked at C:\Rust\cargo\registry\src\index.crates.io-6f17d22bba15001f\libscemu-0.18.5\src\emu\structures.rs:363:53:
called `Option::unwrap()` on a `None` value
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

test.bin.gz

I use scemu/pyscemu and Speakeasy in parallel
I highly appreciate the speed of scemu

Thank you very much

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