// HackTheBox  ·  writeup

PowerShell_Script

HackTheBox Very Easy base64iconv
Malware Analysis

Scenario

Analyze a suspicious PowerShell script from a Windows host (CyberChef suggested for decoding).

Executive Summary

A suspicious PowerShell script wrapped its real logic in a base64 blob passed to powershell as an encoded command. The launcher arguments hid the window and ran it non-interactively, so a user would never see or interrupt it. The decoded script built a .NET web client, set a spoofed browser user agent so its traffic blended in with normal browsing, and reused the logged-in user’s default credentials to get through an authenticating proxy. It then contacted a hardcoded HTTP address on a non-standard port to fetch the payload. Everything was recovered statically by decoding the blob; nothing was executed.

Artifacts

Encoding note: PowerShell’s -EncodedCommand is base64 over UTF-16LE text, so a plain base64 decode shows null-byte-spaced garbage. Convert from UTF-16LE after decoding. CyberChef does the same with From Base64 then Decode text (UTF-16LE).

Execution

Q1 — What encoding is the malicious script using?

The launcher line in script.ps1 passes the payload through -Enc, the short form of -EncodedCommand. That switch takes base64 of UTF-16LE text, which is why the blob decodes cleanly only once the UTF-16LE step is added.

base64 -d script.ps1 | iconv -f UTF-16LE -t UTF-8
Click flag to reveal base64

Defense Evasion

Q2 — What parameter in the powershell script makes it so that the powershell window is hidden when executed?

The answer is in the launcher arguments, not in the decoded body. Read the switches in front of -Enc: the window-style switch is written in its short form with the value Hidden, so no console window appears when the script runs.

cat script.ps1
Click to reveal answer -W Hidden
Q3 — What parameter in the Powershell script prevents the user from closing the process?

Same launcher line. -NonI is the short form of -NonInteractive, which runs PowerShell without an interactive prompt, so there is nothing for the user to interact with or dismiss. Together with the hidden window it keeps the process out of sight.

cat script.ps1

Gotcha: The question wording suggests a “prevent close” switch, but the parameter that matches the four-character format hint is the non-interactive one.

Click flag to reveal -NonI

Command and Control

Q4 — What line of code allows the script to interact with websites and retrieve information from them?

Decode the blob and look for the object that does the networking. The script instantiates a .NET System.Net.WebClient. The casing is deliberately mixed (New-ObjEcT, SySTeM.NET.WebCliENt), a cheap signature-evasion trick, so copy the line exactly as it appears.

base64 -d script.ps1 | iconv -f UTF-16LE -t UTF-8
Click to reveal answer $WC=New-ObjEcT SySTeM.NET.WebCliENt
Q5 — What is the user agent string that is being spoofed in the malicious script?

The next lines of the decoded script set the web client’s user agent. It claims to be Internet Explorer 11 on Windows 7 (Trident/7.0; rv:11.0), which makes the request look like ordinary browser traffic in proxy logs.

base64 -d script.ps1 | iconv -f UTF-16LE -t UTF-8
Click flag to reveal Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Q6 — What line of code is used to set the proxy credentials for authentication in the script?

The script assigns the client’s proxy credentials from the system credential cache, so it authenticates to a corporate proxy as whoever is logged in without needing a stored password. Again the casing is scrambled, and the answer must match it character for character.

base64 -d script.ps1 | iconv -f UTF-16LE -t UTF-8
Click to reveal answer $wc.PROxY.CrEdenTialS = [SysTem.NEt.CRedeNTIAlCAcHE]::DeFAULTNetWOrKCredENTiAls
Q7 — When the malicious script is executed, what is the URL that the script contacts to download the malicious payload?

The payload address is hardcoded in the decoded script: a plain HTTP URL to a bare IP on port 7443, ending in an .asp page. The IP and non-standard port make it a good block-list and proxy-log pivot.

base64 -d script.ps1 | iconv -f UTF-16LE -t UTF-8
Click flag to reveal http://98.103.103.170:7443/index.asp

Attack Summary

PhaseAction
ExecutionPowerShell launched with an encoded command (-Enc) carrying a base64 UTF-16LE payload
Defense EvasionHidden window and non-interactive mode keep the process invisible to the user
Defense EvasionMixed-case cmdlet and type names dodge simple string signatures
Command and ControlWebClient created with a spoofed IE11 user agent
Command and ControlDefault network credentials set as proxy credentials to pass an authenticating proxy
Command and ControlPayload requested from a hardcoded HTTP URL on port 7443

IOCs

TypeValue
URLhxxp[://]98[.]103[.]103[.]170[:]7443/index[.]asp
IP98[.]103[.]103[.]170
User agentMozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Launcher switches-W Hidden, -NonI, -Enc

MITRE ATT&CK

TechniqueIDDescription
Command and Scripting Interpreter: PowerShellT1059.001Encoded PowerShell launcher
Obfuscated Files or Information: Command ObfuscationT1027.010Base64 payload and mixed-case names
Hide Artifacts: Hidden WindowT1564.003-W Hidden
Application Layer Protocol: Web ProtocolsT1071.001HTTP request with a spoofed browser user agent
Ingress Tool TransferT1105Script contacts a hardcoded URL for the payload

Defender Takeaways

Encoded PowerShell with hidden-window switches is a detection primitive on its own. A command line combining -Enc, -W Hidden and -NonI is rarely legitimate. Alert on that combination in process-creation logs (Sysmon 1 or 4688 with command-line auditing) and in PowerShell Script Block Logging, which records the decoded script.

Case-mangled cmdlets defeat case-sensitive matching. New-ObjEcT and SySTeM.NET.WebCliENt slip past naive string rules. Normalise case before matching, or key on behaviour such as Net.WebClient use from a hidden PowerShell process.

A spoofed user agent is only convincing until it is compared with the process. An IE11 user agent from powershell.exe is a mismatch worth hunting in proxy logs. Pair user-agent analytics with the originating process.

Default proxy credentials mean the proxy cannot save you from an authenticated user. Because the script borrows the logged-in identity, proxy authentication gives no protection. Restrict egress to known destinations and block direct-to-IP HTTP on odd ports like 7443.

Conclusion

The whole payload chain was recoverable with one decode: a hidden, non-interactive PowerShell launcher that borrowed the user’s proxy identity and pulled a payload from a bare IP. Base64 added no real protection, so logging decoded script content is what turns this from invisible into trivial to catch.