11/01/2024, 11:59PM
AoE (soft deadline) 11/06/2024, 11:59PM
AoE (hard deadline)
CTF-3 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-3 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-3.tar.gz
to your home directory and
extract it; you should get ctf-3/
, which, in turn,
should contain the following files: Makefile
,
exp4.c
, exp5.c
, vcat4.o
,
vcat5
, trnd
, and README
.
Make sure that (1) no one else has access to ctf-3/
(e.g., chmod go-rx ctf-3) and
(2) trnd
can be executed
(e.g., chmod u+x trnd). Type
cd ctf-3 and start hacking!
Yes, it's vcat.
Again :-).
vcat4
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 vcat4
.
Similarly to CTF-1 and CTF-2, you may
run vcat4
by typing make vcat4_run.
This make(1)
directive wraps the execution of
vcat4
with setarch i686 -3, which
emulates a 32-bit x86 environment (i686
)
with a proper 3GB user space
(-3
). Recall that the department machines are
64-bit; hence, do not invoke vcat4
directly, like
./vcat4, because you will end up solving a different
assignment :-). Similarly, if you need to execute
vcat4
under gdb(1)
, type
make vcat4_dbg. To aid the exploitation process, we
provide exp4
(exp4.c
). This binary
dumps in stdout(3)
the contents of a particular
payload (i.e., variable
unsigned char payload[]
in exp4.c
).
By running make vcat4_exp, make(1)
will
effectively execute ./exp4 | ./vcat4, under
setarch i686 -3, thereby allowing you to feed
vcat4
with the exact contents of
unsigned char payload[]
. Lastly, if you wish to
execute ./exp4 | ./vcat4 under gdb(1)
,
and attach the debugger to vcat4
, run
make vcat4_dbg and commence execution as follows:
r < <(./exp4).
vcat4
contains a stack-based buffer overflow, but
it is hardened, against both code injection and code
reuse (i.e.,
ret2libc-style attacks), with executable space protection
and address space layout randomization.
exp4
contains a template payload
(unsigned char payload[]
in exp4.c
)
that smashes the stack of vcat4
and transfers
control to address 0xdeadbeef
.
mgk1
,
mgk2
, rnd1
, and
rnd2
.0x0defaced
(4 bytes) to
mgk1
; and (b) invokes
raise(SIGUSR1)
using the
return-to-plt
(ret2plt) technique. What
should be the value of payload (i.e.,
variable unsigned char payload[]
in exp4.c
) for getting the
flag?rnd1
and rnd2
(4
bytes each); (b) adds them; (c)
stores the result tomgk2
;
and (d) invokes
raise(SIGUSR2)
using the
return-to-plt
(ret2plt) technique. What should
be the value of payload (i.e.,
variable unsigned char payload[]
in exp4.c
) for getting the
flag?vcat4
.
Similarly to vcat4
, vcat5
is a
vulnerable program that reads from
stdin(3)
and writes to stdout(3)
.
Again, you are not given the source code of
vcat5
.
You may run vcat5
by typing
make vcat5_run. Also, if you need to execute
vcat5
under gdb(1)
, type
make vcat5_dbg. To aid the exploitation process, we
provide exp5
(exp5.c
), which: (a)
dumps in stdout(3)
the value of macro
FMT_STR
and the contents of variable
unsigned char payload[]
; and (b) reads from
stdin(3)
a hexadecimal value as a
string literal. By running make vcat5_exp,
make(1)
will effectively execute
./exp5 < fifo | ./vcat5 > fifo, allowing you
to feed vcat5
with the exact contents of
FMT_STR
and unsigned char payload[]
,
and exp5
with the output of vcat5
.
Lastly, if you wish to execute ./exp5 | ./vcat5 under
gdb(1)
, and attach the debugger to
vcat5
, run make vcat5_dbg and commence
execution as follows: r < <(sleep 1; ./exp5).
vcat5
contains both a stack-based buffer
overflow and a format string vulnerability. However, it is
hardened, against both code injection and code reuse,
with executable space protection
and full address space layout randomization;
vcat5
is a position-independent
executable (PIE). exp5
contains: (1) a format
string template (FMT_STR
) for leaking a 4-byte
hexadecimal value from the stack of vcat5
; and (2)
a template payload (unsigned char payload[]
) that
smashes the stack of vcat5
and transfers control to
address 0xdeadbeef
.
vcat5
(e.g., a saved
return address). What should be the value of
the format string template (i.e.,
macro FMT_STR
in
exp5.c
) to achieve that?0x0defaced
(4 bytes) to
mgk1
; and (b) invokes
raise(SIGUSR1)
using the
return-to-plt (ret2plt) technique.
What should be the value of payload
(i.e., variable
unsigned char payload[]
in
exp5.c
) for getting the flag?
(You must modify exp5.c
in order to dynamically compose the required
payload.)rnd1
and rnd2
(4
bytes each); (b) adds them; (c)
stores the result tomgk2
;
and (d) invokes
raise(SIGUSR2)
. What should be the
value of payload (i.e., variable
unsigned char payload[]
in
exp5.c
) for getting the flag?
(You must modify exp5.c
in order to dynamically compose the required
payload.)vcat5
under gdb(1)
,
but without feeding exp5
with the output of vcat5
.
Therefore, the leaked address of
vcat5
will be printed in
stdout(3)
, allowing you to
experiment with different format string
templates until you complete
Warm-up. Once you have
successfully leaked an address belonging to the
.text section of
vcat5
, you can manually feed it to
exp5
, by typing it in
stdin(3)
, which, in turn, will
compute the base address of
vcat5
(see variable
unsigned long baddr
in
exp5.c
) using the macro
BIN_BASE_OFF
that you need to
adjust accordingly. Armed with that
information, you can then dynamically compute
the absolute address of each gadget, or symbol,
in vcat5
, and attempt Flag
3 and Flag 4.vcat5
.
vcat4
by executing
./exp4 > flag#, where # is the
respective flag number (e.g., to dump the
payload for flag 2, run ./exp4 > flag2,
once make vcat4_exp succeeds). Dump the
two functioning payloads in separate files,
named flag1
and flag2
. 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.
For vcat5
, include the modified
exp5.c
twice: (1) as
exp5-flag3.c
for flag 3; and (2) as
exp5-flag4.c
for flag
4—i.e., copy exp5.c
to
exp5-flag3.c
once
make vcat5_exp succeeds for flag 3, and to
exp5-flag4.c
once make vcat5_exp
succeeds for flag 4. If a payload file or an exploit
file is missing, we will assume that your exploit does
not work properly and read your README
file
(see below) for partial credit.
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
– 0x4
) 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-3/
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-3 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.