Check whether the Code has the Integer Operation Security Vulnerability.

Source: Internet
Author: User

CheckCodeInteger Operation Security Vulnerability

Abstract: Michael Howard raised the question about the Integer Operation Security Vulnerability and elaborated that it can be used to protect its own applications.ProgramSecurity Plan.

Many years ago, few people have heard of integer overflow attacks, but now it seems that every few days it will have a new form. The following short list shows some integer overflow security errors found in the last few months:

• Sun RPC xdr_array

• OpenSSH Authentication

• Apache Chunked Encoding

• Microsoft JScript

• FreeBSD socket and system CILS

• Snort TCP packet reassembly

I don't want to explain what integers are. I suppose you know what they are and there are two types (signed and unsigned). When the value is negative, set the high value of a signed integer to 1, which is a complement to 2.Algorithm. You also know that the integer sizes are different. The most common integers are 64-bit, 32-bit, 16-bit, and 8-bit. This is all I have mentioned about integers. For this article, it is sufficient to know this knowledge.

Three major integer operations can cause security vulnerabilities:

• Overflow and Underflow

• Signed and unsigned errors

• Truncation

Depending on their own circumstances, these problems may not produce security errors. However, if your code shows one or more of these problems and your code operates on the memory, the possibility of a buffer overflow error or application failure increases. Let's take a closer look at each item.

Overflow and Underflow

Let's take a quick look at the problem with this code?

Bool func (size_t cbsize ){

If (cbsize <1024 ){

// We never deal with a string trailing null

Char * Buf = new char [cbSize-1];

Memset (BUF, 0, cbSize-1 );

// Do stuff

Delete [] Buf;

Return true;

} Else {

Return false;

}

}

 

The code is correct, right? It verifies that the cbsize is not greater than 1 kb, and the new or malloc should always be allocated 1 kb correctly, right? Let's ignore the following fact that the return value of new or malloc should be checked at this time. Similarly, cbsize cannot be negative because it is size_t. But what if the cbsize is zero? Check the Buffer Allocation code, which deducts one from the buffer size request. Subtract from zero to generate the size_t variable. This is an unsigned integer with a limit of 0 xffffffff (assuming a 32-bit value) or 4 GB. Your application is only over, or worse!

See the following similar questions:

Bool func (char * S1, size_t len1,

Char * S2, size_t len2 ){

If (1 + len1 + len2> 64)

Return false;

// Accommodate for the trailing null in the addition

Char * Buf = (char *) malloc (len1 + len2 + 1 );

If (BUF ){

Stringcchcopy (BUF, len1 + len2, S1 );

Stringcchcat (BUF, len1 + len2, S2 );

}

// Do other stuff with Buf

If (BUF) Free (BUF );

Return true;

}

