forbytten blogs

Fake Boost Writeup - Cyber Apocalypse 2024

Last update:

1 Introduction

This writeup covers the Fake Boost Forensics challenge from the Hack The Box Cyber Apocalypse 2024 CTF, which was rated as having an ‘easy’ difficulty. The challenge involved the forensic analysis of HTTP traffic containing obfuscated PowerShell and AES encrypted data.

The description of the challenge is shown below.

Fake Boost challenge description

2 Key Techniques

The key techniques employed in this writeup are:

3 Artifacts Summary

The downloaded artifact had the following hash:

$ shasum -a256 forensics_fake_boost.zip
19953ff5d4e82ce9b4c6c56117626458dd0b23fd5a5e41780d47b67170c5f2e7  forensics_fake_boost.zip

The zip file contained a single packet capture file:

$ unzip forensics_fake_boost.zip
Archive:  forensics_fake_boost.zip
  inflating: capture.pcapng

$ shasum -a256 capture.pcapng
3895763f539214af2dfe44f522c21b0ca80d57113aa8d19d19344e6030f210a8  capture.pcapng

4 Packet analysis

capture.pcap was opened in Wireshark. The Statistics->Protocol Hierarchy menu highlighted the presence of HTTP traffic:

The packet capture was summarized via the Wireshark protocol hierarchy tool, identifying HTTP traffic

4.1 Exporting the HTTP objects

The HTTP objects corresponding to frames 328 and 15422 were exported:

Exporting HTTP objects from Wireshark

5 Analyzing frame 328 - GET /freediscordnitro response

The GET /freediscordnitro response was identified as ASCII text with very long lines:

$ file freediscordnitro
freediscordnitro: ASCII text, with very long lines (8111), with CRLF line terminators

It appeared to be obfuscated PowerShell:

$ head -c 100 freediscordnitro  && echo ""
$jozeq3n = "9ByXkACd1BHd19ULlRXaydFI7BCdjVmai9ULoNWYFJ3bGBCfgMXeltGJK0gNxACa0dmblxUZk92YtASNgMXZk92Q

The last line creates an alias pWn to Invoke-Expression and uses it to invoke the expression stored in the $LOaDcODEoPX3ZoUgP2T6cvl3KEK variable:

$ tail -2  freediscordnitro  && echo ""
$LOaDcODEoPX3ZoUgP2T6cvl3KEK = [sYSTeM.TeXt.ENcODING]::UTf8.geTSTRiNG([SYSTEm.cOnVeRT]::FRoMBaSe64sTRing("$s0yAY2gmHVNFd7QZ")) ;
$U9COA51JG8eTcHhs0YFxrQ3j = "Inv"+"OKe"+"-EX"+"pRe"+"SSI"+"On" ; New-alIaS -Name pWn -VaLuE $U9COA51JG8eTcHhs0YFxrQ3j -FoRcE ; pWn $lOADcODEoPX3ZoUgP2T6cvl3KEK ;

The PowerShell script was defanged by using sed to delete the last line and outputting the result to freediscordnitro-defanged.psh:

$ sed -Ee '$d' freediscordnitro > freediscordnitro-defanged.psh

A statement was appended to echo the contents of the $LOaDcODEoPX3ZoUgP2T6cvl3KEK variable:

$ echo 'echo $LOaDcODEoPX3ZoUgP2T6cvl3KEK' >> freediscordnitro-defanged.psh

The defanged script was executed and the result output to freediscordnitro-decoded.psh, then converted from DOS to Unix line endings:

$ pwsh freediscordnitro-defanged.psh > freediscordnitro-decoded.psh
$ dos2unix  freediscordnitro-decoded.psh
dos2unix: converting file freediscordnitro-decoded.psh to Unix format...

freediscordnitro-decoded.psh contained an AES encryption key:

$AES_KEY = "Y1dwaHJOVGs5d2dXWjkzdDE5amF5cW5sYUR1SWVGS2k="

As well as the corresponding encryption functions:

