Professional Documents
Culture Documents
CS161 Proj1 Writeup PDF
CS161 Proj1 Writeup PDF
Main Idea:
The exploit in this problem takes advantage of the fact that the fread() function takes in an unsigned
int as the size parameter whereas the size check in the code checks a signed int. Therefore we were able to
successfully pass the size check while writing more than 128 bytes to msg, resulting in a standard buffer
overflow exploit.
Magic Numbers:
First we determined the Address of msg to be 0xbffff5a8, and the address of rip 0xbffff63c.
Therefore the number of bytes from the start of the buffer to the start of the rip was 0xbffff63c -
0xbffff5a8 = 148 bytes. Next we overwrite rip with 0xbffff63c + 4 = 0xbffff640
because we want to replace it with the address of the shellcode which we placed 4 bytes above the
original value of the rip. We made the first byte of the file 0xff which specifies the size of the file. This
value just has to be greater than 152 + sizeOf(SHELLCODE).
Exploit Structure:
print('\xff' + 148*'A'+ '\x40\xf6\xff\xbf' + SHELLCODE)
1. \xff
- Specifies size of file.
2. 148 * 'A'
- Fill up message with garbage to put us right in front of the rip.
3. '\x40\xf6\xff\xbf'
- Address we overwrite rip with, 4 bytes above original address, points to
shellcode.
GDB Output:
(gdb) x/16x msg + 140
0xbffff634: 0xb7ffcf88 0xbffff658 0x00401397 0xbffff7f4
0xbffff644: 0x00000000 0x00000000 0x00401373 0x00000000
0xbffff654: 0xbffff670 0xbffff6f0 0xb7f82ef2 0xbffff6e4
0xbffff664: 0x00000002 0x00000000 0xb7f82ef2 0x00000002
Here we have the gdb output before and after the exploit for the address of msg + 140 (I do this for
convenience so we don’t have to display 140 bytes of garbage here). Now, since we have outputted msg
+ 140, notice that there are still 8 bytes of garbage (blue) since we did 148 * ‘A’, and then we have our
modified rip (red), and the shellcode (green).
This study source was downloaded by 100000787455739 from CourseHero.com on 09-19-2023 06:21:09 GMT -05:00
https://www.coursehero.com/file/130350869/CS161-Proj1-Writeuppdf/
Question 3: Polaris
Main Idea:
In order to exploit the vulnerability of the Polaris satellite, we were required to first leak the stack canary.
Once we knew the exact value of the canary, we were able to treat the exploit like a standard buffer
overflow problem, with the only difference of resetting the original value of the canary.
Magic Numbers:
In order to leak the stack canary we took advantage of the way in which the for loop increments i in
dehexify. When the conditional, (c.buffer[i]=='\\' && c.buffer[i+1]=='x'),
evaluates to True, the program effectively skips over the proceeding two characters in buf and increments
i by 4. This allows us to ignore the Null Terminator and access the canary’s value. Therefore, we can fill
buf with 12 bytes of garbage followed by “\\x” so the program skips to the canary and writes it into
answer.
In order to overwrite the original value of the canary, we had to pad buf with a null termination
character plus 15 bytes of garbage (buffer is 16 bytes long) followed by the canary’s original value.
Using gbd we found the address of the rip to be \xbffff674 and the address of the canary to be \
xbffff668. Therefore we needed to pad buf with (bffff674 - bffff668) + 4 = 8 bytes of compiler
padding after replacing the canary. We then place the SHELLCODE directly after the rip so that the
instruction pointer points to our malicious code after the function returns.
Exploit Structure:
1. p.send('AAAAAAAAAAAA\\x\n')
- Exploits for loop structure to write canary value to answer
2. can = p.recv(17)[13:17]
- Stores canary value in can
3. rip = '\x74\xf6\xff\xbf'
- Address of rip
4. p.send('\x00' + 'A' * 15 + can + 'B' * 8 + rip + SHELLCODE + '\n')
- Fill 16 bytes of buf, replace original canary value, 8 bytes of garbage to get to rip,
address of rip, SHELLCODE
GDB Output:
Buf before our exploit:
This study source was downloaded by 100000787455739 from CourseHero.com on 09-19-2023 06:21:09 GMT -05:00
https://www.coursehero.com/file/130350869/CS161-Proj1-Writeuppdf/
Buf after our exploit:
We have the null terminator and 15 bytes of garbage in blue. Then we have the canary in orange. Then
we have 8 more bytes of garbage in blue. Then we have the address of rip in red. Then finally the
remaining is the shellcode in green.
Question 4: Vega
Main Idea:
For this exploit we took advantage of an off-by-one vulnerability found in the flip function of flipper.c.
This vulnerability exists because the for loop indexes into the 64th bit of buf when it should have broken
after the 63rd. This extra iteration allows us to index into the least significant byte of the sfp because it is
placed directly above buf in the stack. By changing the last byte of the sfp we can relocate its value to
point to a known location in buf where we will put the shellcode address, which lives in an environment
variable at the top of stack. When the current function returns, the sfp is now pointing right under the
address of the shellcode. After the next function returns, the rip will point at the address of the shellcode
which gets moved into the eip register, allowing us to run our malicious shellcode.
It is important to note that anytime we add things to the buf we need to XOR the values with
\x20 since in flipper, every time something is added to buf it is XOR’d with \x20.
Magic Numbers:
We first found the address of the shell code in the environment variable using the command “x/2wx
*((char **)environ+2)” in gdb. Then we found the address of buf which was \xbffff490. With this
information we were able to overwrite the last byte of the sfp with \x90 which moved the pointer to the
beginning of buf. We filled buf first with 4 bytes of padding followed by the address of the shellcode
(which we determined to be \xbffffe71) so that the rip points to the shellcode address when the eip is
popped. Note that as we inputted the shellcode address, we had to XOR each byte with \x20 since as the
flipper function inputs bytes into buffer, it XOR’s those bytes with \x20. After the shellcode address,
we filled the rest of buf with 56 bytes of garbage followed by our overwrite value (\x90).
Exploit Structure:
1. shellAddr = '\x51\xde\xdf\x9f'
- Address of XOR’d shellcode in environment variable
2. overWriteVal = '\xb0'
This study source was downloaded by 100000787455739 from CourseHero.com on 09-19-2023 06:21:09 GMT -05:00
https://www.coursehero.com/file/130350869/CS161-Proj1-Writeuppdf/
-The XOR’d value that we used to overwrite the lsb of the sfp to point to the
beginning of buf
3. print('A'*4 + shellAddr + 'B'*56 + overWriteVal)
- Fill buf with 4 bytes of garbage so rip will point to shellAddr, then 56 bytes of
garbage followed by overWriteVal to overwrite lsb of sfp
GDB Output:
Buf before exploitf:
The red shows how the last byte of the sfp is changed after running the exploit. The green shows
how we added the shellcode address four bytes above the start of buf.
Question 5: Deneb
Main Idea:
For this exploit, we took advantage of the fact that the program checks the size of the file before it’s read.
Therefore, we were able to add more bytes to the file after the size check but before it’s read, so that
more bytes are read into buf than the program had anticipated. This reduces the problem to a standard
buffer overflow exploit.
Since the shellcode is smaller than the size of buf, we were able to put the shellcode at the bottom of buf
(by writing the shellcode to the file at the start before the size check), and then running our standard
buffer overflow exploit to modify the rip such that it points to the address of buf (which is the start of our
shellcode).
Magic Numbers:
We started by finding the address of buf = 0xbffff5e8:
This study source was downloaded by 100000787455739 from CourseHero.com on 09-19-2023 06:21:09 GMT -05:00
https://www.coursehero.com/file/130350869/CS161-Proj1-Writeuppdf/
Next, we found the address of th eip = 0xbffff67c:
We see that, 0xbffff67c - 0xbffff5e8 = 0x98 = 148 bytes between the bottom of buf and the eip
(including compiler padding).
We found that the shellcode was 84 bytes long and since we placed the shellcode at the bottom of buf,
we needed to add 148 - 84 = 64 bytes of garbage in order to modify the rip. After adding the garbage,
we modify the rip to be equal to the address of the buf = 0xbffff5e8, since that is where the shellcode is.
The number of bytes to read is equal to the total number of bytes we have added to the file which is
84 (shellcode) + 64 (garbage) + 4 (modified rip) = 152 bytes.
Exploit Structure:
f = open("hack", "w")
f.write(SHELLCODE)
f.close()
p.start()
assert p.recv(30) == 'How many bytes should I read? '
f = open("hack", "a")
f.write("A" * 64 + '\xe8\xf5\xff\xbf')
f.close()
p.send("152\n")
1. We open the file and write in the shellcode such that it fills 84 bytes of buf and passes the size
check
2. After completing the size check we open the file again and append 64 bytes of garbage (see
magic numbers)
3. In addition to appending garbage, we also modify the rip to point to the address of buf (where
our shellcode is stored)
This study source was downloaded by 100000787455739 from CourseHero.com on 09-19-2023 06:21:09 GMT -05:00
https://www.coursehero.com/file/130350869/CS161-Proj1-Writeuppdf/
4. Finally, we use p.send to specify the number of bytes (152) we have added to the file.
GDB Output:
Using two terminals, we were able to retrieve the gdb output for before and after our exploit was run.
Here we have 84 bytes of the shellcode (green) at the start of buf, then we have our 64 bytes of garbage
(blue), and the modified rip (red).
Question 6: Rigel
Main Idea:
The goal of this part of the project was to execute a ret2esp attack in order to bypass the ASLR and then
use a buffer overflow attack to change the rip accordingly and add our shellcode.
In order to bypass the ASLR, we had to first find the jmp *esp instruction; we see that this instruction is
hardcoded in its decimal form within the magic function of the orbit.c file. After finding the address of
the instruction using GDB, we were able to change the rip of the function to point to the jmp *esp
instruction using a standard buffer overflow attack. We know that because of the jmp *esp instruction,
the instruction pointer will point to the stack pointer. Thus,
This study source was downloaded by 100000787455739 from CourseHero.com on 09-19-2023 06:21:09 GMT -05:00
https://www.coursehero.com/file/130350869/CS161-Proj1-Writeuppdf/
we added our shellcode above the modified rip and therefore, the stack pointer will point to the start of
the shellcode once our exploit is run.
Magic Numbers:
Using GDB and looking for the orl instruction (since the line in the magic function is i ^= 58623), we
found the address of the jmp *esp instruction:
Therefore we know we will need to modify the rip of the function to be 0x08049217. We
In order to calculate how much garbage we needed in order to overflow the buffer, we calculated the
difference between the eip and buf: 0xbf86f3fc - 0xbf863e8 = 20 bytes.
Exploit Structure:
print('A' * 20 + '\x17\x92\x04\x08' + SHELLCODE)
1. Write 20 bytes of garbage in order to overflow the buffer (see the magic numbers for how we
arrived at 20 bytes)
2. Modify the rip to be equal to the address of the jmp *esp instruction, being sure to add it
following little endian convention
3. Add the shellcode (such that it is above the rip)
This study source was downloaded by 100000787455739 from CourseHero.com on 09-19-2023 06:21:09 GMT -05:00
https://www.coursehero.com/file/130350869/CS161-Proj1-Writeuppdf/
GDB Output:
Before the exploit:
After 20 bytes of garbage (blue), the rip is overwritten with 0x08049217 (red), which points to the
shellcode directly after the rip (green).
This study source was downloaded by 100000787455739 from CourseHero.com on 09-19-2023 06:21:09 GMT -05:00
https://www.coursehero.com/file/130350869/CS161-Proj1-Writeuppdf/