mirror of
https://github.com/calebstewart/pwncat.git
synced 2024-11-27 19:04:15 +01:00
Added enumerators for capabilities, kernel exploits, and package managers
This commit is contained in:
parent
8dea0b61e8
commit
da591f9a22
@ -1,32 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
import textwrap
|
|
||||||
|
|
||||||
import pwncat
|
|
||||||
from pwncat.commands.base import CommandDefinition
|
|
||||||
|
|
||||||
|
|
||||||
class Command(CommandDefinition):
|
|
||||||
|
|
||||||
PROG = "service"
|
|
||||||
ARGS = {}
|
|
||||||
|
|
||||||
def run(self, args):
|
|
||||||
with pwncat.victim.open("/tmp/pwncat", "w") as filp:
|
|
||||||
filp.write(
|
|
||||||
textwrap.dedent(
|
|
||||||
"""
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
while [ 1 ]; do
|
|
||||||
echo "Running"
|
|
||||||
sleep 3
|
|
||||||
done
|
|
||||||
|
|
||||||
"""
|
|
||||||
).lstrip()
|
|
||||||
)
|
|
||||||
pwncat.victim.env(["chmod", "777", "/tmp/pwncat"])
|
|
||||||
|
|
||||||
pwncat.victim.create_service(
|
|
||||||
"pwncat", "test pwncat service", "/tmp/pwncat", "root", False
|
|
||||||
).start()
|
|
53
pwncat/enumerate/capabilities.py
Normal file
53
pwncat/enumerate/capabilities.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import dataclasses
|
||||||
|
from typing import Generator, List
|
||||||
|
|
||||||
|
from colorama import Fore
|
||||||
|
|
||||||
|
import pwncat
|
||||||
|
from pwncat.enumerate import FactData
|
||||||
|
|
||||||
|
name = "pwncat.enumerate.capabilities"
|
||||||
|
provides = "file.caps"
|
||||||
|
per_user = True
|
||||||
|
always_run = False
|
||||||
|
|
||||||
|
|
||||||
|
@dataclasses.dataclass
|
||||||
|
class FileCapabilityData(FactData):
|
||||||
|
|
||||||
|
path: str
|
||||||
|
""" The path to the file """
|
||||||
|
caps: List[str]
|
||||||
|
""" List of strings representing the capabilities (e.g. "cap_net_raw+ep") """
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
line = f"{Fore.CYAN}{self.path}{Fore.RESET} -> ["
|
||||||
|
line += ",".join(
|
||||||
|
f"{Fore.BLUE if c != 'ep' else Fore.RED}{c}{Fore.RESET}" for c in self.caps
|
||||||
|
)
|
||||||
|
line += "]"
|
||||||
|
return line
|
||||||
|
|
||||||
|
|
||||||
|
def enumerate() -> Generator[FactData, None, None]:
|
||||||
|
"""
|
||||||
|
Enumerate executables with assigned capabilities
|
||||||
|
|
||||||
|
:return: generator of FileCapability data
|
||||||
|
"""
|
||||||
|
|
||||||
|
if pwncat.victim.which("getcap") is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
with pwncat.victim.subprocess(f"getcap -r / 2>/dev/null", "r") as filp:
|
||||||
|
for line in filp:
|
||||||
|
line = line.strip().decode("utf-8")
|
||||||
|
# I don't know why this would happen, but just in case
|
||||||
|
if " = " not in line:
|
||||||
|
continue
|
||||||
|
|
||||||
|
filename, caps = [x.strip() for x in line.split(" = ")]
|
||||||
|
caps = caps.split(",")
|
||||||
|
|
||||||
|
yield FileCapabilityData(filename, caps)
|
1157
pwncat/enumerate/kernel-exploit.py
Normal file
1157
pwncat/enumerate/kernel-exploit.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,7 @@ from pwncat import util
|
|||||||
import pwncat
|
import pwncat
|
||||||
|
|
||||||
name = "pwncat.enumerate.system"
|
name = "pwncat.enumerate.system"
|
||||||
provides = "system.version.kernel"
|
provides = "system.kernel.version"
|
||||||
per_user = False
|
per_user = False
|
||||||
|
|
||||||
|
|
||||||
|
71
pwncat/enumerate/system/packages.py
Normal file
71
pwncat/enumerate/system/packages.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import dataclasses
|
||||||
|
from typing import Generator, List
|
||||||
|
|
||||||
|
from colorama import Fore
|
||||||
|
|
||||||
|
import pwncat
|
||||||
|
from pwncat.enumerate import FactData
|
||||||
|
|
||||||
|
name = "pwncat.enumerate.capabilities"
|
||||||
|
provides = "system.packages"
|
||||||
|
per_user = True
|
||||||
|
always_run = False
|
||||||
|
|
||||||
|
|
||||||
|
@dataclasses.dataclass
|
||||||
|
class PackageData(FactData):
|
||||||
|
"""
|
||||||
|
Information describing an installed package
|
||||||
|
"""
|
||||||
|
|
||||||
|
name: str
|
||||||
|
version: str
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
line = f"{Fore.CYAN}{self.name}{Fore.RESET}"
|
||||||
|
if self.version is not None:
|
||||||
|
line += f" version {Fore.BLUE}{self.version}{Fore.RESET}"
|
||||||
|
return line
|
||||||
|
|
||||||
|
|
||||||
|
def enumerate() -> Generator[FactData, None, None]:
|
||||||
|
"""
|
||||||
|
Enumerate installed packages agnostic to the underlying package manager
|
||||||
|
|
||||||
|
:return: generator of package data
|
||||||
|
"""
|
||||||
|
|
||||||
|
rpm = pwncat.victim.which("rpm")
|
||||||
|
if rpm is not None:
|
||||||
|
with pwncat.victim.subprocess(f"rpm -qa", "r") as filp:
|
||||||
|
for line in filp:
|
||||||
|
line = line.decode("utf-8").strip()
|
||||||
|
if "-" in line:
|
||||||
|
line = line.split("-")
|
||||||
|
package = "-".join(line[:-1])
|
||||||
|
version = line[-1]
|
||||||
|
else:
|
||||||
|
package = line
|
||||||
|
version = None
|
||||||
|
yield PackageData(package, version)
|
||||||
|
|
||||||
|
dpkg = pwncat.victim.which("dpkg")
|
||||||
|
if dpkg is not None:
|
||||||
|
with pwncat.victim.subprocess(f"dpkg -l", "r") as filp:
|
||||||
|
line = ""
|
||||||
|
try:
|
||||||
|
while not line.startswith("+"):
|
||||||
|
line = next(filp).strip().decode("utf-8")
|
||||||
|
except StopIteration:
|
||||||
|
line = None
|
||||||
|
if line is not None:
|
||||||
|
for line in filp:
|
||||||
|
line = line.strip().decode("utf-8")
|
||||||
|
line = [c for c in line.split(" ") if c != ""]
|
||||||
|
# This shouldn't happen
|
||||||
|
if len(line) < 3:
|
||||||
|
continue
|
||||||
|
package = line[1]
|
||||||
|
version = line[2]
|
||||||
|
yield PackageData(package, version)
|
@ -2,5 +2,8 @@
|
|||||||
This package contains privilege escalation methods based on enumeration facts.
|
This package contains privilege escalation methods based on enumeration facts.
|
||||||
|
|
||||||
This could be passwords that the enumeration module found, or private keys or
|
This could be passwords that the enumeration module found, or private keys or
|
||||||
anything else of use.
|
anything else of use. This is just an organizational module. Nothing special
|
||||||
|
happens here compared to other privesc modules. It just helps me keep the
|
||||||
|
different methods straight.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -480,7 +480,7 @@ class Victim:
|
|||||||
f"pruning {Fore.RED}{name}{Fore.RESET} from busybox"
|
f"pruning {Fore.RED}{name}{Fore.RESET} from busybox"
|
||||||
)
|
)
|
||||||
|
|
||||||
util.success(f"pruned {len(provides)-len(new_provides)} setuid entries")
|
util.success(f"pruned {len(provides) - len(new_provides)} setuid entries")
|
||||||
provides = new_provides
|
provides = new_provides
|
||||||
|
|
||||||
# Let the class know we now have access to busybox
|
# Let the class know we now have access to busybox
|
||||||
|
Loading…
Reference in New Issue
Block a user