NTFSTool is a forensic tool focused on NTFS volumes. It supports reading partition info (MBR, partition table, VBR) but also information on Master File Table, Bitlocker encrypted volume, EFS encrypted files, USN journal and more.
Download the latest binaries on AppVeyor or by checking the last GitHub artefacts.
See below for some examples of the features!
NTFSTool displays the complete structure of master boot record, volume boot record, partition table and $MFT file record. It is also possible to dump any file (even $MFT or SAM) or parse and analyze USN journal, LogFile including streams from Alternate Data Stream (ADS). $MFT can be dumped as csv or json with Zone.Identifier parsing to quickly identify downloaded files. The undelete command will search for any file record marked as "not in use" and allow you to retrieve the file (or part of the file if it was already rewritten). It support input from image file, live disk or virtual like VeraCrypt and TrueCrypt, but you can also use tools like OSFMount to mount your disk image. Sparse and compressed files (lznt1, xpress) are also supported.
For bitlocked partition, it can display FVE records, check a password and key (bek, password, recovery key), extract VMK and FVEK. There is no bruteforce feature because GPU-based cracking is better (see Bitcracker and Hashcat) but you can get the hash for these tools.
Masterkeys, private keys and certificates can be listed, displayed and decrypted using needed inputs (SID, password). Certificates with private keys can be exported using the backup command.
Reinmport the backup on another machine to be able to read your encrypted file again!
Or you can use the efs.decrypt
command to decrypt a file using the backed-up key.
More information on Mimikatz Wiki
USN journal records can be analyzed using custom rules to detect suspicious programs and actions but also to have an overview of the journal (% of file deleted, created ...)
Default rules: Rules/default.json
{
"id": "lsass-dump",
"description": "Dumped LSASS.exe process.",
"severity": "high",
"rule": {
"filename": "lsass(\\.(dmp|dump))?"
}
}
See an example of run here: usn.analyze
There is a limited shell with few commands (exit, cd, ls, cat, pwd, cp, quit, rec).
Command rec
shows the MFT record details.
Help command displays description and examples for each command.
Options can be entered as decimal or hex number with "0x" prefix (ex: inode).
ntfstool help [command]
Command | Description |
---|---|
info | Display information for all disks and volumes |
mbr | Display MBR structure, code and partitions for a disk |
gpt | Display GPT structure, code and partitions for a disk |
vbr | Display VBR structure and code for a specidifed volume (ntfs, fat32, fat1x, bitlocker supported) |
extract | Extract a file from a volume. |
image | Create an image file of a disk or volume. |
mft.dump | Dump $MFT file in specified format: csv, json, raw. |
mft.record | Display FILE record details for a specified MFT inode. Almost all attribute types supported |
mft.btree | Display VCN content and Btree index for an inode |
bitlocker.info | Display information and hash ( |
bitlocker.decrypt | Decrypt a volume to a file using password, recovery key or bek. |
bitlocker.fve | Display information for the specified FVE block. |
efs.backup | Export EFS keys in PKCS12 (pfx) format. |
efs.decrypt | Decrypt EFS encrypted file using keys in PKCS12 (pfx) format. |
efs.certificate | List, display and export system certificates (SystemCertificates/My/Certificates). |
efs.key | List, display, decrypt and export private keys (Crypto/RSA). |
efs.masterkey | List, display and decrypt masterkeys (Protect). |
reparse | Parse and display reparse points from $Extend$Reparse. |
logfile.dump | Dump $LogFile file in specified format: csv, json, raw. |
usn.analyze | Analyze $UsnJrnl file with specified rules. Output : csv or json. |
usn.dump | Dump $UsnJrnl file in specified format: csv, json, raw. |
shadow | List volume shadow snapshots from selected disk and volume. |
streams | Display Alternate Data Streams |
undelete | Search and extract deleted files for a volume. |
shell | Start a limited Unix-like shell |
smart | Display S.M.A.R.T data |
- Some unsupported cases. WIP.
- No documentation 😶.
Feel free to open an issue or ask for a new feature!
-
Install Visual Studio 2022
-
Install vcpkg (for required third-party libs) as described here: vcpkg#getting-started
git clone https://github.com/microsoft/vcpkg .\vcpkg\bootstrap-vcpkg.bat
-
Integrate it to your VisualStudio env:
vcpkg integrate install
At build time, VisualStudio will detect the vcpkg.json
file and install required packages automatically.
Third-party libraries:
- openssl: OpenSSL is an open source project that provides a robust, commercial-grade, and full-featured toolkit for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols.
- nlohmann-json: JSON for Modern C++
- distorm: Powerful Disassembler Library For x86/AMD64
- cppcoro: A library of C++ coroutine abstractions for the coroutines TS.
- re2: RE2 is a fast, safe, thread-friendly alternative to backtracking regular expression engines.
info |
|
info disk=3 |
|
info disk=3 volume=1 |
|
mbr disk=2 |
|
gpt disk=1 |
|
vbr disk=3 volume=1 |
|
extract disk=0 volume=4 inode=0 output=d:\mymft |
|
extract disk=3 volume=1 from=\bob.txt output=d:\bob.txt |
|
extract disk=0 volume=4 --system output=d:\system |
|
image disk=2 volume=2 output=d:\imagevol.raw |
|
image disk=2 output=d:\image.raw |
|
mft.dump disk=2 volume=2 output=d:\mft.raw |
|
mft.dump disk=2 volume=2 output=d:\mft.csv format=csv |
|
Sample of mft.csv (check the end of the last line for Zone.Identifier data) |
RecordIndex,InUse,Type,Filename,Ext,Size,Parents,Time_MFT,Time_Create,Time_Alter,Time_Read,Att_Archive,Att_Compressed,Att_Device,Att_Encrypted,Att_Hidden,Att_Normal,Att_NotIndexed,Att_Offline,Att_Readonly,Att_Reparse,Att_Sparse,Att_System,Att_Temp,USN,Hardlinks,ADS,ZoneId,ReferrerUrl,HostUrl 0,"True","File","$MFT","",1048576,"5","2022-03-17 01:25:10","2022-03-17 01:25:10","2022-03-17 01:25:10","2022-03-17 01:25:10","False","False","False","False","True","False","False","False","False","False","False","True","False",0,1,"","","","" 1,"True","File","$MFTMirr","",4096,"5","2022-03-17 01:25:10","2022-03-17 01:25:10","2022-03-17 01:25:10","2022-03-17 01:25:10","False","False","False","False","True","False","False","False","False","False","False","True","False",0,1,"","","","" 2,"True","File","$LogFile","",67108864,"5","2022-03-17 01:25:10","2022-03-17 01:25:10","2022-03-17 01:25:10","2022-03-17 01:25:10","False","False","False","False","True","False","False","False","False","False","False","True","False",0,1,"","","","" 3,"True","File","$Volume","",0,"5","2022-03-17 01:25:10","2022-03-17 01:25:10","2022-03-17 01:25:10","2022-03-17 01:25:10","False","False","False","False","True","False","False","False","False","False","False","True","False",0,1,"","","","" ... 397,"True","File","vswhere.exe",".exe",457824,"103911","2020-10-19 18:42:19","2019-06-11 10:07:50","2019-06-11 10:07:52","2021-12-27 14:54:49","True","False","False","False","False","False","False","False","False","False","False","False","False",35944347632,1,"Zone.Identifier","3","https://github.com/microsoft/vswhere/releases","https://github-production-release-asset-2e65be.s3.amazonaws.com/78482723/06868000-5585-11e9-9001-982f1fcb7ef1?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20190611%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20190611T100747Z&X-Amz-Expires=300&X-Amz-Signature=bc494e9edaafb03874097ae46466c5562d34252f14f21140c70e6a1a1fc5e5c4&X-Amz-SignedHeaders=host&actor_id=40250307&response-content-disposition=attachment%3B%20filename%3Dvswhere.exe&response-content-type=application%2Foctet-stream" |
mft.record disk=2 volume=1 inode=5 (root folder) |
|
mft.btree disk=0 volume=1 inode=5 (root folder) |
|
bitlocker.info disk=3 volume=1 |
|
bitlocker.info disk=3 volume=1 password=badpassword |
|
bitlocker.info disk=3 volume=1 password=123456789 |
|
bitlocker.decrypt disk=3 volume=1 output=decrypted.img fvek=35b8197e6d74d8521f49698d5f5565892cf286ae5323c65631965c905a9d7da4 |
|
bitlocker.fve disk=3 volume=1 fve_block=2 |
|
efs.backup disk=0 volume=4 password=123456 |
|
efs.decrypt disk=0 volume=4 from=c:\cat.png pfx=z:\my_backup.pfx password=backup output=c:\socute.png |
|
efs.certificate disk=0 volume=4 |
|
efs.certificate disk=0 volume=4 inode=0xb5a4 |
|
efs.certificate disk=0 volume=4 inode=0xb5a4 output=mycert |
|
efs.key disk=0 volume=4 |
|
efs.key disk=0 volume=4 inode=742107 |
|
efs.key disk=0 volume=4 inode=742107 masterkey=34fac126105ce30...178c5bff4979eb |
|
efs.key disk=0 volume=4 inode=742107 masterkey=34...eb output=mykey |
|
efs.masterkey disk=0 volume=4 |
|
efs.masterkey disk=0 volume=4 inode=0x80544 |
|
efs.masterkey disk=0 volume=4 inode=0x80544 sid="S-1-5-21-1521398...3175218-1001" password="ntfst00l" |
|
reparse disk=0 volume=4 |
|
logfile.dump disk=4 volume=1 output=logfile.csv format=csv |
|
Sample of logfile.csv |
LSN,ClientPreviousLSN,UndoNextLSN,ClientID,RecordType,TransactionID,RedoOperation,UndoOperation,MFTClusterIndex,TargetVCN,TargetLCN 5269000,5268967,5268967,0,1,24,SetNewAttributeSizes,SetNewAttributeSizes,2,10,43700 5269019,5269000,5269000,0,1,24,UpdateNonresidentValue,Noop,0,0,37594 5269044,5269019,5269019,0,1,24,SetNewAttributeSizes,SetNewAttributeSizes,2,10,43700 5269063,5269044,5269044,0,1,24,SetNewAttributeSizes,SetNewAttributeSizes,2,10,43700 5269082,5269063,5269063,0,1,24,UpdateNonresidentValue,Noop,0,0,37594 5269103,5269082,5269082,0,1,24,SetNewAttributeSizes,SetNewAttributeSizes,2,10,43700 5269122,5269103,0,0,1,24,ForgetTransaction,CompensationLogRecord,0,0,18446744073709551615 5269133,0,0,0,1,24,UpdateResidentValue,UpdateResidentValue,2,13,43703 |
From dump : usn.analyze from=usn_dump rules=d:\rules.json output=d:\usn_analyze_results.csv format=csv |
From running system : usn.analyze disk=4 volume=1 rules=d:\rules.json output=d:\usn_analyze_results.csv format=csv |
|
usn.dump disk=4 volume=1 output=usn.csv format=csv |
|
Sample of usn.csv |
MajorVersion,MinorVersion,FileReferenceNumber,FileReferenceSequenceNumber,ParentFileReferenceNumber,ParentFileReferenceSequenceNumber,Usn,Timestamp,Reason,SourceInfo,SecurityId,FileAttributes,Filename 2,0,53,4,5,5,0,2020-02-26 21:43:36,FILE_CREATE,0,0,DIRECTORY,volume:\Nouveau dossier 2,0,53,4,5,5,96,2020-02-26 21:43:36,FILE_CREATE+CLOSE,0,0,DIRECTORY,volume:\Nouveau dossier 2,0,53,4,5,5,192,2020-02-26 21:43:38,RENAME_OLD_NAME,0,0,DIRECTORY,volume:\Nouveau dossier 2,0,53,4,5,5,288,2020-02-26 21:43:38,RENAME_NEW_NAME,0,0,DIRECTORY,volume:\test 2,0,53,4,5,5,360,2020-02-26 21:43:38,RENAME_NEW_NAME+CLOSE,0,0,DIRECTORY,volume:\test 2,0,53,4,5,5,432,2020-02-26 21:43:39,OBJECT_ID_CHANGE,0,0,DIRECTORY,volume:\test 2,0,53,4,5,5,504,2020-02-26 21:43:39,OBJECT_ID_CHANGE+CLOSE,0,0,DIRECTORY,volume:\test 2,0,54,2,53,4,576,2020-02-26 21:43:41,FILE_CREATE,0,0,ARCHIVE,volume:\test\Nouveau document texte.txt |
shadow disk=0 volume=4 |
|
streams disk=0 volume=4 from=c:\test.pdf |
|
undelete disk=4 volume=1 |
|
undelete disk=2 volume=1 format=csv output=mydeletedfiles.csv |
|
undelete disk=4 volume=1 inode=41 output=restored_kitten.jpg |
|
shell disk=4 volume=1 |
|
smart disk=1 |
|