forked from lautarolecumberry/DetectingFilelessMalware
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request lautarolecumberry#2 from lautarolecumberry/fix/Mem…
…2Disk fix mem2disk
- Loading branch information
Showing
3 changed files
with
111 additions
and
61 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
name: Windows.Memory.Mem2Disk | ||
author: Lautaro Lecumberry, Dr. Michael Denzel | ||
description: | | ||
This artifact compares executables in memory (RAM) with those | ||
on hard disk. This way, RAM injections are detected. This rarely | ||
happens legitimately and is mostly used by malware. | ||
This check is executed without dumping the memory and works live | ||
on the target system(s). | ||
parameters: | ||
- name: IgnoreOneByteOffsets | ||
description: Relative Virtual Adresses (RVA) cause an offset in the code in memory of a process. | ||
This is the case when the field BaseOfData is set to 0x8000. It creates false | ||
positives and is fairly safe to ignore (1-byte injections are really hard). | ||
default: True | ||
type: bool | ||
- name: UploadFindings | ||
description: Upload all executables where code in memory does not match code on disk. This | ||
can potentially generate a lot of traffic. Dry-run before enabling this option. | ||
default: False | ||
type: bool | ||
|
||
precondition: SELECT OS From info() where OS = 'windows' | ||
|
||
sources: | ||
- query: | | ||
-- first get all processes | ||
LET GetPids = | ||
SELECT Pid, Username | ||
FROM pslist() | ||
-- get all memory pages for a certain pid | ||
LET InfoFromVad = | ||
SELECT | ||
atoi(string="0x"+split(string=AddressRange, sep="-")[0]) as Address, | ||
filter(list=ProcessChain, regex=Pid)[0].Exe as Path | ||
FROM Artifact.Windows.System.VAD(PidRegex=str(str=Pid)) | ||
WHERE MappingName | ||
AND Protection =~ "xr-" | ||
AND MappingName =~ "(exe)$" | ||
-- parse the executable (PE) from memory (specifically, the text segment) | ||
LET GetMetadata = | ||
SELECT Path, | ||
Address, | ||
parse_pe(file=Path).Sections[0] AS TextSegmentData | ||
FROM InfoFromVad | ||
WHERE Address != 0 | ||
-- read the executable from memory and hard disk | ||
LET GetContent = | ||
SELECT *, | ||
format(format="%#x", args=Address) AS AddressHex, | ||
format(format="%x", | ||
args=read_file(accessor="process", | ||
offset=Address, | ||
filename=format(format="/%d", args=Pid), | ||
length=TextSegmentData.Size) | ||
) AS MemoryData, | ||
format(format="%x", | ||
args=read_file(accessor="file", | ||
offset=TextSegmentData.FileOffset, | ||
filename=Path, | ||
length=TextSegmentData.Size) | ||
) AS DiskData | ||
FROM GetMetadata | ||
WHERE len(list=MemoryData) != 0 | ||
AND len(list=DiskData) != 0 | ||
-- compare the executable from memory and hard disk | ||
-- only print the ones where they do not match | ||
LET Compare = | ||
SELECT Pid, | ||
Path, | ||
TextSegmentData.Size AS Size, | ||
MemoryData = DiskData AS Comparison | ||
FROM GetContent | ||
WHERE NOT Comparison | ||
-- compare with uploading the suspicious executables | ||
LET CompareAndUpload = | ||
SELECT *, | ||
upload( | ||
file=format(format="/%d", args=Pid), | ||
--offset=Address, | ||
--length=TextSegmentData.Size, | ||
name=Path+".mem", | ||
accessor="process" | ||
) AS UploadMem, | ||
upload( | ||
file=Path, | ||
--offset=TextSegmentData.FileOffset, | ||
--length=TextSegmentData.Size, | ||
name=Path+".disk", | ||
accessor="file" | ||
) AS UploadDisk | ||
FROM Compare | ||
-- for every process, evaluate the memory-harddisk-comparison | ||
SELECT * FROM foreach( | ||
row=GetPids, | ||
query=if(condition=UploadFindings, then=CompareAndUpload, else=Compare) | ||
) |