TLDR;$SDS是 NTFS 文件系统的工件。此项目包含驱动器上所有文件和文件夹的安全描述符,这意味着它将包含文件所有者的信息和文件的权限。我还为这个工件编写了一个 Rust ? 解析器,你可以从我的 Github 下载。
原文连接:https://u0041.co/blog/post/5
嗨,你好!自从我写博客以来已经有一段时间了,但我一直在忙于其他项目 ?
NTFS 有一个名为 $Secure 的文件,其中包含系统上所有文件的安全描述符。$Secure包含三个流,每个流包含不同的数据,以帮助检索特定文件的安全描述符。以下是带有描述的$Secure数据流:
- $SDH:在流中包含安全描述符哈希和偏移量$SDS查找
- $SII:包含流中的安全 ID 和偏移量查找$SDS。可以从每个 MFT 记录中存在的 $STANDARD_INFORMATION 属性中的安全 ID 字段中检索安全 ID
- $SDS:包含卷上所有文件和目录的所有安全描述符
$SDS流
$SDS包含数字取证最重要的数据。此属性包含安全描述符的列表,每个安全描述符包含以下数据:
- 对象所有者 SID
- 对象组 SID
- 对象自由访问控制列表 (DACL),标识分配或拒绝对对象的访问权限的用户和组
- 对象系统访问控制列表 (SACL),SACL 可以监视对受保护对象的访问
$SDS结构
Offset | Size | Type | 描述 |
0 | 4 | U32 | 安全描述符哈希 |
4 | 4 | U32 | 安全描述符标识符,可以从 $STANDARD_INFORMATION 属性中的 MFT 记录中检索 |
8 | 8 | U64 | 安全描述符数据偏移量($SDS) |
16 | 4 | U32 | 安全描述符数据大小($SDS) |
20 | – | Security Descriptor Struct | 安全描述符结构数据 |
– | – | – | 16 位对齐填充 |
如何找到MFT记录的安全描述符?
从 MFT 记录中的 $STANDARD_INFO 属性检索安全 ID,然后分析$SDS并从$SDS记录的 ID 字段中的 MFT 记录中查找安全 ID。下面是一个示例 MFT 记录以及 $SDS 中的相应安全描述符:
MFT 记录(使用 https://github.com/omerbenamram/mft 进行分析):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
{ "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记录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
{ "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" } } ] } } } |
从上面的记录中,我们可以看到名为 test.txt 的文件归 SID S-1-5-32-544 的用户(管理员)和 SID S-1-5-21-412210041-3083678082-150370041-513 的组(用户)拥有
这件神器的意义是什么?
以下是$SDS工件在数字取证分析过程中如何提供帮助的一些示例:
- 您有一个恶意文件被对手删除,但该文件的$MFT记录仍然存在?您可以使用$SDS项目查找创建此恶意文件的用户,并将该用户标记为已泄露,以检测此用户生成的其他项目
- 您在Web服务器上找到了一个Webshell,并想知道它是如何被删除的?您可以检查文件所有者的$SDS工件,以查看它是 Web 服务器进程还是其他用户。如果是 Web 服务器用户,这可能意味着攻击者利用了 Web 服务器中的漏洞并删除了 webshell。否则,webshell 可能已通过其他方式作为持久性丢弃在服务器上
- 一些加密矿工操纵其文件的权限以防止其他进程访问它们。$SDS工件将帮助您在离线分析中检查文件权限
从上面的示例中,您可以看到$SDS工件在分析过程中如何提供帮助。
SDSParser
我在 Rust ? 中开发了一个解析器来解析$SDS流,您可以从 Github 下载sds_parser
BUILD
要从源代码构建,请确保已安装 Rust,然后运行以下命令:
1 |
git clone </code><a href="https://github.com/AbdulRhmanAlfaifi/SDSParser-rs" target="_blank" rel="noreferrer noopener">https://github.com/AbdulRhmanAlfaifi/SDSParser-rs</a><code>cd SDSParser-rs</code><code>cargo build --release |
您将在目标/发布/sds_parser找到编译的二进制文件
使用预编译的二进制文件
您还可以在发布部分中使用预编译的二进制文件