ufrisk / pcileech

Direct Memory Access (DMA) Attack Software
GNU Affero General Public License v3.0
4.68k stars 703 forks source link

memory dump seems to be empty #164

Closed sec-hack-research closed 3 years ago

sec-hack-research commented 3 years ago

Hi,

first of all, thank you for your intensive work. It finally motivated me to invest some more time in DMA based attacks.

Here is the issue I am facing since a few days, and I am not sure if it is a bug or a (stupid) mistake that I've made. I hope one can help me with this.

Pre-work that I've done

Used Hardware

Screamer M.2 USB-C (R04) + JTAGSerial pack from Lambdaconcept.

Hardware setup

So I've thought: 000x7ff7e3d70000 4.0K r C:\Windows\System32\notepad.exe might be of interest.

Check if PCILeech actually works

On the attacker machine: ./pcileech probe

with the result: [+] using FTDI device: 0403:601f (bus 1, device 92) [+] FTDIFTDI SuperSpeed-FIFO Bridge000000000001 Memory Map: START END #PAGES 0000000000000000 - 000000000009ffff 000000a0 00000000000c0000 - 000000008f7fffff 0008f740 0000000100000000 - 000000086effffff 0076f000

Current Action: Probing Memory Access Mode: Normal Progress: 34544 / 34544 (100%) Speed: 171 MB/s Address: 0x000000086F000000 Pages read: 8382432 / 8843264 (94%) Pages failed: 460832 (5%) Memory Probe: Completed.

Read memory content of notepad

Now begins my issue, where I've now read multiple documents on how Windows organizes his memory and how pmap actually shows the content. Sorry in advance, since for an expert, many things might be obvious - but I still need to learn a lot. Obviously, I can't read from 0x7ff7e3d70000, and I guessed PCILeech reads complete pages. Page-size seemed to be 4k (?).

0x7ff7e3d70000 devided by 4000 -> 0x1FFDF8F5C

Display memory content:

./pcileech display -min 0x1FFDF8F5C

resulted in (and I hope the following text is not the memory content of my opened keepass..):

[+] using FTDI device: 0403:601f (bus 1, device 92) [+] FTDIFTDI SuperSpeed-FIFO Bridge000000000001 Memory Display: Contents for address: 0x00000001FFDF8000 0f50 c6 01 74 0b 48 8d 4c 24 40 ff 15 11 57 12 00 c7 ..t.H.L$@...W... 0f60 44 24 20 00 00 00 00 4c 8d 0d d2 f7 1d 00 4c 8d D$ ....L......L. 0f70 05 53 e0 1d 00 33 d2 48 8b cf e8 4c 77 0f 00 48 .S...3.H...Lw..H 0f80 85 c0 75 0e 48 8b d3 48 8b cf ff 15 40 56 12 00 ..u.H..H....@V.. 0f90 eb 0b 48 8b d0 48 8b cb e8 23 00 00 00 48 8b 4c ..H..H...#...H.L 0fa0 24 78 48 33 cc e8 b6 49 0f 00 4c 8d 9c 24 80 00 $xH3...I..L..$.. 0fb0 00 00 49 8b 5b 20 49 8b 73 28 49 8b e3 5f c3 cc ..I.[ I.s(I.... 0fc0 4c 8b dc 57 48 83 ec 70 49 c7 43 b0 fe ff ff ff L..WH..pI.C..... 0fd0 49 89 5b 18 49 89 73 20 48 8b 05 31 94 1d 00 48 I.[.I.s H..1...H 0fe0 33 c4 48 89 44 24 68 48 8b fa 48 8b d9 33 f6 89 3.H.D$hH..H..3.. 0ff0 74 24 24 48 3b d1 75 43 41 b9 68 14 00 00 4c 8d t$$H;.uCA.h...L. 1000 ef f5 fa 36 39 89 58 66 ba 0e 95 e9 7c 15 99 ae ...69.Xf....|... 1010 d3 59 e8 5c 98 02 db 5f f5 3c 8d 8e 73 01 2b dd .Y.....<..s.+. 1020 e8 df a1 6a 83 41 7a d1 0e 34 8a 7b b0 5c 0c 71 ...j.Az..4.{..q 1030 6d 17 3a c4 6e dc 22 f6 60 9d 18 ae c8 71 bd 1e m.:.n.".`....q.. 1040 c0 5e 37 c7 d5 d1 2d 9c 1c 17 c4 77 bc ea 78 ad .^7...-....w..x.

