fix go bin analysis

This commit is contained in:
carved4
2025-08-07 11:07:26 -07:00
parent 2bf6eb3c49
commit 17e923a880
4 changed files with 195 additions and 52 deletions
+72 -28
View File
@@ -53,7 +53,8 @@ document.addEventListener('DOMContentLoaded', function() {
suspiciousImports: document.getElementById('suspiciousImports'),
suspiciousImportsList: document.getElementById('suspiciousImportsList'),
suspiciousImportsCount: document.getElementById('suspiciousImportsCount'),
suspiciousImportsSummary: document.getElementById('suspiciousImportsSummary')
suspiciousImportsSummary: document.getElementById('suspiciousImportsSummary'),
suspiciousImportsTitle: document.getElementById('suspiciousImportsTitle')
};
@@ -258,31 +259,59 @@ document.addEventListener('DOMContentLoaded', function() {
// Handle suspicious imports
if (pe.suspicious_imports && pe.suspicious_imports.length > 0) {
elements.suspiciousImports.classList.remove('hidden');
elements.suspiciousImportsCount.textContent = `${pe.suspicious_imports.length} Found`;
elements.suspiciousImportsList.innerHTML = pe.suspicious_imports.map(imp => `
<div class="border-b border-gray-800 last:border-b-0 pb-3">
<div class="flex items-center justify-between mb-2">
<div class="flex items-center space-x-2">
<span class="text-red-500 font-mono">${imp.dll}</span>
<span class="text-gray-400">→</span>
<span class="text-gray-300 font-mono">${imp.function}</span>
<span class="ml-2 px-2 py-0.5 text-xs bg-red-500/20 text-red-400 rounded-full">[${imp.category || 'Unknown'}]</span>
// Check if it's a Go binary
const isGoBinary = pe.is_go_binary || false;
// Update title and count with appropriate styling
if (isGoBinary) {
elements.suspiciousImportsTitle.textContent = 'API Imports Analysis (Go Runtime)';
elements.suspiciousImportsCount.className = 'px-3 py-1 text-sm bg-blue-500/10 text-blue-400 rounded-full';
elements.suspiciousImportsCount.textContent = `${pe.suspicious_imports.length} Found (Go Runtime)`;
} else {
elements.suspiciousImportsTitle.textContent = 'Suspicious Imports Analysis';
elements.suspiciousImportsCount.className = 'px-3 py-1 text-sm bg-red-500/10 text-red-500 rounded-full';
elements.suspiciousImportsCount.textContent = `${pe.suspicious_imports.length} Found`;
}
elements.suspiciousImportsList.innerHTML = pe.suspicious_imports.map(imp => {
// Use different colors for Go runtime imports
const dllColor = isGoBinary ? 'text-blue-400' : 'text-red-500';
const categoryBg = isGoBinary ? 'bg-blue-500/20' : 'bg-red-500/20';
const categoryText = isGoBinary ? 'text-blue-400' : 'text-red-400';
const borderColor = isGoBinary ? 'border-blue-900/20' : 'border-red-900/20';
return `
<div class="border-b border-gray-800 last:border-b-0 pb-3">
<div class="flex items-center justify-between mb-2">
<div class="flex items-center space-x-2">
<span class="${dllColor} font-mono">${imp.dll}</span>
<span class="text-gray-400">→</span>
<span class="text-gray-300 font-mono">${imp.function}</span>
<span class="ml-2 px-2 py-0.5 text-xs ${categoryBg} ${categoryText} rounded-full">[${imp.category || 'Unknown'}]</span>
${isGoBinary ? '<span class="ml-2 px-2 py-0.5 text-xs bg-gray-500/20 text-gray-400 rounded-full">Go Runtime</span>' : ''}
</div>
${imp.hint !== null && imp.hint !== undefined ? `<span class="text-xs text-gray-500">Hint: ${imp.hint}</span>` : ''}
</div>
<div class="flex items-center space-x-2">
<svg class="w-4 h-4 text-yellow-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
</svg>
<span class="text-sm text-gray-400">${imp.note}</span>
</div>
<span class="text-xs text-gray-500">Hint: ${imp.hint}</span>
</div>
<div class="flex items-center space-x-2">
<svg class="w-4 h-4 text-yellow-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
</svg>
<span class="text-sm text-gray-400">${imp.note}</span>
</div>
</div>
`).join('');
`;
}).join('');
elements.suspiciousImportsSummary.textContent =
`Found ${pe.suspicious_imports.length} potentially suspicious imports that may indicate malicious capabilities.`;
// Update summary message based on Go binary detection
if (isGoBinary) {
elements.suspiciousImportsSummary.textContent =
`Go binary detected: ${pe.suspicious_imports.length} imports found are typically part of Go runtime and are not necessarily malicious.`;
} else {
elements.suspiciousImportsSummary.textContent =
`Found ${pe.suspicious_imports.length} potentially suspicious imports that may indicate malicious capabilities.`;
}
}
// Add checksum info display
@@ -292,20 +321,35 @@ document.addEventListener('DOMContentLoaded', function() {
elements.calculatedChecksum.textContent = pe.checksum_info.calculated_checksum;
// Set checksum status
elements.checksumStatus.className = `px-3 py-1 text-sm rounded-full ${
pe.checksum_info.is_valid ? 'bg-green-500/10 text-green-500' : 'bg-red-500/10 text-red-500'
}`;
elements.checksumStatus.textContent = pe.checksum_info.is_valid ? 'Valid' : 'Invalid';
const isGoBinary = pe.checksum_info.is_go_binary || false;
const isValid = pe.checksum_info.is_valid;
if (isValid) {
elements.checksumStatus.className = 'px-3 py-1 text-sm rounded-full bg-green-500/10 text-green-500';
elements.checksumStatus.textContent = 'Valid';
} else if (isGoBinary) {
elements.checksumStatus.className = 'px-3 py-1 text-sm rounded-full bg-blue-500/10 text-blue-400';
elements.checksumStatus.textContent = 'Go Binary';
} else {
elements.checksumStatus.className = 'px-3 py-1 text-sm rounded-full bg-red-500/10 text-red-500';
elements.checksumStatus.textContent = 'Invalid';
}
// Add checksum notes if needed
if (!pe.checksum_info.is_valid) {
const isGoBinary = pe.checksum_info.is_go_binary || false;
const noteText = isGoBinary
? 'Go binaries typically have non-standard PE checksums - This is normal behavior'
: 'Invalid checksum - Common in packed/modified payloads';
const iconColor = isGoBinary ? 'text-blue-500' : 'text-yellow-500';
elements.checksumNotes.innerHTML = `
<div class="flex items-center space-x-2">
<svg class="w-4 h-4 text-yellow-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg class="w-4 h-4 ${iconColor}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
</svg>
<span>Invalid checksum - Common in packed/modified payloads</span>
<span>${noteText}</span>
</div>
`;
}
+59 -11
View File
@@ -193,6 +193,22 @@
{% if file_info.pe_info.checksum_info and not file_info.pe_info.checksum_info.is_valid %}
<!-- Checksum Details -->
{% if file_info.pe_info.checksum_info.is_go_binary %}
<div class="bg-blue-500/10 p-4 rounded-lg border border-blue-900/20 mb-6">
<h3 class="text-sm font-medium text-blue-400 mb-2">Go Binary Checksum</h3>
<p class="text-sm text-gray-400 mb-3">Go binaries typically have non-standard PE checksums - This is normal behavior</p>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<p class="text-sm text-gray-400">Stored Checksum</p>
<p class="text-gray-200 font-mono">{{ file_info.pe_info.checksum_info.stored_checksum }}</p>
</div>
<div>
<p class="text-sm text-gray-400">Calculated Checksum</p>
<p class="text-gray-200 font-mono">{{ file_info.pe_info.checksum_info.calculated_checksum }}</p>
</div>
</div>
</div>
{% else %}
<div class="bg-yellow-500/10 p-4 rounded-lg border border-yellow-900/20 mb-6">
<h3 class="text-sm font-medium text-yellow-400 mb-2">Checksum Mismatch</h3>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
@@ -207,6 +223,7 @@
</div>
</div>
{% endif %}
{% endif %}
<!-- PE Sections -->
<div class="mb-6">
@@ -249,24 +266,55 @@
</div>
</div>
<!-- Suspicious Imports -->
<!-- Suspicious Imports -->
{% if file_info.pe_info.suspicious_imports %}
<div>
<h3 class="text-sm font-medium text-gray-400 mb-3">Suspicious Imports</h3>
{% if file_info.pe_info.is_go_binary %}
<h3 class="text-sm font-medium text-gray-400 mb-3">API Imports (Go Runtime)</h3>
<div class="mb-3 p-3 bg-blue-500/10 rounded-lg border border-blue-900/20">
<div class="flex items-center space-x-2">
<svg class="w-4 h-4 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<span class="text-sm text-blue-300 font-medium">Go Binary Detected</span>
</div>
<p class="text-sm text-gray-400 mt-1 ml-6">
These imports are typically part of the Go runtime and are not necessarily malicious.
Go binaries automatically include these system calls for memory management, threading, and OS interaction.
</p>
</div>
{% else %}
<h3 class="text-sm font-medium text-gray-400 mb-3">Suspicious Imports</h3>
{% endif %}
<div class="space-y-4">
{% for dll, imports in file_info.pe_info.grouped_suspicious_imports.items() %}
<div class="bg-red-500/10 p-4 rounded-lg border border-red-900/20">
<h4 class="text-red-400 font-mono mb-2">{{ dll }}</h4>
<div class="space-y-2">
{% for import in imports %}
<div class="pl-4 border-l-2 border-red-900/20">
<p class="text-gray-300 font-mono">{{ import.function }} <span class="text-red-300">[{{ import.category }}]</span></p>
<p class="text-sm text-gray-400 mt-1">{{ import.note }}</p>
{% if file_info.pe_info.is_go_binary %}
<div class="bg-blue-500/10 p-4 rounded-lg border border-blue-900/20">
<h4 class="text-blue-400 font-mono mb-2">{{ dll }} <span class="ml-2 px-2 py-0.5 text-xs bg-gray-500/20 text-gray-400 rounded-full">Go Runtime</span></h4>
<div class="space-y-2">
{% for import in imports %}
<div class="pl-4 border-l-2 border-blue-900/20">
<p class="text-gray-300 font-mono">{{ import.function }} <span class="text-blue-300">[{{ import.category }}]</span></p>
<p class="text-sm text-gray-400 mt-1">{{ import.note }}</p>
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</div>
{% else %}
<div class="bg-red-500/10 p-4 rounded-lg border border-red-900/20">
<h4 class="text-red-400 font-mono mb-2">{{ dll }}</h4>
<div class="space-y-2">
{% for import in imports %}
<div class="pl-4 border-l-2 border-red-900/20">
<p class="text-gray-300 font-mono">{{ import.function }} <span class="text-red-300">[{{ import.category }}]</span></p>
<p class="text-sm text-gray-400 mt-1">{{ import.note }}</p>
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
+1 -1
View File
@@ -359,7 +359,7 @@
<!-- Suspicious Imports Analysis -->
<div id="suspiciousImports" class="bg-gray-900/30 rounded-lg p-4 mb-4 hidden">
<div class="flex items-center justify-between mb-4">
<span class="text-base text-gray-300">Suspicious Imports Analysis</span>
<span id="suspiciousImportsTitle" class="text-base text-gray-300">Suspicious Imports Analysis</span>
<span id="suspiciousImportsCount" class="px-3 py-1 text-sm bg-red-500/10 text-red-500 rounded-full">
<!-- Count populated by JS -->
</span>
+63 -12
View File
@@ -203,12 +203,49 @@ class SecurityAnalyzer:
return dll_function_map
def _detect_go_binary(self, pe):
"""Detect if PE is a Go binary by looking for Go runtime indicators"""
try:
# Look for Go-specific strings in sections
go_indicators = [
b'runtime.',
b'go.runtime',
b'sync.',
b'go.sync',
b'go.string',
b'go.func',
b'go.buildid',
b'go.buildinfo',
b'runtime.main',
b'runtime.goexit',
b'runtime.newproc',
b'runtime.mallocgc'
]
for section in pe.sections:
section_data = section.get_data()
for indicator in go_indicators:
if indicator in section_data:
return True
# Also check for typical Go section names
go_sections = ['.go.buildinfo', '.go.plt']
for section in pe.sections:
section_name = section.Name.decode().rstrip('\x00')
if section_name in go_sections:
return True
return False
except Exception:
return False
def analyze_pe_imports(self, pe):
"""Analyze PE imports for suspicious behavior"""
suspicious_imports = []
is_go_binary = self._detect_go_binary(pe)
if not hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
return suspicious_imports
return suspicious_imports, is_go_binary
for entry in pe.DIRECTORY_ENTRY_IMPORT:
dll_name = entry.dll.decode().lower()
@@ -228,11 +265,12 @@ class SecurityAnalyzer:
'function': func_name,
'category': category,
'note': description,
'hint': imp.hint if hasattr(imp, 'hint') else 0
'hint': imp.ordinal if hasattr(imp, 'ordinal') else None,
'is_go_runtime': is_go_binary # Add flag for Go runtime imports
})
break
return suspicious_imports
return suspicious_imports, is_go_binary
def analyze_pe_sections(self, pe, entropy_calculator):
"""Analyze PE sections with entropy and detection notes"""
@@ -408,8 +446,10 @@ class RiskCalculator:
if pe_info.get('checksum_info'):
checksum = pe_info['checksum_info']
if checksum.get('stored_checksum') != checksum.get('calculated_checksum'):
pe_risk += 25
risk_factors.append("PE checksum mismatch detected")
# Don't penalize Go binaries for checksum mismatches as they commonly have zero checksums
if not checksum.get('is_go_binary', False):
pe_risk += 25
risk_factors.append("PE checksum mismatch detected")
return pe_risk, risk_factors
@@ -450,7 +490,7 @@ class Utils:
try:
pe = pefile.PE(filepath)
suspicious_imports = self.security_analyzer.analyze_pe_imports(pe)
suspicious_imports, is_go_binary = self.security_analyzer.analyze_pe_imports(pe)
sections_info = self.security_analyzer.analyze_pe_sections(pe, self.calculate_entropy)
# Check PE Checksum
@@ -475,12 +515,14 @@ class Utils:
'imports': list(set(entry.dll.decode() for entry in getattr(pe, 'DIRECTORY_ENTRY_IMPORT', []))),
'suspicious_imports': suspicious_imports,
'malware_categories': malware_categories,
'detection_notes': self._build_pe_detection_notes(is_valid_checksum, suspicious_imports, malware_categories, sections_info),
'detection_notes': self._build_pe_detection_notes(is_valid_checksum, suspicious_imports, malware_categories, sections_info, is_go_binary),
'is_go_binary': is_go_binary,
'checksum_info': {
'is_valid': is_valid_checksum,
'stored_checksum': hex(stored_checksum),
'calculated_checksum': hex(calculated_checksum),
'needs_update': calculated_checksum != stored_checksum
'needs_update': calculated_checksum != stored_checksum,
'is_go_binary': is_go_binary
}
}
@@ -490,18 +532,27 @@ class Utils:
print(f"Error analyzing PE file: {e}")
return {'pe_info': None}
def _build_pe_detection_notes(self, is_valid_checksum, suspicious_imports, malware_categories, sections_info):
def _build_pe_detection_notes(self, is_valid_checksum, suspicious_imports, malware_categories, sections_info, is_go_binary=False):
"""Build detection notes for PE analysis"""
detection_notes = []
if not is_valid_checksum:
detection_notes.append('Invalid PE checksum - Common in modified/packed files (~83% correlation with malware)')
if is_go_binary:
detection_notes.append('Go binary with non-standard PE checksum - This is normal for Go binaries')
else:
detection_notes.append('Invalid PE checksum - Common in modified/packed files (~83% correlation with malware)')
if suspicious_imports:
detection_notes.append(f'Found {len(suspicious_imports)} suspicious API imports - Review import analysis')
if is_go_binary:
detection_notes.append(f'Go binary detected: {len(suspicious_imports)} imports found are typically part of Go runtime - Not necessarily malicious')
else:
detection_notes.append(f'Found {len(suspicious_imports)} suspicious API imports - Review import analysis')
for category, count in malware_categories.items():
detection_notes.append(f'Found {count} suspicious imports in category "{category}"')
if is_go_binary:
detection_notes.append(f'Found {count} imports in category "{category}" (Go runtime related)')
else:
detection_notes.append(f'Found {count} suspicious imports in category "{category}"')
# Special detection notes for high-risk categories
high_risk_categories = {