ryrdd / app.py
wuhp's picture
Update app.py
95a1301 verified
import gradio as gr
import json
import re
import tempfile
from fpdf import FPDF
import os
# ==========================================
# 1. ENHANCED BASE TEMPLATE (Data-Driven)
# ==========================================
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
-------------------------------------------
"""
# ==========================================
# 2. UPDATED PARSING FUNCTIONS
# ==========================================
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"
# ==========================================
# 3. PREMIUM DARK-MODE PDF GENERATOR
# ==========================================
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
# ==========================================
# 4. GRADIO INTERFACE
# ==========================================
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()