10/18/2024, 11:59PM
AoE (soft deadline) 10/23/2024, 11:59PM
AoE (hard deadline)
CTF-2 is specifically designed
to run on the department machines. You are expected to do
all the development on that particular environment,
which is also what we will be using for grading. Do not run
CTF-2 on your personal desktop, laptop, VM, or any
other non-standard setting—you are free to do so, if you
insist or know what you are doing, but we are not going to
provide support in such cases. If you are connecting remotely,
use ssh(1)
and follow the instructions
provided by tstaff.
Copy ctf-2.tar.gz
to your home directory and
extract it; you should get ctf-2/
, which, in turn,
should contain the following files: Makefile
,
exp2.c
, exp3.c
, vcat2.o
,
vcat3.o
, hlp.o
, trnd
,
magic.so
, magic.txt
, and
README
. Make sure that
(1) no one else has access to ctf-2/
(e.g., chmod go-rx ctf-2) and
(2) trnd
can be executed
(e.g., chmod u+x trnd). Type
cd ctf-2 and start hacking!
vcat is back!
vcat2
is a vulnerable program that reads
from stdin(3)
(standard input) and writes to
stdout(3)
(standard output)—it is roughly
equivalent to executing cat -. As always, you are
not given the source code of vcat2
.
Similarly to CTF-1, you may run
vcat2
by typing make vcat2_run. This
make(1)
directive wraps the execution of
vcat2
with
setarch i686 -3 -R, which emulates a 32-bit x86
environment (i686
), with a proper 3GB user space
(-3
) and without support for address space layout randomization
(-R
). Recall that the department machines are
64-bit; hence, do not invoke vcat2
directly, like
./vcat2, because you will end up solving a different
assignment :-). Similarly, if you need to execute
vcat2
under gdb(1)
, type
make vcat2_dbg. More importantly, to aid the
exploitation process, we provide exp2
(exp2.c
). This binary dumps in
stdout(3)
the contents of a particular payload
(i.e., variable unsigned char payload[]
in exp2.c
). By running make vcat2_exp,
make(1)
will effectively execute
./exp2 | ./vcat2, under
setarch i686 -3 -R, thereby allowing you to feed
vcat2
with the exact contents of
unsigned char payload[]
. Lastly, if you wish to
execute ./exp2 | ./vcat2 under gdb(1)
,
and attach the debugger to vcat2
, run
make vcat2_dbg and commence execution as follows:
r < <(./exp2).
vcat2
contains a stack-based buffer overflow, and
exp2
already exploits this vulnerability
using the
jmp *%esp technique. In particular,
exp2
smashes the stack of vcat2
,
overwrites a (saved) return address with the address of a
jmp *%esp
gadget (located in the
.text
section of vcat2
), and
effectively transfers the control right above the overwritten
return address on the stack. The payload variable
(unsigned char payload[]
in exp2.c
)
contains a template that transfers control to a
“dummy” shellcode that consists of a single
trap instruction (int 3
), thereby
raising a SIGTRAP signal and terminating the
execution of vcat2
.
int 3
(0xcc
) with a proper,
NULL-free shellcode for invoking the
following (chain of) system calls:
kill(getpid(), SIGUSR1)
. More
specifically, first invoke
getpid()
, to get the process
identifier (pid) of
vcat2
, and then proceed to call
kill()
, with pid and
SIGUSR1 as first and
second argument, respectively. What
should be the value of payload (i.e.,
variable unsigned char payload[]
in exp2.c
) for getting the
flag?int 3
(0xcc
) with a proper,
NULL-free shellcode for invoking the
following (chains of) system calls: write(open("magic.txt", O_WRONLY, 0), "xyzzy", 5); kill(getpid(), SIGUSR2)
.
Start by invoking open()
, for
opening the file magic.txt, in
write-only mode, and getting the respective
file descriptor (fd). Next,
proceed to call write()
, using
the fd you got from the previous
call to open()
, for writing the
word “xyzzy” in
magic.txt. Lastly, repeat the
chain of system calls for flag 1
(kill(getpid(), SIGUSR2)
), but
this time invoke kill()
with
SIGUSR2. What should be the value
of payload (i.e., variable
unsigned char payload[]
in
exp2.c
) for getting the flag?%eax
.
Similarly to vcat2
, vcat3
is a
vulnerable program that reads from
stdin(3)
and writes to stdout(3)
.
Again, you are not given the source code of
vcat3
.
You may run vcat3
by typing
make vcat3_run. Also, if you need to execute
vcat3
under gdb(1)
, type
make vcat3_dbg. To aid the exploitation process, we
provide exp3
(exp3.c
), which dumps
in stdout(3)
the contents of a particular payload
(i.e., variable unsigned char payload[]
in exp3.c
). By running make vcat3_exp,
make(1)
will effectively execute
./exp3 | ./vcat3, allowing you to feed
vcat3
with the exact contents of
unsigned char payload[]
. Lastly, if you wish to
execute ./exp3 | ./vcat3 under gdb(1)
,
and attach the debugger to vcat3
, run
make vcat3_dbg and commence execution as follows:
r < <(./exp3).
vcat3
contains a stack-based buffer overflow, but
it is hardened against code injection with executable space protection.
exp3
contains a template payload
(unsigned char payload[]
in exp3.c
)
that smashes the stack of vcat3
and transfers
control to address 0xdeadbeef
.
raise(SIGUSR1)
, using the
return-to-libc (ret2libc) technique.
What should be the value of payload
(i.e., variable
unsigned char payload[]
in
exp3.c
) for getting the flag?system("echo -n xyzzy! > magic.txt");
raise(SIGUSR2)
; for this flag you have
to leverage the ret2libc chaining
technique. What should be the value of
payload (i.e., variable
unsigned char payload[]
in
exp3.c
) for getting the flag?open("magic.txt", O_WRONLY, 0);
write(3, "!xyzzy", 6);
raise(SIGUSR2)
; for this flag you have
to leverage both the ret2libc
chaining and %esp lifting
techniques. What should be the value of
payload (i.e., variable
unsigned char payload[]
in
exp3.c
) for getting the flag?flag1
, flag2
, etc.
You can double-check that you have correctly dumped a
functioning payload (e.g., you have not
accidentally corrupted it, or overwritten it, with
something else) by running
make vcat#_run < flag#
(or cat flag# | make vcat#_run), where
# is the respective flag number. If a
payload file is missing, we will assume that your
exploit does not work properly and read your
README
file (see below) for partial credit.
You do not need to submit separate payloads for
the extra credit; if the respective payload is
alphanumeric you will get the extra points automatically.
README
.
First, edit section
0x0
(whoami), and fill
‘Name’,
‘Login’, and
‘Hostname’, with your (full)
name, CS login, and hostname(1)
of the
machine that you tested all your exploits.
Next, fill every other section
(0x1
– 0x5
) with the
corresponding answer(s) if you cannot capture
a flag: you can still get partial credit by
providing a brief description of your attack plan
(e.g., what exactly you plan on corrupting,
with what values, and why; or what you plan on
injecting, where, and why), the actions you took for
implementing it (i.e., partial or incomplete
payload values, memory dumps, and gdb(1)
excerpts), as well as your findings.ctf-2/
to submit
your hand-in—you may want to
alias
that command for multiple submissions (or future
hand-ins). You can resubmit as many times as you
like, prior to the deadline, but note that your old
submission(s) will be overwritten by the
latest one.You should not discuss CTF-2 with anyone except the CSCI 1650 course staff. You may consult “outside sources of information”, but you must cite them; and you may rely on such sources only for concepts, not for solutions to problems—the hand-in must be entirely your own work.