analyze_pkgbuild_safety
Analyze PKGBUILD content for security risks like dangerous commands, obfuscated code, and suspicious patterns to audit AUR packages before installation.
Instructions
[SECURITY] Analyze PKGBUILD content for security issues and dangerous patterns. Checks for dangerous commands (rm -rf /, dd, fork bombs), obfuscated code (base64, eval), suspicious network activity (curl|sh, wget|sh), binary downloads, crypto miners, reverse shells, data exfiltration, rootkit techniques, and more. Returns risk score (0-100) and detailed findings. Use this tool to manually audit AUR packages before installation.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| pkgbuild_content | Yes | Raw PKGBUILD content to analyze |
Implementation Reference
- src/arch_ops_server/aur.py:919-1189 (handler)The main handler function implementing the tool logic. Performs static code analysis on PKGBUILD files to detect malicious patterns, obfuscation, reverse shells, miners, and other threats using regex patterns and scoring.def analyze_pkgbuild_safety(pkgbuild_content: str) -> Dict[str, Any]: """ Perform comprehensive safety analysis on PKGBUILD content. Checks for: - Dangerous commands (rm -rf /, dd, fork bombs, etc.) - Obfuscated code (base64, eval, encoding tricks) - Network activity (reverse shells, data exfiltration) - Binary downloads and execution - Privilege escalation attempts - Cryptocurrency mining patterns - Source URL validation - Suspicious file operations Args: pkgbuild_content: Raw PKGBUILD text Returns: Dict with detailed safety analysis results including: - safe: boolean - red_flags: critical security issues - warnings: suspicious patterns - info: informational notices - risk_score: 0-100 (higher = more dangerous) - recommendation: action recommendation """ import re from urllib.parse import urlparse red_flags = [] # Critical security issues warnings = [] # Suspicious but not necessarily malicious info = [] # Informational notices lines = pkgbuild_content.split('\n') logger.debug(f"Analyzing PKGBUILD with {len(lines)} lines") # ======================================================================== # CRITICAL PATTERNS - Definitely malicious # ======================================================================== dangerous_patterns = [ # Destructive commands (r"rm\s+-rf\s+/[^a-zA-Z]", "CRITICAL: rm -rf / or /something detected - system destruction"), (r"\bdd\b.*if=/dev/(zero|random|urandom).*of=/dev/sd", "CRITICAL: dd overwriting disk detected"), (r":\(\)\{.*:\|:.*\}", "CRITICAL: Fork bomb detected"), (r"\bmkfs\.", "CRITICAL: Filesystem formatting detected"), (r"fdisk.*-w", "CRITICAL: Partition table modification detected"), # Reverse shells and backdoors (r"/dev/tcp/\d+\.\d+\.\d+\.\d+/\d+", "CRITICAL: Reverse shell via /dev/tcp detected"), (r"nc\s+-[^-]*e\s+/bin/(ba)?sh", "CRITICAL: Netcat reverse shell detected"), (r"bash\s+-i\s+>&\s+/dev/tcp/", "CRITICAL: Interactive reverse shell detected"), (r"python.*socket.*connect", "CRITICAL: Python socket connection (potential backdoor)"), (r"perl.*socket.*connect", "CRITICAL: Perl socket connection (potential backdoor)"), # Malicious downloads and execution (r"curl[^|]*\|\s*(ba)?sh", "CRITICAL: Piping curl to shell (remote code execution)"), (r"wget[^|]*\|\s*(ba)?sh", "CRITICAL: Piping wget to shell (remote code execution)"), (r"curl.*-o.*&&.*chmod\s+\+x.*&&\s*\./", "CRITICAL: Download, make executable, and run pattern"), # Crypto mining patterns (r"xmrig|minerd|cpuminer|ccminer", "CRITICAL: Cryptocurrency miner detected"), (r"stratum\+tcp://", "CRITICAL: Mining pool connection detected"), (r"--donate-level", "CRITICAL: XMRig miner option detected"), # Rootkit/malware installation (r"chattr\s+\+i", "CRITICAL: Making files immutable (rootkit technique)"), (r"/etc/ld\.so\.preload", "CRITICAL: LD_PRELOAD manipulation (rootkit technique)"), (r"HISTFILE=/dev/null", "CRITICAL: History clearing (covering tracks)"), ] # ======================================================================== # SUSPICIOUS PATTERNS - Require careful review # ======================================================================== suspicious_patterns = [ # Obfuscation techniques (r"base64\s+-d", "Obfuscation: base64 decoding detected"), (r"xxd\s+-r", "Obfuscation: hex decoding detected"), (r"\beval\b", "Obfuscation: eval usage (can execute arbitrary code)"), (r"\$\(.*base64.*\)", "Obfuscation: base64 in command substitution"), (r"openssl\s+enc\s+-d", "Obfuscation: encrypted content decoding"), (r"echo.*\|.*sh", "Obfuscation: piping echo to shell"), (r"printf.*\|.*sh", "Obfuscation: piping printf to shell"), # Suspicious permissions and ownership (r"chmod\s+[0-7]*7[0-7]*7", "Dangerous: world-writable permissions"), (r"chown\s+root", "Suspicious: changing ownership to root"), (r"chmod\s+[u+]*s", "Suspicious: setuid/setgid (privilege escalation risk)"), # Suspicious file operations (r"mktemp.*&&.*chmod", "Suspicious: temp file creation with permission change"), (r">/dev/null\s+2>&1", "Suspicious: suppressing all output (hiding activity)"), (r"nohup.*&", "Suspicious: background process that persists"), # Network activity (r"curl.*-s.*-o", "Network: silent download detected"), (r"wget.*-q.*-O", "Network: quiet download detected"), (r"nc\s+-l", "Network: netcat listening mode (potential backdoor)"), (r"socat", "Network: socat usage (advanced networking tool)"), (r"ssh.*-R\s+\d+:", "Network: SSH reverse tunnel detected"), # Data exfiltration (r"curl.*-X\s+POST.*--data", "Data exfiltration: HTTP POST with data"), (r"tar.*\|.*ssh", "Data exfiltration: tar over SSH"), (r"scp.*-r.*\*", "Data exfiltration: recursive SCP"), # Systemd/init manipulation (r"systemctl.*enable.*\.service", "System: enabling systemd service"), (r"/etc/systemd/system/", "System: systemd unit file modification"), (r"update-rc\.d", "System: SysV init modification"), (r"@reboot", "System: cron job at reboot"), # Kernel module manipulation (r"modprobe", "System: kernel module loading"), (r"insmod", "System: kernel module insertion"), (r"/lib/modules/", "System: kernel module directory access"), # Compiler/build chain manipulation (r"gcc.*-fPIC.*-shared", "Build: creating shared library (could be malicious)"), (r"LD_PRELOAD=", "Build: LD_PRELOAD manipulation (function hijacking)"), ] # ======================================================================== # INFORMATIONAL PATTERNS - Good to know but not necessarily bad # ======================================================================== info_patterns = [ (r"sudo\s+", "Info: sudo usage detected"), (r"git\s+clone", "Info: git clone detected"), (r"make\s+install", "Info: make install detected"), (r"pip\s+install", "Info: pip install detected"), (r"npm\s+install", "Info: npm install detected"), (r"cargo\s+install", "Info: cargo install detected"), ] # ======================================================================== # SCAN PATTERNS LINE BY LINE # ======================================================================== for i, line in enumerate(lines, 1): # Skip comments and empty lines for pattern matching stripped_line = line.strip() if stripped_line.startswith('#') or not stripped_line: continue # Check dangerous patterns (red flags) for pattern, message in dangerous_patterns: if re.search(pattern, line, re.IGNORECASE): logger.warning(f"Red flag found at line {i}: {message}") red_flags.append({ "line": i, "content": line.strip()[:100], # Limit length for output "issue": message, "severity": "CRITICAL" }) # Check suspicious patterns for pattern, message in suspicious_patterns: if re.search(pattern, line, re.IGNORECASE): logger.info(f"Warning found at line {i}: {message}") warnings.append({ "line": i, "content": line.strip()[:100], "issue": message, "severity": "WARNING" }) # Check informational patterns for pattern, message in info_patterns: if re.search(pattern, line, re.IGNORECASE): info.append({ "line": i, "content": line.strip()[:100], "issue": message, "severity": "INFO" }) # ======================================================================== # ANALYZE SOURCE URLs # ======================================================================== source_urls = re.findall(r'source=\([^)]+\)|source_\w+=\([^)]+\)', pkgbuild_content, re.MULTILINE) suspicious_domains = [] # Known suspicious TLDs and patterns suspicious_tlds = ['.tk', '.ml', '.ga', '.cf', '.gq', '.cn', '.ru'] suspicious_url_patterns = [ (r'bit\.ly|tinyurl|shorturl', "URL shortener (hides true destination)"), (r'pastebin|hastebin|paste\.ee', "Paste site (common for malware hosting)"), (r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', "Raw IP address (suspicious)"), ] for source_block in source_urls: # Extract URLs from source array urls = re.findall(r'https?://[^\s\'"]+', source_block) for url in urls: try: parsed = urlparse(url) domain = parsed.netloc.lower() # Check for suspicious TLDs if any(domain.endswith(tld) for tld in suspicious_tlds): warnings.append({ "line": 0, "content": url, "issue": f"Suspicious domain TLD: {domain}", "severity": "WARNING" }) suspicious_domains.append(domain) # Check for suspicious URL patterns for pattern, message in suspicious_url_patterns: if re.search(pattern, url, re.IGNORECASE): warnings.append({ "line": 0, "content": url, "issue": message, "severity": "WARNING" }) except Exception as e: logger.debug(f"Failed to parse URL {url}: {e}") # ======================================================================== # DETECT BINARY DOWNLOADS # ======================================================================== binary_extensions = ['.bin', '.exe', '.AppImage', '.deb', '.rpm', '.jar', '.apk'] for ext in binary_extensions: if ext in pkgbuild_content.lower(): warnings.append({ "line": 0, "content": "", "issue": f"Binary file type detected: {ext}", "severity": "WARNING" }) # ======================================================================== # CALCULATE RISK SCORE # ======================================================================== # Risk scoring: red_flags = 50 points each, warnings = 5 points each, cap at 100 risk_score = min(100, (len(red_flags) * 50) + (len(warnings) * 5)) # ======================================================================== # GENERATE RECOMMENDATION # ======================================================================== if len(red_flags) > 0: recommendation = "❌ DANGEROUS - Critical security issues detected. DO NOT INSTALL." safe = False elif len(warnings) >= 5: recommendation = "⚠️ HIGH RISK - Multiple suspicious patterns detected. Review carefully before installing." safe = False elif len(warnings) > 0: recommendation = "⚠️ CAUTION - Some suspicious patterns detected. Manual review recommended." safe = True # Technically safe but needs review else: recommendation = "✅ SAFE - No critical issues detected. Standard review still recommended." safe = True logger.info(f"PKGBUILD analysis complete: {len(red_flags)} red flags, {len(warnings)} warnings, risk score: {risk_score}") return { "safe": safe, "red_flags": red_flags, "warnings": warnings, "info": info, "risk_score": risk_score, "suspicious_domains": list(set(suspicious_domains)), "recommendation": recommendation, "summary": { "total_red_flags": len(red_flags), "total_warnings": len(warnings), "total_info": len(info), "lines_analyzed": len(lines) } }
- MCP Tool schema definition including name, description, and input validation schema for the analyze_pkgbuild_safety tool.name="analyze_pkgbuild_safety", description="[SECURITY] Analyze PKGBUILD content for security issues and dangerous patterns. Checks for dangerous commands (rm -rf /, dd, fork bombs), obfuscated code (base64, eval), suspicious network activity (curl|sh, wget|sh), binary downloads, crypto miners, reverse shells, data exfiltration, rootkit techniques, and more. Returns risk score (0-100) and detailed findings. Use this tool to manually audit AUR packages before installation.", inputSchema={ "type": "object", "properties": { "pkgbuild_content": { "type": "string", "description": "Raw PKGBUILD content to analyze" } }, "required": ["pkgbuild_content"] } ),
- src/arch_ops_server/server.py:1209-1213 (registration)Tool execution handler in the MCP server's call_tool dispatcher that invokes the analyze_pkgbuild_safety function with user arguments and formats the JSON response.elif name == "analyze_pkgbuild_safety": pkgbuild_content = arguments["pkgbuild_content"] result = analyze_pkgbuild_safety(pkgbuild_content) return [TextContent(type="text", text=json.dumps(result, indent=2))]
- src/arch_ops_server/server.py:26-34 (registration)Import statement in server.py that brings the analyze_pkgbuild_safety handler into scope for MCP tool registration and execution.from . import ( # Wiki functions search_wiki, get_wiki_page_as_text, # AUR functions search_aur, get_aur_info, get_pkgbuild, analyze_pkgbuild_safety,
- Tool metadata providing categorization, platform compatibility, permissions, workflow context, and related tools for analyze_pkgbuild_safety."analyze_pkgbuild_safety": ToolMetadata( name="analyze_pkgbuild_safety", category="security", platform="any", permission="read", workflow="audit", related_tools=["analyze_package_metadata_risk", "install_package_secure"], prerequisite_tools=[] ),