An absent defense
Last updated
Was this helpful?
Last updated
Was this helpful?
Looking at the remaining files from the S3 dump, theres nothing that will allow us to escalate our privileges or lateral movement.
The openemr-5.0.2.tar.gz seems to be the exact same copy from the trial-data-management-poc bit bucket URL.
Recall that how in Flag 2, we noticed that the web-prod EC2 instance contains some azure credentials, lets try and dump it all.
Reading the msal_token_cache.json file, there is a bunch of bearer access token, however some of those had already expired, and some are expiring soon.
So this is not a good way to access the nacer azure account as it might expire any time.
Scrolling further down, we found a credential type called refresh token. By having a refresh token, we are able to obtain new access and refresh token pairs whenever the current one expires. The dedfault lifetime of refresh token is 90days, which allow us to maintain persistency on nacer Azure account, even if we lose access to the EC2.
Using the tool TokenTacticsV2, we are able to get a access token using the refresh token
Using the AzureManagementToken, we are able to authenticate using Azure Powershell.
As nacer have access over storage, we are able to list out the storage account. Lets get a storage account token and enumerate the storage account.
Refering to Azure Storage REST API, we will be
Listing Container
Listing blobs in container
Downloading the blobs from the container
This seems to be a rabbit hole, since the export-users.sh does not contain much useful information.
However one thing to take note is that the RESOURCE_GROUP in the export_users.sh is different from the storage container resoure group. This could be useful in the future as we might be able to identify other storage container in different resource group.
Now that we have finish enumerating Azure Resources, lets pivot into enumerating Entra ID (Azure Active Directory). Ill be using one of my favourite tool GraphRunner to enumerate via the graph api.
Its very straight forward to use GraphRunnerGUI, where we can just plug the graph api acess token and use it to run certain commands.
Using GraphRunner, we managed to retreived a list of user and 1 new potential password.
As we dont have much to work off, lets try and spray the potential password against our user list. I will be using MSOLSpray.
Next, lets try and enumerate to check if MFA is being used using MFASweep.
From the MFASweep output, it seems like there isnt any Conditional Access Policies or MFA in place to restrict the user yuki.
Using the Azure Portal, we are able to sucesfully authenticate and access the Azure Portal interface.
Again looking at the recent resources, two of them stand out immidiately
mpprod storage account (we access it previously)
pharsignt-dev function app
Going to the All Resource Page, we also only have access to this two resource.
Looking at the storage browser, it only show the export-user.sh.
However, by default it will only show active blobs. We are able to view recently deleted blobs by swapping the options.
We are able to then download the user_export_20240202.csv file using the Storage Browser.
Looking at the downloaded file, it seems to contain email address as well as hashed password. Lets copy out the hashed password into a text file and try cracking it.
Using hash-identifier, the hash seems to be a possible sha-256 hash.
We have a new password and username to be added to our loot.
Pivoting back into the function app we can see the function app domain as well as the http trigger
Trying to use Azure Portal to perform more enumeration on the function app fails due to lack of permission. From the function name HttpPharSightTrigger01
and the Trigger being HTTP, we can try enumerate the default domain to see if theres any error message.
Referring to Azure Functions docmentation, we are able to craft the route to trigger the function.
Sending a GET request to https://pharsight-dev.azurewebsites.net/api/HttpPharSightTrigger01 shows a instruction as well as sample data that we can use.
Sending a POST request with the data, we are returned with output and data.
The output seems to be from a database that show the number of columns. This might be suseptible to SQL Injection. I will proxy the request over the burpsuite so that I do not need to deal with escaping shell properly.
Looking at Brupsuite, we are able to see the request in the HTTP request tab.
Next, I will forward the request to repeater by pressing Ctrl + R. I also changed the trialname to a single quote.
From the error we received, we are certain that this application is vulnerable to SQL Injection.
Now lets try and craft the original SQL Query based on our output, and then try and perform SQL Injection.
Based on the previous output, we have 6 columns along with their data type
The output ItemArray also matches the number of column.
So a valid assumption of how the SQL might work is
From the data type, we can also safely assume that its a Windows SQL server. But for sanity check, lets attempt to retrieve the banner
Getting Table Name
Output Data: appusers, database_firewall_rules, Participants
Getting Table Column
Output Data: id, password, username
Getting username and password
Other than the flag, we also get a set of credential for nina.
Now lets add nina password to our loot.
Use Refresh Token to get access token
Enumerate Azure Resources (storage account)
Use TokenTacticsV2 to request an MSGraphToken
Plug the access token to raph runner to enumerate AzureAD and Outlook
Plaintext credential spotted in Outlook
Spray with MSOLSpray using new credentials and check for MFA with MFASweep
Access yuki account with new credential
Download database dump from Storage Account versioning and crack the hashes
Identify that theres a Function App running and enumerate the function app
Perform SQL Injection to get flag and nina credential