
CVE-2019-0708 bluekeep 脆弱性検出
これは、Microsoft リモート デスクトップの CVE-2019-0708 脆弱性に対する簡易スキャナです。 現在、この脆弱性の影響を受ける約 70 万台のマシンがパブリック インターネット上に存在します。 これに対し、リモート デスクトップを公開しているもののパッチ適用済みで悪用に対して安全なマシンは約 200 万台です。多くの専門家は、今後数か月以内に WannaCry や notPetya に似た壊滅的なインターネットワームが出現すると予想しています。 そのため、ネットワークをスキャンしてシステムにパッチを適用してください。このツールを使えば、ネットワークをスキャンして脆弱なマシンを見つけることが簡単にできます。
このツールを使用するには、コマンドラインで実行する「バイナリ」をダウンロードするか、ソースをダウンロードしてコンパイルします。Windows 用のプリコンパイル済みバイナリが利用可能です。
このツールは、https://github.com/zerosum0x0/CVE-2019-0708 の rdesktop パッチに完全に基づいています。
macOS と Windows で簡単にコンパイルできるようにコードをトリミングし、複数のターゲットをスキャンする機能も追加しました。
これは、作られてからわずか数日で、実験的なものです。ただし、masscan の助けを借りてインターネット全体をスキャンしてテストしているため、多くの問題をかなり迅速に解決しています。質問やコメントがある場合は、Twitter(@erratarob)で連絡してみてください。
ネットワークをスキャンするには、次のように実行します:
rdpscan 192.168.1.1-192.168.1.1.255
これにより、アドレスごとに 1 行の結果が出力され、このバグに対して脆弱な場合は VULNERABLE、安全(おそらく)な場合は SAFE、ターゲットから応答がないなどプログラムがステータスを判別できなかった場合は UNKNOWN と表示されます。ほとんどのターゲットは応答しないため、統計的に大半が UNKNOWN になります。
これはかなり遅いです。コマンドライン引数 --workers 1000 を追加すると速度を上げられます。さらに、最初に masscan を使ってポート 3389 が利用可能なマシンをすばやく探し、その結果得られたマシンだけを rdpscan で脆弱性スキャンするという方法でも、さらに高速化できます。
masscan 10.0.0.0/8 -p3389 --rate 1000000 >ips.txt
rdpscan --file ips.txt > results.txt
または、出力をパイプでつないで 1 つのステップで実行することもできます:
masscan 10.0.0.0/8 -p3389 --rate 1000000 | rdpscan --file -
-d パラメータを使うと、より詳細な診断情報が得られ、stderr に出力されます。これは、私が通常プログラムを実行する方法です:
rdpscan --file ips.txt 2> diag.txt 1> results.txt
難しいのは、OpenSSL ライブラリをインストールし、システム上の他のバージョンと競合しないようにすることです。Debian Linux では、次のようにします:
$ sudo apt install libssl-dev
この問題を解決したら、次のようにすべての .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
ファイルの形式は、1 行に 1 つのアドレス、名前、または範囲です。masscan が生成したテキストもそのまま使用できます。余分な空白はトリミングされ、空行は無視され、コメント行も無視されます。コメントとは、# 文字または // 文字で始まる行のことです。
出力は stdout に送信され、VULNERABLE、SAFE、または UNKNOWN のステータスが示されます。それぞれに追加の理由が含まれる場合があります。
149.129.120.24 - UNKNOWN - FIN received
45.60.213.160 - SAFE - not RDP but HTTP
208.43.229.89 - SAFE - CredSSP required
170.104.127.137 - UNKNOWN - FIN received
86.188.190.117 - UNKNOWN - connect timeout
62.15.34.157 - SAFE - Target appears patched
216.15.251.120 - VULNERABLE -- got appid
69.62.158.174 - VULNERABLE -- got appid
92.111.20.13 - SAFE - Target appears patched
これは grep や cut などの Unix コマンドで処理できます。脆弱なマシンだけのリストを取得するには:
./rdpscan 10.0.0.0/8 | grep 'VULN' | cut -f1 -d'-'
"UNKNOWN" とマークされたものは、後でスキャンする価値があるでしょう。特に "FIN received" は、通常、インターネット上の遅延が原因で相手側が接続を早期に終了したことを意味します。それらをファイルに保存し、次のスキャンで --file オプションを使って再読み込みしてください。
"CredSSP required"(つまり NLA 必須)が "SAFE" であるかどうかは議論の余地があります。これは、脆弱性をテスト/トリガーする前にパスワードログインが必要であることを意味します。パッチ未適用で認証済みユーザーに対して脆弱な可能性はありますが、ワームや未認証ユーザーによる悪用はできません。
スキャンする各 IP アドレスについて、stdout には常に 1 つだけステータスが出力されるはずです。もちろん、同じ IP アドレスを複数回指定した場合は、そのアドレスに対して複数のステータスが出力されます。
ただし、このコードは rdestkop に基づいているため、ステータスに至らない特定のプロトコルエラーがあります。これらのエラーを発生させるパブリック IP アドレスをお持ちの場合は、ぜひ修正したいのでお知らせください。
-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" の結果がかなり多くなります。