"Heartbleed" is called one of the most serious security vulnerabilities in the history of the Internet. It affects a large number of frequently-used websites and services, including Gmail, which many people use every day, users' passwords and credit cards may be easily disclosed. But we may not know much about it. We may think it is none of my business.
I randomly found a relatively large website (the domain name is not mentioned), and then looked at the returned information in the debugger:
We can see that the website server also uses OpenSSL. In fact, the usage of OpenSSL is still quite high. If you frequently access the Internet, you can say that you are dealing with OpenSSL almost every day, and your personal information is stored on various websites, once a website leaks important information, such as credit cards and bank cards, you may lose some money.
Curious people may want to know What mistakes OpenSSL programmers have made. Fortunately, geek websites like XKCD demonstrate the principle of this vulnerability in the most easy-to-understand way:
Translation of fried eggs on the other side
The so-called heartbleed comes from heartbeat detection, which means that the user initiates a Client Hello inquiry by sending a TSL encrypted link, test whether the server works normally online (the image is a heart pulse). The server sends back to server hello, indicating that SSL communication is established normally. The length of pad length is appended to each query. A bug occurs. If the pad length is greater than the actual length, the server returns the same size of characters, this results in out-of-bounds access to information in the memory ......
In the cartoon, the user's Meg request returns "hat five hundred letters", and then the color server returns the first 500 words including the hat in the memory, that is to say, the server understands the "Five hundred letters" sentence to display 500 letters and then returns the first 500 letters operated by others on the server to Meg, here, there is a lot of private information.
Does it look like this out-of-bounds memory leakage bug is 2?
So let's look at it at the code level? Assume that the heartbeat information struct is defined:
struct hb { int type; int length; unsigned char *data; };
Type indicates the heartbeat type and length indicates the data size. The content structure of the data field is as follows:
The Type field occupies one byte, the payload field occupies two bytes, and the rest is the specific content of payload, as shown in the following details:
Byte number |
Remarks |
0 |
Type |
1-2 |
The specific content size in data is payload. |
3-len |
Specific content pl |
When the server receives the message, it will parse the message, that is, it will parse the string in the data, get the type by parsing the 0th bits, get the payload by the 1-2 bits, apply for (1 + 2 + payload) memory size, and then copy the corresponding data to the new memory.
The following is a simple example to illustrate this problem. If the data sent by the client is "006 abcdef", type = 0, payload = 06, PL = 'abcdef', apply for (1 + 2 + 6 = 9) memory, and then write type, payload, and PL to the newly applied memory.
If everyone is honest, the above process will not have any problems. However, there are always so many people in the world who don't "score". They will be very dishonest. For example, there are only six strings "abcdef" sent by the client, but I have to set payload to 500. If the server does not perform any boundary check when it is silly, directly apply for (1 + 2 + 500) memory size, in addition, all the content of "abcdef **********" is copied to the newly applied memory and sent back to the client.
In this way, the restless people will obtain a lot of sensitive information on the server, which may include bank account information, electronic transaction information, and many other security information.
Of course, the actual struct definition is as follows:
typedef struct ssl3_record_st{int type; /* type of record */unsigned int length; /* How many bytes available */unsigned int off; /* read/write offset into ‘buf‘ */unsigned char *data; /* pointer to the record data */unsigned char *input; /* where the decode bytes are */unsigned char *comp; /* only used with decompression - malloc()ed */unsigned long epoch; /* epoch number, needed by DTLS1 */unsigned char seq_num[8]; /* sequence number, needed by DTLS1 */} SSL3_RECORD;
Each SSLv3 record contains a type field, a length field, and a pointer to the recorded data ).
In dtls1_process_heartbeat, there is a statement like this:
/* Read type and payload length first */hbtype = *p++;n2s(p, payload);pl = p;
The first byte of the SSLv3 record indicates the heartbeat packet type. The macro N2s extracts the first two bytes from the array pointed to by the pointer P and saves them to the variable payload. This is actually the length of the heartbeat packet load ). Note that the program does not check the actual length of this SSLv3 record. The variable PL points to the heartbeat packet data provided by the visitor.
I often see that the variable name payload is used when many tools are used to name variables. Is it common for developers of OpenSSL to do something like this?
What is this OpenSSL heartbleed vulnerability?