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.")