So I though, great, he seems to read memory content. To verify, I've also read 0x1FFDF9000, which resulted in different content.

Dump memory to file

My logical next step was to try to dump the potentially interesting content to a file.

./pcileech dump -min 0x1FFDF8F5C -max 0x1FFDF8F68

[+] using FTDI device: 0403:601f (bus 1, device 92) [+] FTDIFTDI SuperSpeed-FIFO Bridge000000000001 Memory Dump: Successful.

However, the resulting file is empty!

-rw-rw-r-- 1 user user 0 Feb 5 13:48 pcileech-1ffdf8f5c-1ffdf8f68-1210135-134857.raw

-> Is this now a bug, or am I doing something wrong? <-

If I can "display" memory content, why can't I dump this to a file? Since with "display" I did see something, I also thought I do not have to inject any kernel-module to the target-system. A "full dump" seems to work, but it is quite slow and with my 32GB of RAM - produces quite big analysis files.

./pcileech dump

[+] using FTDI device: 0403:601f (bus 1, device 92) [+] FTDIFTDI SuperSpeed-FIFO Bridge000000000001 Memory Dump: Initializing ... Done. Current Action: Dumping Memory Access Mode: Normal Progress: 34544 / 34544 (100%) Speed: 22 MB/s Address: 0x0000000100000000 Pages read: 8382368 / 8843264 (94%) Pages failed: 460896 (5%) Memory Dump: Successful.

-rw-rw-r-- 1 user user 34G Feb 5 15:51 pcileech-0-86f000000-1210135-152600.raw

What am I doing wrong? Thanks for your time in advance!

Cheers, Dennis

ufrisk commented 3 years ago

It's good to see that PCILeech seems to be working.

When you try to read the notepad memory you're messing up virtual memory with physical memory.

Virtual memory is what processes on the CPU executes in. Your notepad address: 0x7ff7e3d70000 is a virtual address specific to notepad.

Virtual addresses are translated into physical addresses by the Memory Management Unit (MMU) on the CPU using Page Tables. The max physical address is: 0x86effffff according to the probe.

Please check out my MemProcFS, it should do what you want; i.e. translate physical memory into virtual memory in a virtual file system. It's Windows only though. Download MemProcFS; Install the Dokany virtual file system driver; Download the FTDI driver and run it with: MemProcFS.exe -device fpga https://github.com/ufrisk/MemProcFS


About the speed; even tho Linux have slightly lower read performance than Windows due to driver support what you're experiencing is just extremely slow. I suspect that you have a USB2 connection - i.e. a USB2 port on your computer; or the cable (or extension) being USB2 only.

But please test with the MemProcFS on Windows for this. Please let me know how it goes.

sec-hack-research commented 3 years ago

Hi,

some more details / infos and of course new questions.

Info about the initial filed issue (to be closed):

Since I of course wanted to follow your advice and appreciate the time you take for my "support/bug" questions, I've now also installed Windows10 on my attacker-machine. After struggling a bit around with the FTDI driver and certain other issues, I've finally managed to execute

