mirror of
https://github.com/calebstewart/pwncat.git
synced 2024-11-30 20:34:15 +01:00
Merge branch 'powershell-utilities' of github.com:calebstewart/pwncat into powershell-utilities
This commit is contained in:
commit
9c522b6997
@ -12,6 +12,12 @@ from pwncat.platform import PlatformError
|
|||||||
from pwncat.platform.windows import PowershellError, Windows
|
from pwncat.platform.windows import PowershellError, Windows
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
TODO: We could parse the `type` here and determine if we have access to
|
||||||
|
non-default network shares?
|
||||||
|
https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/getaccessmask-method-in-class-win32-share
|
||||||
|
"""
|
||||||
|
|
||||||
class NetworkShare(Fact):
|
class NetworkShare(Fact):
|
||||||
def __init__(self, source, name: str, caption: str, tag: str, install_date: str, path:str, status:str, share_type:str):
|
def __init__(self, source, name: str, caption: str, tag: str, install_date: str, path:str, status:str, share_type:str):
|
||||||
super().__init__(source=source, types=["network.shares"])
|
super().__init__(source=source, types=["network.shares"])
|
||||||
|
@ -13,7 +13,7 @@ from pwncat.platform.windows import PowershellError, Windows
|
|||||||
|
|
||||||
|
|
||||||
class UACData(Fact):
|
class UACData(Fact):
|
||||||
def __init__(self, source, registry_values=Dict):
|
def __init__(self, source, registry_values:Dict):
|
||||||
super().__init__(source=source, types=["protections.uac"])
|
super().__init__(source=source, types=["protections.uac"])
|
||||||
|
|
||||||
self.registry_values: bool = registry_values
|
self.registry_values: bool = registry_values
|
||||||
|
@ -0,0 +1,69 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
|
import pwncat
|
||||||
|
import rich.markup
|
||||||
|
from pwncat import util
|
||||||
|
from pwncat.db import Fact
|
||||||
|
from pwncat.modules import ModuleFailed
|
||||||
|
from pwncat.modules.enumerate import EnumerateModule, Schedule
|
||||||
|
from pwncat.platform import PlatformError
|
||||||
|
from pwncat.platform.windows import PowershellError, Windows
|
||||||
|
|
||||||
|
|
||||||
|
class AlwaysInstallElevatedData(Fact):
|
||||||
|
def __init__(self, source, enabled:bool, context: str):
|
||||||
|
super().__init__(source=source, types=["system.alwaysinstallelevated"])
|
||||||
|
|
||||||
|
self.enabled: bool = enabled
|
||||||
|
self.context: str = context
|
||||||
|
|
||||||
|
|
||||||
|
def title(self, session):
|
||||||
|
out = "AlwaysInstallElevated is " + "[bold green]enabled[/bold green]" if self.enabled else "[red]disabled[/red]"
|
||||||
|
out += f" for this {self.context}"
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
class Module(EnumerateModule):
|
||||||
|
"""Enumerate the current Windows Defender settings on the target"""
|
||||||
|
|
||||||
|
PROVIDES = ["system.alwaysinstallelevated"]
|
||||||
|
PLATFORM = [Windows]
|
||||||
|
|
||||||
|
def enumerate(self, session):
|
||||||
|
|
||||||
|
|
||||||
|
registry_value = "AlwaysInstallElevated"
|
||||||
|
registry_keys = [
|
||||||
|
"HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Installer\\",
|
||||||
|
"HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Installer\\"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
for registry_key in registry_keys:
|
||||||
|
try:
|
||||||
|
result = session.platform.powershell(
|
||||||
|
f"Get-ItemPropertyValue {registry_key} -Name {registry_value}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not result:
|
||||||
|
raise ModuleFailed(
|
||||||
|
f"failed to retrieve registry value {registry_value}"
|
||||||
|
)
|
||||||
|
|
||||||
|
status = bool(result[0])
|
||||||
|
|
||||||
|
except PowershellError as exc:
|
||||||
|
if "does not exist" in exc.errors[0]["Message"]:
|
||||||
|
status = bool(0) # default
|
||||||
|
else:
|
||||||
|
raise ModuleFailed(
|
||||||
|
f"could not retrieve registry value {registry_value}: {exc}"
|
||||||
|
) from exc
|
||||||
|
|
||||||
|
if registry_key.startswith('HKCU'):
|
||||||
|
yield AlwaysInstallElevatedData(self.name, status, "current user")
|
||||||
|
else:
|
||||||
|
yield AlwaysInstallElevatedData(self.name, status, "local machine")
|
54
pwncat/modules/windows/enumerate/system/environment.py
Normal file
54
pwncat/modules/windows/enumerate/system/environment.py
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
|
import pwncat
|
||||||
|
import rich.markup
|
||||||
|
from pwncat import util
|
||||||
|
from pwncat.db import Fact
|
||||||
|
from pwncat.modules import ModuleFailed
|
||||||
|
from pwncat.modules.enumerate import EnumerateModule, Schedule
|
||||||
|
from pwncat.platform import PlatformError
|
||||||
|
from pwncat.platform.windows import PowershellError, Windows
|
||||||
|
|
||||||
|
|
||||||
|
class EnvironmentData(Fact):
|
||||||
|
def __init__(self, source, variable:str, value:str):
|
||||||
|
super().__init__(source=source, types=["system.environment"])
|
||||||
|
|
||||||
|
self.variable: bool = variable
|
||||||
|
self.value: str = value
|
||||||
|
|
||||||
|
|
||||||
|
def title(self, session):
|
||||||
|
return f"[cyan]{rich.markup.escape(self.variable)}[/cyan] = [blue]{rich.markup.escape(self.value)} [/blue]"
|
||||||
|
|
||||||
|
|
||||||
|
class Module(EnumerateModule):
|
||||||
|
"""Enumerate the current Windows Defender settings on the target"""
|
||||||
|
|
||||||
|
PROVIDES = ["system.environment"]
|
||||||
|
PLATFORM = [Windows]
|
||||||
|
|
||||||
|
def enumerate(self, session):
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = session.platform.powershell(
|
||||||
|
f"Get-ChildItem env:\\ | Select Name,Value"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not result:
|
||||||
|
raise ModuleFailed(
|
||||||
|
f"failed to retrieve env: PSDrive"
|
||||||
|
)
|
||||||
|
|
||||||
|
environment = result[0]
|
||||||
|
|
||||||
|
except PowershellError as exc:
|
||||||
|
raise ModuleFailed(
|
||||||
|
f"failed to retrieve env: PSDrive"
|
||||||
|
) from exc
|
||||||
|
|
||||||
|
for pair in environment:
|
||||||
|
yield EnvironmentData(self.name, pair["Name"], pair["Value"])
|
@ -38,8 +38,8 @@ class ProcessData(Fact):
|
|||||||
out = f"[cyan]{rich.markup.escape(self.process_name)}[/cyan] (PID [blue]{self.pid}[/blue]) status [yellow]{rich.markup.escape(self.status)}[/yellow] as user [magenta]{self.user_name}[/magenta]"
|
out = f"[cyan]{rich.markup.escape(self.process_name)}[/cyan] (PID [blue]{self.pid}[/blue]) status [yellow]{rich.markup.escape(self.status)}[/yellow] as user [magenta]{self.user_name}[/magenta]"
|
||||||
if "NT AUTHORITY\\SYSTEM" in self.user_name:
|
if "NT AUTHORITY\\SYSTEM" in self.user_name:
|
||||||
out = out.replace("[magenta]", "[red]").replace("[/magenta]", "[/red]")
|
out = out.replace("[magenta]", "[red]").replace("[/magenta]", "[/red]")
|
||||||
if self.status == "Unknown":
|
if self.status == "Running":
|
||||||
out = f"[dim]{out}[/dim]"
|
out = out.replace("[yellow]", "[green]").replace("[/yellow]", "[/green]")
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user