dasec / fishy Goto Github PK
View Code? Open in Web Editor NEWToolkit for Filesystem based Data Hiding Techniques.
License: MIT License
Toolkit for Filesystem based Data Hiding Techniques.
License: MIT License
Parse APFS images that aren't perfectly prepared as the Wiki entry explains. Possible solution: find first NXSB instance and count the used blocks.
The new metadata encryption feature needs to be documented in:
Several improvements can/have to be made to the APFS Timestamp technique:
The choice of which timestamps should be written to needs to be simplified and accessible from the console (right now, the code would have to be changed).
Instead of writing to 4 bytes, the technique should only write to 30 bits.
The fileslack subcommand traverses the directory structure and uses all found files, if a directory is given as the destination. The info switch does not respect this, but treats a directory as a file, which results in unusable and false output.
I tried to write something to file slack of an NTFS filesystem, but got this:
$ echo "Simple test" | fishy -d utils/testfs-ntfs.dd fileslack -w -d another -m /tmp/meta.json
filesize:12
Traceback (most recent call last):
File "/usr/bin/fishy", line 11, in <module>
load_entry_point('fishy==0.1', 'console_scripts', 'fishy')()
File "/usr/lib/python3.6/site-packages/fishy-0.1-py3.6.egg/fishy/cli.py", line 127, in main
do_fileslack(args, device)
File "/usr/lib/python3.6/site-packages/fishy-0.1-py3.6.egg/fishy/cli.py", line 46, in do_fileslack
slacker.write(sys.stdin.buffer, args.destination)
File "/usr/lib/python3.6/site-packages/fishy-0.1-py3.6.egg/fishy/file_slack.py", line 75, in write
slack_metadata = self.fs.write(instream, filepaths)
File "/usr/lib/python3.6/site-packages/fishy-0.1-py3.6.egg/fishy/ntfs/ntfsSlackSpace.py", line 23, in write
m = self.slackTool.write(instream, filepaths)
File "/usr/lib/python3.6/site-packages/fishy-0.1-py3.6.egg/fishy/ntfs/ntfsSlack.py", line 121, in write
raise Exception("Not enough slack space")
Exception: Not enough slack space
Don't know if it matters, but the actual filesize is 4 Bytes on my system...
$ ls -l utils/fs-files/another
-rwxr-xr-x 1 xxxxx users 4 Oct 26 20:48 utils/fs-files/another
I used the ntfs-image created by running ./create_testfs.sh
Writing to other files, like 'long_file.txt', work fine.
Some Info-Switches that incorporate both non-metadata and metadata variants throw exceptions after printing the information when no metadata is used.
E.g. ext4 Superblock Slack throws a "not implemented" exception.
The construct library changed some things in their recent 2.9.X release so that our code is currently incompatible with their current version.
Maybe someone has the time to fix those incompatibilities. Meanwhile I will fix our requirements to construct in its pre 2.9 version.
The current info method of the ntfs.fileslack module lacks some information, that the user would need to thoughfully handle fileslack. My suggestion would be to unify the output to match the output of the fat.fileslack module.
For instance:
$ fishy -d testfs-fat12.dd fileslack -d another -m /tmp/foo -i
File: another
Occupied in last cluster: 4
Ram Slack: 508
File Slack: 1536
Implement Block Group class for Data / Inode Bitmaps and Data Blocks
When reading larger amounts of hidden data, the technique reads parts of the filesystem structure instead of the hidden data (e.g. seems to happen when reading a volume superblock for the first time).
As of right now, Timestamp Hiding in APFS hides data in 4 bytes of the nanosecond part of the timestamps. This potentially also affects the seconds of the timestamp.
To fix: Either write to only 3 bytes of the timestamp or determine the exact amount of bits (likely 30) and use them.
The metadata encryption feature needs to be unit tested.
If a user supplies a directory plus a file in this directory as destinations for fileslack exploitation, the autoexpansion of directories could lead to multiple writes into the slack space of the same file. For instance:
$ fishy -d testfs_fat12.dd fileslack -w -m "meta.json" -d adir/afile.txt -d adir longfile.txt
would first write into adir/afile.txt
, then expand adir
to adir/afile.txt
and then write again into the slack space of adir/afile.txt
.
This is an issue in FAT fileslack implementation, but I'm not sure if the NTFS implementation is affected.
InodeTable.getAllInodes always returns empty list. Seems like it cannot parse APFS structures correctly.
Use getpass.getpass()
Implement GDT class for parsing GDT.
Reading metadata files via the cli tool failes since the introduction of the metadata encryption feature.
Without encryption of the metadata file:
$ echo nonsense | fishy -d testfs-fat12.dd fileslack -d onedirectory -m /tmp/foo -w
$ fishy metadata -m /tmp/foo
Traceback (most recent call last):
File "/usr/bin/fishy", line 11, in <module>
load_entry_point('fishy', 'console_scripts', 'fishy')()
File "/home/matti/Seafile/Dokumente/Studium/5.Semester/PSE_-_Projekt_Systementwicklung/fishy/fishy/cli.py", line 204, in main
do_metadata(args)
File "/home/matti/Seafile/Dokumente/Studium/5.Semester/PSE_-_Projekt_Systementwicklung/fishy/fishy/cli.py", line 24, in do_metadata
meta.read(args.metadata)
File "/home/matti/Seafile/Dokumente/Studium/5.Semester/PSE_-_Projekt_Systementwicklung/fishy/fishy/metadata.py", line 211, in read
self.metadata = json.loads(instream.read().decode("utf8"))
AttributeError: 'str' object has no attribute 'decode'
With encryption of the metadata file:
$ echo nonsense | fishy -d testfs-fat12.dd -p lol fileslack -d onedirectory -m /tmp/foo -w
$ fishy metadata -m /tmp/foo
Traceback (most recent call last):
File "/usr/bin/fishy", line 11, in <module>
load_entry_point('fishy', 'console_scripts', 'fishy')()
File "/home/matti/Seafile/Dokumente/Studium/5.Semester/PSE_-_Projekt_Systementwicklung/fishy/fishy/cli.py", line 204, in main
do_metadata(args)
File "/home/matti/Seafile/Dokumente/Studium/5.Semester/PSE_-_Projekt_Systementwicklung/fishy/fishy/cli.py", line 24, in do_metadata
meta.read(args.metadata)
File "/home/matti/Seafile/Dokumente/Studium/5.Semester/PSE_-_Projekt_Systementwicklung/fishy/fishy/metadata.py", line 211, in read
self.metadata = json.loads(instream.read().decode("utf8"))
File "/usr/lib/python3.6/codecs.py", line 321, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa6 in position 9: invalid start byte
As the unit tests for reading and writing metadata pass, there might some inconsistencies between the tests and the usage via the cli.
We still need to decide under which license this project will be published...
Has anyone preferences?
MFT record 1 used size: 408
MFT record 2 used size: 303
-> writes Mirror of hidden data 2 (hidden in record 2) to mirror of record 1 at position 303
Don't know which form/which place are the best to document the responsibilities, but we must start somehow, so here some notes about what I remember. Please feel free to add stuff you or others have done.
If an error occures during the write process, already written data should be cleared before the program terminates. As we don't write a metadata file in this case, currently the user is not able to wipe those fragments from disk.
All three named hiding techniques open their filesystem streams by themself. This violates the principles, we defined earlier.
The cli already passes an open filesytem stream to the do_ function. So, they should use it.
Add remaining superblock fields to structure.
Some of us discovered a few problems while running the unittests. Under Debian and arch linux all FAT tests pass, but the NTFS test of MFT File Records failes with:
____________________________________________________________________ TestGetRecordOfFile.test_get_record_of_file ____________________________________________________________________
self = <test_ntfs.TestGetRecordOfFile object at 0x7f78e89e5fd0>, testfs_ntfs_stable1 = ['/tmp/tmpjej3b9pj/testfs-ntfs-stable1.dd']
def test_get_record_of_file(self, testfs_ntfs_stable1):
"""
Tests if the correct record is returned for
the supplied name
"""
with open(testfs_ntfs_stable1[0], 'rb') as fs:
ntfs = NTFS(fs)
assert ntfs.get_record_of_file('$MFT') == 0
assert ntfs.get_record_of_file('$MFTMirr') == 1
assert ntfs.get_record_of_file('$BadClus') == 8
assert ntfs.get_record_of_file('another') == 64
> assert ntfs.get_record_of_file('onedirectory/nested_directory') == 69
E AssertionError: assert 71 == 69
E + where 71 = <bound method NTFS.get_record_of_file of <fishy.ntfs.ntfs_filesystem.ntfs.NTFS object at 0x7f78e89e5748>>('onedirectory/nested_directory')
E + where <bound method NTFS.get_record_of_file of <fishy.ntfs.ntfs_filesystem.ntfs.NTFS object at 0x7f78e89e5748>> = <fishy.ntfs.ntfs_filesystem.ntfs.NTFS object at 0x7f78e89e5748>.get_record_of_file
tests/test_ntfs.py:69: AssertionError
Under ubuntu there are issues with the FAT tests but NTFS tests pass.
I was not able to reproduce the FAT test failures under the latest ubuntu version.
As suggested by the authority(tm) we should put our wrapper modules into their own directory, so the root package looks not so messy.
Implement hiding technique for Reserved GDT Blocks
The are some inconsistencies in the cli interface.
metadata
subcommand does not require a device (-d
), but all other commands do.fileslack
subcommand should not require a metadata fileAlso it might be nicer to move the -d
option behind the subcommand.
The argparse configuration should require all options which are actually required and should not require options, which are not required...
Edit:
add_mutually_exclusive_group
-d
option must be required, when writing to fileslackSome other things are wrong or need extension in the help output:
We need to add some sections to the documentation:
Why we wrote this tool, why should our program be used, analysis of existing tools...
Use case of our tool
Document create_testfs.sh
including testfs filestructure (the reason/test case for each file/directory)
Limitations of our program (e.g. linux only)
Evaluation of our program and hiding techniques
Extended usage, e.g. use pipes to add checksumming and encryption
Metadata: explicitly mention that it is serialized as json
Filesystem data structures for ntfs and ext4
Hiding Technique documentation (nearly all)
List all implemented hiding techiques in README.md AND doc/source/01_getting_started.rst
Api Reference for nearly all important modules
Development: move notes from readme to documentation and extend it
Future work (-> turn following bullet points into continuous text!)
-c
optionExtend "abstract"
include documentation structure (01_overview.rst)
Turn most bullet points into text
Make sphinx size included images to a format that fits on page for the pdf version.
For all:
e.g. calculate the amount of inodes needed and only extract that amount instead of all inodes (might break info switches - need to be changed as well)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.