• Tidak ada hasil yang ditemukan

Memory Corruption Bugs (MSTG-CODE-8)

Dynamic Analysis

XSS issues can be best detected using manual and/or automated input fuzzing, i.e. injecting HTML tags and special characters into all available input fields to verify the web application denies invalid inputs or escapes the HTML meta-characters in its output.

Areflected XSS attackrefers to an exploit where malicious code is injected via a malicious link.

To test for these attacks, automated input fuzzing is considered to be an effective method. For example, the BURP Scanner is highly effective in identifying reflected XSS vulnerabilities. As always with automated analysis, ensure all input vectors are covered with a manual review of testing parameters.

Integer overflows: When the result of an arithmetic operation exceeds the maximum value for the integer type defined by the programmer, this results in the value “wrapping around”

the maximum integer value, inevitably resulting in a small value being stored. Conversely, when the result of an arithmetic operation is smaller than the minimum value of the inte- ger type, an integer underflowoccurs where the result is larger than expected. Whether a particular integer overflow/underflow bug is exploitable depends on how the integer is used.

For example, if the integer type were to represent the length of a buffer, this could create a buffer overflow vulnerability.

Format string vulnerabilities: When unchecked user input is passed to the format string parameter of the printf family of C functions, attackers may inject format tokens such as

‘%c’ and ‘%n’ to access memory. Format string bugs are convenient to exploit due to their flexibility. Should a program output the result of the string formatting operation, the attacker can read and write to memory arbitrarily, thus bypassing protection features such as ASLR.

The primary goal in exploiting memory corruption is usually to redirect program flow into a loca- tion where the attacker has placed assembled machine instructions referred to asshellcode. On iOS, the data execution prevention feature (as the name implies) prevents execution from memory defined as data segments. To bypass this protection, attackers leverage return-oriented program- ming (ROP). This process involves chaining together small, pre-existing code chunks (“gadgets”) in the text segment where these gadgets may execute a function useful to the attacker or, call mprotect to change memory protection settings for the location where the attacker stored the shellcode.

Android apps are, for the most part, implemented in Java which is inherently safe from memory corruption issues by design. However, native apps utilizing JNI libraries are susceptible to this kind of bug. Similarly, iOS apps can wrap C/C++ calls in Obj-C or Swift, making them susceptible to these kind of attacks.

Buffer and Integer Overflows

The following code snippet shows a simple example for a condition resulting in a buffer overflow vulnerability.

voidcopyData(char*userId) { char smallBuffer[10];// size of 10 strcpy(smallBuffer, userId);

}

To identify potential buffer overflows, look for uses of unsafe string functions (strcpy, strcat, other functions beginning with the “str” prefix, etc.) and potentially vulnerable programming constructs, such as copying user input into a limited-size buffer. The following should be consid- ered red flags for unsafe string functions:

• strcat

• strcpy

• strncat

• strlcat

• strncpy

• strlcpy

• sprintf

• snprintf

• gets

Also, look for instances of copy operations implemented as “for” or “while” loops and verify length checks are performed correctly.

Verify that the following best practices have been followed:

• When using integer variables for array indexing, buffer length calculations, or any other security-critical operation, verify that unsigned integer types are used and perform precon- dition tests are performed to prevent the possibility of integer wrapping.

• The app does not use unsafe string functions such asstrcpy, most other functions beginning with the “str” prefix,sprint,vsprintf,gets, etc.;

• If the app contains C++ code, ANSI C++ string classes are used;

• In case ofmemcpy, make sure you check that the target buffer is at least of equal size as the source and that both buffers are not overlapping.

• iOS apps written in Objective-C use NSString class. C apps on iOS should use CFString, the Core Foundation representation of a string.

• No untrusted data is concatenated into format strings.

Static Analysis

Static code analysis of low-level code is a complex topic that could easily fill its own book. Auto- mated tools such asRATS combined with limited manual inspection efforts are usually sufficient to identify low-hanging fruits. However, memory corruption conditions often stem from complex causes. For example, a use-after-free bug may actually be the result of an intricate, counter- intuitive race condition not immediately apparent. Bugs manifesting from deep instances of over- looked code deficiencies are generally discovered through dynamic analysis or by testers who invest time to gain a deep understanding of the program.

Dynamic Analysis

Memory corruption bugs are best discovered via input fuzzing: an automated black-box software testing technique in which malformed data is continually sent to an app to survey for potential vulnerability conditions. During this process, the application is monitored for malfunctions and crashes. Should a crash occur, the hope (at least for security testers) is that the conditions creating the crash reveal an exploitable security flaw.

Fuzz testing techniques or scripts (often called “fuzzers”) will typically generate multiple instances of structured input in a semi-correct fashion. Essentially, the values or arguments generated are at least partially accepted by the target application, yet also contain invalid elements, potentially triggering input processing flaws and unexpected program behaviors. A good fuzzer exposes a substantial amount of possible program execution paths (i.e. high coverage output). Inputs are either generated from scratch (“generation-based”) or derived from mutating known, valid input data (“mutation-based”).

For more information on fuzzing, refer to theOWASP Fuzzing Guide.