{"id":19544865,"url":"https://github.com/ariary/aravisfs","last_synced_at":"2025-04-26T19:31:48.856Z","repository":{"id":109492678,"uuid":"388521528","full_name":"ariary/AravisFS","owner":"ariary","description":"Encrypted filesystem 🔐 And a CLI to remotely and securely interact with  (if you want to store encrypted private data on ☁️)","archived":false,"fork":false,"pushed_at":"2022-04-08T08:04:00.000Z","size":14552,"stargazers_count":3,"open_issues_count":3,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-04T17:11:39.375Z","etag":null,"topics":["cloud","encryption","filesystem","pentest-tool","privacy","security"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ariary.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-07-22T16:04:30.000Z","updated_at":"2023-08-31T08:10:34.000Z","dependencies_parsed_at":"2023-07-14T22:17:27.149Z","dependency_job_id":null,"html_url":"https://github.com/ariary/AravisFS","commit_stats":{"total_commits":167,"total_committers":2,"mean_commits":83.5,"dds":"0.13772455089820357","last_synced_commit":"c2f0dd3f0d2567dd898e913160e55766bb6b6014"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ariary%2FAravisFS","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ariary%2FAravisFS/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ariary%2FAravisFS/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ariary%2FAravisFS/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ariary","download_url":"https://codeload.github.com/ariary/AravisFS/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251041427,"owners_count":21527193,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloud","encryption","filesystem","pentest-tool","privacy","security"],"created_at":"2024-11-11T03:32:40.618Z","updated_at":"2025-04-26T19:31:47.498Z","avatar_url":"https://github.com/ariary.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\u003ch1 align=\"center\"\u003e AravisFS 🗻🌄\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\n\tA remote fake encrypted filesystem  🔐 \u003ci\u003eAnother non production-ready software\u003c/i\u003e\n\u003c/p\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n\t🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟\n\tAny idea, criticism, contribution is welcome\n\tNo pretention just to learn and keep my mind busy\n\t🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟\n\u003c/div\u003e\n\t\n----\n\n\u003cp align=\"center\"\u003e\n\u003cstrong\u003e\u003ca href=\"#-idea\"\u003e🔦 Idea\u003c/a\u003e\u003c/strong\u003e\n|\n\u003cstrong\u003e\u003ca href=\"#-installation\"\u003e💺 Installation\u003c/a\u003e\u003c/strong\u003e\n|\n\u003cstrong\u003e\u003ca href=\"#-usage\"\u003e🚀 Usage\u003c/a\u003e\u003c/strong\u003e\n|\n\u003cstrong\u003e\u003ca href=\"#-how-does-it-work\"\u003e🧙 How does it work?\u003c/a\u003e\u003c/strong\u003e\n|\n\u003cstrong\u003e\u003ca href=\"#limitsimprovements\"\u003e💭Limits/improvements\u003c/a\u003e\u003c/strong\u003e\n\u003c/p\u003e\n\n----\n\n\t\n## 🔦 Idea\n**Aim?**\nProviding a fake encrypted FS and utilities to interact with.  The objective is to leak as little information as possible. \n\nThe local machine is our trusted environment where we could manipulate the key, the clear-text data etc. This is our **(light side)**.\n\n 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)\n\nFor this purpose we use 2 utilities, each on different side:\n- `adret`: Encrypt/decrypt fs etc. Deal with key \u0026 clear-text data ***(light side)***\n - `ubac`: Interact with encrypted fs. Deal with no \"sensitive\" data (no key \u0026 clear-text manipulation) ***(dark side)***\n\n*We accept to leak information about the fs structure (number of file/folder, size)* on the dark side\n\n***Note:*** `adretctl` offer a much clever user experience of adret utility with a CLI etc. See [usage](#-usage)\n\n\n\n**Use case?**\n - To avoid your volume being spied on by your cloud provider\n - 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.\n - To get a manipulable ransomware \n - To share data with colleague without setting up a hardened db or others. (just share and update `.arfs` file)\n - To boast of having an encrypted fs .. but practically unusable anyway\n\n**Why \"fake\"?**\n - Cause encryption isn't strong enough *(AES ECB)*\n - 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)*\n\n## 💺 Installation\n\n Clone the repo and download the dependencies locally:\n```    \ngit clone https://github.com/ariary/AravisFS.git\nmake before.build\n```\n\n To build `adret` :\n\n     make build.adret\n    \n To build `adretctl` :\n\n     make build.adretclt\n\t    \nIdem, to build `ubac`:\n\n    make build.ubac\n\n***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](https://medium.com/@PenTest_duck/almost-all-the-ways-to-file-transfer-1bd6bf710d65))\n\n## 🚀 Usage \n### Adretctl \u0026 ubac demo\n ![demo](https://github.com/ariary/AravisFS/blob/main/img/adretctldemo.gif)\n\n*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*\n\nSee [adretctl spec](#target-3---to-the-infinite---interactive-prompt-w-fs-cli)\n\n### 🔒 Encrypt folder/fs\n\nSee [demo encrypt (.GIF)](https://github.com/ariary/AravisFS/blob/main/img/encryptfs.gif)\n\n### 🔍 Explore encrypted folder\n\u003cdetails\u003e\n\t\u003csummary\u003eList folder content from my encrypted fs\u003c/summary\u003e\nFirst I encrypt my fs :\n\n    (local) $ adret encryptfs -key=\u003csecret\u003e \u003cpath\u003e\n    [...]\n    test/mytestfolder/titi\n    [...]\n    done! Encrypted fs saved in encrypted.arafs\n\nThen 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 `\u003cmyfolder\u003e`from my host, *otherwise it has real no sense* (see [example](https://github.com/ariary/AravisFS/blob/main/img/encryptfs.gif))\n\nSay I want to `ls` in ` \"test/mytestfolder/titi\"`, so I encrypt first the encrypt the path:\n\n    (local) $ adret darkenpath -key=\"toto\" \"test/mytestfolder/titi\"\n    **We obtain encrypted path! COPY THE RESULT**\n\nThen we do the `ls` in our encrypted fs:\n\n    (remote) ubac ls -path=myencryptedfs.arafs \u003cencryptedpath_from_adret\u003e \n    **We obtain ls result! COPY THE RESULT**\n\nAnd finally decrypt the result of ls:\n\n    (local) $ adret decryptls -key=\"toto\"\n    tutu tutu.txt utut.txt\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\t\u003csummary\u003ePrint file content from my encrypted fs\u003c/summary\u003e\n\nIdem as above with `ls` but change the `ubac` command with:\n\n    (remote) ubac cat -path=myencryptedfs.arafs \u003cencryptedpath_from_adret\u003e\n\n\u003c/details\u003e\n\u003cdetails\u003e\n\t\u003csummary\u003ePrint  encrypted fs tree\u003c/summary\u003e\nFirst retrieve encrypted tree from encrypted fs:\n\n    (remote) ubac tree test/arafs/medium.arafs\n    **We obtain the encrypted tree result! COPY THE RESULT**\n   \n  Then decrypt it to print it with (assume the fs was encrypted with the key \"toto\"):\n\n      (local) $ adret decrypttree -key=\"toto\" \u003cencryptedtree_from_ubac\u003e\n\u003c/details\u003e\n   \n\n### 🤖 Automate a bit \nIf you want to interact with your remote encrypted fs more fluidly\n\n**Prerequisites**\n\n - my encrypted fs + `ubac`on remote\n - remote is accesible on port `\u003cip\u003e:\u003cport\u003e`\n - `adret` on local \n - have the `key` which encrypt the fs\n\n\u003cdetails\u003e\n\u003csummary\u003eList folder content from remote encrypted fs\u003c/summary\u003e\nStart your `ubac` listener on the remote where the encrypted fs is :\n\n    (remote) $ ubac listen -path=\"./test/arafs/encrypted.arafs\" 4444\n\t** IT WILL LAUNCH AN HTTP SERVER WAITING FOR REQUEST ON PORT 4444***\n\nAn local machine configure your environment variable to dial with remote ubac listenerConnect to the listener with your local machine:\n\n    (local) $ eval `adret configremote -port=\"4444\" -host=\u003cremote_ubac_hostname\u003e`\n\nI can now interact directly with my encrypted fs on my local machine and obtain direct result:\n\n    (remote) $ adret remotels -key=toto test/mytestfolder\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\t\u003csummary\u003ePrint file content from remote encrypted fs\u003c/summary\u003e\n\tLaunch \u003ccode\u003eubac\u003c/code\u003e listener and config local host wit \u003ccode\u003eadret\u003c/code\u003e like \u003ca href=\"#list-folder-content-from-remote-encrypted-fs\"\u003eabove\u003c/a\u003e and launch `remotecat`:\n\n    (remote) $ adret remotecat -key=toto test/mytestfolder/toto.txt\n\u003c/details\u003e\n\t\n### ✂️ Manipulate encrypted fs\n\u003cdetails\u003e\n\t\u003csummary\u003eRemove a file from encrypted fs\u003c/summary\u003e\n\nFirst retrieve encrypted tree from encrypted fs:\n\n    (remote) ubac tree test/arafs/medium.arafs\n    **We obtain the encrypted tree result! COPY THE RESULT**\n\nThen get a patch (which describes the changes you want to make):\n```\n(local) adret rmpatch -key=toto -tree=\u003coutput_ubac_tree\u003e \u003cresource_I_want_to_remove\u003e\n***WE OBTAIN A PATCH COPY IT***\n```\n\nThen apply the patch onto the encrypted fs\n```\n(remote) ubac applypatch -path=encrypted.arafs \u003cmy_patch\u003e\n``` \n\u003c/details\u003e\n\t\n\n## 🧙 How does it work?\nMagic!\n\n### How  is the fs encrypted ?\n\nWhen 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).\n\nThe 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**\n\n#### Encrypted fs data structure\nFor 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.\n\n##### Resource\nA resource is:\n|  |  ||\n|--|--|--|\n|🔐name  | type |🔐content|\n\n**name**: is the encrypted value of the path of the resource\n**type** : is the type of the ressource within the fs. it could be:\n- folder\n-  file\n\n**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\n\n#### Example: Search in encrypted fs\n\nTake the example of  `ubac ls -path=myencryptedfs.arafs darkpath` which aims to perform `ls` of the `darkpath` in `myencryptedfs.arafs`.\n\nFirst it will search the `darkpath` (it is an encrypted path) name in the list which is `myencryptedfs.arafs` . \nIf the type is file it will return the filename. \nIf the type is a folder it will take the content part which is all its child resources encyrpted.\n\n### How does the remote interaction work  with the encrypted fs?\nHere the sequence of a `remotecat`. \n\nPreviously we have our `ubac` listener launch on an accesible port on remote and the encrypted fs in the same location as the listener:\n\n 1. `remotecat  -key=\u003ckey\u003e path/to/file`\n 2. The path is encrypted using the `darkenpath`function ~~\u003e `darkenedpath`\n 3. The adret send a request to the ubac listener to perform a `cat` with `darkenedpath`\n 4. The ubac listener perform the cat and return the encrypted result to `adret`\n 5. `adret` decrypt it and print the result\n\n### How does the fs is modified ?\n\nAs 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 \n 1. Ask `ubac` to get the tree of the encrypted FS\n 2. `Darkenpath` the parent directory of the resource which will be modified (or added)\n 3. Ask `ubac` content of the parent directory (to modify it also)\n   * 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)\n 5. 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)\n 6. Provide the patch to `ubac` to apply it on the FS\n\n##### Tree\nTree is a structure containaing all the Resource in the ecrypted fs. It is a `Node` list\n\nA `Node` on ubac side is:\n|  |  |\n|--|--|\n|🔐name  | type|\n\nOn 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):\n|  |  |\t |\n|--|--|--|\n|🔐name  | type |🔐Parent|\n\nwhere `Parent` is the prefix of the resource name (ie resource parent directory).\n\n##### Patch\nPatch 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).\n\n(`to_add` \u0026 `to_change` contain a list of the resource with their content associated)\n\n#### Example: remove an element\n\n 1. ask ubac the tree\n 2. Ask adret the patch to delete the resource\n  add to `to_delete` the resource + modify parent resource content (withdraw the resource of it) and add parent resource to `to_change`\n\t - if resource is a folder: add to `to_delete` all the resource with prefix containing \u003cresource_to_delete_name\u003e (ie under the directory)\n 3. Provide the the patch to ubac, and let ubac apply it\n\n## 💭Limits/improvements\n- `adret` encrypt using AES ECB (attack possible). *A more robust AES encryption scheme change the nonce at each encryption =\u003e 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)*\n- 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*\n- you can't perform \"`ls .`\". *As we search for resource with its exact name we do not have `.` resource from now*\n- launch `adret` in the same directory of the fs you want to encrypt *Otherwise it will keep prefix like \"../\" etc, (see filesystem.GetDirectoryContent)*\n- for `adret decrypt cat` we could not `cat` big file. *It is due to the fact that we take the encrypted content to show from command-line. Hence we are limited by `ARG_MAX` length (`getconf ARG_MAX`to know the value). For such reason avoid embedding binary file (or try to compress it using `upx` command before). This limitation applies for all command in fact*\n\t- Workaround for `ARG_MAX` length: Save the arg in file and pass it with `$(cat \u003cFILE\u003e)`\n- file permissions\n- CLi flag and command parsing is homemade (see [cobra](https://github.com/spf13/cobra) to improve/facilitate)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fariary%2Faravisfs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fariary%2Faravisfs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fariary%2Faravisfs/lists"}