Showing posts with label Hack. Show all posts
Showing posts with label Hack. Show all posts

Sunday, July 28, 2019

ShellShock: Vulnerability, Patch and Exploit Analysis


ShellShock vulnerability is a serious vulnerability in the widely used Bash shell. Bash is by far the most popular shell and is the default shell distributed with Linux and Mac OS X. In addition, it is used by many computers and servers that are exposed to the Internet. The patch was released on September 24th along with the announcement of the vulnerability, but attackers on the Internet relied on the fact that not everyone was going to promptly patch their computers and therefore started attacking vulnerable machines on the Internet.

The ShellShock vulnerability itself was a simple logic flaw in the Bash code rather than a memory corruption, making it very easy for a large audience to understand and exploit. To make matters worse, this vulnerability is “wormable” in that it does not require user interaction, allows untrusted/unauthenticated users to execute code on a remote machine and its exploit can be embedded into a malicious script to automate its proliferation around the Internet at an exponential rate. Some currently known attack vectors include (1) CGI-based web servers, SSH servers and DHCP clients, all of which are widely used services around the Internet.

The Vulnerability:
The vulnerability itself was the simple fact that Bash allowed the user to define functions and include multiple commands inside environment variables that are passed to Bash. This is dangerous in situations when the value of the environment variable passed to the new Bash instance is supplied by an unauthenticated and untrusted source.

The Fix:
The Fix for the ShellShock vulnerability was implemented in the patch “bash43-025” released on the GNU FTP website (2). Below is the relevant annotated code change inside Bash 4.3, which is the newest supported version of Bash.