C:\dev\pcileech-bin>pcileech probe

 Memory Map:
 START              END               #PAGES
 0000000000000000 - 000000000009ffff  000000a0
 00000000000c0000 - 000000008f7fffff  0008f740
 0000000100000000 - 000000086effffff  0076f000

 Current Action: Probing Memory
 Access Mode:    Normal
 Progress:       34544 / 34544 (100%)
 Speed:          283 MB/s
 Address:        0x000000086F000000
 Pages read:     8382432 / 8843264 (94%)
 Pages failed:   460832 (5%)
Memory Probe: Completed.

From Windows, I in fact do manage to dump memory to a file.

C:\dev\pcileech-bin>pcileech.exe dump -min 0x100000000 -max 0x100002000

 Current Action: Dumping Memory
 Access Mode:    Normal
 Progress:       0 / 0 (100%)
 Speed:          8 kB/s
 Address:        0x0000000100002000
 Pages read:     2 / 2 (100%)
 Pages failed:   0 (0%)
Memory Dump: Successful.

07.02.2021 15:18 8.192 pcileech-100000000-100002000-20210207-151842.raw

Without my dump mistake on physical and virtual memory, using the right addresses, this also works from LInux:

./pcileech dump -min 0x100000000 -max 0x100002000

[+] using FTDI device: 0403:601f (bus 1, device 2)
[+] FTDIFTDI SuperSpeed-FIFO Bridge000000000001
 Current Action: Dumping Memory
 Access Mode:    Normal
 Progress:       0 / 0 (100%)
 Speed:          8 kB/s
 Address:        0x0000000100002000
 Pages read:     2 / 2 (100%)
 Pages failed:   0 (0%)
Memory Dump: Successful.

-rw-rw-r-- 1 user user 8192 Feb 7 16:13 pcileech-100000000-100002000-1210137-161303.raw

Thus, my original topic obviously can be closed. Thanks.

MemProcFS

