Skip to content

Commit b0e71a1

Browse files
committed
Documentation and makefile improvements
1 parent e8cf456 commit b0e71a1

15 files changed

+820
-42
lines changed

LICENSE

+674
Large diffs are not rendered by default.

README.md

+29-9
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,19 @@
33
<img src="./data/maliketh_logo.png" alt="Maliketh logo" width="900" height="300"/>
44
</p>
55

6-
# Maliketh
6+
<p align="center">
7+
A multi-user, customizable C2 framework.
8+
</p>
79

8-
Maliketh is a multi-user, customizable C2 framework. The goal of Maliketh is to provide a flexible, easy to use C2 framework that can be customized to fit the needs of the operator. The poster used in the initial presentation is located [here](./data/Maliketh%20C2%20Poster.png).
10+
---
11+
12+
The goal of Maliketh is to provide a flexible, easy to use C2 framework that can be customized to fit the needs of the operator. The poster used in the initial presentation is located [here](./data/Maliketh%20C2%20Poster.png).
913

1014
## Implant features
1115

12-
The implant is written in C++ and targeted for Windows. The main feature of the implant is its ability to change its behavior based on the configuration file it receives from the server. This allows the operator to customize the implant to fit their needs. The implant also has the following features (see [here](./design/opcodes.md) for more info):
16+
The initial implant was written in C++ and targeted for Windows, but a Golang implant has also been implemented and supports all major platforms.
17+
18+
The main feature of the implant is its ability to change its behavior based on the configuration file it receives from the server. This allows the operator to customize the implant to fit their needs. The implant also has the following features (see [here](./design/opcodes.md) for more info):
1319

1420
* File upload/download
1521
* Command execution
@@ -24,17 +30,31 @@ The implant is written in C++ and targeted for Windows. The main feature of the
2430

2531
## Future work
2632

