feat: ARTEX(2026) threat narrative — common banner + Standards tab Why-now section (KO/EN)
Browse files
app.py
CHANGED
|
@@ -521,6 +521,31 @@ def area_help(lang):
|
|
| 521 |
return '<div style="font-weight:700;color:#2e1065;font-size:13px;margin:6px 0 4px">' + head + '</div>' + grid
|
| 522 |
|
| 523 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 524 |
def guideline_html(lang):
|
| 525 |
ko = (lang == "ko")
|
| 526 |
def chk(items):
|
|
@@ -586,6 +611,7 @@ def guideline_html(lang):
|
|
| 586 |
'<div style="font-size:12px;letter-spacing:4px;color:#d6bcff;font-weight:800">C H I T O S · ' + _L("준거 체계", "Standards", lang) + '</div>'
|
| 587 |
'<div style="font-size:20px;font-weight:800;margin-top:6px;color:#fff">' + hero_t + '</div>'
|
| 588 |
'<div style="color:#e9d5ff;font-size:12.5px;margin-top:4px">' + hero_s + '</div></div>'
|
|
|
|
| 589 |
+ _h2(h_map)
|
| 590 |
+ '<table style="width:100%;border-collapse:collapse"><tr>'
|
| 591 |
'<th style="border:1px solid #e4e9ef;padding:8px;background:#f5f3ff;text-align:left">' + th[0] + '</th>'
|
|
@@ -612,6 +638,19 @@ def guideline_html(lang):
|
|
| 612 |
return html_out
|
| 613 |
|
| 614 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 615 |
def header_html(lang):
|
| 616 |
return ('<div id="title" style="padding:10px 0 4px"><div style="font-size:13px;letter-spacing:5px;color:#8b5cf6;font-weight:800">C H I T O S</div>'
|
| 617 |
'<h1 style="margin:6px 0;color:#2e1065">' + _L("보안 · SEO · AI가시성 진단", "Security · SEO · AI-Visibility Diagnosis", lang) + '</h1>'
|
|
@@ -629,7 +668,7 @@ def relang(label, last_scan, last_deep):
|
|
| 629 |
lang = "en" if str(label).startswith("Eng") else "ko"
|
| 630 |
o1u = gr.update(value=build_report(last_scan, deep=False, lang=lang, show_upsell=True)) if last_scan else gr.update()
|
| 631 |
o2u = gr.update(value=build_report(last_deep["d"], deep=True, verified_email=last_deep.get("email"), lang=lang)) if last_deep else gr.update()
|
| 632 |
-
return (lang, gr.update(value=label), header_html(lang), desc1(lang), desc2(lang), desc3(lang),
|
| 633 |
area_help(lang), guideline_html(lang), footer_html(lang), o1u, o2u)
|
| 634 |
|
| 635 |
|
|
@@ -639,6 +678,7 @@ with gr.Blocks(title="CHITOS 인스턴트 스캔", css=CSS, theme=gr.themes.Soft
|
|
| 639 |
last_scan = gr.State(None)
|
| 640 |
last_deep = gr.State(None)
|
| 641 |
hdr = gr.HTML(header_html("ko"))
|
|
|
|
| 642 |
with gr.Row():
|
| 643 |
lang_radio = gr.Radio(["한국어", "English"], value="한국어", label="🌐 언어 / Language", min_width=260)
|
| 644 |
with gr.Tabs():
|
|
@@ -674,7 +714,7 @@ with gr.Blocks(title="CHITOS 인스턴트 스캔", css=CSS, theme=gr.themes.Soft
|
|
| 674 |
g_ft = gr.HTML(footer_html("ko"))
|
| 675 |
|
| 676 |
_ins = [lang_radio, last_scan, last_deep]
|
| 677 |
-
_outs = [lang_state, lang_radio, hdr, g_d1, g_d2, g_d3, g_ah, g_gl, g_ft, o1, o2]
|
| 678 |
lang_radio.change(relang, _ins, _outs)
|
| 679 |
demo.load(relang, _ins, _outs,
|
| 680 |
js="() => [ (navigator.language||'en').toLowerCase().startsWith('ko') ? '한국어' : 'English', null, null ]")
|
|
|
|
| 521 |
return '<div style="font-weight:700;color:#2e1065;font-size:13px;margin:6px 0 4px">' + head + '</div>' + grid
|
| 522 |
|
| 523 |
|
| 524 |
+
def _artex_section(lang):
|
| 525 |
+
if lang == "ko":
|
| 526 |
+
head = "🚨 왜 지금인가 — ARTEX 사태 (2026)"
|
| 527 |
+
bullets = ["오픈소스 <b>AI 침투 에이전트 ‘ARTEX’</b>(DeepSeek 기반)가 정찰·침투·탈취를 <b>자동</b> 수행",
|
| 528 |
+
"국내 <b>은행 7곳 이상</b> 침해, 약 <b>6.8만 건</b> 개인정보 유출 — <b>미패치 내부 애플리케이션</b>이 진입점",
|
| 529 |
+
"Microsoft: 중국계 <b>Storm-0940</b>이 ARTEX로 <b>MS365 2,250 테넌트</b> 로그인 시도 / 대만 <b>91APP</b> 주문DB 침해",
|
| 530 |
+
"공격 표면 = <b>웹·인프라 위생</b> + <b>AI 에이전트 권한·도구 오남용</b> (이중용도 도구의 악용)"]
|
| 531 |
+
resp = "치토스 대응: <b>웹서비스 · AX 인프라 · AI 모델 · AI 에이전트(AX-RAY)</b> 4대 진단 + 금융보안원 17항목 레드티밍으로 공격·방어 양면을 점검합니다."
|
| 532 |
+
src = "출처(2026): bankinfosecurity.asia · therecord.media · techtimes.com"
|
| 533 |
+
else:
|
| 534 |
+
head = "🚨 Why now — the ARTEX incident (2026)"
|
| 535 |
+
bullets = ["The open-source <b>AI penetration agent “ARTEX”</b> (DeepSeek-based) runs recon, breach and exfiltration <b>autonomously</b>",
|
| 536 |
+
"<b>7+ Korean banks</b> breached, ~<b>68,000 records</b> leaked — <b>unpatched internal applications</b> were the entry point",
|
| 537 |
+
"Microsoft: China-aligned <b>Storm-0940</b> used ARTEX against <b>2,250 MS365 tenants</b> / Taiwan's <b>91APP</b> order DB breached",
|
| 538 |
+
"Attack surface = <b>web/infra hygiene</b> + <b>AI-agent privilege & tool misuse</b> (abuse of a dual-use tool)"]
|
| 539 |
+
resp = "CHITOS response: four diagnoses — <b>Web Service · AX Infra · AI Model · AI Agent (AX-RAY)</b> — plus FSI 17-item red-teaming, covering both attack and defense."
|
| 540 |
+
src = "Sources (2026): bankinfosecurity.asia · therecord.media · techtimes.com"
|
| 541 |
+
lis = "".join('<li style="margin:3px 0">%s</li>' % b for b in bullets)
|
| 542 |
+
return ('<div style="border:1px solid #fecaca;background:#fef2f2;border-radius:12px;padding:13px 16px;margin-bottom:14px">'
|
| 543 |
+
'<b style="color:#b42318;font-size:14px">' + head + '</b>'
|
| 544 |
+
'<ul style="margin:8px 0 6px;padding-left:18px;font-size:12.5px;color:#374151;line-height:1.6">' + lis + '</ul>'
|
| 545 |
+
'<div style="font-size:12.5px;color:#2e1065;background:#f5f3ff;border-radius:8px;padding:8px 11px;margin-top:4px">🛡 ' + resp + '</div>'
|
| 546 |
+
'<div style="font-size:10.5px;color:#9ca3af;margin-top:6px">' + src + '</div></div>')
|
| 547 |
+
|
| 548 |
+
|
| 549 |
def guideline_html(lang):
|
| 550 |
ko = (lang == "ko")
|
| 551 |
def chk(items):
|
|
|
|
| 611 |
'<div style="font-size:12px;letter-spacing:4px;color:#d6bcff;font-weight:800">C H I T O S · ' + _L("준거 체계", "Standards", lang) + '</div>'
|
| 612 |
'<div style="font-size:20px;font-weight:800;margin-top:6px;color:#fff">' + hero_t + '</div>'
|
| 613 |
'<div style="color:#e9d5ff;font-size:12.5px;margin-top:4px">' + hero_s + '</div></div>'
|
| 614 |
+
+ _artex_section(lang)
|
| 615 |
+ _h2(h_map)
|
| 616 |
+ '<table style="width:100%;border-collapse:collapse"><tr>'
|
| 617 |
'<th style="border:1px solid #e4e9ef;padding:8px;background:#f5f3ff;text-align:left">' + th[0] + '</th>'
|
|
|
|
| 638 |
return html_out
|
| 639 |
|
| 640 |
|
| 641 |
+
def threat_banner(lang):
|
| 642 |
+
if lang == "ko":
|
| 643 |
+
t = ("⚠ <b>2026년, 오픈소스 AI 해킹 에이전트 ‘ARTEX’</b>가 국내 은행 7곳 이상을 침투해 약 <b>6.8만 건</b>의 개인정보가 유출됐습니다 "
|
| 644 |
+
"(<b>미패치 내부 시스템</b>이 진입점 · MS365 2,250 테넌트·대만 금융까지 확산). "
|
| 645 |
+
"공격이 AI 에이전트로 자동화된 시대 — 방어도 AI로. 치토스는 <b>웹·인프라·AI 모델·AI 에이전트</b>를 함께 진단합니다.")
|
| 646 |
+
else:
|
| 647 |
+
t = ("⚠ <b>In 2026 the open-source AI hacking agent “ARTEX”</b> breached 7+ Korean banks, leaking ~<b>68,000 records</b> "
|
| 648 |
+
"(entry point: <b>unpatched internal systems</b> · spread to 2,250 MS365 tenants and finance in Taiwan). "
|
| 649 |
+
"Attacks are now automated by AI agents — so is defense. CHITOS diagnoses <b>web, infra, AI models and AI agents</b> together.")
|
| 650 |
+
return ('<div style="background:#1b0f2e;border:1px solid #7c3aed;border-radius:12px;padding:12px 16px;margin:4px 0 2px;'
|
| 651 |
+
'color:#f3e8ff;font-size:12.5px;line-height:1.55">' + t + '</div>')
|
| 652 |
+
|
| 653 |
+
|
| 654 |
def header_html(lang):
|
| 655 |
return ('<div id="title" style="padding:10px 0 4px"><div style="font-size:13px;letter-spacing:5px;color:#8b5cf6;font-weight:800">C H I T O S</div>'
|
| 656 |
'<h1 style="margin:6px 0;color:#2e1065">' + _L("보안 · SEO · AI가시성 진단", "Security · SEO · AI-Visibility Diagnosis", lang) + '</h1>'
|
|
|
|
| 668 |
lang = "en" if str(label).startswith("Eng") else "ko"
|
| 669 |
o1u = gr.update(value=build_report(last_scan, deep=False, lang=lang, show_upsell=True)) if last_scan else gr.update()
|
| 670 |
o2u = gr.update(value=build_report(last_deep["d"], deep=True, verified_email=last_deep.get("email"), lang=lang)) if last_deep else gr.update()
|
| 671 |
+
return (lang, gr.update(value=label), header_html(lang), threat_banner(lang), desc1(lang), desc2(lang), desc3(lang),
|
| 672 |
area_help(lang), guideline_html(lang), footer_html(lang), o1u, o2u)
|
| 673 |
|
| 674 |
|
|
|
|
| 678 |
last_scan = gr.State(None)
|
| 679 |
last_deep = gr.State(None)
|
| 680 |
hdr = gr.HTML(header_html("ko"))
|
| 681 |
+
g_threat = gr.HTML(threat_banner("ko"))
|
| 682 |
with gr.Row():
|
| 683 |
lang_radio = gr.Radio(["한국어", "English"], value="한국어", label="🌐 언어 / Language", min_width=260)
|
| 684 |
with gr.Tabs():
|
|
|
|
| 714 |
g_ft = gr.HTML(footer_html("ko"))
|
| 715 |
|
| 716 |
_ins = [lang_radio, last_scan, last_deep]
|
| 717 |
+
_outs = [lang_state, lang_radio, hdr, g_threat, g_d1, g_d2, g_d3, g_ah, g_gl, g_ft, o1, o2]
|
| 718 |
lang_radio.change(relang, _ins, _outs)
|
| 719 |
demo.load(relang, _ins, _outs,
|
| 720 |
js="() => [ (navigator.language||'en').toLowerCase().startsWith('ko') ? '한국어' : 'English', null, null ]")
|