commit 46076ce1822104fb596cca02e8ac890b8fd437e8
Author: Louis Burda <quent.burda@gmail.com>
Date: Fri, 5 Apr 2024 20:11:32 +0200
Add challenge files
Diffstat:
9 files changed, 220 insertions(+), 0 deletions(-)
diff --git a/chall/description b/chall/description
@@ -0,0 +1 @@
+I was unable to come up with an interesting vulnerability, so instead I just cheated like all the hardware hackers do and used a laser instead. Have fun ;)
diff --git a/chall/flipnote.zip b/chall/flipnote.zip
Binary files differ.
diff --git a/solve/Dockerfile b/solve/Dockerfile
@@ -0,0 +1,57 @@
+FROM ubuntu:jammy-20240227@sha256:77906da86b60585ce12215807090eb327e7386c8fafb5402369e421f44eff17e as builder
+
+ADD --chmod=0755 --checksum=sha256:4c97fd03a3b181996b1473f3a99b69a1efc6ecaf2b4ede061b6bd60a96b9325a \
+ https://raw.githubusercontent.com/reproducible-containers/repro-sources-list.sh/v0.1.0/repro-sources-list.sh \
+ /usr/local/bin/repro-sources-list.sh
+
+RUN \
+ --mount=type=cache,target=/var/cache/apt,sharing=locked \
+ --mount=type=cache,target=/var/lib/apt,sharing=locked \
+ /usr/local/bin/repro-sources-list.sh && \
+ apt-get update && apt-get install -y \
+ musl-dev \
+ musl-tools \
+ make \
+ xz-utils \
+ gcc
+
+WORKDIR /work
+
+ADD --chmod=0666 --checksum=sha256:4300f2fbc3996bc389d3c03a74662bfff3106ac1930942c5bd27580c7ba5053d \
+ https://yx7.cc/code/ynetd/ynetd-0.1.2.tar.xz \
+ /work/ynetd-0.1.2.tar.xz
+
+RUN tar -xJf ynetd-0.1.2.tar.xz && cd ynetd-0.1.2 && CC="musl-gcc" CFLAGS="-static" make
+
+COPY vuln.c .
+RUN gcc -g -pie -fcf-protection -frandom-seed=0 -fno-plt -fstack-protector-all -fstack-clash-protection -O3 -g -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -Wall -Wextra vuln.c -o vuln
+
+RUN echo "7cdf302e663641c132daaae59f82ceaebd8780f37eccc7844e17ddea3c82b664 /work/vuln" | sha256sum --check
+
+FROM ubuntu:jammy-20240227@sha256:77906da86b60585ce12215807090eb327e7386c8fafb5402369e421f44eff17e
+COPY --from=builder /work/ynetd-0.1.2/ynetd /ynetd
+COPY --from=builder /work/vuln /vuln
+
+ADD --chmod=0755 --checksum=sha256:4c97fd03a3b181996b1473f3a99b69a1efc6ecaf2b4ede061b6bd60a96b9325a \
+ https://raw.githubusercontent.com/reproducible-containers/repro-sources-list.sh/v0.1.0/repro-sources-list.sh \
+ /usr/local/bin/repro-sources-list.sh
+
+RUN \
+ --mount=type=cache,target=/var/cache/apt,sharing=locked \
+ --mount=type=cache,target=/var/lib/apt,sharing=locked \
+ /usr/local/bin/repro-sources-list.sh && \
+ apt-get update && \
+ apt-get install -y dropbear rsync openssh-client && \
+ rm /var/cache/ldconfig/aux-cache /var/log/apt/term.log /var/log/apt/history.log /var/log/dpkg.log /var/log/alternatives.log && \
+ rm -rf /etc/dropbear/dropbear_*_host_key
+
+COPY --chmod=600 --chown=root:root dropbear_ecdsa_host_key dropbear_ed25519_host_key dropbear_rsa_host_key /etc/dropbear/
+
+RUN chown root /vuln && chmod 4555 /vuln
+COPY ./flag /flag
+RUN chmod 600 /flag
+RUN useradd -d /home/ctf/ -m -s /bin/bash ctf && passwd -d ctf
+
+WORKDIR /home/ctf
+
+CMD ["dropbear", "-FBREkwp", "1024"]
+\ No newline at end of file
diff --git a/solve/dropbear_ecdsa_host_key b/solve/dropbear_ecdsa_host_key
Binary files differ.
diff --git a/solve/dropbear_ed25519_host_key b/solve/dropbear_ed25519_host_key
Binary files differ.
diff --git a/solve/dropbear_rsa_host_key b/solve/dropbear_rsa_host_key
Binary files differ.
diff --git a/solve/flag b/solve/flag
@@ -0,0 +1 @@
+CSCG{TESTFLAG}
diff --git a/solve/vuln b/solve/vuln
Binary files differ.
diff --git a/solve/vuln.c b/solve/vuln.c
@@ -0,0 +1,159 @@
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#define MAX_NOTES 16
+
+extern char edata;
+extern char data_start;
+
+static inline char *read_line(char **line_buf, size_t *size) {
+ *size = getdelim(line_buf, size, '\n', stdin);
+ if (*size == 0) {
+ puts("Invalid line");
+ exit(EXIT_FAILURE);
+ }
+ return *line_buf;
+}
+
+void add_note(size_t *sizes, char **notes) {
+ printf("Note: ");
+ for (size_t i = 0; i < MAX_NOTES; i++) {
+ if (sizes[i] == 0) {
+ notes[i] = NULL;
+ sizes[i] = getdelim(¬es[i], &sizes[i], '\n', stdin);
+ printf("Added note: %ld\n", i);
+ return;
+ }
+ }
+ puts("Too many notes");
+ exit(EXIT_FAILURE);
+}
+
+void remove_note(char **line_buf, size_t *size, size_t *sizes, char **notes) {
+ printf("Index: ");
+ char *line = read_line(line_buf, size);
+ unsigned long index = strtoul(line, NULL, 0);
+ if (index >= MAX_NOTES) {
+ puts("Invalid index");
+ exit(EXIT_FAILURE);
+ }
+ free(notes[index]);
+ sizes[index] = 0;
+}
+
+void edit_note(char **line_buf, size_t *size, size_t *sizes, char **notes) {
+ printf("Index: ");
+ char *line = read_line(line_buf, size);
+ unsigned long index = strtoul(line, NULL, 0);
+ if (index >= MAX_NOTES || sizes[index] == 0) {
+ puts("Invalid index");
+ exit(EXIT_FAILURE);
+ }
+ printf("Note: ");
+ line = read_line(line_buf, size);
+ if (*size - 2 > sizes[index]) {
+ puts("Invalid size");
+ exit(EXIT_FAILURE);
+ }
+ memcpy(notes[index], line, *size - 1);
+}
+
+void flip_bit(char **line_buf, size_t *size, char **notes, int *flips) {
+ if (*flips == 0) {
+ puts("The laser malfunctions and kills the program!");
+ exit(EXIT_FAILURE);
+ }
+ printf("Index: ");
+ unsigned long index = strtoul(read_line(line_buf, size), NULL, 0);
+ if (index >= MAX_NOTES || notes[index] == NULL) {
+ puts("Invalid index");
+ exit(EXIT_FAILURE);
+ }
+ printf("Offset: ");
+ char offset = (char)strtol(read_line(line_buf, size), NULL, 0);
+ size_t byte = offset / 8;
+ size_t bit = offset & 0b111;
+
+ puts("The laser is positioned and shoots at the selected memory location!");
+ notes[index][byte] ^= 0b1 << bit;
+ *flips = *flips - 1;
+}
+
+void exit_handler() {
+ mprotect(&data_start, (size_t)&edata - (size_t)&data_start,
+ PROT_READ | PROT_WRITE);
+}
+
+int main() {
+
+ char *notes[MAX_NOTES];
+ size_t sizes[MAX_NOTES];
+ char *line_buf = NULL;
+ size_t size = 0;
+
+ int flips = 2;
+
+ char buf[0x80];
+
+ memset(buf, 0, sizeof(buf));
+ memset(notes, 0, sizeof(notes));
+ memset(sizes, 0, sizeof(sizes));
+
+ setvbuf(stdin, buf, _IOFBF, sizeof(buf));
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ mprotect(&data_start, (size_t)&edata - (size_t)&data_start, PROT_READ);
+ on_exit(&exit_handler, NULL);
+
+ if (setuid(0)) {
+ puts("Not running as root :(");
+ }
+
+ puts("╭────────────────────────────────────────────────────╮");
+ puts("│ FlipNote │");
+ puts("│ │");
+ puts("│ Instructions: │");
+ puts("│ - Type 'a' or 'A' to add a note │");
+ puts("│ - Type 'e' or 'E' to edit a note │");
+ puts("│ - Type 'f' or 'F' to use a laser to flip a bit │");
+ puts("│ - Type 'r' or 'R' to remove a note │");
+ puts("│ - Type 'q' or 'Q' to quit the program │");
+ puts("│ │");
+ puts("╰────────────────────────────────────────────────────╯");
+ for (;;) {
+ printf("> ");
+ switch (read_line(&line_buf, &size)[0]) {
+ case 'a':
+ case 'A':
+ add_note(sizes, notes);
+ break;
+ case 'e':
+ case 'E':
+ edit_note(&line_buf, &size, sizes, notes);
+ break;
+ case 'f':
+ case 'F':
+ flip_bit(&line_buf, &size, notes, &flips);
+ break;
+ case 'r':
+ case 'R':
+ remove_note(&line_buf, &size, sizes, notes);
+ break;
+ case 'q':
+ case 'Q':
+ exit(EXIT_SUCCESS);
+ default:
+ printf("Invalid option: ");
+ puts(line_buf);
+ break;
+ }
+ }
+
+ free(line_buf);
+ return 0;
+}
+\ No newline at end of file