通过SSH隧道实现RDP连接的完整指南
Carrie Roberts //*
我多次需要提醒自己如何通过SSH连接设置RDP访问,因此决定在此记录以供将来参考。希望这对您也有用。我从事"对手模拟"工作,因此使用"攻击者"和"目标"等术语呈现这些信息,但这些信息对于执行系统管理任务也很有用。
我们将介绍的第一个场景是:您可以访问内部网络上的Linux机器,并希望RDP到同一内部网络上的Windows机器。如果您在内部网络上放置了Dropbox(例如,插入内部网络以太网端口的Raspberry Pi计算机),或者您可以执行内部网络上已存在的Linux机器上的命令,则可能会出现这种情况。无论哪种情况,您都可以使用以下技术RDP到内部网络上的目标。下图显示了此场景的起点。
这里,攻击者系统位于一个无法从互联网访问的内部网络上。攻击者操作系统是Windows。接下来,我们在互联网上有一台Linux计算机(例如Digital Ocean Droplet)。我们将互联网上的此系统称为外部系统。在此示例中,外部系统的IP地址为208.8.8.8,并且SSH服务在端口443上监听。灰色框外部的红色框表示端口443在外部接口上监听。在外部接口上监听意味着其他远程系统可以连接到它。红色框显示两次只是为了在后续连接步骤中更清晰,但实际上只有一个端口443在监听。我们,攻击者,完全控制攻击者和外部机器。
转到目标内部网络,我们有一个Dropbox(Linux),我们可以执行命令。Dropbox的SSH服务在端口22上监听,允许网络上的其他系统与之交互。最后,我们有想要RDP到的目标Windows系统。目标已启用RDP并在端口3389上监听,我们拥有允许RDP到此机器的用户的凭据。在此示例中,目标的IP地址为10.2.2.222。
本教程中的所有SSH身份验证都将使用公钥/私钥对完成。假设Dropbox有一个名为db.key的私钥文件,并且公钥(db.pub)已添加到外部服务器上的authorized_keys文件中。还假设攻击者系统以类似方式设置,使用名为at.ppk或at.key的私钥,并且其公钥已添加到外部和Dropbox系统上的authorized_keys文件中。对于使用PuTTY/plink作为SSH客户端的示例,您需要使用私钥的ppk版本。如果您的密钥对是在Linux上生成的,可以使用PuTTYgen工具将私钥转换为ppk格式。
我们将采取的第一步是通过SSH将Dropbox连接到外部系统。由于内部网络无法从互联网访问,连接必须从Dropbox本身启动。我们可以使用以下SSH命令将Dropbox连接到外部系统。
|
|
现在我们有了从Dropbox到外部系统的连接(隧道)。箭头显示连接的方向。
然而,这并不完全是我们想要的。我们希望能够通过刚刚设置的隧道转发RDP连接。为此,我们将告诉SSH开始监听内部端口5001,并将连接到该内部端口的任何内容通过SSH隧道转发回去。这称为反向SSH端口转发。之所以是"反向",是因为监听端口是在我们SSH到的系统上创建的,而不是在我们SSH来自的系统上。以下命令将为我们设置反向SSH端口转发。在此命令中,术语"localhost"指的是具有SSH服务在端口22上监听的Dropbox。
|
|
端口号周围的绿色框表示此端口仅在本地接口上监听。除了通过SSH隧道外,此端口无法被远程系统访问。
关于持久性的说明。您可能希望确保从Dropbox到外部系统的SSH隧道保持连接。例如,您可能已将Dropbox留在现场,并且没有隧道就无法再通过命令行访问它。在这种情况下,您应考虑使用autossh命令,如下所示。如果未安装autossh,可以按照此处的说明安装它。
|
|
Autossh用于监视和重新启动SSH会话。-M 0选项禁用监视端口,而是使用两个"Alive"选项检查连接的健康状况。ExitOnForwardFailure意味着如果autossh无法绑定到远程端口(在此情况下为5001),它将退出。这将使我们明显看到我们寻求的完整连接尚未发生。
如果您担心Dropbox可能会重新启动,并且希望确保SSH隧道重新启动,您可以将其安装为服务。这可以通过在/etc/systemd/system/autossh.service创建以下文件,然后将其注册为服务来完成。请记住将208.8.8.8替换为您的外部服务器的IP。
|
|
以下命令将读取新的autssh.service文件,启动服务并检查其状态。
|
|
确保状态显示为"active (running)",如下图所示。
最后,设置服务在启动时启动,并确保SSH服务也在启动时启动。
|
|
现在,您可以尝试重新启动Dropbox,并确认到外部服务的隧道已启动并正常运行,包括反向端口转发回Dropbox。
Dropbox已连接,现在让我们将攻击者系统连接到外部系统。首先,我们将设置两个环境变量,以便于复制和粘贴最终命令。将这两个命令中的IP地址替换为您的外部服务器的IP地址和目标系统的内部IP。从攻击者系统上的cmd窗口运行这些命令。
|
|
现在,在设置上述环境变量的同一窗口中运行以下命令。从包含攻击者私钥at.ppk的目录运行此命令。如果您的密钥是在Linux中生成的,可以使用Puttygen.exe打开密钥并将其保存为ppk格式。如果您从与at.ppk文件所在目录不同的目录运行此命令,则需要提供文件的完整路径,例如命令中引用的两个位置的"c:\Users\admin.ssh\at.ppk"。
|
|
如果您收到错误"plink is not recognized as an internal or external command",请将plink.exe复制到您运行命令的同一目录(例如您的.ssh目录)。
要理解此命令的作用,我们确实需要按相反顺序查看它。首先执行的是"-proxycmd"后面的命令。命令的proxycmd部分如下所示。
|
|
仅运行此proxycmd后我们的连接状态如下所示。命令的"-nc"部分告诉plink打开到127.0.0.1端口5001的隧道,而不是会话。
接下来,我们查看plink链接命令的前半部分。这实际上是在上述proxycmd之后运行的。
|
|
此SSH连接通过先前使用proxycmd创建的隧道建立。这就是为什么它可以访问在端口5001上监听的内部端口。命令的最后部分使用本地端口转发选项"-L"将通过隧道连接到本地端口3390的任何内容发送到目标上的端口3389。完整命令运行后,这就是我们创建的内容。
请注意,我们选择本地端口3390是因为如果您尝试使用RDP客户端连接到localhost 3389,Windows会抱怨"您的计算机无法连接到另一个控制台"错误,如下所示。
最后,我们现在可以使用Windows内置的RDP客户端从攻击者系统RDP到目标系统。
对于"用户名"字段,您可以使用".\username"以使用本地帐户登录。如果使用域帐户,请确保包含域名后跟反斜杠(例如"intdomain\carrie")。
如果我们不想尝试RDP到内部网络,而是想使用攻击者机器上的互联网浏览器,就像它在内部网络上一样,该怎么办?这可以通过修改从攻击者系统运行的plink命令来完成。
|
|
执行此命令后,配置攻击者系统上的浏览器以使用localhost 9999上的socks代理。您可以在Firefox中通过转到设置(右上角的汉堡菜单)–>选项,搜索"Proxy",然后单击"Configure how Firefox connects to the Internet"旁边的"Settings…“来完成此操作。
确保选中"Socks v5"以及"Proxy DNS when using SOCKS v5”。清除"No Proxy for"文本框中的任何内容,然后单击OK。您现在可以从攻击者系统上的浏览器浏览内部网络,就像浏览器在Dropbox上一样。
您可以使用FoxyProxy附加组件在Firefox和Chrome中快速更改代理服务器。这就是使用FoxyProxy配置此功能的方式。
Chrome、IE和Edge使用系统代理设置。您可以将系统代理更改为指向端口9999上的动态Socks代理,但您可能会将比仅浏览器流量更多的流量发送到内部网络,这可能是不希望的。我建议使用Firefox,因为它管理与系统代理分开的自己的代理设置。或者,您可以使用Foxyproxy附加组件与Firefox或Chrome一起直接控制代理。
我们已经完成了使用Windows攻击系统和Linux Dropbox的演练。对于下一个场景,让我们将Windows攻击者系统换为Linux系统,如下图所示。
在Dropbox上执行的命令将与第一个场景中保持相同。唯一会改变的命令是从攻击者系统执行的命令。从攻击者系统上的终端窗口,我们定义我们的IP地址:
|
|
然后从同一终端窗口执行以下SSH命令。
|
|
现在我们有了从攻击者机器上的端口3390到目标服务器上的端口3389的完整通信路径。我们可以使用任何Linux RDP客户端连接到我们的目标。在此示例中,我将使用xfreerdp,可以使用以下命令安装。建议使用Xfreerdp而不是rdesktop,因为它 readily支持NLA。
|
|
要连接到目标服务器,我们只需指定用户名和要连接的主机,系统将提示我们输入用户的密码。
|
|
如果您作为域用户连接,请记住包含Active Directory域名以及用户名。
|
|
作为运行上述长SSH命令的替代方案,我们可以在攻击者系统上的SSH配置文件(/root/.ssh/config)中添加以下内容。
|
|
有了我们的SSH配置文件,我们的命令简化为以下内容,用于将RDP转发到目标系统。
|
|
或者,如果我们想创建动态Socks代理,请使用以下命令。它允许我们使用攻击机器上的浏览器,就像它在目标内部网络上一样。
|
|
这完成了我们的第二个场景。现在让我们将Linux Dropbox换为Windows Dropbox。这可能是一个我们字面上放在目标内部网络上的系统,或者一个已经存在并且我们现在可以执行命令的系统。下图显示了此场景的起点。
首先,我们将在3390上设置本地端口监听,并将其转发到我们的目标上的端口3389。运行此命令需要管理权限,您可以通过右键单击cmd.exe并选择"以管理员身份运行"来获得。
|
|
现在我们设置了通信通道的以下部分。
以下是一些netsh注释,您可能想稍后了解,但现在不要运行它们。要删除我们刚刚添加的规则,请将上述命令中的"add"更改为delete。 要显示代理规则,请使用"show all"命令
|
|
要清除所有端口代理,请使用"reset"
|
|
现在我们只需要执行我们之前学到的两个命令来完成设置,一个来自Dropbox,一个来自攻击者系统。从Dropbox,从包含at.ppk私钥和plink可执行文件的目录运行以下命令。
|
|
此时,我们已设置了通信通道的以下部分。
从运行Linux的攻击者机器执行以下命令。请注意,这假设本教程前面描述的SSH配置文件(/root/.ssh/config)已创建。
|
|
现在我们有了完整的通信路径,准备就绪。
最后,从攻击者机器RDP到目标系统。此处的示例使用xfreerdp。
|
|
或者,除了设置RDP访问,我们还可以设置浏览器访问。这不需要管理权限即可在Windows Dropbox上运行命令。在这种情况下不使用"netsh interface portproxy …“命令。从攻击者系统运行以下命令。
|
|
最后,在运行此命令后,配置您的浏览器以使用localhost 9999上的Socks代理。请记住,对于此浏览选项,我们不需要"netsh interface portproxy …“命令,因此我们可以在没有对Windows Dropbox的管理访问权限的情况下浏览目标内部网络。
感谢Carrie Roberts的另一篇出色的客座博客。
您可以在她的课程中向Carrie学习更多! 在此处查看它们: 攻击模拟工具:Atomic Red Team、CALDERA等 PowerShell for InfoSec 提供实时/虚拟和点播!