Talal190x/MalwareScannerTalalAli
1
1import os, time, json, requests, pathlib2import gradio as gr3from datetime import datetime4 5 6GREEN = "#22c55e"7CSS = f"""8<style>9html, body, #root, .gradio-container {{ background:#ffffff !important; }}10.h-title {{ text-align:center; font-weight:800; font-size:26px; color:{GREEN}; margin: 6px 0 14px; }}11.greenbox textarea, .greenbox input {{ background:{GREEN} !important; color:#ffffff !important; border-radius:10px !important; }}12.greenbox .wrap {{ background:{GREEN} !important; color:#ffffff !important; border-radius:10px !important; }}13.greenbox *::placeholder {{ color:#ffffff !important; opacity:0.8; }}14#upload_box {{ background:{GREEN} !important; color:#ffffff !important; border-radius:10px !important; border:none !important; }}15#upload_box * {{ color:#ffffff !important; }}16#upload_json pre, #upload_json code, #result_json pre, #result_json code {{17 background:{GREEN} !important; color:#ffffff !important; border-radius:10px !important;18}}19#scan_btn {{ background:{GREEN} !important; color:#ffffff !important; border-radius:10px !important; font-weight:700 !important; }}20label {{ color:#000 !important; font-weight:600; }}21</style>22"""23 24VT_KEY = "0d73c487e0260520bfa6124c411f4f5579612ca06e9a4524a2cc01325deb208e" 25HEADERS = {"x-apikey": VT_KEY}26DIRECT_LIMIT = 32 * 1024 * 1024 27 28def _upload_file(path: str):29 size = pathlib.Path(path).stat().st_size30 if size <= DIRECT_LIMIT:31 url = "https://www.virustotal.com/api/v3/files"32 else:33 up = requests.get("https://www.virustotal.com/api/v3/files/upload_url", headers=HEADERS, timeout=60)34 up.raise_for_status()35 url = up.json()["data"]36 with open(path, "rb") as f:37 r = requests.post(url, headers=HEADERS, files={"file": (pathlib.Path(path).name, f)}, timeout=600)38 r.raise_for_status()39 return r.json()40 41def _submit_url(u: str):42 r = requests.post("https://www.virustotal.com/api/v3/urls", headers=HEADERS, data={"url": u}, timeout=60)43 r.raise_for_status()44 return r.json()45 46def _wait_analysis(analysis_id: str, max_wait: int = 180):47 url = f"https://www.virustotal.com/api/v3/analyses/{analysis_id}"48 t0 = time.time()49 while True:50 r = requests.get(url, headers=HEADERS, timeout=60)51 r.raise_for_status()52 js = r.json()53 status = js.get("data", {}).get("attributes", {}).get("status")54 if status == "completed":55 return js56 if time.time() - t0 > max_wait:57 return js58 time.sleep(3)59 60def vt_scan(file, url_text):61 if not VT_KEY:62 return "NO KEY", "Set VT_API_KEY first.", "{}", "{}"63 64 if file is not None:65 target = getattr(file, "name", "file")66 up = _upload_file(file.name)67 elif url_text and url_text.strip():68 target = url_text.strip()69 up = _submit_url(target)70 else:71 return "NO INPUT", "Please upload a file or enter a URL first.", "{}", "{}"72 73 analysis_id = up.get("data", {}).get("id") or up.get("data", {}).get("analysis_id")74 res = _wait_analysis(analysis_id)75 76 attrs = res.get("data", {}).get("attributes", {})77 stats = attrs.get("stats", {})78 malicious = int(stats.get("malicious", 0))79 suspicious = int(stats.get("suspicious", 0))80 undetected = int(stats.get("undetected", 0))81 harmless = int(stats.get("harmless", 0))82 timeout = int(stats.get("timeout", 0))83 failure = int(stats.get("failure", 0))84 total = malicious + suspicious + undetected + harmless + timeout + failure85 86 verdict = "MALWARE" if (malicious > 0 or suspicious > 0) else "GOODWARE"87 t = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")88 summary = (89 f"Target: {target}\n"90 f"Checked: {t}\n"91 f"Verdict: {verdict}\n"92 f"Engines -> total:{total} | malicious:{malicious} | suspicious:{suspicious} | "93 f"undetected:{undetected} | harmless:{harmless} | timeout:{timeout} | failure:{failure}\n"94 f"Analysis status: {attrs.get('status','unknown')}"95 )96 97 return verdict, summary, json.dumps(up, indent=2, ensure_ascii=False), json.dumps(res, indent=2, ensure_ascii=False)98 99with gr.Blocks(title="malware scanner", css=CSS) as app:100 gr.HTML("<div class='h-title'>malware scanner</div>")101 102 file_in = gr.File(label="Upload file (APK / any)", elem_id="upload_box")103 url_in = gr.Textbox(label="Scan URL (optional)", placeholder="https://example.com/app.apk",104 elem_classes=["greenbox"], lines=1)105 106 btn = gr.Button("Run Scan", elem_id="scan_btn")107 108 verdict = gr.Textbox(label="Verdict", interactive=False, lines=1, elem_classes=["greenbox"])109 summary = gr.Textbox(label="Summary", interactive=False, lines=6, elem_classes=["greenbox"])110 upload_json = gr.Code(label="Upload JSON", language="json", elem_id="upload_json")111 result_json = gr.Code(label="Result JSON", language="json", elem_id="result_json")112 113 btn.click(vt_scan, [file_in, url_in], [verdict, summary, upload_json, result_json])114 115app.launch(share=True)