I do see your point that probably MemProcFS is the "environment/tool" that would be of high interest for me. I think for analytical things or forensic tasks, this would be super-perfect (according to what I've seen from your public presentations and read from the docu). However, I of course want to be as stealthy as possible. I have not even started to read your code, and because of the complexity, I have my doubts that this would be an easy task for me to do.

Question-1:

Is MemProcFS (on the target machine) injecting and executing any new kernel-modules or similar to do its job? If so, wouldn't it be an "easy" job for Microsoft or any antivirus software (even though I have my doubts that an antivirus-software could intercept execution of kernel-modules) to monitor what kernel-modules are loaded and before execution do some sanity-checks to find out if the new kernel-module might be unknown/malicious? Similar to Secure Boot and sbsign/kmodsign? Yes, in theory with DMA, an attacker would be able to circumvent the check (e.g., exchange the signature-used-pub-keys or simply exchange jump-equal with jump-not-equal), but the required attack would be a very "targeted attack" and the OS provider could make your tool-update-life very hard (to catch up with OS updates/countermeasures).

Same for "Anti-Virus" or "Anti-Cheat" software etc., wouldn't they be able to read out what kernel-modules are loaded and compare hashes of them to known signature-files? Or malware could delete itself from memory/disc if certain forensic-kernel-modules are detected.

Question-2 (most important one):

So far, I've failed to use MemProcFS. "FPGA://devreload=1,algo=0" seems to cause the FPGA to hang and require a target-system-reboot. But by executing

MemProcFS.exe -device FPGA://devreload=0,algo=0 -waitinitialize -memmap auto -pythonpath C:\Users\Win10Login\AppData\Local\Programs\Python\Python39 -mount Z -vv

I do see a LOT debug-output, ending with:

(more content above that I've removed)
VmmWinReg_KeyInitialize: BAD HBIN HEADER: Hive=ffffa20d0aee6000 HBin=00007000 Sig=43464908
VmmWinReg_KeyInitialize: BAD HBIN HEADER: Hive=ffffa20d0aee6000 HBin=00008000 Sig=40000852
VmmWinReg_KeyInitialize: BAD HBIN HEADER: Hive=ffffa20d0aee6000 HBin=00009000 Sig=1200424b
VmmWinReg_KeyInitialize: BAD HBIN HEADER: Hive=ffffa20d0aee6000 HBin=0000a000 Sig=d73dc041
VmmWinReg_KeyInitialize: BAD HBIN HEADER: Hive=ffffa20d0aee6000 HBin=0000b000 Sig=50535010
VmmWinReg_KeyInitialize: BAD HBIN HEADER: Hive=ffffa20d0aee6000 HBin=0000c000 Sig=a4030a69
VmmWinReg_KeyInitialize: BAD HBIN HEADER: Hive=ffffa20d0aee6000 HBin=0000d000 Sig=699306a0
VmmWinReg_KeyInitialize: BAD HBIN HEADER: Hive=ffffa20d0aee6000 HBin=0000e000 Sig=194dea17
VmmWinReg_KeyInitialize: BAD HBIN HEADER: Hive=ffffa20d0aee6000 HBin=0000f000 Sig=33325052
VmmWinReg_KeyInitialize: BAD HBIN HEADER: Hive=ffffa20d0aee6000 HBin=00010000 Sig=544c8800
VmmWinReg_KeyInitialize: BAD HBIN HEADER: Hive=ffffa20d0aee6000 HBin=00011000 Sig=47706068
VmmWinReg_KeyInitialize: BAD HBIN HEADER: Hive=ffffa20d0aee6000 HBin=00012000 Sig=090aa400
VmmWinReg_KeyInitialize: BAD HBIN HEADER: Hive=ffffa20d0aee6000 HBin=00013000 Sig=5341424e
VmmWinReg_KeyInitialize: BAD HBIN HEADER: Hive=ffffa20d0aee6000 HBin=00014000 Sig=0b4e5243
VmmWinReg_KeyInitialize: BAD HBIN HEADER: Hive=ffffa20d0aee6000 HBin=00015000 Sig=545f0068
LcMemMap_AddRange: 0000000000001000-000000000009bfff -> 0000000000001000
LcMemMap_AddRange: 0000000000100000-0000000000101fff -> 0000000000100000
LcMemMap_AddRange: 0000000000103000-0000000086da0fff -> 0000000000103000
LcMemMap_AddRange: 0000000086da3000-000000008e0b4fff -> 0000000086da3000
LcMemMap_AddRange: 000000008e59d000-000000008e643fff -> 000000008e59d000
LcMemMap_AddRange: 000000008f7ff000-000000008f7fffff -> 000000008f7ff000
LcMemMap_AddRange: 0000000100000000-000000086effffff -> 0000000100000000
PluginManager: Load DLL: 'm_vmemd.dll'
VmmPyPluginManager: Python Path: C:\Users\Win10Login\AppData\Local\Programs\Python\Python39\;C:\Users\Win10Login\AppData\Local\Programs\Python\Python39\python39.zip;C:\Users\Win10Login\AppData\Local\Programs\Python\Python39\DLLs\;C:\Users\Win10Login\AppData\Local\Programs\Python\Python39\Lib\;C:\Users\Win10Login\AppData\Local\Programs\Python\Python39\Lib\site-packages\;C:\dev\MemProcFS-bin\;C:\dev\MemProcFS-bin\pylib\

=============== MemProcFS - THE MEMORY PROCESS FILE SYSTEM ===============
 - Author:           Ulf Frisk - pcileech@frizk.net
 - Info:             https://github.com/ufrisk/MemProcFS
 - License:          GNU Affero General Public License v3.0
   --------------------------------------------------------------------
   MemProcFS is free open source software. If you find it useful please
   become a sponsor at: https://github.com/sponsors/ufrisk Thank You :)
   --------------------------------------------------------------------
 - Version:          3.8.3
 - Mount Point:      M:\
 - Operating System: Windows 10.0.19041 (X64)
==========================================================================

MOUNT: Failed. Status Code: -3

Interesting here aswell is, I've tried to mount to Z:\ (unused in my attacker-windows), but the debug-message indicates I've tried to mount to M:. A second try to curiously mount to Q ("-mount Q"), now results in the correct error message:

(more content that I've removed above)
 - Mount Point:      Q:\
 - Operating System: Windows 10.0.19041 (X64)
==========================================================================

MOUNT: Failed. Status Code: -3

Any idea why M: Q: V: Y: (and probably more) work (work means correct error message), but Z: does "fallback" to "M:\"?

And of course, what might be the reason to not mount? My cmd-shell is running with admin privs. The directory does contain FTD3XX.dll and I think I've installed dokan correctly (but do not have any more idea how to debug if dokan is the issue here, since DLLs of dokan seem to be present in the relevant windows folders).

Running with -vvv by the way causes it to run for >10 minutes, but the overall outcome is the same: "MOUNT: Failed. Status Code: -3"

Some more dokan output:

"C:\dev\Dokan\full\dokan\x64\Release>dokanctl.exe /i d
Driver path: 'C:\Windows\system32\drivers\dokan1.sys'
Installing driver...
DokanServiceInstall: Service (Dokan1) is already installed
Driver install failed

C:\dev\Dokan\full\dokan\x64\Release>dokanctl.exe /i n
Driver path: 'C:\Windows\system32\drivers\dokan1.sys'
network provider install ok"

Dokan-Version:

C:\dev\Dokan\full\dokan\x64\Release>dokanctl.exe /v
Driver path: 'C:\Windows\system32\drivers\dokan1.sys'
dokanctl : Jan 14 2021 10:57:44
Dokan version : 141
Dokan Error: Failed to open \\.\Dokan_1 with code 2
Dokan driver version : 0x0

What might go wrong here with the mounting within MemProcFS? Thanks in advance.

Kind regards, Dennis

ufrisk commented 3 years ago

1) MemProcFS is read-only unless you actively write something, for example by editing a virtual memory backed file. Some AC's commonly detect PCILeech devices by looking at which devices are attached to the system. There are ways around this. I'm not doing cheats but there is plenty of information on this if you google on that topic.

2) Very Verbose (-vv) output is just that. Very verbose; the error messages tell you that something went wrong in parsing a few memory pages belonging to the Windows Registry; this is normal and no worries about that.

3) M: is the default option unless you specify something else. Maybe there was an error in your driver mount syntax or something else. As far as the different Dokan error codes; please check the Dokan project for this.

