Alpine Linux: from vulnerability discovery to code execution a-vulnerability warning-the black bar safety net

ID MYHACK58:62201787473
Type myhack58
Reporter 佚名
Modified 2017-06-29T00:00:00


One, Foreword Recently I was in the Alpine Linux package Manager found two serious vulnerabilities, exploits, numbered CVE-2017-9669 and CVE-2017-9671。 If you are using Alpine, an attacker may use these two holes in your host to execute malicious code. Alpine Linux is a lightweight Linux distribution, in the past few years more and more welcomed by the people, the main reason may be it is in the container, especially Dokcer has a huge advantage. The official Docker repository most have with the alpine corresponding to the version number, and alpine warehouse pull amount was already more than 1 million times. Alpine design philosophy is Safety-oriented distributions, the relevant developers are also putting a lot of effort to achieve this concept, they used the method of including in the kernel to add the defense mechanisms, and the use of modern binary protection mechanisms to compile the user space of the package, packet in. For these reasons, we in the Twistlock in the use of the Alpine in. As a security researcher, I decided to study in depth under the alpine's internal mechanism, looking to be able to endanger all the alpine users of major Safety defects. Second, to apk for the target to find vulnerabilities Many of the tools together to form the alpine release, which I want to take a look at The is apk, this is the alpine package Manager. If I could package installed before tampering with their contents, or allow the Manager to downgrade a package, then I can be on the target system to execute code. After some initial research, I finally decided to try the apk in some parts of the fuzzy test fuzzing it. I for apk made some changes, compile the apk so that it applies to afl tools accurate to say, I wrote a small program, using file as a program input. In the past I had used the afl to successfully dig out some zero-day exploit, so I think through the fuzz of some of the possible loopholes of the function, I can find the apk in the presence of vulnerabilities. I wrote a small program major focus in the tar parsing code. Apk to gz compressed package tar.gz the form accepts the update file, so I extracted the received tar stream that parts of the code, directly give it an input file. This is a perfect fuzz point, because this app has a lot of code used to parse the user's input, and I found all the crash point will be prior to any signing process. The relative ratio, in the parsing of a specific packet when the collapse point is not particularly important, because the apk on file the signature for verification. My guess is correct. Less than a day, the afl just found this small program in a large number of Crash points. I these crashing points are classified, and then through the debugging means locating the specific vulnerability. After some painful attempts, to solve some errors, I in tar of analytic functions found in the two paragraphs may result in a heap overflow code. Third, vulnerability analysis Overflow vulnerability exists in the following code, located in the archive. c source file: case 'L': / GNU long name extension / if (blob_realloc(&longname, an entry. size+1)) goto err_nomem; entry. name = longname. ptr; is->read(is, entry. name, entry. size); entry. name[entry. size] = 0; offset += entry. size; entry. size = 0; break; First to understand this code. This code from the archive. c apk_parse_tar function. This function receives data from the apk_istream the tar stream, parses this data stream, parsing out each data segment invokes a callback function. Typically, a tar stream comprises a plurality of 512 byte data blocks, the data stream at the beginning of the tar head of the data block, and then followed a number of file data blocks. The head of the field there is a field for the typeflag is used to represent the data stream contains file of type. This field is also used to represent certain data block of purposes, such as longname, or“the GNU long name extension”logo indicates the next byte will contain the containing file name. If the file name length exceeds 100 bytes will use this identification. Therefore, when the parser encounters a longname data block, it will be based on the size of the allocated buffer, and then from the data stream, copy the name information to the buffer. This process corresponds to the buffer name as longname, if the need to expand the size of the buffer, the program used a function for blob_realloc it. blob_realloc function of the code is as follows: static int blob_realloc(apk_blob_t b, int newsize) { char tmp; if (b->len >= newsize) return 0; tmp = realloc(b->ptr, newsize); if (! tmp) return-ENOMEM; b->ptr = tmp; b->len = newsize; return 0; } The problem is that this function will accept an int type for the size parameter, of type int was a signed type. b->len is of type long, which indicates that this variable is also a symbol type. Therefore, these two variables the comparison result is also a signed type. You may be curious about this treatment what will be the problem. You can try it when the size exceeds 0x80000000 when the program processing the scene. For unsigned integer, unsigned int, 0x80000000 in decimal is 2147483648, if it is a signed integer, this value is the corresponding decimal number is-2147483648, even on a 64-bit host using gcc to compile, int and long usually the case will be compiled as a 32-bit value in. In other words, when the size ratio of the signed integer maximum value is greater, the program will think that size is a negative number, therefore blob_realloc will return 0, and does not modify the buffer content. Then the program will call The is->read, the number of bytes copied to the buffer, these bytes size exceeds the buffer allocated of size, will cover a heap on the follow-up data. read function considers the size of the type is an unsigned type, and the processing of tar. gz gzi_read Function, This function is located in the gunzip. c, it is desired to obtain a size_t parameter is an unsigned type. Simply modify the blob_realloc definition, the parameter type from int to size_t is not sufficient to solve this problem, because when the variable value than the entry. size The maximum value is also large, such as entry. size+1, or occurs an integer overflow problem, will eventually cause buffer overflow, and before the case. If an attacker is able to predict the program execution when the memory layout, then he can exploit this buffer overflow vulnerability to achieve code execution purposes, specifically, he can cover the stack on a function of the offset, which points to him the setting of any function to do this. At this point, I don't want to release the exploit PoC code, in the near future, if this vulnerability is repaired, and the attacker is difficult to exploit this vulnerability, I will release the PoC code, at the same time describes the entire use process. MITRE will be the vulnerability number CVE-2017-9669。 We can in code find blob_realloc another call, this part of the code responsible for parsing tar file of the pax header information, there is a similar buffer overflow vulnerabilities, this vulnerability number CVE-2017-9671。 Fourth, the vulnerability The attacker can be through a variety of ways to use such a buffer overflow vulnerability. The most direct method is to attempt to exploit this vulnerability on the target system of the code execution. Exploit the only prerequisite is the need to know the program's memory layout information. Such as ASLR, address space layout randomization such as protection mechanisms may prevent an attacker using this vulnerability, but an attacker may still bypass these protection mechanisms to complete the code execution. I will in the subsequent articles of this aspect of the content.

[1] [2] next