function Create-AesManagedObject($key, $IV, $mode) {
    $aesManaged = New-Object "System.Security.Cryptography.AesManaged"

    if ($mode="CBC") { $aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC }
    elseif ($mode="CFB") {$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CFB}
    elseif ($mode="CTS") {$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CTS}
    elseif ($mode="ECB") {$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::ECB}
    elseif ($mode="OFB"){$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::OFB}


    $aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
    $aesManaged.BlockSize = 128
    $aesManaged.KeySize = 256
    if ($IV) {
        if ($IV.getType().Name -eq "String") {
            $aesManaged.IV = [System.Convert]::FromBase64String($IV)
        }
        else {
            $aesManaged.IV = $IV
        }
    }
    if ($key) {
        if ($key.getType().Name -eq "String") {
            $aesManaged.Key = [System.Convert]::FromBase64String($key)
        }
        else {
            $aesManaged.Key = $key
        }
    }
    $aesManaged
}

function Encrypt-String($key, $plaintext) {
    $bytes = [System.Text.Encoding]::UTF8.GetBytes($plaintext)
    $aesManaged = Create-AesManagedObject $key
    $encryptor = $aesManaged.CreateEncryptor()
    $encryptedData = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length);
    [byte[]] $fullData = $aesManaged.IV + $encryptedData
    [System.Convert]::ToBase64String($fullData)
}

6 Obtaining part 1 of the flag

The decoded PowerShell was also found to contain part1 of the flag, base64 encoded:

$ grep part1 freediscordnitro-decoded.psh
$part1 = "SFRCe2ZyMzNfTjE3cjBHM25fM3hwMDUzZCFf"

