پروندهی حادثهی امنیتی داخل نوتبوک marimo
خلاصهٔ کاملتر
نویسندهی این پست، که کار رو تو مرکز دفاع سایبری بانک DNB انجام داده، میگه پاسخ به حادثه بیشتر از هر چیز یه کار «یکپارچهسازی»ه: هشدارها تو Splunk یا Sentinel یا Defender XDR هستن، دادهی آسیبپذیری تو Databricks یا Snowflake، و بقیهی زمینه — وضعیت کنترلپلین ابر، مالک دارایی، تیکت تغییر، فید تهدید — باید همون لحظه کشیده بشه بیرون. SIEM تو جستجو خوبه و داشبورد تو نمایش، ولی وسط تحقیق کار ذاتاً اکتشافیه.
انتخاب marimo هم دلیل مشخصی داره: نوتبوک رو مثل یه برنامهی بازتولیدپذیر میبینه. برخلاف نوتبوک سنتی که سلولها میتونن خارج از ترتیب اجرا بشن و خروجی به state پنهان وابسته بشه، اینجا سلولهای وابسته از روی کدی که واقعاً جلوی چشمته دوباره حساب میشن. هاست یا بازهی زمانی رو عوض کنی، همهی کوئریها و نمودارهای پاییندستی از نو اجرا میشن — دقیقاً چیزی که تو پاسخ به حادثه لازمه تا نتیجهگیری همیشه به شواهدی که ساختنش وصل بمونه.
برای منابعی که SQL نمیفهمن، تیم یه SDK نوشته: با دکوریتورهایی مثل @spl.df و @kql.df یه تابع فقط رشتهی SPL یا KQL رو برمیگردونه و دکوریتور احراز هویت، اجرا، تبدیل نوع و کش رو خودش انجام میده. اعلام صریح نوع ستونها (ts، str، int) هم JSON بینوع Splunk رو کست میکنه و هم drift اسکیما رو با خطا داد میزنه بهجای اینکه بیصدا ستون null بده. خروجی بهشکل جدول ibis روی یه DuckDB محلی میشینه، پس نتیجهی Splunk و Defender XDR و Snowflake همونجا با هم جوین میشن.
ظریفترین بخش، کش کردن زمانه. اگه کلید کش رو روی رشتهی نسبی مثل -24h بسازی، فردا صبح که آنالیست نوتبوکو باز میکنه کش میخوره و دادهی دیروز رو بدون هیچ هشداری تحویل میگیره. راهحلشون تابع rt()ه که همون لحظهی فراخوانی، عبارت نسبی رو به تایماستمپ مطلق UTC تبدیل میکنه:
# BAD: the string "-1h" never changes, so the cache key never changes
await connections(earliest_time="-1h", latest_time="now")
# GOOD: rt() resolves to an absolute timestamp at call time
await connections(earliest_time=rt("-1h"), latest_time=rt("now"))سه مثال کاری هم تو پست هست: شکار درایورهای آسیبپذیر با جوین فید LOLDrivers روی تلهمتری لود درایور، تشخیص GetSystem سیلور با یه جوین زمانی ۳۰ ثانیهای بین تزریق ترد و تغییر privilege، و یه پروندهی Risk-Based Alerting که پنج کوئری زمینه رو موازی با asyncio.gather میگیره. حرف اصلی نویسنده اینه که بهجای نگهداشتن یه قالب نوتبوک برای هر نوع هشدار، ایجنت از طریق marimo-pair همون نوتبوکی رو میسازه که این پرونده لازم داره.
نکات کلیدی:
- نوتبوک marimo چون واکنشی و بازتولیدپذیره، نتیجهگیری همیشه به کوئری و شواهدش وصل میمونه
- SDK اختصاصی، SPL و KQL رو اجرا میکنه و نتیجه رو بهشکل دیتافریم تایپدار برمیگردونه
- بکاند ibis روی DuckDB باعث میشه دادهی Splunk و Defender XDR و Snowflake محلی جوین بشن
- تابع rt() جلوی کش شدن بازههای زمانی نسبی و تحویل دادهی بیات رو میگیره
- با marimo-pair ایجنت داخل همون سطح تحلیل آنالیست سلول مینویسه و اجرا میکنه، نه از بیرون




