这是一个针对 Microsoft 远程桌面中 CVE-2019-0708 漏洞的快速简陋扫描器。目前,公共互联网上约有 90 万台机器易受此漏洞影响,因此预计很快会出现类似 WannaCry 和 notPetya 的蠕虫。因此,请扫描您的网络,并对易受攻击的系统进行修补(或至少启用 NLA)。
这是一个命令行工具。您可以下载源代码自行编译,也可以从上述链接下载适用于 Windows 或 macOS 的预编译二进制文件。
此工具完全基于 https://github.com/zerosum0x0/CVE-2019-0708 中的 rdesktop 补丁。我只是精简了代码,以便在 macOS 和 Windows 上轻松编译,并增加了扫描多个目标的功能。
这只是几天的实验性版本。不过,我正在通过对整个互联网进行扫描(借助 masscan)来测试它,因此我会很快解决很多问题。您可以在 Twitter(@erratarob) 上联系我寻求帮助/意见。
要扫描一个网络,按如下方式运行:
rdpscan 192.168.1.1-192.168.1.255
对于每个地址,会输出以下三种结果之一:
当目标 IP 地址不存在时,旧版本会打印消息"UNKNOWN - connection timed out"。扫描大型网络时,这会生成大量无关系统的信息。因此,新版本默认不输出此信息,除非在命令行添加 -v(详细模式)。
您可以通过增加工作线程数来提高扫描大型网络的速度:
rdpscan --workers 10000 10.0.0.0/8
不过,在我的机器上,无论我将此参数设置得多高,由于系统限制,它最多只能产生约 1500 个工作线程。
您可以将此工具与 masscan 结合使用(如下文第二部分所述)以进一步提高速度。
有三种一般性响应:
虽然三种主要响应是 SAFE、VULNERABLE 和 UNKNOWN,但它们包含额外的描述文本以解释诊断结果。本节描述您会看到的各种字符串。
我们认为目标安全的主要原因有三种:
这意味着我们已确认系统存在此漏洞。
未知结果有无数种变体:
此 rdpscan 工具速度较慢,每秒只能扫描几百个目标。您可以使用 masscan 来加速。masscan 工具速度大约是它的 1000 倍,但目标信息有限。
步骤如下:
masscan 的输出导入 rdpscan,使其只扫描我们知道活跃的目标。简单的方法是在命令行中直接组合它们:
masscan 10.0.0.0/8 -p3389 | rdpscan --file -
我通常分两步操作:
masscan 10.0.0.0/8 -p3389 > ips.txt
rdpscan --file ips.txt --workers 10000 >results.txt
困难的部分是安装 OpenSSL 库,并且不与系统上的其他版本冲突。以下是我测试过的几个 Linux 版本的例子,但不同发行版的包名经常变化。此外,还有多种兼容 OpenSSL API 的选择,如 BoringSSL 和 LibreSSL。
$ sudo apt install libssl-dev
$ sudo yum install openssl-devel
解决该问题后,只需像这样将所有 .c 文件编译在一起:
$ gcc *.c -lssl -lcrypto -o rdpscan
我在目录中放了一个 Makefile 来完成此操作,因此您可能只需要:
$ make
代码是用 C 编写的,因此需要安装 C 编译器,例如:
$ sudo apt install build-essential
本节描述较明显的构建错误。
ssl.h:24:25: fatal error: openssl/rc4.h: No such file or directory
这意味着您没有安装 OpenSSL 头文件,或者它们不在路径中。请记住,即使您安装了 OpenSSL 二进制文件,也不意味着您安装了开发组件。您需要同时安装头文件和库。
要在 Debian 上安装这些东西,请执行:
$ sudo apt install libssl-dev
要修复路径问题,请添加编译标志 -I/usr/local/include 或类似的。
一个链接器问题的例子如下:
Undefined symbols for architecture x86_64:
"_OPENSSL_init_ssl", referenced from:
_tcp_tls_connect in tcp-fac73c.o
"_RSA_get0_key", referenced from:
_rdssl_rkey_get_exp_mod in ssl-d5fdf5.o
"_SSL_CTX_set_options", referenced from:
_tcp_tls_connect in tcp-fac73c.o
"_X509_get_X509_PUBKEY", referenced from:
_rdssl_cert_to_rkey in ssl-d5fdf5.o
我在 macOS 上遇到此问题,因为存在多个版本的 OpenSSL。我通过硬编码路径来修复:
$ gcc *.c -lssl -lcrypto -I/usr/local/include -L/usr/local/lib -o rdpscan
根据其他人的评论,如果您使用 Homebrew 安装,以下命令行可能在 macOS 上有效。不过我仍然遇到上述链接错误,因为我安装了其他冲突的 OpenSSL 组件。
gcc $(brew --prefix)/opt/openssl/lib/libssl.a $(brew --prefix)/opt/openssl/lib/libcrypto.a -o rdpscan *.c
上一节提供了运行程序的快速入门提示。本节提供更深入的帮助。
要扫描单个目标,只需传递目标地址:
./rdpscan 192.168.10.101
您可以传入 IPv6 地址和 DNS 名称。您也可以传入多个目标。例如:
./rdpscan 192.168.10.101 exchange.example.com 2001:0db8:85a3::1
您还可以扫描地址范围,使用起始-结束的 IPv4 地址或 IPv4 CIDR 规范。不支持 IPv6 范围,因为它们太大。
./rdpscan 10.0.0.1-10.0.0.25 192.168.0.0/16
默认情况下,它一次只扫描 100 个目标。您可以使用 --workers 参数增加此数字。但是,无论您将此参数设置得多高,实际上一时间最多只能运行大约 500 到 1500 个工作线程,具体取决于您的系统。
./rdpscan --workers 1000 10.0.0.0/24
您可以在命令行中指定目标,也可以使用 --file 参数从文件加载:
./rdpscan --file ips.txt
文件的格式是每行一个地址、名称或范围。它还可以消费 masscan 生成的文本。额外的空白字符会被修剪,空行被忽略,注释行也会被忽略。注释 是以 # 字符或 // 字符开头的行。
输出发送到 stdout,给出 VULNERABLE、SAFE 或 UNKNOWN 的状态。每个状态可能有额外原因。这些原因已在上面描述。
211.101.37.250 - SAFE - CredSSP/NLA required
185.11.124.79 - SAFE - not RDP - SSH response seen
125.121.137.42 - UNKNOWN - no connection - refused (RST)
40.117.191.215 - SAFE - CredSSP/NLA required
121.204.186.182 - SAFE - CredSSP/NLA required
99.8.11.148 - SAFE - CredSSP/NLA required
121.204.186.114 - SAFE - CredSSP/NLA required
49.50.145.236 - SAFE - CredSSP/NLA required
106.12.74.155 - VULNERABLE - got appid
222.84.253.26 - SAFE - CredSSP/NLA required
144.35.133.109 - UNKNOWN - RDP protocol error - receive timeout
199.212.226.196 - UNKNOWN - RDP protocol error - receive timeout
183.134.58.152 - UNKNOWN - no connection - refused (RST)
83.162.246.149 - VULNERABLE - got appid
您可以使用 grep 和 cut 等 Unix 命令进一步处理。要获取仅存在漏洞的机器列表:
./rdpscan 10.0.0.0/8 | grep 'VULN' | cut -f1 -d'-'
参数 -dddd 表示 诊断 信息,添加的 d 越多,打印的细节越多。这发送到 stderr 而非 stdout,以便您可以分离流。在 bash 中操作如下:
./rdpscan --file myips.txt -ddd 2> diag.txt 1> results.txt
添加 -d 参数会将连接的诊断信息转储到 stderr。
./rdpscan 62.15.34.157 -d
[+] [62.15.34.157]:3389 - connecting...
[+] [62.15.34.157]:3389 - connected from [10.1.10.133]:49211
[+] [62.15.34.157]:3389 - SSL connection
[+] [62.15.34.157]:3389 - version = v4.8
[+] [62.15.34.157]:3389 - Sending MS_T120 check packet
[-] [62.15.34.157]:3389 - Max sends reached, waiting...
62.15.34.157 - SAFE - Target appears patched
在 macOS/Linux 上,您可以像往常一样将 stdout 和 stderr 分别重定向到不同文件:
./rdpscan --file ips.txt 2> diag.txt 1> results.txt
工具包含 SOCKS5 支持:
./rdpscan --file ips.txt --socks5 localhost --socks5port 9050
这会使连接问题变得更糟,因此您会得到更多 "UNKNOWN" 结果。
为了发布作为本项目 releases 附带的 Windows 和 macOS 二进制文件,我静态链接了 OpenSSL,这样就不需要单独包含,程序可以直接运行。本节描述如何做到这一点,特别是因为 OpenSSL 官方页面上的说明似乎已过时。
这两个步骤都从下载 OpenSSL 源代码并将其放在 rdpscan 目录旁边开始:
git clone https://github.com/openssl/openssl
对于 Windows,您需要先安装某种版本的 Perl。我使用 ActiveState 提供的那个。
接下来,您需要一个特殊的"汇编器"。我使用推荐的 NASM。
接下来,您需要一个编译器。我使用 VisualStudio 2010。您可以从 Microsoft 下载最新的 "Visual Studio Community Edition"(现在是 2019 版)。
现在您需要构建 makefile。进入 OpenSSL 目录并运行 Configure Perl 程序:
perl Configure VC-WIN32
我选择 Windows 的 32 位版本,因为还有很多旧版 Windows 存在,我希望程序尽可能兼容旧版本。
我想要完全静态的构建,包括 C 运行时。为此,我打开生成的 makefile 并编辑,将 C 编译标志从 /MD(表示使用 DLL)更改为 /MT。同时,我在 CPPFLAGS 中添加了 -D_WIN32_WINNT=0x501,这将 OpenSSL 限制为在 Windows XP 和 Server 2003 上也能工作的功能。否则,如果您在这些旧系统上运行,会报错找不到 bcrypt.dll。
现在需要确保一切都在 PATH 中。我将 nasm.exe 复制到 PATH 中的某个目录。对于 Visual Studio 2010,我运行了 vcvars32.bat 来设置编译器的路径变量。
此时在命令行中,我输入:
nmake
这将生成库。静态库是 libssl_static.lib 和 libcrypto_static.lib,我用于在 rdpscan 中链接。
首先,您需要安装一个编译器。我使用 Apple 的开发工具,安装 XCode 和编译器。我认为您也可以使用 Homebrew 安装 gcc。
然后进入 OpenSSL 源代码目录并创建 makefile:
perl Configure darwin64-x86_64-cc
现在简单构建:
make depend
make
此时,它创建了动态(.dylib)和静态(.lib)库。我删除了动态库,以便默认链接静态库。
然后在 rdpscan 中构建 macOS 的 makefile:
make -f Makefile.macos
这将编译所有 rdpscan 源文件,然后链接到您刚才在 ../openssl 目录中构建的 OpenSSL 库。
这应该生成一个 3 MB 的可执行文件。如果您只得到了一个 200 KB 的可执行文件,说明您错误地链接了动态库。