Closed Dfte closed 1 week ago
Here is what I have done concerning the write files on disks. In donpapi/libs/utils.py I added the following function:
def dump_file_to_loot_directories(local_filepath, file_content=b"") -> None:
os.makedirs(os.path.dirname(local_filepath), exist_ok = True)
with open(local_filepath, "wb") as f:
f.write(file_content)
And here is how to use it with the example of the PowerShell history collector:
import os
import ntpath
from typing import Any
from dploot.lib.target import Target
from dploot.lib.smb import DPLootSMBConnection
from donpapi.core import DonPAPICore
from donpapi.lib.logger import DonPAPIAdapter
from donpapi.lib.utils import dump_file_to_loot_directories
class PowerShellHistory:
user_directories = ["\\Users\\{username}\\AppData\\Roaming\\Microsoft\\Windows\\PowerShell\\PSReadLine\\"]
def __init__(self, target: Target, conn: DPLootSMBConnection, masterkeys: list, options: Any, logger: DonPAPIAdapter, context: DonPAPICore, false_positive: list, max_filesize: int) -> None:
self.tag = self.__class__.__name__
self.target = target
self.conn = conn
self.masterkeys = masterkeys
self.options = options
self.logger = logger
self.context = context
self.false_positive = false_positive
self.max_filesize = max_filesize
self.found = 0
def run(self):
self.logger.display("Gathering powershell history files")
for user in self.context.users:
for directory in self.user_directories:
directory_path = directory.format(username=user)
self.dig_files(directory_path=directory_path, recurse_level=0, recurse_max=10)
if self.found > 0:
self.logger.secret(f"Found {self.found} powershell history files", self.tag)
def dig_files(self, directory_path, recurse_level=0, recurse_max=10):
directory_list = self.conn.remote_list_dir(self.context.share, directory_path)
if directory_list is not None:
for item in directory_list:
if item.get_longname() not in self.false_positive:
new_path = ntpath.join(directory_path, item.get_longname())
file_content = self.conn.readFile(self.context.share, new_path)
self.found += 1
absolute_local_filepath = os.path.join(self.context.target_output_dir, *(new_path.split('\\')))
dump_file_to_loot_directories(absolute_local_filepath, file_content)
collector_dir_local_filepath = os.path.join(self.context.global_output_dir, self.tag, new_path.replace("\\", "_"))
dump_file_to_loot_directories(collector_dir_local_filepath, file_content)
And to do so I only had to add the following lines in donpapi/core.py:
self.global_output_dir = os.path.join(output_dir, DPP_LOOT_DIR_NAME)
self.target_output_dir = os.path.join(output_dir, DPP_LOOT_DIR_NAME, self.host)
os.makedirs(self.target_output_dir, exist_ok=True)
Since each collector inherits the self objects, it was kinda easy!
Now files are dumped as absolute path and also in the collector sub directory:
Let me know if it suits you! :)
Closing as I'll push a better version.
Heyo friends!
This PR reworks quite a few things concerning the collectors engine! Hope you'll like it!!
Changes
Collectors loading
First of all, I removed COLLECTOR dict and all collectors manual imports in entry.py. Instead I replaced them with the following piece of code which dynamically loads files in the donpapi/collectors folders:
To do so, I had to retrieve the root dirname of donpapi using:
This function returns two dicts:
Doing so makes PR'ing much easier since all we'll have to do is to add a file in donpapi/collectors/, let's say PowerShellHistory.py and respect the following format:
Note that the class name MUST be the same as the collector filename (hence PowerShellHistory.py).
Much easier :D
Collector tags
Collector tags were removed for the following:
Which dynamically builds the tag value based on the class name.
We can now call self.logger.secrets the following way:
Instead of the old:
Collectors parameters mutualization
Looking at the collectors, I realised that some of them rely on a false_positive list (there will be more because of the multiple previous PR's I did). Instead of having "magic variables", I mutualized them in the entry.py file:
All collectors inherit these two parameters and as such it will be much more easier to add new false positive users, when found, without struggling modifying all collector files manually.
What needs to be done
As I mentionned in https://github.com/login-securite/DonPAPI/pull/80 I believe it is interesting to store files found by collectors in a separate directory as well as in donpapi/loot/TARGET/[...]/. All we need to do is to add another parameter which contains the $HOME/.donpapi/loot directory and write dump files function for all collectors which will write files into their own collector directory.
For example with the PowerShellHistory module:
Doing so makes:
All of that I will take care of once this PR is validated :)
See ya !!
Post Scriptum
I already adapted the previously PRed collectors, this is what it looks like for the moment :eyes: