Unknown Malware Using Azure Functions as C2 Published: 2025-09-07 · Archived: 2026-04-05 20:48:24 UTC On August 28, 2025, an ISO named Servicenow-BNM-Verify.iso was uploaded to VirusTotal from Malaysia with very low detections: The ISO image contains 4 files, two of them hidden. servicenow-bnm-verify.lnk , a shortcut file that simply executes PanGpHip.exe PanGpHip.exe , a legitimate Palo Alto Networks executable libeay32.dll , a legitimate OpenSSL library (hidden) libwaapi.dll , a malicious library (hidden) servicenow-bnm-verify.lnk only executes the legitimate Palo Alto executable. The metadata of the LNK file reveals the machine used to create the link ( desktop-rbg1pik ), the user ( john.GIB ), and the creation date ( 08/25/2025 (04:39:00.540) [UTC] ), 3 days before the LNK ISO was uploaded to VirusTotal. The target path of the LNK points to the executable in the excluded folder. This is likely a location in the threat actor’s development environment. Even though that path does not exist on the victim’s device, the LNK falls back to its same directory, where PanGpHip.exe also resides. LNK metadata: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [Link Info] Location flags: 0x00000001 (VolumeIDAndLocalBasePath) Drive type: 3 (DRIVE_FIXED) Drive serial number: fa5a-f20e Volume label (ASCII): Local path (ASCII): C:\Users\john.GIB\Desktop\excluded\paloalto\PanGpHip.exe [Distributed Link Tracker Properties] Version: 0 NetBIOS name: desktop-rbg1pik Droid volume identifier: 711034a2-0123-44ae-ae6c-462a77afcd54 Droid file identifier: 6b9dc172-816d-11f0-a497-7c214a295e9f Birth droid volume identifier: 711034a2-0123-44ae-ae6c-462a77afcd54 Birth droid file identifier: 6b9dc172-816d-11f0-a497-7c214a295e9f MAC address: 7c:21:4a:29:5e:9f UUID timestamp: 08/25/2025 (04:39:00.540) [UTC] https://dmpdump.github.io/posts/AzureFunctionsMalware/ Page 1 of 10 17 18 UUID sequence number: 9367 Payload Injection The presence of hidden DLLs and a legitimate executable is typically indicative of DLL side-loading. The libwaapi.dll library contains malicious logic that is executed when it is dynamically loaded by the legitimate PanGpHip.exe executable using LoadLibraryW . This DLL, although malicious, has almost no detection in VirusTotal: The only exported function in libwaapi.dll that implements code is wa_api_setup . The rest of the exports do not have any code. https://dmpdump.github.io/posts/AzureFunctionsMalware/ Page 2 of 10 The wa_api_setup export: Uses an array of function pointers to call GetConsoleWindow , SetForegroundWindow , GetForegroundWindow , and ShowWindow with its second argument set to 0, which is SW_HIDE according to the API documentation. This is a common technique to hide the console from the victim It then creates/checks mutex 47c32025 via the CreateMutexExW API If the mutex does not exist, it executes a payload injection function that I renamed to fn_payload_injection The fn_payload_injection function implements logic to inject payload in memory. This function starts by computing the SHA-256 hash of string rdfY*&689uuaijs . This hash ( B639D4DC948B66A2AAB5B59D0B4114B4B11229E9DED0F415B594B8ADE11F8180 ) is subsequently used as the RC4 key for payload decryption. If the SHA2 computation is successful, it proceeds to deobfuscate the string chakra.dll with a simple algorithm that resembles a Caesar cipher. https://dmpdump.github.io/posts/AzureFunctionsMalware/ Page 3 of 10 The legitimate chakra.dll is loaded from the C:\Windows\System32\ folder and a loop is implemented to find the first readable + executable section in the DLL. When that section is found, its memory permissions are set to writable ( PAGE_READWRITE ) via the ZwProtectVirtualMemory API and the content is zeroed out. The injector then proceeds to base64-decode a payload stored in the .data section of the DLL to the target section in the loaded chakra.dll . After decoding the payload, it is RC4 decrypted with the previously computed key ( B639D4DC948B66A2AAB5B59D0B4114B4B11229E9DED0F415B594B8ADE11F8180 ). https://dmpdump.github.io/posts/AzureFunctionsMalware/ Page 4 of 10 Once the deobfuscated/decrypted payload is written to the DLL, an integrity check is implemented by comparing the SHA2 hash of the injected payload to a hard-coded SHA2 value ( 550c27fd8dc810df2056f1ec4a749a94ab4befc8843ba913c5f1197ef381a0a5 ). If the integrity check passes, memory permission is restored to PAGE_EXECUTE_READ and it proceeds to execute the injected payload. Injected Payload The injected payload is an obfuscated shellcode that loads an embedded DLL. We can quickly find the embedded payload by loading the shellcode in a hex editor. However, we can see that the embedded payload needs to be processed before execution. It is not a clean PE. https://dmpdump.github.io/posts/AzureFunctionsMalware/ Page 5 of 10 Reviewing the shellcode, we can see that the buffer with the embedded portable executable is processed by the RtlDecompressBuffer API using 0x102 as the first argument. Looking at the prototype of RtlDecompressBuffer , we can see that the first argument is the compression format: https://dmpdump.github.io/posts/AzureFunctionsMalware/ Page 6 of 10 1 2 3 4 5 6 7 8 NT_RTL_COMPRESS_API NTSTATUS RtlDecompressBuffer( [in] USHORT CompressionFormat, [out] PUCHAR UncompressedBuffer, [in] ULONG UncompressedBufferSize, [in] PUCHAR CompressedBuffer, [in] ULONG CompressedBufferSize, [out] PULONG FinalUncompressedSize ); In order to understand what the 0x102 means, we can check the ReactOS documentation. Here we can see that macro definitions indicate that 0x0100 is COMPRESSION_ENGINE_MAXIMUM and 0x0002 is COMPRESSION_FORMAT_LZNT1 . So, essentially, the embedded payload has maximum compression for LZNT1 . We can then decompress the final payload embedded within the shellcode. The decompressed payload is an obfuscated DLL (SHA2: c0fc5ec77d0aa03516048349dddb3aa74f92cfe20d4bca46205f40ab0e728645) which I could not correlate to any payload I’ve seen before - possibly due to the obfuscation. I am still working on deobfuscating this payload, but here are some initial observations. The DLL timestamp is May 5, 1984, which was likely modified. The malicious functionality is implemented in the DllUnload exported function. A quick string review via emulation suggests that the DLL implements module unhooking to avoid detection. https://dmpdump.github.io/posts/AzureFunctionsMalware/ Page 7 of 10 This final payload implements a loop to the C2, sending a POST request with victim profile data to logsapi.azurewebsites[.]net/api/logs . The data is sent encoded/encrypted in a POST request. https://dmpdump.github.io/posts/AzureFunctionsMalware/ Page 8 of 10 The Azure websites C2 hosts Azure Functions. Azure Functions is a serverless solution that operates with event-driven triggers and bindings. The encrypted data sent to the C2 can be captured before it is encrypted. We can see that it is an XML containing the computer name, user name, the OS uptime, protocol, process running the malware, parent process, and other values that I am still reviewing. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 64 // likely architecture 3 3916 3380 60 30 1759243228 805074430 false %random string% v2.17.3 //unknown version HTTP_HTTPS SUE48 Windows 10.0 (OS Build 1337) // OS build (1337 is an interesting value. %COMPUTERNAME% 0d 6h 43m //uptime %COMPUTERNAME%\%USER% // computer name and user name %PROCESS% //process the malware is executing from %PARENTPROCESS% //parent process https://dmpdump.github.io/posts/AzureFunctionsMalware/ Page 9 of 10 I am still deobfuscating this final payload to understand all the details, and I may post a follow up blog post once I am done. This sample seems to be quite unique, but @L3hu3s0 found another DLL (SHA2: 28e85fd3546c8ad6fb2aef37b4372cc4775ea8435687b4e6879e96da5009d60a ) with the same imphash ( B74596632C4C9B3A853E51964E96FC32 ) uploaded from Singapore on September 5, 2025. I reviewed that DLL and it is pretty much the same thing, with some minor differences. IOCs Servicenow-BNM-Verify.iso: 0ba328aeb0867def650694c5a43fdd47d719c6b3c55a845903646ccdbf3ec239 servicenow-bnm-verify.lnk: 9e312214b44230c1cb5b6ec591245fd433c7030cb269a9b31f0ff4de621ff517 libeay32.dll: 1fa3e14681bf7f695a424c64927acfc26053ebaa54c4a2a6e30fe1e24b4c20a8 libwaapi.dll: b03a2c0d282cbbddfcf6e7dda0b4b55494f4a5c0b17c30cd586f5480efca2c17 PanGpHip.exe: b778d76671b95df29e15a0af4d604917bfba085f7b04e0ce5d6d0615017e79db Decrypted shellcode: 550c27fd8dc810df2056f1ec4a749a94ab4befc8843ba913c5f1197ef381a0a5 Decompressed DLL: c0fc5ec77d0aa03516048349dddb3aa74f92cfe20d4bca46205f40ab0e728645 Related DLL: 28e85fd3546c8ad6fb2aef37b4372cc4775ea8435687b4e6879e96da5009d60a C2: logsapi.azurewebsites[.]net Source: https://dmpdump.github.io/posts/AzureFunctionsMalware/ https://dmpdump.github.io/posts/AzureFunctionsMalware/ Page 10 of 10