
CVE-2019-0708 bluekeep 취약점 탐지
이것은 Microsoft 원격 데스크톱의 CVE-2019-0708 취약점을 위한 빠르고 간단한(quick-and-dirty) 스캐너입니다. 현재 공개 인터넷에는 이 취약점에 취약한 약 700,000대의 머신이 있으며, 원격 데스크톱이 노출되어 있지만 패치되어 악용으로부터 안전한 약 2,000,000대의 머신과 대조됩니다. 많은 사람들은 앞으로 몇 달 안에 WannaCry 및 notPetya와 유사한 파괴적인 인터넷 웜이 나타날 것으로 예상합니다. 따라서 네트워크를 스캔하고 시스템을 패치하십시오. 이 도구를 사용하면 취약한 머신을 찾기 위해 네트워크를 쉽게 스캔할 수 있습니다.
이 도구를 사용하려면 명령줄에서 실행할 "바이너리"를 다운로드하거나, 소스를 다운로드하여 컴파일할 수 있습니다. Windows용 미리 컴파일된 바이너리가 있습니다.
이 도구는 전적으로 https://github.com/zerosum0x0/CVE-2019-0708의 rdesktop 패치를 기반으로 합니다.
macOS와 Windows에서 쉽게 컴파일할 수 있도록 코드를 간단히 정리했으며,
여러 대상을 스캔하는 기능도 추가했습니다.
이것은 불과 며칠 된 실험적인 코드입니다. 하지만 masscan의 도움을 받아
전체 인터넷을 스캔하며 테스트하고 있기 때문에 많은 문제를
빠르게 해결해 나가고 있습니다. 도움/의견은 트위터(@erratarob)로 연락해 주세요.
네트워크를 스캔하려면 다음과 같이 실행합니다:
rdpscan 192.168.1.1-192.168.1.1.255
그러면 각 주소에 대해 한 줄의 결과가 출력되며, 버그에 취약하면 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
또는 한 단계로, 한쪽 출력을 다른 쪽으로 파이프합니다:
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
시작-끝(begin-end) 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 상태를 표시합니다.
각각에 대한 추가적인 이유가 있을 수 있습니다.
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에 항상 하나의 상태만 표시되어야 합니다.
물론 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" 결과가 훨씬 더 많이 나옵니다.