AravisFS π»π
A remote fake encrypted filesystem π Another non production-ready software
ππππππππππ
Any idea, criticism, contribution is welcome
No pretention just to learn and keep my mind busy
ππππππππππ
π¦ Idea | πΊ Installation | π Usage | π§ How does it work? | πLimits/improvements
π¦ Idea
Aim? Providing a fake encrypted FS and utilities to interact with. The objective is to leak as little information as possible.
The local machine is our trusted environment where we could manipulate the key, the clear-text data etc. This is our (light side).
On another untrusted location we have our "encrypted file system". We do not want to manipulate key or clear text but we want to be able to interact as much as possible with the encrypted fs. This is our (dark side). Practically, it is a cloud space (or any other space when we want to store data without being spied on. On compromise machine during a Pentest for example)
For this purpose we use 2 utilities, each on different side:
adret
: Encrypt/decrypt fs etc. Deal with key & clear-text data (light side)ubac
: Interact with encrypted fs. Deal with no "sensitive" data (no key & clear-text manipulation) (dark side)
We accept to leak information about the fs structure (number of file/folder, size) on the dark side
Note: adretctl
offer a much clever user experience of adret utility with a CLI etc. See usage
Use case?
- To avoid your volume being spied on by your cloud provider
- To make a temporary folder/fs on a target machine if you are a black hat and you do not want to be spied on by forensic people. Or if you want to hide a payload.
- To get a manipulable ransomware
- To share data with colleague without setting up a hardened db or others. (just share and update
.arfs
file) - To boast of having an encrypted fs .. but practically unusable anyway
Why "fake"?
- Cause encryption isn't strong enough (AES ECB)
- Cause it does not provide a real fs, just a representation of it. (And to be honest it only encrypts a folder but by extension we say a filesystem)
πΊ Installation
Clone the repo and download the dependencies locally:
git clone https://github.com/ariary/AravisFS.git
make before.build
To build adret
:
make build.adret
To build adretctl
:
make build.adretclt
Idem, to build ubac
:
make build.ubac
REMINDER: use adret
/adretctl
in an trusted environment cause it will manipulate clear-text data and key. Transfer ubac
utility where you encrypted fs is (w/ tftp, python web server, nc, certutil, etc Be creative)
π Usage
Adretctl & ubac demo
In this demo, I have an encrypted fs (encrypt with key "toto") on the untrusted zone. ubac listen
expose it and interact with it using adretctl
: browse it, cat file and delete a directory
See adretctl spec
π Encrypt folder/fs
π Explore encrypted folder
List folder content from my encrypted fs
First I encrypt my fs :(local) $ adret encryptfs -key=<secret> <path>
[...]
test/mytestfolder/titi
[...]
done! Encrypted fs saved in encrypted.arafs
Then I put the result, our encrypted fs .arafs
, and ubac
utility on the dark zone the way I want( It could be a target machine, my OVH server, container on GKE, etc). I could then remove <myfolder>
from my host, otherwise it has real no sense (see example)
Say I want to ls
in "test/mytestfolder/titi"
, so I encrypt first the encrypt the path:
(local) $ adret darkenpath -key="toto" "test/mytestfolder/titi"
**We obtain encrypted path! COPY THE RESULT**
Then we do the ls
in our encrypted fs:
(remote) ubac ls -path=myencryptedfs.arafs <encryptedpath_from_adret>
**We obtain ls result! COPY THE RESULT**
And finally decrypt the result of ls:
(local) $ adret decryptls -key="toto"
tutu tutu.txt utut.txt
Print file content from my encrypted fs
Idem as above with ls
but change the ubac
command with:
(remote) ubac cat -path=myencryptedfs.arafs <encryptedpath_from_adret>
Print encrypted fs tree
First retrieve encrypted tree from encrypted fs:(remote) ubac tree test/arafs/medium.arafs
**We obtain the encrypted tree result! COPY THE RESULT**
Then decrypt it to print it with (assume the fs was encrypted with the key "toto"):
(local) $ adret decrypttree -key="toto" <encryptedtree_from_ubac>
π€ Automate a bit
If you want to interact with your remote encrypted fs more fluidly
Prerequisites
- my encrypted fs +
ubac
on remote - remote is accesible on port
<ip>:<port>
adret
on local- have the
key
which encrypt the fs
List folder content from remote encrypted fs
Start your `ubac` listener on the remote where the encrypted fs is :(remote) $ ubac listen -path="./test/arafs/encrypted.arafs" 4444
** IT WILL LAUNCH AN HTTP SERVER WAITING FOR REQUEST ON PORT 4444***
An local machine configure your environment variable to dial with remote ubac listenerConnect to the listener with your local machine:
(local) $ eval `adret configremote -port="4444" -host=<remote_ubac_hostname>`
I can now interact directly with my encrypted fs on my local machine and obtain direct result:
(remote) $ adret remotels -key=toto test/mytestfolder
Print file content from remote encrypted fs
Launchubac
listener and config local host wit adret
like above and launch `remotecat`:
(remote) $ adret remotecat -key=toto test/mytestfolder/toto.txt
βοΈ Manipulate encrypted fs
Remove a file from encrypted fs
First retrieve encrypted tree from encrypted fs:
(remote) ubac tree test/arafs/medium.arafs
**We obtain the encrypted tree result! COPY THE RESULT**
Then get a patch (which describes the changes you want to make):
(local) adret rmpatch -key=toto -tree=<output_ubac_tree> <resource_I_want_to_remove>
***WE OBTAIN A PATCH COPY IT***
Then apply the patch onto the encrypted fs
(remote) ubac applypatch -path=encrypted.arafs <my_patch>
π§ How does it work?
Magic!
How is the fs encrypted ?
When the adret
utlity encrypt a folder it returns what we called the "encrypted filesystem" wich has .arafs
extension. It is in fact a text file of the fs representation (encrypted of course).
The structure of the content of the .arafs
file is influenced by the following constraint: it musts be used to retrieve data without using the key
Encrypted fs data structure
For this reason, the data stracture of the content is a (unordered) list of all the "resources" present in the folder. In that way, we could only know how many resources the encrypted fs has and also the size of the fs without having the key.
Resource
A resource is:
πname | type | πcontent |
name: is the encrypted value of the path of the resource type : is the type of the ressource within the fs. it could be:
- folder
- file
content: is the content of the resource ie a list of child resources name if type is folder or the file content if type is file
Example: Search in encrypted fs
Take the example of ubac ls -path=myencryptedfs.arafs darkpath
which aims to perform ls
of the darkpath
in myencryptedfs.arafs
.
First it will search the darkpath
(it is an encrypted path) name in the list which is myencryptedfs.arafs
.
If the type is file it will return the filename.
If the type is a folder it will take the content part which is all its child resources encyrpted.
How does the remote interaction work with the encrypted fs?
Here the sequence of a remotecat
.
Previously we have our ubac
listener launch on an accesible port on remote and the encrypted fs in the same location as the listener:
remotecat -key=<key> path/to/file
- The path is encrypted using the
darkenpath
function ~~>darkenedpath
- The adret send a request to the ubac listener to perform a
cat
withdarkenedpath
- The ubac listener perform the cat and return the encrypted result to
adret
adret
decrypt it and print the result
How does the fs is modified ?
As the encrypted FS is represented in a JSON file format and ubac
has no acknowledge about what is inside (and couldn't obtain), we must have 5 steps to modify the encrypted fs
- Ask
ubac
to get the tree of the encrypted FS Darkenpath
the parent directory of the resource which will be modified (or added)- Ask
ubac
content of the parent directory (to modify it also)
- if the resource is a directory, it will use the tree to delete all resources under it (which the Tree structure we won't have to launch it recursively)
- With the tree, craft the patch to apply on the FS with
adret
. Patch depend of the logic (if you want to remove, add a ressource etc) - Provide the patch to
ubac
to apply it on the FS
Tree
Tree is a structure containaing all the Resource in the ecrypted fs. It is a Node
list
A Node
on ubac side is:
πname | type |
On adret side, it is the same concept. A tree is a list of Node but the Node
contains another field Parent
which is the resource parent directory ( the resource is represented by name
field in Node):
πname | type | πParent |
where Parent
is the prefix of the resource name (ie resource parent directory).
Patch
Patch is used to inform ubac
which resources it will change. So it contains 3 list: to_delete
for resources that must be removed, to_add
for resources that must be added, to_change
for resources that must be change (theirs contents).
(to_add
& to_change
contain a list of the resource with their content associated)
Example: remove an element
- ask ubac the tree
- Ask adret the patch to delete the resource
add to
to_delete
the resource + modify parent resource content (withdraw the resource of it) and add parent resource toto_change
- if resource is a folder: add to
to_delete
all the resource with prefix containing <resource_to_delete_name> (ie under the directory)
- if resource is a folder: add to
- Provide the the patch to ubac, and let ubac apply it
πLimits/improvements
adret
encrypt using AES ECB (attack possible). A more robust AES encryption scheme change the nonce at each encryption => for the same input different outputs at each encryption. It is a problem as darkenpath must provide the same path encrypted as the initial encryption (when we encrypt the fs)- you can't encrypt a filesystem w/ a folder/file having
'\'
in its name. It is due to the way we encapsulate resource in directory content - you can't perform "
ls .
". As we search for resource with its exact name we do not have.
resource from now - launch
adret
in the same directory of the fs you want to encrypt Otherwise it will keep prefix like "../" etc, (see filesystem.GetDirectoryContent) - for
adret decrypt cat
we could notcat
big file. It is due to the fact that we take the encrypted content to show from command-line. Hence we are limited byARG_MAX
length (getconf ARG_MAX
to know the value). For such reason avoid embedding binary file (or try to compress it usingupx
command before). This limitation applies for all command in fact- Workaround for
ARG_MAX
length: Save the arg in file and pass it with$(cat <FILE>)
- Workaround for
- file permissions
- CLi flag and command parsing is homemade (see cobra to improve/facilitate)