Google Unveils GoStringUngarbler to Crack Go-Based Malware Encryption


Google’s FLARE team has released GoStringUngarbler, an open-source tool designed to dismantle string obfuscation in Go binaries protected by the garble compiler.

This innovation addresses growing concerns over malware authors exploiting garble’s advanced literal transformations, which render traditional static analysis ineffective.

The tool combines emulation-driven string extraction with binary patching to produce deobfuscated executables, fundamentally altering reverse engineering workflows for security analysts.

Garble’s Obfuscation Architecture

The garble compiler enhances Go binary protection through AST-level transformations that preserve program semantics while complicating static analysis.

GoStringUngarbler: Deobfuscating Strings in Garbled Binaries
GoStringUngarbler: Deobfuscating Strings in Garbled Binaries

Its -literals flag activates four distinct string encryption methodologies, each requiring specialized decryption approaches.

Stack-Based Transformations

Garble implements three stack manipulation techniques for runtime string decryption:

Simple transformation employs byte-wise arithmetic operations using a randomly generated key and operator (XOR/ADD/SUB). The compiler generates a decryptor function template as shown below:

key := make([]byte, len(data)) 

obfRand.Read(key) 

op := randOperator(obfRand) 

for i, b := range key { 

    data[i] = evalOperator(op, data[i], b) 

}

This produces assembly patterns where RBX/RCX registers hold decrypted string pointers and lengths before calling runtime_slicebytetostring.

GoStringUngarblerGoStringUngarbler
GoStringUngarbler

Swap transformation introduces position-dependent encryption through byte pair swapping and dynamic local keys:

for i := len(positions) - 2; i >= 0; i -= 2 { 

    localKey := byte(i) + byte(positions[i]^positions[i+1]) + shiftKey 

    data[positions[i]], data[i+1] = evalOperator(op, data[i+1], localKey), 

                                   evalOperator(op, data[i], localKey) 

}

The resulting control flow contains nested loops that shuffle byte order while applying cascading XOR operations1.

Shuffle transformation implements multi-layered obfuscation through permutation matrices and index scrambling:

shuffledIdxs := obfRand.Perm(len(fullData)) 

for i, b := range fullData { 

    shuffledFullData[shuffledIdxs[i]] = b 

}

Analysts face encrypted data fragments interleaved with decryption keys across randomized memory regions.

Seed Transformation Mechanics

This chain-based approach creates cryptographic dependencies between bytes using evolving seed values:


seed := byte(obfRand.Uint32()) 

for i, b := range data { 

    encB := evalOperator(op, b, seed) 

    seed += encB 

}

Decompiled code reveals successive CALL instructions that sequentially update the seed through arithmetic operations.

Split Transformation Infrastructure

Garble partitions strings into chunked ciphertexts managed through state machines:

switchCases := []ast.Stmt{&ast.CaseClause{ 

    List: []ast.Expr{ah.IntLit(decryptIndex)}, 

    Body: shuffleStmts(obfRand, 

        &ast.AssignStmt{ 

            Lhs: []ast.Expr{ast.NewIdent("i")}, 

            Tok: token.ASSIGN, 

            Rhs: []ast.Expr{ah.IntLit(exitIndex)}, 

        }, 

        decryptLogic)}}

Control flow jumps between randomized SWITCH cases to reassemble encrypted payloads.

GoStringUngarbler’s Deobfuscation Pipeline

The tool implements a three-stage process combining pattern recognition, emulation, and binary modification:

1. Subroutine Identification

Regular expressions target garble’s assembly fingerprints preceding runtime_slicebytetostring calls:

48 8D 5C ?? ??     lea     rbx, [rsp+] 

B9 ?? ?? ?? ??     mov     ecx,  

E8 ?? ?? ?? ??     call    runtime_slicebytetostring

YARA rules classify transformation types based on register initialization patterns.

2. Emulation Engine

Unicorn-based emulation executes decryptors from identified prologues:

49 3B ?? ??        cmp     rsp, [+] 

76 ??              jbe     short 

Memory snapshots capture decrypted strings post-emulation without executing malware payloads.

3. Binary Patching

Original decryptors undergo surgical replacement with static string loads:

xor     eax, eax 

lea     rbx, 0x5FFD00  ; Decrypted string address 

mov     ecx, 0x1A      ; String length 

call    runtime_slicebytetostring 

ret

The remaining function space gets padded with INT3 breakpoints to prevent execution artifacts.

Implications for Malware Analysis

GoStringUngarbler introduces paradigm shifts in three key areas:

  1. Automated TTP Extraction: Over 92% of garble-obfuscated strings in tested samples were successfully recovered, enabling faster IOC generation.
  2. Cross-Platform Analysis: Python implementation allows integration with disassemblers like Ghidra and Binary Ninja without vendor lock-in.
  3. Proactive Defense: Open-source availability (Mandiant GitHub) lets EDR vendors incorporate deobfuscation into scanning pipelines pre-execution.

Google’s breakthrough demonstrates that garble’s protections—while sophisticated—are not insurmountable.

By combining instruction pattern analysis with emulation and surgical binary editing, GoStringUngarbler delivers practical countermeasures against evolving Go malware threats.

Security teams should integrate this tool into reverse engineering workflows to neutralize obfuscation advantages currently exploited by adversaries.

Collect Threat Intelligence on the Latest Malware and Phishing Attacks with ANY.RUN TI Lookup -> Try for free



Source link