$ echo -n 'SFRCe2ZyMzNfTjE3cjBHM25fM3hwMDUzZCFf' |base64 -d
HTB{fr33_N17r0G3n_3xp053d!_

7 Analyzing frame 15422 - POST /rj1893rj1joijdkajwda request

rj1893rj1joijdkajwda was found to contain base64 encoded data. However, the decoded data was of an as-yet unidentified binary type. It was conjectured that it was AES encrypted by the aforementioned encryption functions.

$ cat rj1893rj1joijdkajwda|base64 -d |file -
/dev/stdin: data

$ cat rj1893rj1joijdkajwda|base64 -d |xxd|head
00000000: 6c41 beac 6711 c982 9eaa 5cd7 6f44 1555  lA..g.....\.oD.U
00000010: 1bc5 a791 3dbe 6952 486d e9bc 34c0 1a86  ....=.iRHm..4...
00000020: dad3 9531 bdea 70bf efb4 b967 b532 7e0b  ...1..p....g.2~.
00000030: 8882 2766 2342 fc44 b5b5 2ed2 9b39 9b73  ..'f#B.D.....9.s
00000040: df55 71df 61e7 52a0 0394 6cd6 df13 e791  .Uq.a.R...l.....
00000050: 2be6 2738 165a 01cd 0eed a629 f0f7 d902  +.'8.Z.....)....
00000060: dfcd 1645 a59c ab50 9cf2 243a 9590 4fff  ...E...P..$:..O.
00000070: 2a89 b8bb 1f2d 3a52 637c 8879 2c2a f19f  *....-:Rc|.y,*..
00000080: 6dba cbf9 b96b ddf4 4f55 d078 7607 0939  m....k..OU.xv..9
00000090: 2c33 189f 2c19 c3ae 21b0 7f32 b84f eefe  ,3..,...!..2.O..

8 Creating PowerShell AES decryption code

PowerShell AES decryption code was found online at https://gist.github.com/ctigeek/2a56648b923d198a6e60. This was used to create the following decrypt.psh script:

function Create-AesManagedObject($key, $IV, $mode) {
    $aesManaged = New-Object "System.Security.Cryptography.AesManaged"

    if ($mode="CBC") { $aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC }
    elseif ($mode="CFB") {$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CFB}
    elseif ($mode="CTS") {$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CTS}
    elseif ($mode="ECB") {$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::ECB}
    elseif ($mode="OFB"){$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::OFB}


    $aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
    $aesManaged.BlockSize = 128
    $aesManaged.KeySize = 256
    if ($IV) {
        if ($IV.getType().Name -eq "String") {
            $aesManaged.IV = [System.Convert]::FromBase64String($IV)
        }
        else {
            $aesManaged.IV = $IV
        }
    }
    if ($key) {
        if ($key.getType().Name -eq "String") {
            $aesManaged.Key = [System.Convert]::FromBase64String($key)
        }
        else {
            $aesManaged.Key = $key
        }
    }
    $aesManaged
}

function Decrypt-String($key, $encryptedStringWithIV) {
    $bytes = [System.Convert]::FromBase64String($encryptedStringWithIV)
    $IV = $bytes[0..15]
    $aesManaged = Create-AesManagedObject $key $IV
    $decryptor = $aesManaged.CreateDecryptor();
    $unencryptedData = $decryptor.TransformFinalBlock($bytes, 16, $bytes.Length - 16);
    $aesManaged.Dispose()
    [System.Text.Encoding]::UTF8.GetString($unencryptedData).Trim([char]0)
}

$AES_KEY = "Y1dwaHJOVGs5d2dXWjkzdDE5amF5cW5sYUR1SWVGS2k="
$backToPlainText = Decrypt-String $AES_KEY "bEG+rGcRyYKeqlzXb0QVVRvFp5E9vmlSSG3pvDTAGoba05Uxvepwv++0uWe1Mn4LiIInZiNC/ES1tS7Smzmbc99Vcd9h51KgA5Rs1t8T55Er5ic4FloBzQ7tpinw99kC380WRaWcq1Cc8iQ6lZBP/yqJuLsfLTpSY3yIeSwq8Z9tusv5uWvd9E9V0Hh2Bwk5LDMYnywZw64hsH8yuE/u/lMvP4gb+OsHHBPcWXqdb4DliwhWwblDhJB4022UC2eEMI0fcHe1xBzBSNyY8xqpoyaAaRHiTxTZaLkrfhDUgm+c0zOEN8byhOifZhCJqS7tfoTHUL4Vh+1AeBTTUTprtdbmq3YUhX6ADTrEBi5gXQbSI5r1wz3r37A71Z4pHHnAoJTO0urqIChpBihFWfYsdoMmO77vZmdNPDo1Ug2jynZzQ/NkrcoNArBNIfboiBnbmCvFc1xwHFGL4JPdje8s3cM2KP2EDL3799VqJw3lWoFX0oBgkFi+DRKfom20XdECpIzW9idJ0eurxLxeGS4JI3n3jl4fIVDzwvdYr+h6uiBUReApqRe1BasR8enV4aNo+IvsdnhzRih+rpqdtCTWTjlzUXE0YSTknxiRiBfYttRulO6zx4SvJNpZ1qOkS1UW20/2xUO3yy76Wh9JPDCV7OMvIhEHDFh/F/jvR2yt9RTFId+zRt12Bfyjbi8ret7QN07dlpIcppKKI8yNzqB4FA=="
echo $backToPlainText

9 Obtaining part 2 of the flag

The decryption script was executed:

$ pwsh decrypt.psh
[
    {
        "ID":  "1212103240066535494",
        "Email":  "YjNXNHIzXzBmX1QwMF9nMDBkXzJfYjNfN3J1M18wZmYzcjV9",
        "GlobalName":  "phreaks_admin",
        "Token":  "MoIxtjEwMz20M5ArNjUzNTQ5NA.Gw3-GW.bGyEkOVlZCsfQ8-6FQnxc9sMa15h7UP3cCOFNk"
    },
    {
        "ID":  "1212103240066535494",
        "Email":  "YjNXNHIzXzBmX1QwMF9nMDBkXzJfYjNfN3J1M18wZmYzcjV9",
        "GlobalName":  "phreaks_admin",
        "Token":  "MoIxtjEwMz20M5ArNjUzNTQ5NA.Gw3-GW.bGyEkOVlZCsfQ8-6FQnxc9sMa15h7UP3cCOFNk"
    }
]

The base64 encoded email fields were found to contain part 2 of the flag:

$ echo -n 'YjNXNHIzXzBmX1QwMF9nMDBkXzJfYjNfN3J1M18wZmYzcjV9' | base64 -d
b3W4r3_0f_T00_g00d_2_b3_7ru3_0ff3r5}

10 Combining the flag parts

The combined flag parts resulted in:

HTB{fr33_N17r0G3n_3xp053d!_b3W4r3_0f_T00_g00d_2_b3_7ru3_0ff3r5}

11 Conclusion

The flag was submitted and the challenge was marked as pwned

Submission of the flag marked the challenge as pwned