Skip to content

Commit ac42eb8

Browse files
authored
Merge pull request PowerShellMafia#157 from Meatballs1/localgrouprecursion
Fix Get-NetLocalGroup Recursion for LocalGroups
2 parents 8dea905 + 3585c9b commit ac42eb8

File tree

1 file changed

+72
-75
lines changed

1 file changed

+72
-75
lines changed

Recon/PowerView.ps1

Lines changed: 72 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -7691,7 +7691,6 @@ function Get-NetLocalGroup {
76917691

76927692
if($API) {
76937693
# if we're using the Netapi32 NetLocalGroupGetMembers API call to get the local group information
7694-
76957694
# arguments for NetLocalGroupGetMembers
76967695
$QueryLevel = 2
76977696
$PtrInfo = [IntPtr]::Zero
@@ -7734,9 +7733,8 @@ function Get-NetLocalGroup {
77347733
$LocalUser | Add-Member Noteproperty 'AccountName' $Info.lgrmi2_domainandname
77357734
$LocalUser | Add-Member Noteproperty 'SID' $SidString
77367735

7737-
$IsGroup = $($Info.lgrmi2_sidusage -ne 'SidTypeUser')
7736+
$IsGroup = $($Info.lgrmi2_sidusage -eq 'SidTypeGroup')
77387737
$LocalUser | Add-Member Noteproperty 'IsGroup' $IsGroup
7739-
77407738
$LocalUser.PSObject.TypeNames.Add('PowerView.LocalUserAPI')
77417739

77427740
$LocalUsers += $LocalUser
@@ -7793,9 +7791,11 @@ function Get-NetLocalGroup {
77937791
$Member | Add-Member Noteproperty 'ComputerName' $Server
77947792

77957793
$AdsPath = ($_.GetType().InvokeMember('Adspath', 'GetProperty', $Null, $_, $Null)).Replace('WinNT://', '')
7794+
$Class = $_.GetType().InvokeMember('Class', 'GetProperty', $Null, $_, $Null)
77967795

77977796
# try to translate the NT4 domain to a FQDN if possible
77987797
$Name = Convert-ADName -ObjectName $AdsPath -InputType 'NT4' -OutputType 'Canonical'
7798+
$IsGroup = $Class -eq "Group"
77997799

78007800
if($Name) {
78017801
$FQDN = $Name.split("/")[0]
@@ -7804,33 +7804,30 @@ function Get-NetLocalGroup {
78047804
$IsDomain = $True
78057805
}
78067806
else {
7807+
$ObjName = $AdsPath.split("/")[-1]
78077808
$Name = $AdsPath
78087809
$IsDomain = $False
78097810
}
78107811

78117812
$Member | Add-Member Noteproperty 'AccountName' $Name
7813+
$Member | Add-Member Noteproperty 'IsDomain' $IsDomain
7814+
$Member | Add-Member Noteproperty 'IsGroup' $IsGroup
78127815

78137816
if($IsDomain) {
78147817
# translate the binary sid to a string
78157818
$Member | Add-Member Noteproperty 'SID' ((New-Object System.Security.Principal.SecurityIdentifier($_.GetType().InvokeMember('ObjectSID', 'GetProperty', $Null, $_, $Null),0)).Value)
7816-
78177819
$Member | Add-Member Noteproperty 'Description' ""
7818-
$Member | Add-Member Noteproperty 'Disabled' $False
7819-
7820-
# check if the member is a group
7821-
$IsGroup = ($_.GetType().InvokeMember('Class', 'GetProperty', $Null, $_, $Null) -eq 'group')
7822-
$Member | Add-Member Noteproperty 'IsGroup' $IsGroup
7823-
$Member | Add-Member Noteproperty 'IsDomain' $IsDomain
7820+
$Member | Add-Member Noteproperty 'Disabled' ""
78247821

78257822
if($IsGroup) {
7826-
$Member | Add-Member Noteproperty 'LastLogin' $Null
7823+
$Member | Add-Member Noteproperty 'LastLogin' ""
78277824
}
78287825
else {
78297826
try {
78307827
$Member | Add-Member Noteproperty 'LastLogin' ( $_.GetType().InvokeMember('LastLogin', 'GetProperty', $Null, $_, $Null))
78317828
}
78327829
catch {
7833-
$Member | Add-Member Noteproperty 'LastLogin' $Null
7830+
$Member | Add-Member Noteproperty 'LastLogin' ""
78347831
}
78357832
}
78367833
$Member | Add-Member Noteproperty 'PwdLastSet' ""
@@ -7843,85 +7840,86 @@ function Get-NetLocalGroup {
78437840

78447841
# translate the binary sid to a string
78457842
$Member | Add-Member Noteproperty 'SID' ((New-Object System.Security.Principal.SecurityIdentifier($LocalUser.objectSid.value,0)).Value)
7846-
78477843
$Member | Add-Member Noteproperty 'Description' ($LocalUser.Description[0])
78487844

7849-
# UAC flags of 0x2 mean the account is disabled
7850-
$Member | Add-Member Noteproperty 'Disabled' $(($LocalUser.userFlags.value -band 2) -eq 2)
7851-
7852-
# check if the member is a group
7853-
$Member | Add-Member Noteproperty 'IsGroup' ($LocalUser.SchemaClassName -like 'group')
7854-
$Member | Add-Member Noteproperty 'IsDomain' $IsDomain
7855-
78567845
if($IsGroup) {
7846+
$Member | Add-Member Noteproperty 'PwdLastSet' ""
7847+
$Member | Add-Member Noteproperty 'PwdExpired' ""
7848+
$Member | Add-Member Noteproperty 'UserFlags' ""
7849+
$Member | Add-Member Noteproperty 'Disabled' ""
78577850
$Member | Add-Member Noteproperty 'LastLogin' ""
78587851
}
78597852
else {
7853+
$Member | Add-Member Noteproperty 'PwdLastSet' ( (Get-Date).AddSeconds(-$LocalUser.PasswordAge[0]))
7854+
$Member | Add-Member Noteproperty 'PwdExpired' ( $LocalUser.PasswordExpired[0] -eq '1')
7855+
$Member | Add-Member Noteproperty 'UserFlags' ( $LocalUser.UserFlags[0] )
7856+
# UAC flags of 0x2 mean the account is disabled
7857+
$Member | Add-Member Noteproperty 'Disabled' $(($LocalUser.userFlags.value -band 2) -eq 2)
78607858
try {
78617859
$Member | Add-Member Noteproperty 'LastLogin' ( $LocalUser.LastLogin[0])
78627860
}
78637861
catch {
78647862
$Member | Add-Member Noteproperty 'LastLogin' ""
78657863
}
78667864
}
7867-
7868-
$Member | Add-Member Noteproperty 'PwdLastSet' ( (Get-Date).AddSeconds(-$LocalUser.PasswordAge[0]))
7869-
$Member | Add-Member Noteproperty 'PwdExpired' ( $LocalUser.PasswordExpired[0] -eq '1')
7870-
$Member | Add-Member Noteproperty 'UserFlags' ( $LocalUser.UserFlags[0] )
78717865
}
78727866
$Member.PSObject.TypeNames.Add('PowerView.LocalUser')
78737867
$Member
78747868

7875-
# if the result is a group domain object and we're recursing, try to resolve all the group member results
7876-
if($Recurse -and $IsDomain -and $IsGroup) {
7877-
7878-
$FQDN = $Name.split("/")[0]
7879-
$GroupName = $Name.split("/")[1].trim()
7880-
7881-
Get-NetGroupMember -GroupName $GroupName -Domain $FQDN -FullData -Recurse | ForEach-Object {
7882-
7883-
$Member = New-Object PSObject
7884-
$Member | Add-Member Noteproperty 'ComputerName' "$FQDN/$($_.GroupName)"
7885-
7886-
$MemberDN = $_.distinguishedName
7887-
# extract the FQDN from the Distinguished Name
7888-
$MemberDomain = $MemberDN.subString($MemberDN.IndexOf("DC=")) -replace 'DC=','' -replace ',','.'
7889-
7890-
$MemberIsGroup = @('268435456','268435457','536870912','536870913') -contains $_.samaccounttype
7891-
7892-
if ($_.samAccountName) {
7893-
# forest users have the samAccountName set
7894-
$MemberName = $_.samAccountName
7895-
}
7896-
else {
7897-
try {
7898-
# external trust users have a SID, so convert it
7899-
try {
7900-
$MemberName = Convert-SidToName $_.cn
7901-
}
7902-
catch {
7903-
# if there's a problem contacting the domain to resolve the SID
7904-
$MemberName = $_.cn
7905-
}
7906-
}
7907-
catch {
7908-
Write-Verbose "Error resolving SID : $_"
7909-
}
7910-
}
7911-
7912-
$Member | Add-Member Noteproperty 'AccountName' "$MemberDomain/$MemberName"
7913-
$Member | Add-Member Noteproperty 'SID' $_.objectsid
7914-
$Member | Add-Member Noteproperty 'Description' $_.description
7915-
$Member | Add-Member Noteproperty 'Disabled' $False
7916-
$Member | Add-Member Noteproperty 'IsGroup' $MemberIsGroup
7917-
$Member | Add-Member Noteproperty 'IsDomain' $True
7918-
$Member | Add-Member Noteproperty 'LastLogin' ''
7919-
$Member | Add-Member Noteproperty 'PwdLastSet' $_.pwdLastSet
7920-
$Member | Add-Member Noteproperty 'PwdExpired' ''
7921-
$Member | Add-Member Noteproperty 'UserFlags' $_.userAccountControl
7922-
$Member.PSObject.TypeNames.Add('PowerView.LocalUser')
7923-
$Member
7924-
}
7869+
# if the result is a group domain object and we're recursing,
7870+
# try to resolve all the group member results
7871+
if($Recurse -and $IsGroup) {
7872+
if($IsDomain) {
7873+
$FQDN = $Name.split("/")[0]
7874+
$GroupName = $Name.split("/")[1].trim()
7875+
7876+
Get-NetGroupMember -GroupName $GroupName -Domain $FQDN -FullData -Recurse | ForEach-Object {
7877+
7878+
$Member = New-Object PSObject
7879+
$Member | Add-Member Noteproperty 'ComputerName' "$FQDN/$($_.GroupName)"
7880+
7881+
$MemberDN = $_.distinguishedName
7882+
# extract the FQDN from the Distinguished Name
7883+
$MemberDomain = $MemberDN.subString($MemberDN.IndexOf("DC=")) -replace 'DC=','' -replace ',','.'
7884+
7885+
$MemberIsGroup = @('268435456','268435457','536870912','536870913') -contains $_.samaccounttype
7886+
7887+
if ($_.samAccountName) {
7888+
# forest users have the samAccountName set
7889+
$MemberName = $_.samAccountName
7890+
}
7891+
else {
7892+
try {
7893+
# external trust users have a SID, so convert it
7894+
try {
7895+
$MemberName = Convert-SidToName $_.cn
7896+
}
7897+
catch {
7898+
# if there's a problem contacting the domain to resolve the SID
7899+
$MemberName = $_.cn
7900+
}
7901+
}
7902+
catch {
7903+
Write-Debug "Error resolving SID : $_"
7904+
}
7905+
}
7906+
7907+
$Member | Add-Member Noteproperty 'AccountName' "$MemberDomain/$MemberName"
7908+
$Member | Add-Member Noteproperty 'SID' $_.objectsid
7909+
$Member | Add-Member Noteproperty 'Description' $_.description
7910+
$Member | Add-Member Noteproperty 'Disabled' $False
7911+
$Member | Add-Member Noteproperty 'IsGroup' $MemberIsGroup
7912+
$Member | Add-Member Noteproperty 'IsDomain' $True
7913+
$Member | Add-Member Noteproperty 'LastLogin' ''
7914+
$Member | Add-Member Noteproperty 'PwdLastSet' $_.pwdLastSet
7915+
$Member | Add-Member Noteproperty 'PwdExpired' ''
7916+
$Member | Add-Member Noteproperty 'UserFlags' $_.userAccountControl
7917+
$Member.PSObject.TypeNames.Add('PowerView.LocalUser')
7918+
$Member
7919+
}
7920+
} else {
7921+
Get-NetLocalGroup -ComputerName $Server -GroupName $ObjName -Recurse
7922+
}
79257923
}
79267924
}
79277925
}
@@ -7934,7 +7932,6 @@ function Get-NetLocalGroup {
79347932
}
79357933
}
79367934

7937-
79387935
filter Get-NetShare {
79397936
<#
79407937
.SYNOPSIS

0 commit comments

Comments
 (0)