1
0
mirror of https://github.com/calebstewart/pwncat.git synced 2024-11-24 01:25:37 +01:00

Added domain site and group enumerations

This commit is contained in:
Caleb Stewart 2021-06-05 01:32:05 -04:00
parent 063eecbbf8
commit 5f0e4bb1c0
4 changed files with 142 additions and 1 deletions

View File

@ -119,7 +119,7 @@ class Group(Fact):
self.members: PersistentList = PersistentList(members)
def __repr__(self):
return f"""Group(gid={self.id}, name={repr(self.name)}, members={repr(self.members)})"""
return f"""Group(gid={repr(self.id)}, name={repr(self.name)}, members={repr(self.members)})"""
class User(Fact):

View File

@ -115,8 +115,10 @@ class WindowsGroup(Group):
description: str,
principal_source: str,
members: List[str],
domain: Optional[str] = None,
):
super().__init__(source=source, name=name, gid=gid, members=members)
self.group_description: str = description
self.principal_source: str = principal_source
self.domain: Optional[str] = domain

View File

@ -0,0 +1,89 @@
#!/usr/bin/env python3
from typing import Any, Dict, List, Optional
from collections import namedtuple
from pwncat.db import Fact
from pwncat.modules import Status, ModuleFailed
from pwncat.facts.windows import WindowsGroup
from pwncat.platform.windows import Windows, PowershellError
from pwncat.modules.enumerate import Schedule, EnumerateModule
class DomainGroup(WindowsGroup):
""" Builds on Windows Groups to add domain specific information """
def __init__(self, source: str, domain: str, data: Dict, members: List[str]):
super().__init__(
source=source,
name=data["samaccountname"],
gid=data["objectsid"],
description=data.get("description"),
principal_source=None,
domain=domain,
members=members,
)
self.types.append("domain.group")
self.grouptype: int = data.get("grouptype") or 0
self.samaccounttype: int = data.get("samaccounttype") or 0
self.objectclass: List[str] = data.get("objectclass") or []
self.cn: str = data.get("cn") or None
self.distinguishedname: Optional[str] = data.get("distinguishedname") or None
self.objectcategory: str = data.get("objectcategory")
def __repr__(self):
return f"""DomainGroup(gid={repr(self.id)}, name={repr(self.name)}, domain={repr(self.domain)}, members={repr(self.members)})"""
class Module(EnumerateModule):
""" Retrieve information on all domain computers """
PLATFORM = [Windows]
PROVIDES = ["domain.group", "group"]
SCHEDULE = Schedule.ONCE
def enumerate(self, session: "pwncat.manager.Session"):
""" Perform enumeration """
# Ensure we have PowerView loaded
yield Status("loading powersploit recon")
session.run("powersploit", group="recon")
try:
domain = session.run("enumerate.domain")[0]
except IndexError:
# Not a domain joined machine
return
try:
yield Status("requesting domain groups")
groups = session.platform.powershell("Get-DomainGroup")[0]
except (IndexError, PowershellError) as exc:
# Doesn't appear to be a domain joined group
return
if isinstance(groups, dict):
groups = [groups]
for group in groups:
try:
yield Status(
f"[cyan]{group['samaccountname']}[/cyan]: requesting members"
)
members = session.platform.powershell(
f"Get-DomainGroupMember \"{group['samaccountname']}\""
)[0]
if isinstance(members, dict):
members = [members]
except (IndexError, PowershellError) as exc:
members = []
members = [member["MemberSID"] for member in members]
yield DomainGroup(
self.name, domain=domain["Name"], data=group, members=members
)

View File

@ -0,0 +1,50 @@
#!/usr/bin/env python3
from typing import Any, Dict
from collections import namedtuple
from pwncat.db import Fact
from pwncat.modules import Status, ModuleFailed
from pwncat.platform.windows import Windows, PowershellError
from pwncat.modules.enumerate import Schedule, EnumerateModule
class SiteObject(Fact):
def __init__(self, source: str, data: Dict):
super().__init__(source=source, types=["domain.site"])
self.site = data
def __getitem__(self, name: str):
""" Shortcut for getting properties from the `self.site` property. """
return self.site[name]
def title(self, session: "pwncat.manager.Session"):
return f"[cyan]{self['distinguishedname']}[/cyan]"
class Module(EnumerateModule):
""" Retrieve information on all domain computers """
PLATFORM = [Windows]
PROVIDES = ["domain.site"]
SCHEDULE = Schedule.ONCE
def enumerate(self, session: "pwncat.manager.Session"):
""" Perform enumeration """
# Ensure we have PowerView loaded
yield Status("loading powersploit recon")
session.run("powersploit", group="recon")
try:
yield Status("requesting domain sites")
sites = session.platform.powershell("Get-DomainSite")[0]
except (IndexError, PowershellError) as exc:
# Doesn't appear to be a domain joined site
return
if isinstance(sites, dict):
yield SiteObject(self.name, sites)
else:
yield from (SiteObject(self.name, site) for site in sites)