CoolFace
Apppublic

Talal190x/MalwareScannerTalalAli

sourceHugging Faceupdated 10mo agoView on Hugging Face
1likes
app.py115 linesDownload Raw Back to root
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)