CTF-3

Preliminaries

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!

vcat4

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.

  1. Warm-up
    • Find the addresses of the following symbols (variables): mgk1, mgk2, rnd1, and rnd2.
  1. Flag 1 (20 points)
    • Replace the provided payload with a ROP payload that: (a) stores the value 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?
  2. Flag 2 (30 points)
    • Replace the provided payload with a ROP payload that: (a) reads the values of 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?

vcat5

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.

  1. Warm-up
    • Replace the provided format string template with one that leaks an address belonging to the .text section of 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?
  1. Flag 3 (20 points)
    • Replace the provided payload with a (dynamically composed) JIT-ROP payload that: (a) stores the value 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.)
  2. Flag 4 (30 points)
    • Replace the provided payload with a (dynamically composed) JIT-ROP payload that: (a) reads the values of 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.)
  • Hints
    • make vcat5_dbg executes 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.
    • SIGUSR1 = 0x0a, SIGUSR2 = 0x0c.
  • Resources
    • Use ROPgadget to search for gadgets in vcat5.

Handin Instructions

  1. Save the payload(s) of your functioning exploit(s) for 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.
  2. Your write-up template is 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 (0x10x4) 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.
  3. Run /course/cs1650/bin/cs1650_handin 0x3 from within 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.

Collaboration Policy

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.