Beyond
This is the beyond page that an additional post enumeration and assessment are conducted as the root
user after compromising the target system.
Web
# systemctl status webapp.service
● webapp.service - WebApp
Loaded: loaded (/etc/systemd/system/webapp.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2024-08-02 17:33:27 EDT; 6 months 5 days ago
Main PID: 385 (su)
Tasks: 0 (limit: 2358)
Memory: 1.2M
CGroup: /system.slice/webapp.service
‣ 385 /usr/bin/su clumsyadmin -c /home/clumsyadmin/webapp/start.sh
Aug 02 17:33:27 xposedapi systemd[1]: Started WebApp.
Aug 02 17:33:27 xposedapi su[385]: (to clumsyadmin) root on none
Aug 02 17:33:27 xposedapi su[385]: pam_unix(su:session): session opened for user clumsyadmin by (uid=0)
Aug 02 17:33:27 xposedapi su[385]: [2024-08-02 17:33:27 -0400] [499] [INFO] Starting gunicorn 20.0.4
Aug 02 17:33:27 xposedapi su[385]: [2024-08-02 17:33:27 -0400] [499] [INFO] Listening at: http://0.0.0.0:13337 (499)
Aug 02 17:33:27 xposedapi su[385]: [2024-08-02 17:33:27 -0400] [499] [INFO] Using worker: sync
Aug 02 17:33:27 xposedapi su[385]: [2024-08-02 17:33:27 -0400] [553] [INFO] Booting worker with pid: 553
Aug 02 17:33:27 xposedapi su[385]: [2024-08-02 17:33:27 -0400] [554] [INFO] Booting worker with pid: 554
Aug 02 17:33:27 xposedapi su[385]: [2024-08-02 17:33:27 -0400] [555] [INFO] Booting worker with pid: 555
Aug 02 17:33:27 xposedapi su[385]: [2024-08-02 17:33:27 -0400] [562] [INFO] Booting worker with pid: 562
/etc/systemd/system/webapp.service
# cat /etc/systemd/system/webapp.service
[Unit]
Description=WebApp
[Service]
ExecStart=su clumsyadmin -c /home/clumsyadmin/webapp/start.sh
[Install]
WantedBy=multi-user.target
/home/clumsyadmin/webapp/start.sh
# pwd
/home/clumsyadmin/webapp
# ll
total 60K
4.0K drwxr-xr-x 6 clumsyadmin clumsyadmin 4.0K Feb 6 14:21 ..
4.0K drwxr-xr-x 2 clumsyadmin clumsyadmin 4.0K Mar 17 2021 templates
4.0K drwxr-xr-x 2 clumsyadmin clumsyadmin 4.0K Feb 9 2021 __pycache__
4.0K drwxr-xr-x 5 clumsyadmin clumsyadmin 4.0K Feb 9 2021 .
4.0K drwxr-xr-x 2 clumsyadmin clumsyadmin 4.0K Feb 9 2021 static
4.0K -rw-r--r-- 1 clumsyadmin clumsyadmin 2.0K Nov 10 2020 main.py
4.0K -rw-r--r-- 1 clumsyadmin clumsyadmin 266 Nov 10 2020 ._main.py
4.0K -rwxr-xr-x 1 clumsyadmin clumsyadmin 210 Nov 2 2020 .___pycache__
4.0K -rwxr-xr-x 1 clumsyadmin clumsyadmin 210 Oct 30 2020 ._start.sh
4.0K -rwxr-xr-x 1 clumsyadmin clumsyadmin 79 Oct 30 2020 start.sh
4.0K -rw-r--r-- 1 clumsyadmin clumsyadmin 210 Oct 30 2020 ._webapp.service
4.0K -rwxr-xr-x 1 clumsyadmin clumsyadmin 210 Oct 30 2020 ._templates
4.0K -rw-r--r-- 1 clumsyadmin clumsyadmin 210 Oct 28 2020 ._requirements.txt
4.0K -rw-r--r-- 1 clumsyadmin clumsyadmin 29 Oct 28 2020 requirements.txt
4.0K -rwxr-xr-x 1 clumsyadmin clumsyadmin 210 Oct 28 2020 ._static
# cat start.sh
#!/bin/bash
cd /home/clumsyadmin/webapp
gunicorn -w 4 -b 0.0.0.0:13337 main:app
# cat main.py
#!/usr/bin/env python3
from flask import Flask, jsonify, request, render_template, Response
from Crypto.Hash import MD5
import json, os, binascii
app = Flask(__name__)
@app.route('/')
def home():
return(render_template("home.html"))
@app.route('/update', methods = ["POST"])
def update():
if request.headers['Content-Type'] != "application/json":
return("Invalid content type.")
else:
data = json.loads(request.data)
if data['user'] != "clumsyadmin":
return("Invalid username.")
else:
os.system("curl {} -o /home/clumsyadmin/app".format(data['url']))
return("Update requested by {}. Restart the software for changes to take effect.".format(data['user']))
@app.route('/logs')
def readlogs():
if request.headers.getlist("X-Forwarded-For"):
ip = request.headers.getlist("X-Forwarded-For")[0]
else:
ip = "1.3.3.7"
if ip == "localhost" or ip == "127.0.0.1":
if request.args.get("file") == None:
return("Error! No file specified. Use file=/path/to/log/file to access log files.", 404)
else:
data = ''
with open(request.args.get("file"), 'r') as f:
data = f.read()
f.close()
return(render_template("logs.html", data=data))
else:
return("WAF: Access Denied for this Host.",403)
@app.route('/version')
def version():
hasher = MD5.new()
appHash = ''
with open("/home/clumsyadmin/app", 'rb') as f:
d = f.read()
hasher.update(d)
appHash = binascii.hexlify(hasher.digest()).decode()
return("1.0.0b{}".format(appHash))
@app.route('/restart', methods = ["GET", "POST"])
def restart():
if request.method == "GET":
return(render_template("restart.html"))
else:
os.system("killall app")
os.system("bash -c '/home/clumsyadmin/app&'")
return("Restart Successful.")