Maximuz23 commited on
Commit
00fe043
Β·
verified Β·
1 Parent(s): 8510853
Files changed (1) hide show
  1. app.py +26 -4
app.py CHANGED
@@ -361,6 +361,23 @@ def enrich_ioc(ioc, ioc_type):
361
  f"Targeted countries: {', '.join(otx.get('countries', [])) or 'not specified'}")
362
 
363
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
364
  # --- bundled retrieval -----------------------------------------------------------
365
  IOC_RE = re.compile(r"hxxp|https?://|\b\d{1,3}\[?\.\]?\d{1,3}\[?\.\]?\d{1,3}\[?\.\]?\d{1,3}\b|\b[a-f0-9]{32,64}\b", re.I)
366
  ACTOR_KW = re.compile(r"\b(actor|group|apt|adversary|profile|who is|what did|techniques does|ttps|campaign)\b", re.I)
@@ -481,8 +498,7 @@ SUGGESTIONS = {
481
  "πŸ› οΈ Who uses Cobalt Strike?": "Which threat actors use the Cobalt Strike tool?",
482
  "πŸ“– Explain technique T1059.001": "Explain MITRE ATT&CK technique T1059.001",
483
  "πŸ”“ Assess CVE-2025-0282 (live)": "Assess CVE-2025-0282 for offensive relevance",
484
- "🌐 Look up a live IOC": ("Look up live threat intelligence for the indicator "
485
- "27.204.192.167 and assess its red team relevance."),
486
  }
487
 
488
  if "messages" not in st.session_state:
@@ -490,11 +506,17 @@ if "messages" not in st.session_state:
490
 
491
  clicked = None
492
  if not st.session_state.messages:
493
- st.markdown("##### Try one of these πŸ‘‡")
494
  cols = st.columns(2)
495
  for i, (label, text) in enumerate(SUGGESTIONS.items()):
496
  if cols[i % 2].button(label, use_container_width=True):
497
- clicked = text
 
 
 
 
 
 
498
 
499
  for msg in st.session_state.messages:
500
  with st.chat_message(msg["role"], avatar=ROBOT if msg["role"] == "assistant" else None):
 
361
  f"Targeted countries: {', '.join(otx.get('countries', [])) or 'not specified'}")
362
 
363
 
364
+ def recent_threatfox_ioc():
365
+ """A random *current* abuse.ch ThreatFox IP indicator, so the demo chip hits live data."""
366
+ key = _env(*ABUSE_KEYS)
367
+ if not key:
368
+ return None
369
+ body = json.dumps({"query": "get_iocs", "days": 1}).encode()
370
+ req = urllib.request.Request("https://threatfox-api.abuse.ch/api/v1/", data=body,
371
+ headers={"Auth-Key": key, "Content-Type": "application/json", "User-Agent": "TextScout-demo"})
372
+ d = json.loads(urllib.request.urlopen(req, timeout=15).read())
373
+ rows = d.get("data") if d.get("query_status") == "ok" else None
374
+ if not isinstance(rows, list) or not rows:
375
+ return None
376
+ import random
377
+ pool = [r for r in rows if r.get("ioc_type") == "ip:port"] or rows
378
+ return random.choice(pool).get("ioc", "").split(":")[0]
379
+
380
+
381
  # --- bundled retrieval -----------------------------------------------------------
382
  IOC_RE = re.compile(r"hxxp|https?://|\b\d{1,3}\[?\.\]?\d{1,3}\[?\.\]?\d{1,3}\[?\.\]?\d{1,3}\b|\b[a-f0-9]{32,64}\b", re.I)
383
  ACTOR_KW = re.compile(r"\b(actor|group|apt|adversary|profile|who is|what did|techniques does|ttps|campaign)\b", re.I)
 
498
  "πŸ› οΈ Who uses Cobalt Strike?": "Which threat actors use the Cobalt Strike tool?",
499
  "πŸ“– Explain technique T1059.001": "Explain MITRE ATT&CK technique T1059.001",
500
  "πŸ”“ Assess CVE-2025-0282 (live)": "Assess CVE-2025-0282 for offensive relevance",
501
+ "🌐 Look up a fresh live IOC": None, # None -> pull a current abuse.ch IOC at click time
 
502
  }
503
 
504
  if "messages" not in st.session_state:
 
506
 
507
  clicked = None
508
  if not st.session_state.messages:
509
+ st.markdown("##### Try one of these πŸ‘‡ Β· or type your own actor / CVE / IP / hash below")
510
  cols = st.columns(2)
511
  for i, (label, text) in enumerate(SUGGESTIONS.items()):
512
  if cols[i % 2].button(label, use_container_width=True):
513
+ if text is None: # live IOC chip: grab a current indicator
514
+ ioc = _safe(recent_threatfox_ioc)
515
+ clicked = (f"Look up live threat intelligence for the indicator {ioc} "
516
+ "and assess its red team relevance." if ioc else
517
+ "Look up live threat intelligence for the indicator 1.1.1.1.")
518
+ else:
519
+ clicked = text
520
 
521
  for msg in st.session_state.messages:
522
  with st.chat_message(msg["role"], avatar=ROBOT if msg["role"] == "assistant" else None):