//CVE-2014-6271: executed with “testbug = () { :;}; echo VULNERABLE”
void initialize_shell_variables (env, privmode)
  char **env;
  int privmode;
{
  ...
  /*
    Now, name = env variable name,
    string = env variable value
    char_index == strlen (name)

    temp_string = "testbug () { :;}; echo VULNERABLE"
    name = "testbug"
    SEVAL_FUNCDEF is OR'ed in below indicating that this was a
    function definition
    SEVAL_ONECMD is OR'ed in below to indicate that we only want
    a single command
  */
  if (legal_identifier (name))
    parse_and_execute (temp_string,
    name,
    SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
  ...
}


int parse_and_execute (string, from_file, flags)
  char *string;
  const char *from_file;
int flags;
{
  ...
  while (*(bash_input.location.string))
  {
    ...
    /*
      1) SEVAL_FUNCDEF was OR'ed into line that called this function
      2) command->type == cm_connection != cm_function_def
      Therefore we execute inside the if statement, which produces an error.
      EX_BADUSAGE is eventually returned from this function.
    */
    if ((flags & SEVAL_FUNCDEF) && command->type != cm_function_def)
    {
      internal_warning ("%s: ignoring function definition attempt", from_file);
      should_jump_to_top_level = 0;
      last_result = last_command_exit_value = EX_BADUSAGE;
      break;
    }
    ...
    /*
      If we didn't go into the above if statement, and we only want one
      command, break out of the while loop now...
    */
    if (flags & SEVAL_ONECMD)
      break;
  }
  ...
}

The Exploit:
The exploit code (3) was also very simple. The below Bash script code triggers the vulnerability and prints “VULNERABLE” to the screen on vulnerable versions of Bash.

export testbug='() { :;}; echo VULNERABLE'
bash

The first line defines a new environment variable called testbug. This new environment variable contains just a function definition (no actual call to the function) followed by an additional command. The function definition is just “() { :;};” which is an unnamed Bash function which has the expression ':' inside of it. In Bash, when the ':' character is evaluated as an expression, it just evaluates to true (4). The function definition is followed by another command which in this case, just prints “VULNERABLE” to the screen. The second line executes a new instances of Bash which will consume this environment variable. This explicit execution of bash is analogous to a web server spawning a new instance of bash.

Other Events:
After the original patch was released for the original ShellShock vulnerability, the community started to find new variants of bugs in Bash and has since assigned multiple new CVEs to these bugs. As of the time of this writing, the discoveries are ongoing. Considering how long ago Bash was written, the old coding style, and the amount of string manipulation that is happening in C, it is very likely that new vulnerabilities (especially memory corruptions) will continue to be found.

Workarounds:
A possible way to avoid execution of vulnerable codepaths includes avoiding setting environment variables to untrusted user supplied input. This advice takes into consideration that new and currently unknown attack vectors and variants are likely to be discovered in the upcoming days and weeks.

References

Monday, November 16, 2015

Visual Heap Spray

Prerequisite Reading:
Previous “Low Fragmentation Heap ReAllocation for Use After Free Exploitation” article
Previous “Attacking V-Table Pointers” article
Heap Sprays are a common method attackers use to introduce determinism in a program’s address space. They aim to control a program’s memory layout in such a way that an attacker can reliably predict what will be in memory at a certain address (Address of Interest) at a certain point in execution.

For example, if there is a Use-After-Free bug, on an object with a V-Table, the object can be reallocated and the offset of the V-Table pointer in the object can point to an address that the attacker knows will contain the spray (Address of Interest). This knowledge often comes from trial and error when writing the exploit.

The Address of Interest makes a big difference in the quality of the exploit. For example, a very popular Address of Interest is 0x0c0c0c0c. The reasoning behind this Address of Interest is that the address must be low in the process’s address space (the highest Nibble of this address is 0x0), yet must be at a higher address in memory than the heap being sprayed (the second highest Nibble is 0xc) so that when the heap grows due to the memory pressure of the spray, it will grow into this address. Using high addresses such as 0xc0c0c0c (the highest Nibble is 0xc) would require that the application freezes for a longer period of time before the heap spray is complete. A victim that is being targeted might get bored and close the process (web browser in this case) due to the fact that it has appeared to freeze during the long time taken to spray, thereby precluding any possibility of successful exploitation.
Visualizations:
Below are some memory usage visualizations taken with the vmmap tool from SysInternals before and after the heap spray. The orange color represents the Backend Heap in the process’s address space. Two things to notice are the large growth in the orange segment of the graphs below and the difference in the “Committed” usage before and after the spray (it grows from about 136 MB to about 698 MB).
Before Spray:

Memory Usage before Heap Spray
 After Spray:
Memory Usage after Heap Spray
Below are graphical representations of the memory layout before and after the spray. The “After Spray” visualization has the approximate address of 0x0c0c0c0c marked for the reader’s convenience. One might make the argument that since 0x0c0c0c0c is relatively early in the heap spray, the heap spray could have been reduced to minimize the time the victim has to wait for the spray to finish.

Before Spray:

Memory Layout before Heap Spray

After Spray:
Memory Layout after Heap Spray

How to Heap Spray in Internet Explorer:

In IE, heap sprays are often done by allocating and assigning large strings from JavaScript. Sprays are often done on the Backend Heap (rather than the Low Fragmentation Heap). In order to get strings allocated on the Backend Heap, the strings must be larger than 16KB. Example JavaScript follows:

for (var z = primeAmount; z < numObjects; z++)
    objectArray[z].title = pattern;

The Heap Spraying technique does not come without some drawbacks, leading to some researchers referring to heap sprays as “For the 99%”. In some cases, exploitation can be made more reliable by finding multiple "good" bugs rather than heap spraying:
  • It might take a long time to spray (user might get impatient and terminate the program).
  • Depending on preexisting memory layout due to external factors (loaded plugins, other webpages visited prior to this one, etc), spraying can be unreliable.
  • Too much spraying might cause the Operating System to swap memory pages out to disk (depending on how much physical memory the victim’s machine has) and JavaScript Exceptions.
  • New IE mitigations might prevent highjacking virtual function calls.
  • There is no guarantee that the Address of Interest will contain the spray-an executable image or something else might be mapped at the Address of Interest, depending on the address space and system configuration unique to the victim. 
Libraries:
The community has done some great work to reduce the barrier of entry into this space. Multiple open source libraries have been written by researchers to abstract away the details of heap mechanics. In the example presented in this article, the heap reallocation/spray was done manually, but libraries such as HeapLib by Alex Sotirov and HeapLib2 by Chris Valasek allow users to just call into them in order to perform reallocation/sprays. Code review of HeapLib2 shows that this article, the prerequisite readings and HeapLib2 all use the same technique to reallocate and spray the heap.

Thursday, June 14, 2012

Disable DEP and ASLR on Windows 7 64bit at compile time


In the development of sample exploit code for this blog (for example the Buffer Overflow post), various Windows attack mitigations had to be enabled or disabled. Two very effective and common mitigations on Windows 7 are DEP and ASLR. In an effort to save the reader frustration, time and effort, the compiler and linker options used to disable DEP and ASLR both independently and together are listed below. The DEP and ASLR columns of Mark Russinovich's popular "Process Explorer" tool are used to determine whether a process has DEP or ASLR enabled.

Disable DEP
First, run "%windir%\system32\SystemPropertiesPerformance.exe" from the commandline, and select the "Data Execution Prevention" tab. Select the second option and specify which application to remove DEP protection for.

Opting out of DEP
In this case, ROP.exe was the executable for which DEP was to be disabled. Next, these are the commandline arguments to compile ROP.c without DEP:

cl ROP.c /GS- /Gs-
editbin ROP.exe /NXCOMPAT:NO

Process Explorer shows DEP as disabled for this process:
 

Disable ASLR
Commandline Arguments:

cl ROP.c /DYNAMICBASE:NO /link /FIXED

Now Process Explorer shows ASLR as Disabled for this process:


 
Disable both DEP and ASLR
Commandline Arguments:

cl ROP.c /DYNAMICBASE:NO /GS- /Gs- /link /FIXED
editbin ROP.exe /NXCOMPAT:NO


The ability to selectively disable different mitigation techniques allows us to build smaller and less complex binaries, and makes it easier to perform static analysis and demonstrate security concepts. However, it is highly recommended to enable these mitigation technologies when building production binaries, as these mitigations greatly increase the security of the resulting binaries.