I just started looking into how buffer overflow attacks work, and tried simulating an attack on Windows 7 using Visual C 2010. The buffer overflow attack is very contrived, it just overwrites the return address to the address of the "buffer" local variable. The buffer holds the string of shellcode.
Whether I run the program in Visual Studio 2010 Debug or not, the program will jump to the shellcode and almost begins execution of it, but I get an Access Violation error, and the program will not continue executing the shellcode.
Why am I getting this error? Is this some sort of protection against buffer overflows in Windows?
How would you get the program to execute the shellcode in the buffer?
edit:
Hans (answer) is correct. This is discussed within the Security chapter of Windows Internals 5th, and the cause of the error is Microsoft's implementation of Executable Space Protection.
If this question helped anyone, any up-votes would be appreciated.
void execute_my_shellcode()
{
char buffer[24];
memcpy(buffer, "\x6A\x21\xFF\x15\x40\x62\x40\x00\x83\xC4\x04\x6A\x0A\xFF\x15\x40\x62\x40\x00\x83\xC4\x04\xC3", 24);
printf("current return address: %p\n", *(int*)((char*)&buffer + 24 + 4));
*(int*)((char*)&buffer + 24 + 4) = (int)&buffer;
printf("return address is now : %p\n\n", (int*)*(int*)((char*)&buffer + 24 + 4) );
}
First of all, your shellcode has nulls in it. Go back through your shellcode and find instructions that don't produce null opcodes (0x00) so that your shellcode doesn't get treated as a string.
Second, an access violation doesn't necessarily mean it's the cause of some type of protection scheme. It may be (out of whim) that your return address or shellcode is trying to make the the EIP register jump to a place that can't be executed in memory.
You will have to expirement more. Each compiler and computer is going to be different. There are ways around just about everything. You may want to research more on the topic in general but the first thing I would suggest is creating a repeating return address that points to a NOP sled in the buffer before the shellcode so that your shellcode get's executed more efficiently and is likely to be more accurate.
The Executable Space Protection is correct, as you stated, but my answers above are both informal and necessary in most cases. Happy hacking :)
Where exactly is the program breaking? Have you tried using OllyDbg to step through the assembly instructions to see if you are at least starting execution of the buffer or failing before then? If you're not executing even the first instruction in the buffer, then likely the stack page (or data section in this case since you supply it as a string literal) has been marked non-executable and you'll have to use another technique. There might be a way to tell Windows to make the stack page executable (or data section in this case) for testing/learning purposes (I know ELF binaries have an executable stack flag and Linux provides the
execstack
utility to edit the flag).If it's breaking after several instructions from your buffer, then it's likely because the instructions in your buffer are trying to (indirectly) call an absolute address (
0xff 0x15 0x40 0x62 0x40 x00
=>call dword ptr ds:[406240]
) and in W7, address space layout randomization (ASLR) may be enabled (I'm not sure if the VS2010 linker sets the IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE bit in the PE header by default).Edit
Based on the additional info you've added to the question, it would appear that the issue of a non-executable stack, mentioned in my first paragraph is the culprit. However, even if you get around that the second issue may still be an issue as you have no clue what will be at 0x00406240 if ASLR is enabled.
There are other protections in place against Buffer Overflow attacks that might make this impossible, such as Guard Pages at each begin and end of the stack frame. There is the Address Space Layout Randomization and others. Here is an article on this.
The fact is also that your shellcode could be containing nullbytes or other types of invalid char's which when converted don't turn into an instruction or valid address... That is for you to figure out.
note I am not giving this latter advice to be abused. You are responsible for legally and correctly using this advice.
This might have worked 10 years ago. These obvious security holes have been patched, the no-execute bit that processors support nowadays are one of the counter-measure.