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

Feature: Alternate Data Streams. #1044

Merged
merged 7 commits into from
Dec 3, 2023

Conversation

forensicxlab
Copy link
Contributor

Hello,
Just added a plugin next to MFTScan to extract ADS from the carved MFT records.
The ISF was also updated to include missing attributes.

Research : https://www.forensicxlab.com/posts/volads/

Best regards.

Copy link
Member

@ikelos ikelos left a comment

Choose a reason for hiding this comment

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

Thanks very much, this looks like it should make a good addition to the framework! There's a few bits to look at (mostly using cast rather than getting the offset and constructing a new object on top of it), but otherwise looks good. As it's a windows plugin, I'd still like @iMHLv2 to give it a review too though...

volatility3/framework/plugins/windows/mftscan.py Outdated Show resolved Hide resolved
volatility3/framework/plugins/windows/mftscan.py Outdated Show resolved Hide resolved
volatility3/framework/plugins/windows/mftscan.py Outdated Show resolved Hide resolved
volatility3/framework/plugins/windows/mftscan.py Outdated Show resolved Hide resolved
volatility3/framework/plugins/windows/mftscan.py Outdated Show resolved Hide resolved
@ikelos ikelos requested a review from iMHLv2 November 22, 2023 12:05
@ikelos
Copy link
Member

ikelos commented Nov 27, 2023

So you can see how I somewhat expected things to be done by looking at the issues/improve-mftscan branch, which changes away the manual offset modification and reading of data to instead construction objects and use the volatility object model to access everything. Hopefully this is much easier/cleaner to read which is why I've been pushing for it...

Copy link
Member

@ikelos ikelos left a comment

Choose a reason for hiding this comment

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

As mentioned above (sorry, I thought I'd posted this already), it does a lot of things manually which makes a great place for errors to sneak in. Rather than doing lots of offset maths out here, I'd much prefer to use the object model which is exactly what volatility is designed for. In the PR #1049 it gives an example of how I was expecting things to run in this...

volatility3/framework/plugins/windows/mftscan.py Outdated Show resolved Hide resolved
volatility3/framework/plugins/windows/mftscan.py Outdated Show resolved Hide resolved
@forensicxlab
Copy link
Contributor Author

forensicxlab commented Nov 28, 2023

Hello @ikelos,

I've introduced your fix to the ADS plugin so you can include your fix when this code lands.
Also added the MFTAttributein a custom class.

I hope you'll be happy with those changes. Learned a lot again about the framework, thank you for all your comments 😊

Best regards.

Copy link
Member

@ikelos ikelos left a comment

Choose a reason for hiding this comment

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

Yep, this looks much better!!! 5:D I'd prefer it if there was a little more error handling in places, but I'd be ok merging this as is if you really don't want to add the error handling, just let me know. Hopefully you're happier with it too? I think it's much more readable and easier to make sense of now... 5:)

volatility3/framework/plugins/windows/mftscan.py Outdated Show resolved Hide resolved
volatility3/framework/symbols/windows/extensions/mft.py Outdated Show resolved Hide resolved
@forensicxlab
Copy link
Contributor Author

Yep, this looks much better!!! 5:D I'd prefer it if there was a little more error handling in places, but I'd be ok merging this as is if you really don't want to add the error handling, just let me know. Hopefully you're happier with it too? I think it's much more readable and easier to make sense of now... 5:)

Yeap let's make things clean ! :) I will propose some exception handling based on your remarks in the coming days ;)
I am happy with it too, much cleaner and logic. Also a good exercise for me for future pull requests 😊

Many thanks.

@ikelos
Copy link
Member

ikelos commented Dec 2, 2023

Thanks, I'm afraid another commit snuck in that conflicts with your pull request. If you could fix it up then we can get it merged in... 5:)

@ikelos
Copy link
Member

ikelos commented Dec 2, 2023

Also please ensure the black formatter runs without issue, so the code formatting is consistent with the rest of the codebase... 5:)

@forensicxlab
Copy link
Contributor Author

forensicxlab commented Dec 3, 2023

Hello @ikelos,
Took some time but I think I have found a way to extract the ADS filename and the ADS content in a pretty way using the object model (no more direct layer reads).

Let me know what you think, I have the feeling that this is much cleaner... :)

Example output.

Volatility 3 Framework 2.5.1
Progress:  100.00               PDB scanning finished                  
Offset  Record Type     Record Number   MFT Type        Filename        ADS Filename    Hexdump Disasm

0xf98001423528  FILE    78477   DATA    PackageManagement_x64 (1).msi   Zone.Identifier
5b 5a 6f 6e 65 54 72 61 [ZoneTra
6e 73 66 65 72 5d 0d 0a nsfer]..
5a 6f 6e 65 49 64 3d 33 ZoneId=3
0x0:    pop     rbx
0x1:    pop     rdx
0x2:    outsd   dx, dword ptr [rsi]
0x3:    outsb   dx, byte ptr [rsi]
0x4:    push    rsp
0x6:    jb      0x69
0x8:    outsb   dx, byte ptr [rsi]
0x9:    jae     0x71
0xb:    jb      0x6b
0xe:    or      eax, 0x6e6f5a0a

Best regards.

Copy link
Member

@ikelos ikelos left a comment

Choose a reason for hiding this comment

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

Yep, this looks very clean. Just a syntactical change to make it a little easier to read, and then just a little question about always disassembling what's found in the ADSes...

interfaces.renderers.Disassembly(
content, 0, architecture.lower()
)
if architecture
Copy link
Member

Choose a reason for hiding this comment

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

I think this would be easier to read as:

disasm = interfaces.renderers.BaseAbsentValue
if architecture:
   disasm = interfaces.renderers.Disassembly(content, 0, architecture.lower())

Copy link
Member

Choose a reason for hiding this comment

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

Also, I get that our assumption is that ADS is most commonly used for hiding executable code, but could this not give a lot of false positives if the data stores in it is just data? Also there seems to be no limit on the amount of data that might be disabled? I assume files that are too large aren't stored in memory, but I just want to know the largest amount of data we might expect to find there, and how it might affect the output in volatility?

Copy link
Contributor Author

@forensicxlab forensicxlab Dec 3, 2023

Choose a reason for hiding this comment

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

I understand,
So, the ADS is mainly used legitimately by Microsoft to introduce for example the Zone.Identifier feature, which is a nice digital forensics clear text artefact to identify the origin of a file. This will be for me our first assumption. Indeed, the value of the ZoneID indicate whether a file is from the internet (3), trusted(2), untrusted(4) etc...The referer url might also be present.
This is a nice pivot point which is the reason for the Hexdump view in order for the analyst to check it in clear text.

A derived usage of this feature can indeed be from an adversary trying to hide malicous code like you said (our second assumption). Although there is some false positives when an ADS doesn't contain any clear text data, the analyst might want to check that the name of the ADS is a common data stream used by Windows and the disam view to identify potential code. But it not a common practice to put code in the ADS.

The largest amount of data you might expect per record is ~600 bytes or less for resident data (the remaining space left of the MFT entry which total size is 1024 bytes). This cannot be larger for a resident file. I think it will not affect the output in volatility3 😊

Copy link
Member

@ikelos ikelos left a comment

Choose a reason for hiding this comment

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

Awesome, all looks good, thanks!

@ikelos ikelos merged commit 799c7ed into volatilityfoundation:develop Dec 3, 2023
14 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.

4 participants