I'll try running it with -vvv for longer periods; running it with -vvv must be extremely painful. My best guess is that there is a timeout while printing massive amount of TLPs which causes dokan to fail. Just don't run it with -vvv unless you absolutetly have to.

sec-hack-research commented 3 years ago

Hi,

I finally managed to use MemProcFS (precompiled)! The (latest) mistake I had above was in fact a broken installation of Dokan.

Thus, to everyone: if you are facing any issues with any error-message regarding the mount itself, I highly suggest to:

With this, I finally was able to use MemProcFS with: MemProcFS.exe -device FPGA://devreload=0,algo=0 -waitinitialize -memmap auto -pythonpath C:\Users\Win10Login\AppData\Local\Programs\Python\Python39 -mount N

Now I will spend some time and evaluate what I could do with it.

Thanks a lot again for your patience and help!

Cheers, Dennis

ufrisk commented 3 years ago

Thanks for the update. I'm glad it seems to be working for you. Also, the API for C/C++/C# or Python may be of interest to you. It's documented in the example projects and the guide. Good Luck with your DMA investigations.

If you should find PCILeech / MemProcFS useful please consider sponsoring the project here on Github. I see people purchasing hardware for hundreds of dollars (of which I receive absolutely zero dollars of) just to be able to run my free open source software. Sponsorships go for as little as $2 and Github is matching it - a $2 sponsorship for you is a $4 sponsorship for me. Thank You 💖