Ever wonder how many users grant full control to Everyone on shares they created? This opens a huge risk, as any virus/worm can write itself to these shares, given the NTFS permissions allow them as well. At any rate, I don’t think it’s a good idea, so I scripted it out and found something like 470 shares where Everyone was granted FullControl access in my environment. OUCH!
Keep in mind, this also shows printers. I didn’t take the time to exclude them, so my script actually finds ~620 vulnerable shares.
For logging, just change $script:logfile = "D:\everyoneshares.txt"
to whatever location you wish.
If you want to see more than just Full Control, change if (($AccessMask -eq "FullControl") -AND ($myshare.ID -eq "Everyone")){$script:mylist += $myshare}
to match your desired output.
It also ignores any share that ends with a $ (administrative or hidden shares), change $shares = gwmi Win32_LogicalShareSecuritySetting -co $comp -erroraction silentlycontinue |? {$_.Name -notlike "*$"}
to $shares = gwmi Win32_LogicalShareSecuritySetting -co $comp -erroraction silentlycontinue
and it will look at ALL shares.
Now here’s the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
#OU Locations, make sure the index is in order, 1, 2, 3, etc. #you cannot have 3 without 2, etc. $ous = @{} $ous[1] = 'LDAP://OU=Servers,DC=domain,DC=com' $ous[2] = 'LDAP://OU=Another OU,DC=domain,DC=com' $ous[3] = 'LDAP://OU=Domain Controllers,DC=domain,DC=com' #set logfile directory $script:logfile = "D:\everyoneshares.txt" #This pulls all computer accounts from AD function getresults($path,$cert) { $objDomain = New-Object System.DirectoryServices.DirectoryEntry $objSearcher = New-Object System.DirectoryServices.DirectorySearcher $objSearcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry($path) $objSearcher.PageSize = 1000 # How many to retrieve at a time. Not output size. $objSearcher.Filter = $strFilter $objSearcher.PropertiesToLoad.Add("cn") >$null $colResults = $objSearcher.FindAll() foreach ($objResult in $colResults) { $objItem = $objResult.Properties $computer = $objItem.cn[0] $computer = $objItem.cn $script:comps += $computer } } #This runs the getresults function for each OU supplied above $script:comps = @() foreach ($ou in 1 .. $ous.Count) { if ($ous.$ou) { $strFilter = "(&(objectClass=Computer))" getresults $ous.$ou } } $comps = $script:comps | Sort name $script:mylist = @() write-host `n foreach ($comp in $comps) {#1 #here's where we actually pull each share from the current computer $shares = gwmi Win32_LogicalShareSecuritySetting -co $comp -erroraction silentlycontinue |? {$_.Name -notlike "*$"} if($shares){#2 foreach ($share in $shares){#3 $SecurityDescriptor = $Share.GetSecurityDescriptor() ForEach ($DACL in $SecurityDescriptor.Descriptor.DACL) {#4 $myshare = "" | Select Server, Share, ID, AccessMask $myshare.Server = $comp $myshare.Share = $share.name $myshare.ID = $DACL.Trustee.Name Switch ($DACL.AccessMask) {#5 2032127 {$AccessMask = "FullControl"} 1179785 {$AccessMask = "Read"} 1180063 {$AccessMask = "Read, Write"} 1179817 {$AccessMask = "ReadAndExecute"} -1610612736 {$AccessMask = "ReadAndExecuteExtended"} 1245631 {$AccessMask = "ReadAndExecute, Modify, Write"} 1180095 {$AccessMask = "ReadAndExecute, Write"} 268435456 {$AccessMask = "FullControl (Sub Only)"} default {$AccessMask = $DACL.AccessMask} }#5 $myshare.AccessMask = $AccessMask if (($AccessMask -eq "FullControl") -AND ($myshare.ID -eq "Everyone")){$script:mylist += $myshare} Clear-Variable AccessMask -ErrorAction SilentlyContinue }#4 }#3 }#2 }#1 $mylist | out-file $script:logfile $count = $mylist.count write-output `n "found $count shares where Everyone was given FullControl" | out-file $script:logfile -append write-host `n |
I pieced this together from a few things I found on the net (querying AD and Shares), then combined the two and added logfile output.
I recommend using Start-Job for this, and get-job to see if it’s finished. You don’t need to provide any input, and depending on your environment size, it could take quite some time. Here’s the expected output:
1 2 3 4 5 6 7 8 9 10 |
Server Share ID AccessMask ------ ----- -- ---------- Server-1 Share-1 Everyone FullControl found 1 shares where Everyone was given FullControl |