27-
- [x] Implement Golang client
33+
- [x] Implement Golang client ([0639f87](https://github.com/cbrnrd/maliketh/commit/0639f8797838469a068d91f095e3307d2d73ecc4))
2834
* [x] Per-operator builder in-server ([917d514](https://github.com/cbrnrd/maliketh/commit/917d514fc6075cc15d0e45b4a1a546e6217e4139))
2935
* [ ] Stealer/basic looter
30-
* [x] AV Disable
31-
* [ ] UAC Bypass (SilentCleanup)
32-
* [ ] BOF/Custom DLL execution for plugins
36+
* [x] AV Disable ([0aeec4c](https://github.com/cbrnrd/maliketh/commit/0aeec4c4be8f1efaeaf15ee3d289507036c691df))
37+
* [ ] Change design of config to be protocol agnostic.
38+
* ie Define an HTTPS layer/adapter and separate out the code better.
3339
* [ ] Keylogger
40+
* [ ] More fine grained backend roles and actions (blocking users, % bot allocation)
41+
* [ ] Add ability to send command to every bot
42+
* [ ] Floods
3443
* [ ] Route RabbitMQ traffic through Admin listener instead of directly connecting
3544
* [ ] Improved anti-vm (check BIOS information)
36-
* [x] Pretty good in golang implant
45+
* [x] Not bad in golang implant
3746
* [x] More stable file uploads/downloads ([91a40f2](https://github.com/cbrnrd/maliketh/commit/91a40f2ba1cded5a025004a6143578fa84baec66))
38-
* [ ] Alternate C2 channels (WireGuard, DNS, Discord, Slack, etc.)
3947
* [x] Basic OS functions built in ([91a40f2](https://github.com/cbrnrd/maliketh/commit/91a40f2ba1cded5a025004a6143578fa84baec66))
4048
* [x] Situational Awareness ([91a40f2](https://github.com/cbrnrd/maliketh/commit/91a40f2ba1cded5a025004a6143578fa84baec66))
49+
50+
## Star History
51+
52+
<a href="https://star-history.com/#cbrnrd/maliketh&Date">
53+
<picture>
54+
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=cbrnrd/maliketh&type=Date&theme=dark" />
55+
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=cbrnrd/maliketh&type=Date" />
56+
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=cbrnrd/maliketh&type=Date" />
57+
</picture>
58+
</a>
59+
60+
<p align="center"><a href="https://github.com/cbrnrd/maliketh#"><img src="http://randojs.com/images/backToTopButtonTransparentBackground.png" alt="Back to top" height="29"/></a></p>

design/implant.md

+30-9
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,40 @@ The C2 server keeps some additional information about each implant. This informa
1515
| `os` | The operating system of the target system | Windows version |
1616
| `arch` | The architecture of the target system | x86, x64, etc. |
1717
| `user` | The user that the implant is running as | |
18-
| `aes_key` | The AES key used to encrypt the implant's communications with the C2 | Base64 encoded |
19-
| `aes_iv` | The AES IV used to encrypt the implant's communications with the C2 | Base64 encoded |
18+
| `server_sk` | The NaCl key to use to decrypt messages from the implant | Base64 encoded |
19+
| `implant_pk` | The NaCL key to use to encrypt messages to the implant | Base64 encoded |
2020
| `created_at` | The time the implant was created | |
2121
| `last_seen` | The time the implant was last seen | |
22-
| `kill_date` | The time the implant should be killed | |
23-
| `jitter` | The percentage value (as a float <= 1.0) of jitter to add to the implant's check-in interval | For example, if the implant checks in every 60 seconds and the jiter is `0.2`, $60<= sleep <= 60 + (60 * 0.2)$|
22+
23+
24+
## Implant configuration
25+
26+
Each implant has a configuration stored in the database. This is intentionally separate from the implant server info because the configuration will be sent to the implant and will be used to configure the implant. The configuration is stored in the `implant_config` table in the database. The following fields are stored:
27+
28+
| Field | Meaning | Notes |
29+
|:-----|:--------|:------|
30+
| `id` | The internal ID | DB primary key|
31+
|`implant_id`| The implant ID this config belongs to | this is not the `id` field of Implant, rather the `implant_id` field |
32+
| `cookie` | The cookie name used for implant identification | |
33+
| `kill_date` | The timestamp of the kill date | |
34+
| `user_agent` | The user agent to use for HTTP requests | |
35+
| `auto_self_destruct` | Self destruct on failed checkins | |
36+
| `sleep_time` | The number of seconds to sleep between tasks and checkins | |
37+
| `jitter` | The % amount of jitter to add to the sleep time | |
38+
| `max_retries` | The maximum number of retries to attempt before giving up | |
39+
| `retry_wait` | The number of seconds to wait between retries | |
40+
| `retry_jitter` | The % amount of jitter to add to the retry wait time | |
41+
| `enc_key` | The base64 encoded public key of the server to use for encryption | |
42+
| `tailoring_hash_function` | The hash function to use for the tailoring hash | Unused |
43+
| `tailoring_hash_rounds` | The number of rounds to use for the tailoring hash | Unused |
44+
| `tailoring_hashes` | A list of hashes to use for tailoring | Unused |
2445

2546
## Registration and authentication
26-
Mostly TODO, but here's the general idea.
2747

28-
There are a few approaches that could work for authentication:
48+
Implants register with the C2 after an initial sleep time. There is a hardcoded AES key for the initial registration. The implant sends a JSON payload containing the following information:
2949

30-
1. Use PKI and ECC keys to encrypt the C2 channel. The client and server would exchange public keys on the first request, then encrypt everything with those keys.
31-
2. Use some sort of Password Authenticated Key Exchange (PAKE) to generate a shared secret key. This would be similar to the above, but would use a password instead of a key pair. (OPAQUE, SPAKE2, etc.)
32-
3. Use Authenticated Encryption (ChaCha20Poly1305, AES-GCM, etc)
50+
| Field | Meaning | Notes |
51+
|:-----|:--------|:------|
52+
|`txid`| The base64 encoded, encrypted, NaCl public key of the implant | `Base64(AES(implant_public_key))` |
3353

54+
The C2 decrypts the payload and stores the implant's public key in the database. The C2 then generates a NaCl keypair and sends the public key and the configured initial configuration to the implant. All further communication is encrypted with the NaCl keypair, and then base64 encoded.

design/opcodes.md

+30
Original file line numberDiff line numberDiff line change
@@ -26,64 +26,94 @@ Arguments for each opcode must be a valid JSON type supported by [SQLAlchemy](ht
2626
Args: List of strings (command and arguments)
2727
Ex: `["ipconfig", "/all"]`
2828

29+
Expected response: The output of the command, if any.
30+
2931
## SELFDESTRUCT
3032

3133
Args: None
3234

35+
Expected response: None
36+
3337
## SYSINFO
3438

3539
Args: None
3640

41+
Expected response: A map of strings (key, value) of system information.
42+
3743
## SLEEP
3844

3945
Args: 1 integer (seconds to sleep)
4046

47+
Expected response: None
48+
4149
## UPDATE_CONFIG
4250

4351
Args: A map of strings (key, value) to update the malleable configuration.
4452
Invalid keys will be ignored. See [profile.md](profile.md#client-options) for a list of valid keys.
4553
Ex: `{"kill_date": "2021-01-01"}`
4654

55+
Expected response: None
56+
4757
## DOWNLOAD
4858

4959
Args: List of 1 string (path to file on the implant)
5060
Ex: `"C:\\Users\\user\\Desktop\\file.txt"`
5161

62+
Expected response: base64 encoded file content
63+
5264
## UPLOAD
5365

5466
Args: List of 2 strings (path to save the file on the implant)
5567
Ex: `["C:\\Users\\user\\Desktop\\file.txt", "b64encoded-file-content=="]`
5668

69+
Expected response: None
70+
5771
## INJECT
5872

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

76+
Expected response: None
77+
6278
## CHDIR
6379

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

83+
Expected response: None
84+
6785
## PWD
6886

6987
Args: None
7088

89+
Expected response: 1 string (current working directory)
90+
7191
## GETENV
7292

7393
Args: None
7494

95+
Expected response: A map of strings (key, value) of environment variables.
96+
7597
## LS
7698

7799
Args: None
78100

101+
Expected response: A list of strings (file names)
102+
79103
## PS
80104

81105
Args: None
82106

107+
Expected response: A map of strings (pid, name) of running processes.
108+
83109
## WHOAMI
84110

85111
Args: None
86112

113+
Expected response: 1 string (current user)
114+
87115
## DISABLE_DEFENDER
88116

89117
Args: None
118+
119+
Expected response: None

design/operator.md

+9-9
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ This will create an operator configuration file that will have a few fields.
3333
Field definitions:
3434
| Field | Meaning | Notes |
3535
|:-----|:-------- | ------ |
36-
| name | The name of the operator this config file is for | |
37-
| secret | The Base64 encoded ED25519 secret key for this operator | |
38-
| c2 | The IP address or domain name of the C2 server this operator is registered for | |
39-
| c2_port | The TCP port to connect to the C2 server on | |
40-
| public | The Base64 encoded ED25519 public key for this operator | |
41-
| signing_key | The Base64 encoded ED25519 secret key for signing messages to the C2 server | |
42-
| verify_key | The Base64 encoded ED25519 public key for verifying messages signed by `signing_key` | |
43-
| server_pub | The Base64 encoded ED25519 public key for the C2 server | Used for encrypting operator -> C2 traffic|
44-
| login_secret | A secret string to be encrypted and signed by `secret` on authentication | |
36+
| `name` | The name of the operator this config file is for | |
37+
| `secret` | The Base64 encoded ED25519 secret key for this operator | |
38+
| `c2` | The IP address or domain name of the C2 server this operator is registered for | |
39+
| `c2_port` | The TCP port to connect to the C2 server on | |
40+
| `public` | The Base64 encoded ED25519 public key for this operator | |
41+
| `signing_key` | The Base64 encoded ED25519 secret key for signing messages to the C2 server | |
42+
| `verify_key` | The Base64 encoded ED25519 public key for verifying messages signed by `signing_key` | |
43+
| `server_pub` | The Base64 encoded ED25519 public key for the C2 server | Used for encrypting operator -> C2 traffic|
44+
| `login_secret` | A secret string to be encrypted and signed by `secret` on authentication | |
4545

4646
## Authentication
4747

design/profile.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Profiles are YAML files with three main top level directives: `client`, `server`
2323
| Option | Description | Required | Type |
2424
|--------|-------------|----------|------|
2525
| `user_agent` | The user agent to use when making HTTP requests | Yes | String |
26-
| `encoding` | The encoding to use when sending encrypted data to the C2. | Yes | One of: `base64`, `hex` |
26+
<!-- | `encoding` | The encoding to use when sending encrypted data to the C2. | Yes | One of: `base64`, `hex` | -->
2727
| `sleep_time` | The number of seconds to sleep between each HTTP request | Yes | Integer |
2828
| `jitter` | % jitter. The implant will sleep for a random amount of time between `sleep` and `sleep * (1 + jitter)` | Yes | Float, `[0, 0.99]` |
2929
| `max_retries` | The maximum number of times to retry a request before giving up | Yes | Integer |

design/specs/implant-c2-http.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ This route allows implants to register with the server. The implant should send
2525

2626
```json
2727
{
28-
"txid": "base64_encoded_public_key"
28+
"txid": "encrypted_base64_encoded_public_key"
2929
}
3030
```
3131

3232
| Field | Purpose |
3333
|:----- | :------ |
34-
| `txid` | The Base64 encoded LibSodium public key to use for encryption from server -> implant |
34+
| `txid` | The Base64 encoded LibSodium public key to use for encryption from server -> implant, encrypted with the C2 registration password |
3535

3636
Example responses:
3737

go_implant/Makefile

+9-5
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,17 @@ endif
1515
ifeq ($(DEBUG),1)
1616
GOFLAGS:=$(GOFLAGS) -gcflags="all=-N -l" -ldflags="-X maliketh.config.DEBUG=true"
1717
else
18-
GOFLAGS:=$(GOFLAGS) -ldflags="-s -w -X maliketh.config.DEBUG=false" -trimpath
18+
GOFLAGS:=$(GOFLAGS) -ldflags="-s -w -X maliketh.config.DEBUG=false" -trimpath -gcflags=all="-l -B"
1919
endif
2020

21+
2122
default: native-debug
2223

2324
native-debug:
24-
$(GO) build -gcflags="all=-N -l" -ldflags="-X maliketh.config.DEBUG=true" -o implant-dev-debug $(MAIN)
25+
$(GO) build $(GOFLAGS) -o implant-dev-debug $(MAIN)
26+
27+
build:
28+
$(GO) build $(GOFLAGS) -o implant-$(shell go env GOOS)-$(GOARCH) $(MAIN)
2529

2630
all: setup deps macos linux windows
2731

@@ -33,17 +37,17 @@ deps:
3337

3438
linux:
3539
@/bin/echo -n "-----> Building Linux binary ($(GOARCH))... "
36-
@GOOS=linux GOARCH=$(GOARCH) $(GO) build $(GOFLAGS) -o build/$(BINARY)-linux-amd64 $(MAIN)
40+
@GOOS=linux GOARCH=$(GOARCH) $(GO) build $(GOFLAGS) -o build/$(BINARY)-linux-$(GOARCH) $(MAIN)
3741
@echo "DONE"
3842

3943
macos:
4044
@/bin/echo -n "-----> Building MacOS binary ($(GOARCH))... "
41-
@GOOS=darwin GOARCH=$(GOARCH) $(GO) build $(GOFLAGS) -o build/$(BINARY)-macos-amd64 $(MAIN)
45+
@GOOS=darwin GOARCH=$(GOARCH) $(GO) build $(GOFLAGS) -o build/$(BINARY)-macos-$(GOARCH) $(MAIN)
4246
@echo "DONE"
4347

4448
windows:
4549
@/bin/echo -n "-----> Building Windows binary ($(GOARCH))... "
46-
@GOOS=windows GOARCH=$(GOARCH) $(GO) build $(GOFLAGS) -o build/$(BINARY)-windows-amd64.exe $(MAIN)
50+
@GOOS=windows GOARCH=$(GOARCH) $(GO) build $(GOFLAGS) -o build/$(BINARY)-windows-$(GOARCH).exe $(MAIN)
4751
@echo "DONE"
4852

4953
clean:

go_implant/README.md

+33-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,34 @@ Most functions are supported on Windows, macOS, and Linux.
55

66
Some functions were adapted from [Coldfire](https://github.com/redcode-labs/Coldfire).
77

8+
## Building
9+
10+
To build the development implant, simply run
11+
12+
```bash
13+
$ make
14+
```
15+
16+
This builds the debug version of the implant for your native OS and architecture.
17+
18+
To build for all supported OSes and architectures, run
19+
20+
```bash
21+
$ make all
22+
```
23+
24+
To build a stripped version of the implant, simply set `DEBUG=0` when running make. Example:
25+
26+
```bash
27+
$ DEBUG=0 make all
28+
```
29+
30+
You can also set the usual `GOOS` and `GOARCH` environment variables to build for a specific OS and architecture using
31+
32+
```bash
33+
$ make build
34+
```
35+
836
## Differences between this and the C++ implant
937
The C++ implant is a bit more optimized for real world use. The golang implant **does not** have:
1038

@@ -16,8 +44,10 @@ The C++ implant is a bit more optimized for real world use. The golang implant *
1644

1745
## TODO
1846

19-
* [] Register retries
20-
* [] Persistence
21-
* [] Do something "normal" when sandbox is detected
47+
* [ ] Register retries
48+
* [ ] Persistence
49+
* [ ] Do something "normal" when sandbox is detected
50+
* [ ] Auto self destruct
51+
* [ ] Jitter
2252

2353

-5.25 MB
Binary file not shown.
-5.59 MB
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)