Similarly, the Code looks well written. It checks the data size and verifies whether malloc is successful, and use safe string handler stringcchcopy and stringcchcat (You can read more about these string handler functions from the http://msdn.microsoft.com/library/en-us/dnsecure/html/strsafe.asp ). However, this Code may be vulnerable to integer overflow. What if len1 is 64 and len2 is 0 xffffff? The code that determines the buffer size legally adds 1, 64, and 0 xffffffff together. Due to the operation restrictions, 64 is generated. Next, the Code allocates only 64 bytes, and then the code generates a new string with a length of 64 bytes, and then connects the 0 xfffffffff bytes to the string. Similarly, the application will end. In some cases, code may be vulnerable to available buffer overflow attacks if you use a well-designed size.

Another lesson here is that if the buffer size calculation is incorrect, the _ safe string processing function is insecure.

JScript Overflow Attack

When multiplication is used, overflow errors of the same type also occur, which occurs in Microsoft JScript errors. This error only indicates that it appears when using the JScript sparse array support:

VaR arr = new array ();

Arr [1] = 1;

Arr [2] = 2;

Arr [0x40000001] = 3;

 

In this example, the array has three elements, and the length is 0x40000001 (decimal: 1073741825 ). However, since this example uses a sparse array, it only occupies an array of three elements in the memory.

The C ++ code that implements the JScript custom sorting routine allocates a temporary buffer on the stack, copies three elements to the temporary buffer, and uses the custom function to sort the temporary buffer, then move the contents of the temporary buffer back to the array. The following code allocates a temporary buffer:

Temporarybuffer = (element *) malloc (elementcount * sizeof (element ));

Element is a 20-byte data structure used to save array items. It seems that the program will try to allocate about 20 GB to the temporary buffer. You may think that the allocation attempt will fail because most computers do not have 20 GB of memory. Then, the JScript general memory insufficiency processing routine will handle this problem. Unfortunately, this has not happened.

When a 32-bit integer algorithm is used, the result (0x0000000500000014) is too large to be saved in a 32-bit value, so we will be attacked by an integer overflow:

0x40000001*0x00000014 = 0x0000000500000014

C ++ will discard all non-conforming bits, so we will get 0x00000014. This is why the allocation does not fail-instead of trying to allocate 20 GB, the allocation only attempts to allocate 20 bytes. Then, the sorting routine assumes that the buffer is large enough to store the three elements in the sparse array. Therefore, it copies 60 bytes of the three elements to the buffer of 20 bytes, in this way, the buffer overflow is 40 bytes. It's so risky!

Signed and unsigned errors

Quickly view the following code. It is similar to the first example. Check whether you can find the error. If you find the error, try to determine the result of the error.

Bool func (char * S1, int len1,

Char * S2, int len2 ){

Char Buf [128];

If (1 + len1 + len2> 128)

Return false;

If (BUF ){

Strncpy (BUF, S1, len1 );

Strncat (BUF, S2, len2 );

}

Return true;

}

The problem here is that the size of the string is stored as a signed integer, so as long as len2 is a negative value, len1 can be greater than 128, and thus the sum is less than 128 bytes. However, calls to strncpy will overflow the Buf buffer.

Truncation error

Let's take a look at the last attack type. You can guess it by using the code example.

Bool func (byte * Name, DWORD cbbuf ){

Unsigned short cbcalculatedbufsize = cbbuf;

Byte * Buf = (byte *) malloc (cbcalculatedbufsize );

If (BUF ){

Memcpy (BUF, name, cbbuf );

// Do stuff with Buf

If (BUF) Free (BUF );

Return true;

}

Return false;

}

This attack, at least, is similar to the preceding JScript error. What if cbbuf is 0x00010020? Cbcalculatedbufsize is only 0x20, because it only copies 16 low bits from 0x00010020. Therefore, only 0x20 bytes are allocated, and 0x00010020 bytes are copied to the newly allocated destination buffer. Note that Microsoft Visual C ++? The/W4 option to compile this code will generate:

Warning c4244 :\\\ 'initializing \\\ ': conversion from \\\ 'dword \\\' to \\\ 'unsigned

Short \ ', possible loss of data

Note that the following operations are not marked as a warning:

Int Len = 16;

Memcpy (BUF, szdata, Len );

The last parameter of memcpy is size_t, and the parameter Len is signed. There is no warning because memcpy always assumes that the third parameter is unsigned and converting to unsigned does not change the output of the function.

Note: If you try to assign a size_t to DWORD, you will receive a warning, not because data may be lost on a 32-bit platform, this is because data will be lost on the 64-bit platform.

Warning c4267 :\\\' =\\\ ': conversion from \\\ 'size _ t \\\' to \\\ 'dword \\\\ ', possible loss

Of data

You will receive this warning because all default C ++ projects are compiled using the-wp64 option, which notifies the compiler to monitor 64-bit portability issues.

Integer operations in managed code

Integer Operation errors may occur in managed languages, such as C # and Visual Basic ?. But the potential damage is significantly reduced because the Code does not directly access the memory. However, calling the local code (assuming that your code is granted the permission to call unmanaged code) may still cause security issues similar to the above. The integers in the general language specification (CLS) are signed. An error is that when variables are treated as unsigned integers in unmanaged code, verify whether it is a signed integer parameter in managed code.

This particular example provides a more general recommendation: Always check the content that is passed to the unmanaged code. Many Integer Operation errors in managed code may cause reliability errors in Visual Basic. net, because if overflow or underflow occurs, all such operations will cause system. overflowexception.

By default, C # does not cause these exceptions. If you want to check these problems, use the checked Keyword:

Uint32 I = 0xfffffff0;

Uint32 J = 0x00000100;

Uint32 K;

Checked {k = I + J ;}

Remedy

Who would think that security problems would occur only when an integer is operated? Simple remedial measures for vulnerable Code are as follows:

If (a + B> MAX) Return-1;

Use this code with an unsigned integer:

If (a + B> = A & A + B <max ){

// Cool!

}

The first operation, A + B> = A, checks whether the surrounding exists, and the second operation ensures that the sum after addition is smaller than the target size.

For Operation Problems In JScript, you can check that the number of elements does not exceed the predefined value, and the predefined value is smaller than the maximum number you will allocate to the memory. For example, the following code potentially allocates up to 64 MB of memory:

Const size_t max = 1024*1024*64;

Const size_t elem_size = sizeof (element );

Const size_t max_elems = max/elem_size;

If (celems> = max_elems)

Return false;

Finally, use unsigned integers such as DWORD and size_t for Array indexes, buffer sizes, and similar objects.

Key code checkpoint

When compiling or checking the code for integer-related problems, remember the following points:

• Use the highest warning level/W4 to compile C and C ++ code.

• Use size_t or DWORD for the buffer size and element count. There is no reason to use signed values for these structures.

• Keep in mind that size_t represents different types based on your platform. Size_t is the size of the memory address. Therefore, it is a 32-bit value on a 32-bit platform, but it is a 64-bit value on a 64-bit platform.

• If the code performs any Integer Operation (adding, multiplication, and so on), the result is used to index the array or calculate the buffer size, make sure that the operands are within a small and understandable range.

• Be cautious with the signed parameters of memory allocation functions (new, malloc, globalalloc, and so on) because they will be treated as unsigned integers.

• Note the c4018, c4389, and c4244 warnings.

• Discard the conversion of c4018, c4389, and c4244 warnings.

• Investigate and disable all use of # pragma warning (disable, cnnnn) with c4018, c4389, and c4244 warnings. In fact, mark them as comments, recompile, and check all new warnings related to integers.

• Code migrated from other platforms or compilers may use different data sizes. Be careful!

• If you call an unmanaged code from a hosted code, make sure its symbols are correct. Many parameters of Win32 API are unsigned Int or DWORD, while many managed code variables are signed.

• Finally, if you are using managed code, make sure to use catch overflowexceptions when appropriate.

detected security vulnerabilities
many people checked my problems last month. It is an integer overflow attack. So what is the problem with the C # code?
string status =\\ "No \\\";
string sqlstring = \\\"\\\";
try {
sqlconnection SQL = new sqlconnection (
\\ "Data Source = localhost; \\\" +

\\\ "User ID = sa; Password = PASSWORD ;\\\");
SQL. open ();
sqlstring =\\ "select hasshipped \\\" +

\\ "from detail where ID = \\\'\\ \ "+ ID + \\\"\\\'\\\";
sqlcommand cmd = new sqlcommand (sqlstring, SQL);

If (INT) cmd. executescalar ()! = 0)
Status =\\ "Yes \";
} catch (sqlexception SE) {
Status = sqlstring + \\ "failed \\\ n \\\ R \\\";
foreach (sqlerror e in se. errors) {
Status + = E. message + \\\ "\\\\\ n \\\ R \\\";

}< br>
} catch (exception E) {
Status = E. tostring ();

}

Michael Howard is the Senior Security Program Manager of Microsoft's secure windows Initiative Group. He is one of the authors of writing secure code and the second edition is now available. He is also the main author of "Designing Secure Web-based applications for Windows 2000. His main task is to ensure that people design, build, test, and record defect-free security systems. His favorite sentence is "one person tool, the weapon of others. "

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.