| import gradio as gr |
| import json |
| import re |
| import tempfile |
| from fpdf import FPDF |
| import os |
|
|
| |
| |
| |
| BASE_TEMPLATE = r"""================================================================================ |
| MALWARE REPORT |
| ================================================================================ |
| Case ID: 260422-DCVWJSFY9P |
| Target Hash (SHA256): 68495981b876b564a856432b021748cea37c6632041a7cf3fe07b07dab84a19a |
| Classification: InfoStealer & Crypto-Clipper (HijackLoader Variant) |
| Malware Family: Vidar / Rhadamanthys / Trojan.AIChatInfoStealer |
| Status: CRITICAL |
| ================================================================================ |
| |
| 1. ANALYSIS CONTEXT & SANDBOX LINKS |
| -------------------------------------- |
| - VirusTotal Interactive Graph: |
| https://www.virustotal.com/graph/embed/gbf22a4e78c614368b3301df758c49a936c2fb87376184055a821ceb018b25353?theme=dark |
| |
| - Triage Behavioral Analysis: |
| https://tria.ge/260422-dcvwjsfy9p/behavioral1 |
| |
| 2. SYSTEM EXECUTION FLOW |
| ---------------------------------------------- |
| The infection initiates via "Download_Ready_928077.exe" (SHA256: 68495981...). |
| It acts as a HijackLoader, staging the Vidar/Rhadamanthys stealer modules. |
| |
| Observed Process Chain: |
| [PID 1124] Download_Ready_928077.exe (Initial Loader / PPID 56) |
| └── [PID 3680] fastfetch.exe (Secondary Payload / SHA256: f7bbd7eb...) |
| ├── [PID 5928] child_proc (System Discovery) |
| └── [PID 2548] child_proc (File System Persistence) |
| |
| Injected/Hollowed Target: |
| [PID 4684] msedge.exe (Injected with Rhadamanthys credential harvesting logic) |
| |
| 3. TECHNICAL FORENSIC MARKERS |
| ---------------------------------------------- |
| Anti-Analysis & Evasion: |
| - Registry Polling: Queries "RaiseExceptionOnPossibleDeadlock" and "Segment Heap" |
| to detect debugger environments and sandbox instrumentation. |
| - Geofencing: Queries "HKLM\SYSTEM\ControlSet001\Control\NLS\Language" |
| to ensure the target host is outside prohibited geographical regions (CIS). |
| |
| Persistence Mechanisms: |
| - Registry Modification: Modifications detected in |
| "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.exe" |
| to ensure the malicious loader executes upon any binary launch. |
| - Fake Artifact Staging: Creates a complex directory structure in |
| "C:\Users\Admin\Downloads\fastfetch-windows-amd64-2.51.1\" |
| masking malicious DLLs (OpenCL.dll / SHA256: aa8b311c...) as system files. |
| |
| 4. MEMORY FORENSICS: CLIPPER MODULE |
| ---------------------------------------------- |
| Live memory analysis of fastfetch.exe (PID 3680) and msedge.exe (PID 4684) |
| confirms active clipboard monitoring. |
| |
| [+] ATTACKER-CONTROLLED WALLETS (Substituted in real-time): |
| - Bitcoin (Legacy): 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa |
| Link: https://blockchair.com/bitcoin/address/1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa |
| |
| - Bitcoin (SegWit): 3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy |
| Link: https://blockchair.com/bitcoin/address/3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy |
| |
| - Ethereum / BSC: 0x71C7656EC7ab88b098defB751B7401B5f6d8976F |
| Link: https://etherscan.io/address/0x71C7656EC7ab88b098defB751B7401B5f6d8976F |
| |
| 5. AUTOMATED DATA EXTRACTION & ENRICHMENT |
| ------------------------------------------- |
| """ |
|
|
| |
| |
| |
|
|
| def parse_vt_graph_json(filepath): |
| try: |
| with open(filepath, 'r', encoding='utf-8') as f: |
| data = json.load(f) |
| mal_f, c2_d, mal_i, clusters = [], [], [], [] |
| for node in data.get('nodes', []): |
| attrs = node.get('entity_attributes', {}) |
| n_type, eid = node.get('type'), node.get('entity_id') |
| if n_type == 'collection': |
| text = node.get('text', '').strip() |
| if text: clusters.append(text) |
| if not attrs.get('has_detections', False): continue |
| if n_type == 'file': mal_f.append(f"{eid} [{attrs.get('type_tag', 'unknown').upper()}]") |
| elif n_type == 'domain': c2_d.append(eid) |
| elif n_type == 'ip_address': mal_i.append(f"{eid} [{attrs.get('country', 'Unknown')}]") |
| |
| output = ["\n[+] VIRUSTOTAL INTELLIGENCE MAPPING"] |
| if clusters: |
| output.append("Family Clusters: " + ", ".join(list(set(clusters)))) |
| output.append("\n[+] MALICIOUS FILE PAYLOADS (SHA256)") |
| for f in list(set(mal_f))[:25]: output.append(f" - {f}") |
| output.append("\n[+] NETWORK COMMAND & CONTROL (C2)") |
| for d in list(set(c2_d))[:15]: output.append(f" - https://{d}") |
| for i in list(set(mal_i))[:10]: output.append(f" - {i}") |
| return "\n".join(output) + "\n" |
| except Exception as e: return f"\n[!] JSON Parsing Error: {str(e)}\n" |
|
|
| def parse_triage_pcap(filepath): |
| try: |
| with open(filepath, 'rb') as f: |
| content = f.read().decode('latin-1', errors='ignore') |
| dom_p = re.compile(r'\b(?:[a-z0-9][a-z0-9-]{3,61}\.)+(?:com|net|org|ru|top|xyz|cc|click|cfd|app|eu|info|biz|live|asia|run|gg|cc|tk|st)\b', re.IGNORECASE) |
| http_p = re.compile(r'(GET|POST)\s+(/[a-zA-Z0-9_.-]+[^\s]*)') |
| |
| noise = ['microsoft', 'windows', 'digicert', 'google', 'cloudflare', 'azure', 'xml', 'schema', 'bing', 'msn', 'edge'] |
| valid_doms = [d for d in list(set(dom_p.findall(content))) if not any(n in d.lower() for n in noise) and len(d) > 8] |
| |
| output = ["\n[+] TRIAGE TRAFFIC ANALYSIS"] |
| output.append("\nIdentified Active C2 Domains:") |
| for d in valid_doms[:15]: output.append(f" - https://{d}") |
| output.append("\nObserved Resource Requests:") |
| for m, u in list(set(http_p.findall(content)))[:10]: output.append(f" - {m} {u[:50]}...") |
| output.append("\n" + "="*80 + "\nEND OF REPORT\n" + "="*80) |
| return "\n".join(output) |
| except Exception as e: return f"\n[!] PCAP Parsing Error: {str(e)}\n" |
|
|
| |
| |
| |
|
|
| class DarkPDF(FPDF): |
| def header(self): |
| self.set_fill_color(0, 0, 0) |
| self.rect(0, 0, 210, 297, 'F') |
| self.set_font('Helvetica', 'B', 15) |
| self.set_text_color(255, 255, 255) |
| self.cell(0, 10, 'MALWARE ANALYSIS', ln=True, align='L') |
| self.set_draw_color(0, 174, 239) |
| self.line(10, 18, 200, 18) |
| self.ln(10) |
|
|
| def create_pdf(text): |
| pdf = DarkPDF() |
| pdf.add_page() |
| pdf.set_auto_page_break(auto=True, margin=15) |
| url_pattern = r'(https?://[^\s]+)' |
| for line in text.split('\n'): |
| if not line.strip() and not line == '': |
| pdf.ln(2) |
| continue |
| pdf.set_text_color(255, 255, 255) |
| pdf.set_font('Helvetica', '', 10) |
| if line.startswith('===='): |
| pdf.set_font('Helvetica', 'B', 12) |
| pdf.set_text_color(0, 174, 239) |
| elif re.match(r'^\d\.', line): |
| pdf.set_font('Helvetica', 'B', 11) |
| pdf.set_text_color(0, 174, 239) |
| elif '[+]' in line: |
| pdf.set_text_color(180, 180, 180) |
| pdf.set_font('Helvetica', 'B', 10) |
| parts = re.split(url_pattern, line) |
| for part in parts: |
| if re.match(url_pattern, part): |
| pdf.set_text_color(0, 174, 239) |
| pdf.set_font('Helvetica', 'U', 10) |
| pdf.write(7, part, link=part.strip().rstrip('.,[]() ')) |
| else: |
| pdf.set_font('Helvetica', '', 10) |
| pdf.write(7, part.encode('latin-1', 'replace').decode('latin-1')) |
| pdf.ln(6) |
| temp_path = os.path.join(tempfile.gettempdir(), "MALWARE_REPORT.pdf") |
| pdf.output(temp_path) |
| return temp_path |
|
|
| |
| |
| |
|
|
| def run_forensics(vt, pcap): |
| report = BASE_TEMPLATE |
| if vt: report += parse_vt_graph_json(vt) |
| if pcap: report += parse_triage_pcap(pcap) |
| else: report += "\n" + "="*80 + "\nEND OF REPORT\n" + "="*80 |
| pdf_file = create_pdf(report) |
| return report, pdf_file |
|
|
| with gr.Blocks(title="Malware Report Pro") as demo: |
| gr.Markdown("# 🛡️ Professional Malware Report Generator") |
| with gr.Row(): |
| with gr.Column(): |
| vt = gr.File(label="VirusTotal Graph JSON") |
| pcap = gr.File(label="Triage PCAP") |
| run_btn = gr.Button("Generate Report", variant="primary") |
| with gr.Column(): |
| pdf_dn = gr.File(label="Download PDF Report") |
| preview = gr.Textbox(label="Report Text View", lines=25, interactive=False) |
| run_btn.click(run_forensics, [vt, pcap], [preview, pdf_dn]) |
|
|
| if __name__ == "__main__": |
| demo.launch() |