7.9 KiB
🛡️ Ghaymah CLI v2 — Attacker-Accessible Surface & Binary Hardening Audit
Target Artifact:
gy-linux-amd64(Production Release Candidate)
Source:https://cliv2.ghaymah.systems/gy-linux-amd64
Auditor: DevSecOps QA & Threat Modeling Assessment
Date: September 20, 2026
Focus: 100% Verifiable, Extracted Artifacts Available to an External Attacker
📊 Executive Summary Checklist
| Hardening Directive | Compiler/Tool Flag | Required State | Actual State | Attacker Accessibility | Status |
|---|---|---|---|---|---|
| Symbol Stripping | -ldflags="-s" |
No .symtab / .strtab |
Absent | Inaccessible (Symbols removed) | ✅ PASS |
| Debug Info Stripping | -ldflags="-w" |
No DWARF .debug_* sections |
Absent | Inaccessible (DWARF removed) | ✅ PASS |
| Path Obfuscation | -trimpath |
Zero developer machine paths | Zero leaks | Inaccessible (No /home/ or C:\Users\) |
✅ PASS |
| Binary Compression | upx --best --lzma |
Packed (UPX0, UPX1, UPX!) |
Uncompressed (11.69 MB) | 🔴 EXPOSED (Plaintext strings in .rodata) |
❌ FAIL |
| Token Storage | Local Encryption | AES-GCM Encrypted | Plaintext JSON | 🔴 EXPOSED (Accessible via config.json) |
❌ FAIL |
| TLS Pinset Integrity | Hardcoded SHA-256 | 4 Valid Base64 Hashes | 4 Hashes in binary | 🟡 VISIBLE (Extracted via strings) | ✅ PASS |
🏗️ Reconstructed Attack Topology (Extracted via Static Analysis)
Using only data extracted from the uncompressed gy-linux-amd64 binary and local filesystem artifacts, an attacker can reconstruct the complete backend microservice topology without access to source code:
graph TD
subgraph "Attacker-Controlled Local Host"
ATTACKER["Attacker / Local Process"]
BINARY["gy-linux-amd64<br>(11.69 MB Unpacked ELF)"]
CONF["~/.config/ghaymah/cli/nhost/config.json<br>🔴 Plaintext Tokens Stored Here"]
end
subgraph "Exposed Backend Endpoints (Extracted from .rodata)"
AUTH["auth.ghaymah.systems<br>(Nhost Authentication API)"]
GQL["graphql.ghaymah.systems<br>(Hasura GraphQL API)"]
S3["s3-nhost-proxy-83e02743fd61.hosted.ghaymah.systems<br>🔴 Exposed Object Storage Proxy"]
LOGS["logs.ghaymah.systems<br>(Log Streaming Server)"]
GENAI["genai.ghaymah.systems<br>(LiteLLM AI Service)"]
REG["registry.ghaymah.systems<br>(Container Registry)"]
CLI_SRV["cli.ghaymah.systems / cliv2.ghaymah.systems<br>(Update & Distribution Host)"]
end
ATTACKER -- "1. Read plaintext refreshToken" --> CONF
ATTACKER -- "2. Extract strings & endpoints" --> BINARY
ATTACKER -- "3. Direct API calls using stolen token" --> AUTH
ATTACKER -- "4. Direct GraphQL queries/mutations" --> GQL
ATTACKER -- "5. Direct artifact upload / probing" --> S3
ATTACKER -- "6. Inspect container images" --> REG
🕵️♂️ Extracted Artifacts & Attacker-Accessible Surface
The data below represents only what an attacker can directly extract from the binary and local configuration using standard analysis tools (strings, grep, cat):
1. Extracted Backend Endpoints & Domains (.rodata)
These URLs were extracted directly from the uncompressed data segments of gy-linux-amd64:
auth.ghaymah.systems
graphql.ghaymah.systems
logs.ghaymah.systems
genai.ghaymah.systems
registry.ghaymah.systems
cli.ghaymah.systems
s3-nhost-proxy-83e02743fd61.hosted.ghaymah.systems
foundhosted.ghaymah.systems
Caution
Attacker Advantage: The specific S3 proxy subdomain (
s3-nhost-proxy-83e02743fd61.hosted.ghaymah.systems) reveals the exact storage gateway used for project build context uploads, allowing an attacker to probe the storage service directly without using the CLI.
2. Extracted Internal Go Packages & Architecture (.gopclntab)
Even with -s -w applied, Go's runtime program counter line table retains package import paths. An attacker extracts:
gitlab.com/ghaymah/go-utils
gitlab.com/ghaymah/go-utils/config
gitlab.com/ghaymah/go-utils/nhost
gitlab.com/ghaymah/go-utils/graphql
Note
This reveals that Ghaymah CLI v2 is architected around
go-utilswith dedicated Nhost auth and Hasura GraphQL client modules.
3. Extracted TLS Public Key Pinset Hashes
The 4 SHA-256 certificate public key hashes are visible in cleartext in the binary:
deRrEjh64wYgxRJ15ayqnD8aBMGHkjGDhegIOZzN3iw=
Jmmi4aU72CahnGAT6ZT6yvWeSv1g1lhahkiK5RDipn8=
T/t6LfgixGVf2RPIMpusT0c7memko1cGuHVTMRRyTqY=
zSJTbrWU36arxt/HzAm7GrMc5op3vsJkUlBDxj4jLHI=
4. Extracted Security Rules & Error Messages
By analyzing string literals, an attacker can reverse-engineer input validation and scanner logic without reading source code:
# Input Validation Rule Leakage:
"invalid app name '%s' — use only letters, numbers, and hyphens (no spaces or slashes)"
# Proxy Detection Leakage:
"Security Warning: A system proxy (%s) was detected. It will be ignored for authentication to prevent credential interception."
# Pre-Deploy Scanner Leakage:
"Wildcard COPY/ADD Detected — Sensitive File Leakage Risk"
"Container Runs as Root User"
"Lines [%s] use wildcard copy instructions (COPY . / or ADD . /) which will include ALL files"
"TLS Pinning failed: public key mismatch. Got %s, which is not in the trusted pinset"
5. Extracted Plaintext Credentials (CWE-312)
Directly extracted from ~/.config/ghaymah/cli/nhost/config.json on the local machine:
{
"token": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODk5NDk4NzQsImh0dHBzOi8vaGFzdXJhLmlvL2p3dC9jbGFpbXMiOnsieC1oYXN1cmEtYWxsb3dlZC1yb2xlcyI6WyJtZSIsInVzZXIiXSwieC1oYXN1cmEtZGVmYXVsdC1yb2xlIjoidXNlciIsIngtaGFzdXJhLXVzZXItaWQiOiJkNjJmOTg4Ni1mY2VkLTRjZjItOThlNC01YjYyMDAwZDRmMDMiLCJ4LWhhc3VyYS11c2VyLWlzLWFub255bW91cyI6ImZhbHNlIn0sImlhdCI6MTc4OTg1OTg3NCwiaXNzIjoiaGFzdXJhLWF1dGgiLCJzdWIiOiJkNjJmOTg4Ni1mY2VkLTRjZjItOThlNC01YjYyMDAwZDRmMDMifQ...",
"refreshToken": "11a90303-237e-467b-b324-54d6ef6e5cf5",
"expiresAt": "2026-09-21T00:17:53.875260112Z",
"userId": "d62f9886-fced-4cf2-98e4-5b62000d4f03"
}
}
Caution
Critical Finding: An attacker who accesses this file gains full, perpetual access to the user's Ghaymah cloud account via the
refreshToken, completely bypassing the CLI.
🛡️ What the Attacker CANNOT Access (Verified Defenses)
Despite the string leaks, the following security barriers were successfully verified:
- No Developer Machine Paths: Searching for
C:\Users\,/home/, or/Users/yielded 0 matches. The-trimpathflag completely stripped build environment paths. - No High-Level Source Code / Comments: Symbol stripping (
-s -w) removed all.symtab,.strtab, and DWARF debugging data. The attacker cannot reconstruct the original Go source code or variable names. - No Credential Interception via Proxy: Setting
HTTP_PROXYorHTTPS_PROXYfails to capture traffic because the binary explicitly ignores proxies for authentication. - No Direct Injection via CLI Flags: Attempts to pass SQLi, XSS, or Path Traversal in
--nameor--idare blocked locally by regex before any network request is sent.
📋 Remediation Priority Checklist
| Priority | Issue | Threat Vector | Fix Action |
|---|---|---|---|
| 🔴 P0 | Plaintext Tokens (CWE-312) | Local account takeover via config.json |
Encrypt config.json with AES-256-GCM using Machine ID salt. |
| 🟡 P1 | Uncompressed Binary (CWE-200) | Trivial endpoint & architecture extraction | Apply upx --best --lzma to scramble string data and reduce size by ~70%. |
| 🟢 P2 | Internal Package Names | Reconnaissance via .gopclntab |
Use Go build obfuscators (e.g., garble) if full symbol obfuscation is required. |