TLDR; $SDS is an artifact for NTFS file systems. This artifact contain security descriptors to all files and folders on the drive, which means it will contain information of the file owner and permissions of the file. I also wrote a Rust 🦀 parser for this artifact that you can download from my Github.
Hello there! It has been a while since I wrote a blog, but I have been busy with other projects 🙂
NTFS has a file called $Secure that contains security descriptors for all files on the system. $Secure contains three streams with each stream containing different data to help retrieve the security descriptor for specific file. The following are the data streams for $Secure with there description:
The $SDS contains the most important data for digital forensics. This attribute contains a list of security descriptor with each security descriptor containing the following data:
Offset | Size | Type | Description |
0 | 4 | u32 | Security descriptor hash |
4 | 4 | u32 | Security descriptor identifier, can be retrieve from MFT record in the $STANDARD_INFORMATION attribute |
8 | 8 | u64 | Security descriptor data offset (in $SDS) |
16 | 4 | u32 | Security descriptor data size (in $SDS) |
20 | - | Security Descriptor Struct | Security descriptor struct data |
- | - | - | 16 bit alignment padding |
Retrieve the security ID from $STANDARD_INFORMATION attribute in MFT record then parser the $SDS and lookup the security ID from the MFT record in the ID field in the $SDS record. The following is an example MFT record along with the corresponding security descriptor from $SDS:
MFT record (parsed using https://github.com/omerbenamram/mft):
{
"header": {
"signature": [
70,
73,
76,
69
],
"usa_offset": 48,
"usa_size": 3,
"metadata_transaction_journal": 580089845936,
"sequence": 306,
"hard_link_count": 1,
"first_attribute_record_offset": 56,
"flags": "ALLOCATED",
"used_entry_size": 384,
"total_entry_size": 1024,
"base_reference": {
"entry": 0,
"sequence": 0
},
"first_attribute_id": 5,
"record_number": 170557
},
"attributes": [
{
"header": {
"type_code": "StandardInformation",
"record_length": 96,
"form_code": 0,
"residential_header": {
"index_flag": 0
},
"name_size": 0,
"name_offset": null,
"data_flags": "(empty)",
"instance": 0,
"name": ""
},
"data": {
"created": "2021-01-23T14:40:32.114948Z",
"modified": "2021-01-23T14:42:17.245694Z",
"mft_modified": "2021-01-23T14:42:17.245694Z",
"accessed": "2022-07-16T00:04:01.549904Z",
"file_flags": "FILE_ATTRIBUTE_ARCHIVE",
"max_version": 0,
"version": 0,
"class_id": 0,
"owner_id": 0,
"security_id": 4538,
"quota": 0,
"usn": 38532584952
}
},
{
"header": {
"type_code": "FileName",
"record_length": 112,
"form_code": 0,
"residential_header": {
"index_flag": 1
},
"name_size": 0,
"name_offset": null,
"data_flags": "(empty)",
"instance": 2,
"name": ""
},
"data": {
"parent": {
"entry": 5,
"sequence": 5
},
"created": "2021-01-23T14:40:32.114948Z",
"modified": "2021-01-23T14:40:32.114948Z",
"mft_modified": "2021-01-23T14:40:32.114948Z",
"accessed": "2021-01-23T14:40:32.114948Z",
"logical_size": 0,
"physical_size": 0,
"flags": "FILE_ATTRIBUTE_ARCHIVE",
"reparse_value": 0,
"name_length": 8,
"namespace": "Win32AndDos",
"name": "test.txt"
}
},
{
"header": {
"type_code": "ObjectId",
"record_length": 40,
"form_code": 0,
"residential_header": {
"index_flag": 0
},
"name_size": 0,
"name_offset": null,
"data_flags": "(empty)",
"instance": 3,
"name": ""
},
"data": {
"object_id": "3C783C19-5D7C-11EB-BE9B-5076AFA95947",
"birth_volume_id": null,
"birth_object_id": null,
"domain_id": null
}
},
{
"header": {
"type_code": "DATA",
"record_length": 32,
"form_code": 0,
"residential_header": {
"index_flag": 0
},
"name_size": 0,
"name_offset": null,
"data_flags": "(empty)",
"instance": 1,
"name": ""
},
"data": "5445535431"
}
],
"valid_fixup": true
}
$SDS record:
{
"hash": 3193908388,
"id": 4538,
"security_descriptor": {
"owner_sid": "S-1-5-32-544",
"group_sid": "S-1-5-21-412210041-3083678082-150370041-513",
"dacl": {
"revision": 2,
"count": 4,
"entries": [
{
"ace_type": "ACCESS_ALLOWED",
"ace_flags": "(empty)",
"data": {
"access_rights": 2032127,
"sid": "S-1-5-32-544"
}
},
{
"ace_type": "ACCESS_ALLOWED",
"ace_flags": "(empty)",
"data": {
"access_rights": 2032127,
"sid": "S-1-5-18"
}
},
{
"ace_type": "ACCESS_ALLOWED",
"ace_flags": "(empty)",
"data": {
"access_rights": 1179817,
"sid": "S-1-5-32-545"
}
},
{
"ace_type": "ACCESS_ALLOWED",
"ace_flags": "(empty)",
"data": {
"access_rights": 1245631,
"sid": "S-1-5-11"
}
}
]
},
"sacl": {
"revision": 2,
"count": 1,
"entries": [
{
"ace_type": "SYSTEM_MANDATORY_LABEL",
"ace_flags": "(empty)",
"data": {
"access_rights": 1,
"sid": "S-1-16-12288"
}
}
]
}
}
}
From the records above we can see that the file named test.txt is owned by the user with the SID S-1-5-32-544 (Administrators) and the group with SID S-1-5-21-412210041-3083678082-150370041-513 (Users)
Here are some examples of how $SDS artifact will help during Digital Forensics analysis:
From the above examples, you can see how the $SDS artifact could be helpful during analysis.
I developed a parser in Rust 🦀 to parser the $SDS stream, You can download sds_parser from Github
To build from source make sure you have Rust installed then run the following commands:
git clone
https://github.com/AbdulRhmanAlfaifi/SDSParser-rscd SDSParser-rs
cargo build --release
You will find the compiled binary at target/release/sds_parser
You can also use the pre-compiled binaries in the release section
No Comments - Yet 😁
Write a comment
You need to login to write comments - you can login from HERE or register from HERE