该项目及其姊妹项目crash 属于我的反审查工具集,用于在敌对的审查环境中建立完全加密的 shell 和 TCP/UDP 转发。它同样适用于取证场景,当没有其他可用手段时,通过 UART 或 adb 从设备中转储数据。
通过 UART 连接到 Pi 的 DNS 查询和 SSH 会话转发
PSC 允许对 shell 会话进行端到端加密,支持单跳或多跳,且不依赖底层传输方式,只要传输层可靠并能收发 Base64 编码数据而不被修改/过滤即可。除了获得的端到端伪终端(例如在端口 shell 中),你还可以转发 TCP 和 UDP 连接,类似于 OpenSSH 的 -L 参数。这一切透明工作,无需在起始点本地分配 IP 地址。这使得取证专家和渗透测试人员能够通过以下途径创建网络连接:
adb shell 会话,当 OEM 的 adbd 不支持 TCP 转发时想象一下,你在 shell 会话内部有一个看不见的 ppp 会话,而远程端实际上并不支持 ppp。
它运行在 Linux、Android、OSX、Windows、FreeBSD、NetBSD 以及(可能)OpenBSD 上。
PSC 还包含 SOCKS4 和 SOCKS5 代理支持,以便通过端口 shell 或调制解调器拨号远程进行实际的网页浏览会话。
编辑 Makefile 以反映你的预共享密钥,这些密钥定义在 Makefile 的顶部。
然后在 Linux 和 OSX 上只需输入 make。
在 BSD 上,你需要安装 GNU make 并使用 gmake。
在 Windows 上,你需要安装 cygwin 并选择相应的 gcc、gcc-g++、make 和 git 包。
在 Linux 上,PSC 将使用 Unix98 伪终端,在其他系统上它将使用 POSIX 伪终端,但这对你来说应该是透明的。我曾经在远古时期出于特定原因添加了 4.4BSD 和 SunOS 的支持,因此它也可能在 Solaris 上构建。
自豪地由以下赞助:
简单且直接。在你的本地机器上,执行 pscl,并传递任何你想要 从 远程站点转发到特定地址的 TCP 或 UDP 端口。例如:
linux:~ > ./pscl -T 1234:[192.168.0.254]:22 -U 1234:[8.8.8.8]:53
PortShellCrypter [pscl] v0.60 (C) 2006-2020 stealth -- github.com/stealth/psc
pscl: set up local TCP port 1234 to proxy to 192.168.0.254:22 @ remote.
pscl: set up local UDP port 1234 to proxy to 8.8.8.8:53 @ remote.
pscl: Waiting for [pscr] session to appear ...
linux:~ >
[ UART / SSH / ... login to remote side ... ]
在远程站点(最后一跳)的 shell 会话中,无论它是在端口 shell、SSH、控制台登录等中,你执行 pscr:
linux:~ > ./pscr
PortShellCrypter [pscr] v0.60 (C) 2006-2020 stealth -- github.com/stealth/psc
pscl: Seen STARTTLS sequence, enabling crypto.
linux:~ >
一旦你执行 pscr,两端会建立加密握手,并在你现有会话之上铺设一层附加协议,这对你是透明的。然后你可以连接到本地机器的 127.0.0.1:1234,通过 TCP 访问 192.168.0.254:22,或通过 UDP 访问 8.8.8.8 解析器。这也适用于 [IPv6] 地址,前提是远程站点具有 IPv6 连接。实际上,你甚至可以用它将 IPv4 软件转换为 IPv6,因为你总是在本地侧连接到 127.0.0.1。
你可以传递多个 -T 和 -U 参数。如果你不清楚会话是否已加密,可以向本地 pscl 进程发送 SIGUSR1,它会告知你。
PSC 在你希望通过远程 SSH shell 使用 tor 时也很有用,你可以将 socks5 和 DNS 端口转发到远程主机的 127.0.0.1 地址。由于 SSH 不转发 UDP 数据包,通常你会使用两个 socat 连接器或类似工具通过 tor 节点进行解析。PSC 的优势在于保持 UDP 数据报边界,而通过 SSH -L 的 socat 可能会破坏数据报边界并产生畸形的 DNS 请求。
会话将使用你在 Makefile 中选择的 PSK 的 aes_256_ctr 进行加密。这种加密方案是可塑的,但添加 AAD 或 OAD 数据会使数据包大小膨胀,而在交互式会话中,每个字节都很重要——由于 Base64 编码,每个键入的字符已经导致发送更多数据。
UART 会话可以通过 screen 使用,但不能通过 minicom,因为 minicom 会创建包含状态行的隐形窗口,并像过滤器一样破坏 PSC 的协议。PSC 试图检测过滤并能够容忍一定程度的数据损坏,但在某些情况下无法恢复。tmux 也存在类似问题。你应该避免将 PSC 与过于干扰/处理输入数据的 pty 处理器堆叠使用。
SHELL 环境变量必须为 pscl 和 pscr 设置,以便 PSC 知道在 pty 上执行哪个 shell。大多数环境中默认设置了 SHELL,但如果没有,则需要以 SHELL=/bin/bash pscl 等方式执行 PSC。
pscl 还支持通过 SOCKS4(-4 port)和 SOCKS5(-5 port)转发 TCP 连接。这会设置 port 作为 TCP 连接的 SOCKS 端口,因此你可以从端口 shell 会话浏览远程网络,而无需在渗透测试期间打开任何其他连接。如果你向 pscl 传递 -N,它将启用远程侧 DNS 名称解析,这样你也可以将其与 chrome 一起使用。但请注意:存在隐私问题,因为浏览器在启动时会尝试解析一系列不受你控制的 DNS 名称。此外,如果你的远程侧 DNS 设置有问题,当 DNS 响应包丢失时,你的打字 shell 可能会阻塞数秒。没有好的、可嵌入且可移植的异步解析器函数,因此我只能依赖单线程中的 getaddrinfo(),代价是如果存在 DNS 问题,可能会阻塞数秒。这就是为什么名称解析必须显式启用。pscr 试图通过 DNS 查找缓存来最小化这个潜在问题,因此在大多数情况下应该可以无痛工作。
如果你传递 -X IP-address(必须是第一个参数),你可以将本地代理绑定到不同于 127.0.0.1 的地址,从而在本地网络中共享代理。
psc 功能允许 TCP 连接或二进制数据块在多个跳之间从远程设备转发/转发到远程设备,即使无法在远程站点安装 pscr 二进制文件。这对于取证目的非常有用,当你无法以其他方式从设备下载工件时(例如通过 UART 连接的手机),或者需要在不接触文件系统以不破坏系统证据时转发连接,或者当根文件系统以只读方式挂载且无法上传工具集时。
这是一个非常酷的功能,因为你可以看到你的 TCP 连接通过本地 tty 跳转到远程机器,而无需在远程安装任何东西。
这完全依赖于本地 pty punkrock 以及向 pscl 传递一个弹跳命令,该命令会在远程 shell 上执行(在没有运行 pscr 的情况下),以及一些状态引擎魔法,用于在本地侧过滤和处理数据。通常,这需要首先将远程 pty 设置为原始模式,然后发出实际命令,以及其他一些通过 -B 传递的细节。参数被分割为以下部分:
:,例如 1234:。stty -echo raw 或 python -c "import tty;tty.setraw(0)"(注意引号要正确,因为 -B 也需要被引用)或类似的命令。pscl 开始发送数据,以避免 stty 实际执行与命令启动之间的竞争,例如 echo GO 完美。nc 127.0.0.1 22 用于将本地端口 1234 弹跳到远程的 SSH 服务器。pscl 重置其 tty 状态。echo FIN 可以实现。推荐使用,否则你可能在识别命令结束时遇到问题。; 分隔,并括在括号中。示例:
如果你想转发一个 TCP 连接,这个示例要求设备上安装了 stty 和 nc,但理论上任何等效工具都可以。
启动本地会话:
./pscl -B '1234:[stty -echo raw;echo GO;nc example.com 22;echo FIN]'
如果你本地连接到端口 1234,这将向远程设备发出命令 stty -echo raw;echo GO;nc example.com 22;echo FIN,然后来回转发它看到的任何数据,并进行速率限制,使其不会超过设备的 tty 速度(默认为 115200)。
当 pscl 会话启动后,通过 UART、ssh -e none ... 或其他方式连接到远程设备,一旦你拥有远程 shell,也在本地输入:
ssh [email protected] -p 1234 以将 SSH 连接从你的本地机器通过远程设备弹跳到 example.com 目的地。当然,更推荐使用 pscr 变体,因为 -B 一次只能弹跳单个连接(尽管你可以传递多个 -B 命令以实现不同的转发),并且在 TCP 会话后可能出现 shell 挂起的风险,因为 pty 处于 raw -echo 模式,取决于最终远程对等方是否也关闭连接,shell 可能之后一直挂起。如果你碰巧看到 pscl 通知连接已完成并看到提示符,你应该 reset 它,以便可以启动新连接。在数据转发期间,你会在 pscl 中看到 7 位 ASCII 的 < 和 > 通知,这只是本地用于调试和进度检测的。
请注意,到远程站点的连接必须是 8 位干净的,即 ssh、telnet、UART 或任何通道 不得处理转义序列(与使用 pscr 时不同)。对于 ssh 连接,这意味着你必须在 pscl 会话中使用 ssh -e none。
接下来是一些处理二进制文件传输的示例,其中 rfile 表示远程文件,lfile 表示本地文件。
要启动一个会话以丢弃远程文件,本地:
./pscl -B '1234:[stty -echo raw;echo GO;dd of=rfile.bin bs=1 count=7350;echo FIN]'
你需要指定远程侧期望的数据量。不使用 dd count=... 也可以(例如 cat>...),但传输完成后会话会挂起,因为 cat 无限等待输入。通过使用 dd count=...,你将获得干净的退出,并通过 FIN 标记收到通知。
然后,通过 ssh 或其他任何方式在刚启动的 pscl 会话内获取远程设备上的 shell。在本地第二个终端上:
dd if=lfile.bin|nc 127.0.0.1 1234
这将连接到 pscl 的本地端口 1234,触发远程的转储命令,将本地 lfile.bin 的二进制数据转发到远程的 rfile.bin。由于速率限制,这可能需要一段时间,并且你只能相信 psc 的进度屏幕来判断传输是否完成。本地的 dd ...|nc ... 命令只会显示本地状态,由于本地 TCP 缓冲区可能毫秒级吞噬整个文件,而文件仍在通过 pty 传输。因此,请确保仅在 pscl 屏幕告诉你完成或者你在 dd ...|nc ... 会话上看到 FIN 结束标记回显时,才按 Ctrl-C。
类似地,可以使用类似的命令将二进制数据从远程设备传输到本地机器以用于取证目的。同样,本地启动会话:
./pscl -B '1234:[stty -echo raw;echo GO;dd if=rfile.bin]' 或
./pscl -B '1234:[stty -echo raw;echo GO;cat rfile.bin]'
然后,通过 ssh 到远程设备获取 shell,然后在本地再次:
nc 127.0.0.1 1234|dd of=lfile.bin bs=1 count=7350
以获得大小为 7350 的 rfile.bin 并复制到本地文件 lfile.bin。
如果设备上没有 stty -echo raw,类似 python -c "import tty;tty.setraw(0)" 也可以工作。请注意,在使用弹跳命令时,远程设备上必须有一个 tty(不仅仅是端口 shell),因为设置原始模式的 stty 命令需要一个真正的 tty。
如果 psc 通过串行连接运行,丢失的位可能会破坏所有乐趣。如果你在没有硬件流控制的情况下运行,最终将遇到位丢失和连接挂起,特别是当设备在使用 弹跳命令 时向你发送数据而没有限速的情况下。向设备转储数据效果更好,因为这些数据通过 pscl 的速率限制。
然而,以下是一些在无法在设备上使用 pscr 和硬件流控制的情况下对我有效的技巧。这仅适用于 UART,因为这是一个潜在不可靠的传输通道。
pscr,以便为发送到你方向的数据设置速率限制。由于朝向设备的方向总是被速率限制,你可以使用弹跳命令将交叉编译的 pscr 二进制文件转储到设备,然后启动一个双向速率限制的会话。tio -o 1 或 -o 2 在发送的输出字节之间增加延迟。115200,也优先选择 38400)。psc 时使用 -DRESPECT_UART_BUFSIZE=4096,但这会使会话非常慢。在 contrib 文件夹中,你还会找到一个 tio-noprefix 补丁,用于禁用转义字符处理,但这个补丁仅对旧版本必要,因为上游已经接受并集成了这个补丁。我强烈建议在使用 UART 时使用 tio。
当通过 tio 使用弹跳命令时,你需要在你的 ~/.tioconfig 文件中添加:
[default]
prefix-ctrl-key = none
这将禁用转义处理,并给你一个 8 位干净的通道。
你可以向 pscl 发送 SIGUSR1,它会告诉你会话是否加密。如果远程 pscr 死亡或退出而无法向本地部分发送信号,pscl 将保持在加密模式并因此挂起。在这种情况下,你可以通过发送 SIGUSR2 强制重置为明文模式,从而可以启动新的会话。
从版本 0.64 开始,psc 支持脚本化套接字,因此你不再需要 screen 来向远程控制台获取/放置文件或转储粘贴缓冲区。取而代之的是,你像这样启动本地会话:
~ > ./pscl -S ~/psc.script_sock
然后你可以像以前一样继续使用它。如果你需要“粘贴”某些内容,你可以这样做:
~ > ./pscsh -S ~/psc.script_sock -f script_/helloworld
这将把 script_/helloworld 的内容“键入”到控制台。在脚本化期间,pscl 的标准输入被阻塞,以便注入的输入不会与任何键入混淆。如果在 pscsh 中省略了 -S,则会自动使用 ~/psc.script_sock。出于安全原因,脚本必须以 script_ 前缀开头。
作为额外奖励,pscr 现在包含了 base64 编码/解码文件的能力,甚至为了方便还支持内嵌回车字符。它与 uuencode -m 兼容。