C, C + + and Java Security coding practice tips and tricks

Source: Internet
Author: User

Security is becoming an increasingly important topic for developers in all types of environments, even embedded systems that used to think security is not a problem. This article describes several types of coding vulnerabilities, identifies what vulnerabilities are, how to reduce the risk of the code being attacked, and how to better identify such flaws in your code.

Inject attack

By injecting information into a running process, an attacker can compromise the running state of a process to reflect a certain ultimate goal that developers cannot protect. For example, an attacker could inject code into a process through a stack overflow (corruption) to execute code selected by the attacker. In addition, an attacker might try to inject data into a database for future use, or inject an unprotected string into a database query to obtain more information than the developer. For whatever purpose, injection is always a bad thing and always needs to be treated with caution.

Perhaps the worst form of injection attack is code injection-placing new code into the memory space of a running process and then instructing the running process to execute the code. If such an attack succeeds, almost anything can be done, because the running process is completely hijacked, executing any code that the attacker wishes to execute.

One of the most famous examples of such attacks is the Windows animated cursor attack, which is the pattern discussed in this article. An attacker uses a simple Web page to download the improperly-created animated cursor file to the viewer's PC, causing the browser to invoke this animated cursor, which may occur when arbitrary code is injected. In fact, this is a perfect attack carrier: because it does not require any actual access to the attacked machine, the end user is not aware of any possible problems, and if the malicious effect of the attack is moderate, then the external impact on the end user is almost zero.

Consider Example 1 (a), which, of course, is rewritten from Windows attacks, which form the basis of such an attack vector. Developers here have made basic assumptions about the reliability of incoming streams. Trust flow and and believe everything is okay. Using a stack-based type that will be deserialized (called), unknown data streams and code injection will certainly appear at some point in time.

(a)
void LoadTypeFromStream(unsigned char* stream, SOMETYPE* typtr)
{
int len;
// Get the size of our type's serialized form
memcpy(&len, stream, sizeof(int));
// De-serialize the type
memcpy(typtr, stream + sizeof(int), len);
}
(b)
void foo(unsigned char* stream)
{
SOMETYPE ty;
LoadTypeFromStream(stream, &ty);
}
(c)
void LoadTypeFromStream
(unsigned char* stream, SOMETYPE* typtr)
{
int len;
// Get the size of our type's serialized form
memcpy(&len, stream, sizeof(int));
// GUARD
if( len < 0 || len > sizeof(SOMETYPE) )
throw TaintedDataException();
// De-serialize the type
memcpy(typtr, stream + sizeof(int), len);
}

Example 1 injection attack.

How did this happen? Suppose you invoke the function in Example 1 (b). We've got an easy to use attack carrier. The problem here is that the size of the SOMETYPE is fixed at compile time. Suppose this type uses 128 byte representations in memory. Let's assume that when you build an incoming stream, the reading of the first 4 bytes (the length of the content to be not serialized) is 256. Now, instead of checking the validity of the content being processed, you copy 256 bytes into a reserved stack space of only 128 bytes.

Given the typical layout of the release pattern stack, you're obviously in trouble. View the stack for reasons. Each called function lays its local data in one frame of the stack, usually by subtracting the known size of the local data from the stack pointer at input, plus any management data required to handle the call chain itself. The ideal function prolog (pseudo code) emitted by the compiler looks like this:

.foo
sub sp, 128  ; sizeof SOMETYPE

Subsequently, the invocation of the available function should look like the following:

push sp   ; push the SOMETYPE
local variable
push ap   ; push the stream
pointer (comes from 1st argument)
call LoadTypeFromStream
ret

Related Article

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.