├── README.md └── inspector.py /README.md: -------------------------------------------------------------------------------- 1 | Privilege Escalation unix helper 2 | 3 | ![version](https://img.shields.io/badge/version-1.0b-red.svg) [![twitter](https://img.shields.io/badge/twitter-@graniet75-blue.svg)](https://twitter.com/graniet75) 4 | 5 | #### SUMMARY 6 | Inspector is a python script for help in privilege escalation, for linux environement. After starting, this script search the kernel version and check if is exploit exists, load file history bash,zsh,mysql... and load list of programs loaded with root user 7 | 8 | Download on server 9 | ```sh 10 | wget https://raw.githubusercontent.com/graniet/Inspector/master/inspector.py 11 | ``` 12 | Execute Inspector 13 | ```sh 14 | python inspector.py 15 | ``` 16 | Or download & execute 17 | ```sh 18 | curl https://raw.githubusercontent.com/graniet/Inspector/master/inspector.py | python 19 | ``` 20 | -------------------------------------------------------------------------------- /inspector.py: -------------------------------------------------------------------------------- 1 | #!usr/bin/env python 2 | 3 | 4 | import os,sys 5 | import time 6 | import platform 7 | 8 | class bcolors: 9 | HEADER = '\033[95m' 10 | OKBLUE = '\033[94m' 11 | OKGREEN = '\033[92m' 12 | WARNING = '\033[93m' 13 | FAIL = '\033[91m' 14 | ENDC = '\033[0m' 15 | BOLD = '\033[1m' 16 | UNDERLINE = '\033[4m' 17 | 18 | class inspector(object): 19 | 20 | def __init__(self): 21 | self.kernel_version = "" 22 | self.start_dir = "" 23 | self.environnement = "" 24 | self.distribution = "" 25 | self.kernel_version = "" 26 | self.history_pattern = [ 27 | {"search":"ssh","content":"possible SSH login"}, 28 | {"search":"mysql ","content":"MySQL database connexion found"}, 29 | {"search":"ftp ","content":"Possible FTP login"} 30 | ] 31 | self.history_listing = ['.bash_history','.mysql_history','.bashrc','.zshrc','.zsh_history'] 32 | self.kernel_exploit = [ 33 | {"name":'w00t', "version":['2.4.10','2.4.16','2.4.17','2.4.18','2.4.19','2.4.20','2.4.21']}, 34 | {"name":"brk", "version":['2.4.10','2.4.18','2.4.19','2.4.20','2.4.21','2.4.22']}, 35 | {"name":'pp_key', "version":['3.8.0', '3.8.1', '3.8.2', '3.8.3', '3.8.4', '3.8.5', '3.8.6', '3.8.7', '3.8.8', '3.8.9', '3.9', '3.10', '3.11', '3.12', '3.13', '3.4.0', '3.5.0', '3.6.0', '3.7.0', '3.8.0', '3.8.5', '3.8.6', '3.8.9', '3.9.0', '3.9.6', '3.10.0', '3.10.6', '3.11.0', '3.12.0', '3.13.0', '3.13.1']}, 36 | {"name":'overlayfs', "version":['3.8.0','3.8.1', '3.8.2', '3.8.3', '3.8.4', '3.8.5', '3.8.6', '3.8.7', '3.8.8', '3.8.9', '3.9', '3.10', '3.11', '3.12', '3.13', '3.4.0', '3.5.0', '3.6.0', '3.7.0', '3.8.0', '3.8.5', '3.8.6', '3.8.9', '3.9.0', '3.9.6', '3.10.0', '3.10.6', '3.11.0', '3.12.0', '3.13.0', '3.13.1']}, 37 | {"name":'rawmodePTY', "version":['2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35', '2.6.36', '2.6.37', '2.6.38', '2.6.39', '3.14', '3.15']}, 38 | {"name":'timeoutpwn', "version":['3.4 ', '3.5 ', '3.6 ', '3.7 ', '3.8 ', '3.8.9 ', '3.9 ', '3.10 ', '3.11 ', '3.12 ', '3.13 ', '3.4.0 ', '3.5.0 ', '3.6.0 ', '3.7.0 ', '3.8.0 ', '3.8.5 ', '3.8.6 ', '3.8.9 ', '3.9.0 ', '3.9.6 ', '3.10.0 ', '3.10.6 ', '3.11.0 ', '3.12.0 ', '3.13.0 ', '3.13.1']}, 39 | {"name":'perf_swevent', "version":['3.0.0', '3.0.1', '3.0.2', '3.0.3', '3.0.4', '3.0.5', '3.0.6', '3.1.0', '3.2', '3.3', '3.4.0', '3.4.1', '3.4.2', '3.4.3', '3.4.4', '3.4.5', '3.4.6', '3.4.8', '3.4.9', '3.5', '3.6', '3.7', '3.8.0', '3.8.1', '3.8.2', '3.8.3', '3.8.4', '3.8.5', '3.8.6', '3.8.7', '3.8.8', '3.8.9']}, 40 | {"name":'msr', "version":['2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.27', '2.6.28', '2.6.29', '2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35', '2.6.36', '2.6.37', '2.6.38', '2.6.39', '3.0.0', '3.0.1', '3.0.2', '3.0.3', '3.0.4', '3.0.5', '3.0.6', '3.1.0', '3.2', '3.3', '3.4', '3.5', '3.6', '3.7.0', '3.7.6']}, 41 | {"name":'memodipper', "version":['2.6.39', '3.0.0', '3.0.1', '3.0.2', '3.0.3', '3.0.4', '3.0.5', '3.0.6', '3.1.0']}, 42 | {"name":'american-sign-language', "version":['2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5', '2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11', '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17', '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', '2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35', '2.6.36']}, 43 | {"name":'full-nelson', "version":['2.6.31', '2.6.32', '2.6.35', '2.6.37']}, 44 | {"name":'half_nelson', "version":['2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5', '2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11', '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17', '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', '2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35', '2.6.36']}, 45 | {"name":'rds', "version":['2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35', '2.6.36']}, 46 | {"name":'pktcdvd', "version":['2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5', '2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11', '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17', '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', '2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35', '2.6.36']}, 47 | {"name":'ptrace_kmod2', "version":['2.6.26', '2.6.27', '2.6.28', '2.6.29', '2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34']}, 48 | {"name":'video4linux', "version":['2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5', '2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11', '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17', '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', '2.6.30', '2.6.31', '2.6.32', '2.6.33']}, 49 | {"name":'can_bcm', "version":['2.6.18','2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', '2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35', '2.6.36']}, 50 | {"name":'reiserfs', "version":['2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', '2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34']}, 51 | {"name":'do_pages_move', "version":['2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', '2.6.30', '2.6.31']}, 52 | {"name":'pipe.c_32bit', "version":['2.4.4', '2.4.5', '2.4.6', '2.4.7', '2.4.8', '2.4.9', '2.4.10', '2.4.11', '2.4.12', '2.4.13', '2.4.14', '2.4.15', '2.4.16', '2.4.17', '2.4.18', '2.4.19', '2.4.20', '2.4.21', '2.4.22', '2.4.23', '2.4.24', '2.4.25', '2.4.26', '2.4.27', '2.4.28', '2.4.29', '2.4.30', '2.4.31', '2.4.32', '2.4.33', '2.4.34', '2.4.35', '2.4.36', '2.4.37', '2.6.15', '2.6.16', '2.6.17', '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', '2.6.30', '2.6.31']}, 53 | {"name":'udp_sendmsg_32bit', "version":['2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5', '2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11', '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17', '2.6.18', '2.6.19']}, 54 | {"name":'sock_sendpage', "version":['2.4.4', '2.4.5', '2.4.6', '2.4.7', '2.4.8', '2.4.9', '2.4.10', '2.4.11', '2.4.12', '2.4.13', '2.4.14', '2.4.15', '2.4.16', '2.4.17', '2.4.18', '2.4.19', '2.4.20', '2.4.21', '2.4.22', '2.4.23', '2.4.24', '2.4.25', '2.4.26', '2.4.27', '2.4.28', '2.4.29', '2.4.30', '2.4.31', '2.4.32', '2.4.33', '2.4.34', '2.4.35', '2.4.36', '2.4.37', '2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5', '2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11', '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17', '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', '2.6.30']}, 55 | {"name":'sock_sendpage2', "version":['2.4.4', '2.4.5', '2.4.6', '2.4.7', '2.4.8', '2.4.9', '2.4.10', '2.4.11', '2.4.12', '2.4.13', '2.4.14', '2.4.15', '2.4.16', '2.4.17', '2.4.18', '2.4.19', '2.4.20', '2.4.21', '2.4.22', '2.4.23', '2.4.24', '2.4.25', '2.4.26', '2.4.27', '2.4.28', '2.4.29', '2.4.30', '2.4.31', '2.4.32', '2.4.33', '2.4.34', '2.4.35', '2.4.36', '2.4.37', '2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5', '2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11', '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17', '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', '2.6.30']}, 56 | {"name":'exit_notify', "version":['2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29']}, 57 | {"name":'udev', "version":['2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29']}, 58 | {"name":'ftrex', "version":['2.6.11', '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17', '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22']}, 59 | {"name":'vmsplice2', "version":['2.6.23', '2.6.24']}, 60 | {"name":'vmsplice1', "version":['2.6.17', '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', '2.6.24', '2.6.24.1']}, 61 | {"name":'h00lyshit', "version":['2.6.8', '2.6.10', '2.6.11', '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16']}, 62 | {"name":'raptor_prctl', "version":[ '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17']}, 63 | {"name":'elflbl', "version":['2.4.29']}, 64 | {"name":'caps_to_root', "version":['2.6.34', '2.6.35', '2.6.36']}, 65 | {"name":'mremap_pte', "version":['2.4.20', '2.2.24', '2.4.25', '2.4.26', '2.4.27']}, 66 | {"name":'krad3', "version":['2.6.5', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11']} 67 | ] 68 | self.logo() 69 | self.load_inspection() 70 | 71 | def get_distribution(self): 72 | try: 73 | distribution_name = platform.linux_distribution()[0] 74 | if distribution_name != "": 75 | return distribution_name 76 | else: 77 | print bcolors.FAIL + "* can't get distribution name." + bcolors.ENDC 78 | print bcolors.FAIL + "* inspector work only with linux." + bcolors.ENDC 79 | return False 80 | except: 81 | print bcolors.FAIL + "[FATAL] can't load distribution name." + bcolors.ENDC 82 | sys.exit() 83 | 84 | def logo(self): 85 | os.system('clear') 86 | print """ _____ _ 87 | \_ \_ __ ___ _ __ ___ ___| |_ ___ _ __ 88 | / /\/ '_ \/ __| '_ \ / _ \/ __| __/ _ \| '__| 89 | /\/ /_ | | | \__ \ |_) | __/ (__| || (_) | | 90 | \____/ |_| |_|___/ .__/ \___|\___|\__\___/|_| 91 | |_| Version: """+bcolors.FAIL+"1.0b"+bcolors.ENDC+""" 92 | """ 93 | 94 | def information(self): 95 | uname = os.popen('uname -a').read() 96 | print bcolors.OKBLUE + "* User : " + os.popen('whoami').read().strip() 97 | print "* Group : " + os.popen('id -Gn').read().strip()[:20] 98 | print "* Shell : " + self.environnement + bcolors.ENDC 99 | 100 | def check_exploit(self): 101 | vulnerable_exploit = [] 102 | current = 0 103 | len_exploit = len(self.kernel_exploit) 104 | for line in self.kernel_exploit: 105 | vulnerable = False 106 | current += 1 107 | for version in line['version']: 108 | if version == self.kernel_version: 109 | vulnerable = True 110 | if vulnerable == True: 111 | vulnerable_exploit.append(str(line['name'])) 112 | sys.stdout.write('\r'+ bcolors.OKBLUE + "* checking exploit "+str(line['name'][:4])+"... ("+str(current)+"/"+str(len_exploit)+")" + bcolors.ENDC) 113 | time.sleep(0.3) 114 | sys.stdout.flush() 115 | if len(vulnerable_exploit) > 0: 116 | for line in vulnerable_exploit: 117 | sys.stdout.write('\r'+ bcolors.OKGREEN + "* vulnerable to : " + str(line) + bcolors.ENDC) 118 | else: 119 | sys.stdout.write('\r'+ bcolors.FAIL + "* Can't find vulnerable exploit" + bcolors.ENDC) 120 | print "..." 121 | 122 | def history_file(self): 123 | find = [] 124 | possible = [] 125 | print bcolors.WARNING + "* Checking history file" + bcolors.ENDC 126 | try: 127 | for line in self.history_listing: 128 | if self.start_dir[-1:] != "/": 129 | read_path = self.start_dir + "/" + line.strip() 130 | else: 131 | read_path = self.start_dir + line.strip() 132 | if os.path.exists(read_path): 133 | find.append(read_path) 134 | if len(find) > 0: 135 | for file in find: 136 | count = 0 137 | print bcolors.OKGREEN + "* reading : " + file + bcolors.ENDC 138 | content_file = open(file).read().split('\n') 139 | print bcolors.WARNING + "* total line : " + str(len(content_file)) + bcolors.ENDC 140 | for file_line in content_file: 141 | count += 1 142 | for line_search in self.history_pattern: 143 | if line_search['search'] in file_line: 144 | if line_search['content'] not in possible: 145 | possible.append(line_search['content']) 146 | for line in possible: 147 | print bcolors.OKBLUE + "* "+ line + bcolors.ENDC 148 | 149 | else: 150 | print bcolors.FAIL + "* Can't get history file..." + bcolors.ENDC 151 | except: 152 | print bcolors.FAIL + "* Can't read history file." 153 | 154 | def load_root_program(self): 155 | print bcolors.OKGREEN + "* load program running with root" + bcolors.ENDC 156 | program = os.popen('find / -perm /6000 -exec ls -ldb {} \; > /tmp/suid_root.txt').read() 157 | if os.path.isfile('/tmp/suid_root.txt'): 158 | print bcolors.OKGREEN + "* program loaded by root : /tmp/suid_root.txt " + bcolors.ENDC 159 | try: 160 | user_input = raw_input("$ inspector (read file ?)[y/N] > ") 161 | if user_input == "y" or user_input == "Y": 162 | file_open = open('/tmp/suid_root.txt').read() 163 | explode = file_open.split('\n') 164 | for line in explode: 165 | if line.strip() != "": 166 | print bcolors.OKBLUE + "* " + bcolors.ENDC + str(line) 167 | except EOFError: 168 | return False 169 | else: 170 | print bcolors.FAIL + "* Can't find program root file" + bcolors.ENDC 171 | 172 | def load_inspection(self): 173 | distribution = self.get_distribution() 174 | if distribution == False: 175 | inputs = raw_input("Can't get distrib name continue? [Y/n]: ") 176 | if inputs != "" and inputs != "Y" and inputs != "y": 177 | sys.exit() 178 | self.distribution = distribution 179 | error = False 180 | print "* Get user directory..." 181 | try: 182 | home = os.path.expanduser("~") 183 | self.start_dir = home 184 | print bcolors.OKGREEN + "* success : " + bcolors.BOLD + str(home) + bcolors.ENDC 185 | except: 186 | print bcolors.FAIL + "* Fail : can't get users directory!" + bcolors.ENDC 187 | error = True 188 | print "* Get shell environnement..." 189 | try: 190 | shell_environement = os.environ['SHELL'] 191 | shell_environement = shell_environement.rsplit("/", 1)[1] 192 | self.environnement = shell_environement 193 | print bcolors.OKGREEN + "* success : "+bcolors.BOLD + str(self.environnement) + bcolors.ENDC 194 | except: 195 | print bcolors.FAIL + "* Fail : can't get shell environnement!" + bcolors.ENDC 196 | 197 | print "* Get kernel version..." 198 | try: 199 | kernel_version = os.popen('uname -r').read().strip() 200 | if "-" in kernel_version: 201 | kernel_version = kernel_version.split('-')[0] 202 | self.kernel_version = kernel_version 203 | print bcolors.OKGREEN + "* success : " + bcolors.BOLD + str(self.kernel_version) + bcolors.ENDC 204 | except: 205 | print bcolors.FAIL + "* Fail : can't get kernel!" + bcolors.ENDC 206 | if error == False: 207 | self.information() 208 | print bcolors.WARNING + "* Checking exploit for : " + str(self.kernel_version) + "..." + bcolors.ENDC 209 | time.sleep(1) 210 | self.check_exploit() 211 | self.history_file() 212 | self.load_root_program() 213 | 214 | 215 | 216 | inspector = inspector() 217 | --------------------------------------------------------------------------------