[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-smarthire-mlflow-initial-access-zh":3,"article-related-smarthire-mlflow-initial-access-zh":30,"series-tools-663ba1ef-830f-4002-b418-a594068f30fa":75},{"id":4,"slug":5,"title":6,"content":7,"summary":8,"source":9,"source_url":10,"author":11,"image_url":12,"cover_image":12,"category":13,"language":14,"translated_content":11,"related_article_id":15,"keywords":16,"key_takeaways":22,"views":26,"created_at":27,"published_at":28,"topic_cluster_id":29},"663ba1ef-830f-4002-b418-a594068f30fa","smarthire-mlflow-initial-access-zh","SmartHire 把 MLflow 變初始存取","\u003Cp data-speakable=\"summary\">我拆 SmartHire 的 MLflow 繞過、Pickle RCE 和可寫 plugin 提權，最後整理成可直接抄的攻擊路徑。\u003C\u002Fp>\u003Cp>我碰到 SmartHire 這類題目時，第一個感覺通常不是「哇好酷」，而是「這東西\u003Ca href=\"\u002Fnews\u002Fthe-athletic-nfl-hub-news-scores-rumors-zh\">怎麼\u003C\u002Fa>又把幾個本來該分開的信任邊界黏在一起」。表面上它像個 AI 招募平台，前台、模型服務、上傳流程、管理腳本都很完整；實際上你一戳，就會發現它把 public app、ML 服務、序列化模型、以及高權限維運腳本全塞在同一條路徑上。這種架構我看多了，最煩的不是它複雜，是它每一層都只比正常多鬆一點點，剛好鬆到能被串成整條鏈。\u003C\u002Fp>\u003Cp>我會把這篇當成一份拆解筆記，不是產品介紹。這次的起點是 \u003Ca href=\"https:\u002F\u002F1337sheets.com\u002Fhack-the-box-htb-smarthire-writeup-medium-weekly-may-16th-2026\u002F\">1337 Sheets 的 SmartHire walkthrough\u003C\u002Fa>，我從裡面抓出 MLflow 繞過、Pickle RCE、以及 writable plugin 提權這三段，然後把它翻成我自己平常做滲透或 lab 時會用的思路。\u003Ca href=\"\u002Fnews\u002F5-jaire-alexander-stats-zh\">重點\u003C\u002Fa>不是背 payload，是看懂這種「看起來很現代，底下卻很老派」的破口怎麼一路接起來。\u003C\u002Fp>\u003Ch2>先別把它當一個站，這其實是兩個信任邊界\u003C\u002Fh2>\u003Cblockquote>“The models.smarthire.htb subdomain was identified as an instance of MLflow, a platform for the machine learning lifecycle.”\u003C\u002Fblockquote>\u003Cp>翻譯一下就是：前台網站跟模型服務不是同一個安全面。很多人一開始只盯主站，結果在\u003Ca href=\"\u002Fnews\u002Fnous-portal-lets-hermes-use-one-login-zh\">登入\u003C\u002Fa>頁、表單、CSRF、或前端 JS 上打轉，最後才發現真正的洞在另一個 vhost。SmartHire 的 \u003Ca href=\"https:\u002F\u002Fmlflow.org\u002F\">MLflow\u003C\u002Fa> 跑在 \u003Ccode>models.smarthire.htb\u003C\u002Fcode>，這代表你要把它當成獨立系統看，而不是主站的附屬頁面。\u003C\u002Fp>\n\u003Cfigure class=\"my-6\">\u003Cimg src=\"https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1779419808086-rps3.png\" alt=\"SmartHire 把 MLflow 變初始存取\" class=\"rounded-xl w-full\" loading=\"lazy\" \u002F>\u003C\u002Ffigure>\n\u003Cp>我之前也踩過這種坑。表面上是單一產品，實際上後面掛著一個模型管理介面、幾個測試 \u003Ca href=\"\u002Ftag\u002Fapi\">API\u003C\u002Fa>、還有一個沒人想碰的 admin host。這種分層如果沒先畫出來，你會一直在錯的地方花力氣。\u003C\u002Fp>\u003Cp>實操上，我會先做三件事：確認 vhost、確認服務角色、確認哪個 host 才真的做 auth。這裡最常見的錯誤是只做 DNS 枚舉，不做 Host header fuzzing。你如果沒把 sibling host 找出來，後面很多漏洞根本不會出現。\u003C\u002Fp>\u003Cul>\u003Cli>先掃 port，再 fuzz Host header。\u003C\u002Fli>\u003Cli>把每個有用的 hostname 都寫進 \u003Ccode>\u002Fetc\u002Fhosts\u003C\u002Fcode>。\u003C\u002Fli>\u003Cli>看到「模型」「admin」「internal」這種字眼就別裝沒事，先當成另一個攻擊面。\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>MLflow 版本老不老，不是資訊，是路線圖\u003C\u002Fh2>\u003Cp>walkthrough 裡面提到這台跑的是 \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fmlflow\u002Fmlflow\">MLflow\u003C\u002Fa> 2.14.1。這種版本資訊我不會只拿來記錄，因為它其實直接告訴你該查哪一類問題。服務版本一老，通常不是只有一個 CVE，而是 auth、模型載入、artifact 處理、預設設定，整包都可能有歷史包袱。\u003C\u002Fp>\u003Cp>白話講，看到舊版 MLflow，我不會先想「我要怎麼憑空造 exploit」，我會先想「這版本的認證邊界是不是早就被人研究爛了」。SmartHire 的流程就是這樣：先有 auth bypass 的可能，再去碰後面的 model artifact 與 deserialization。這比硬拗一個新洞實際多了。\u003C\u002Fp>\u003Cp>我很討厭那種把版本資訊當背景板的寫法。版本不是裝飾品，是你省時間的捷徑。你只要知道服務名跟版本，很多時候就能先把不相關的路徑砍掉。\u003C\u002Fp>\u003Cp>實操寫法很簡單：先抓 banner、頁尾、錯誤訊息、\u003Ca href=\"\u002Ftag\u002Fdocker\">docker\u003C\u002Fa> tag、package metadata，任何能露出版本的地方都不要放過。然後分開查三件事：認證、序列化、模型載入。不要只搜「RCE」，那樣通常只會把自己帶進一堆不對的 PoC。\u003C\u002Fp>\u003Cul>\u003Cli>版本要查到精確 release，不要只查產品名。\u003C\u002Fli>\u003Cli>先看 auth，再看 artifact，再看 deserialization。\u003C\u002Fli>\u003Cli>如果服務看起來像內網工具，但其實對外開著，優先懷疑預設設定。\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>CSV 上傳不是資料功能，是測試入口\u003C\u002Fh2>\u003Cp>SmartHire 的前台有 \u003Ccode>Train Model\u003C\u002Fcode> 和 \u003Ccode>Make Predictions\u003C\u002Fcode> 這種 CSV 上傳流程。這種功能我看到都會先皺眉，因為它常常是假裝成資料匯入，實際上是在替後端 Python 程式餵受控輸入。CSV 本身不會咬人，但 parser、後處理、以及後面的模型流程會。\u003C\u002Fp>\n\u003Cfigure class=\"my-6\">\u003Cimg src=\"https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1779419794802-9b2x.png\" alt=\"SmartHire 把 MLflow 變初始存取\" class=\"rounded-xl w-full\" loading=\"lazy\" \u002F>\u003C\u002Ffigure>\n\u003Cp>這裡最重要的不是「能不能上傳」，而是「上傳後發生什麼事」。如果它只是存檔，那還好；如果它會訓練、載入、轉成模型、再拿去做預測，那你就已經站在 code execution 的門口了。很多 ML app 的問題都不是上傳點本身，而是上傳後那段自動化流程太相信資料格式。\u003C\u002Fp>\u003Cp>我以前遇過一個內部工具也這樣，前端看起來只是讓人丟 CSV，後端卻把檔案交給一串 Python helper 再丟進序列化格式。團隊一直說「我們有檔案大小限制」，我只能說這種限制對 parser 問題幾乎沒用。\u003C\u002Fp>\u003Cp>實操上，我會直接做這幾個測試：\u003C\u002Fp>\u003Cul>\u003Cli>丟奇怪欄位數、空白列、分隔符混亂的 CSV。\u003C\u002Fli>\u003Cli>看後端有沒有用 Pickle、joblib、yaml、或自製格式。\u003C\u002Fli>\u003Cli>確認上傳結果會不會被另一個服務重用。\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>Pickle 不是模型格式，是把刀包成資料\u003C\u002Fh2>\u003Cp>walkthrough 最後走到 Pickle deserialization，這一段我完全不意外。\u003Ca href=\"https:\u002F\u002Fdocs.python.org\u002F3\u002Flibrary\u002Fpickle.html\">Python Pickle\u003C\u002Fa> 只要碰到不可信輸入，基本上就是在賭對方不會把你送進任意物件重建流程。你不是在「讀資料」，你是在叫 Python 幫你還原物件圖，而那個物件圖如果是你控制的，事情就開始變味。\u003C\u002Fp>\u003Cp>SmartHire 這裡比較有意思的是，它不是那種一顆 payload 直接打穿的簡單題。作者先碰到 Python 版本、依賴、以及本地模組路徑的問題，後來才把合法的 \u003Ccode>python_model.pkl\u003C\u002Fcode> 拿來拆。這種過程才像真的攻擊，不是貼一段神奇 payload 就結束。環境不對，payload 常常只會死給你看。\u003C\u002Fp>\u003Cp>我很在意這種細節，因為它告訴你真正可行的路徑不是「亂塞 shellcode」，而是「先理解 target 預期的 object graph，再把惡意行為塞進同一個結構裡」。walkthrough 裡提到 \u003Ccode>utils\u002Fsimplehiringmodel.py\u003C\u002Fcode> 這種本地模組路徑，這就是關鍵：目標不是單純反序列化某個東西，而是會去 import 本地 helper。\u003C\u002Fp>\u003Cp>實操寫法是：先找合法 artifact，拆它的結構、module 名稱、import path、Python 版本，再決定怎麼重建。不要一開始就寫惡意 payload。先把合法格式摸清楚，很多時候你就會知道該在哪裡插手。\u003C\u002Fp>\u003Cul>\u003Cli>先看合法 artifact，不要先做惡意 payload。\u003C\u002Fli>\u003Cli>對齊 Python 版本與依賴。\u003C\u002Fli>\u003Cli>如果有 local module import，就把那條路徑當成攻擊面。\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>預設帳密很土，但土招通常最省事\u003C\u002Fh2>\u003Cp>這個 MLflow 實例最後還碰到 \u003Ccode>admin:password\u003C\u002Fcode>。我知道，這種東西看起來很蠢，但我反而覺得它很真實。很多實戰環境不是只有一個漏洞，而是漏洞加上錯誤設定一起把門打開。auth bypass 可能只是讓你進到登入流程，預設帳密則是讓你不用再跟 session、\u003Ca href=\"\u002Ftag\u002Ftoken\">token\u003C\u002Fa>、或二次驗證糾纏。\u003C\u002Fp>\u003Cp>我最常看到的問題是，很多人會覺得查預設帳密很 low，於是跳過。結果他們花半天研究一個其實不需要的繞過。我的原則剛好相反：只要服務老、外露、又長得像 copy docs 起來的，就先試預設登入。這不是偷懶，這叫先把最便宜的路走完。\u003C\u002Fp>\u003Cp>實操上，你應該把預設帳密當成標準檢查項，不要當成菜鳥題。先試產品文件常見的預設值，再看版本對應的常見 setup 組合。如果有 setup wizard 或初始化頁面，更要假設有人可能只做了一半。\u003C\u002Fp>\u003Cul>\u003Cli>先試文件預設值，再試版本常見預設值。\u003C\u002Fli>\u003Cli>如果有 setup 流程，確認它是不是半完成狀態。\u003C\u002Fli>\u003Cli>同一個服務如果有多個入口，別假設 auth 一定一致。\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>可寫的 plugin 目錄，等於把程式碼執行開給你\u003C\u002Fh2>\u003Cp>後半段的提權才是真正讓人翻白眼的地方。walkthrough 說高權限維運腳本會載入一個 Python plugin 目錄，而那個目錄剛好可寫。這種設計我每次看到都想問一句：你們真的有把「可擴充」跟「可被改 code」分清楚嗎？plugin 如果能被低權限使用者寫入，那它就不是功能，它是後門。\u003C\u002Fp>\u003Cp>白話講，如果 privileged process 會從你能改的路徑載入 Python module，那你根本不需要破密碼或提權漏洞。你只要把會被 import 的檔案換掉，或者新增一個會被吃進去的模組，剩下的交給排程或管理腳本自己跑完。\u003C\u002Fp>\u003Cp>我以前在內部系統也看過類似狀況，service account 擁有某個 script 目錄的執行權，但檔案權限配得亂七八糟。結果一個本來只是「方便維護」的 plugin 機制，直接變成 root shell。這種事不是理論，是很常見的維運失誤。\u003C\u002Fp>\u003Cp>實操寫法要盯這幾個點：\u003C\u002Fp>\u003Cul>\u003Cli>查 \u003Ccode>sudo -l\u003C\u002Fcode>、cron、systemd timer、維運腳本。\u003C\u002Fli>\u003Cli>找所有會被 privileged process 讀取的 writable path。\u003C\u002Fli>\u003Cli>特別注意 Python 的 import path 與 plugin config。\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>我會怎麼把這條鏈固定下來\u003C\u002Fh2>\u003Cp>如果是我自己在打這台，我會把流程壓成很短：先找 split host，再確認 MLflow 版本，接著測 auth 邊界與預設帳密，然後拆合法模型 artifact，最後才去找 writable plugin path。這樣做的好處是，你不會一開始就把時間浪費在亂猜 payload，因為每一步都在縮小空間。\u003C\u002Fp>\u003Cp>這類題目最討厭的地方，不是它難，而是它很會假裝自己很雜。其實它只是把幾個老問題包進一個看起來很新的殼：vhost 分離、舊版服務、使用者可控上傳、反序列化、以及可寫的程式載入路徑。你只要把這幾個點按順序拆開，鏈就很乾淨。\u003C\u002Fp>\u003Cp>我也建議你在做筆記時，直接照發現順序寫，不要照攻擊順序亂排。因為讀者真正需要的是你怎麼想到的，不是你最後 shell 拿得多漂亮。\u003C\u002Fp>\u003Ch2>可抄的模板\u003C\u002Fh2>\u003Cpre>\u003Ccode># SmartHire-style ML app attack checklist（可直接改成你的筆記模板）\n\n## 1) 先切開信任邊界\n- 掃 port\n- fuzz Host header 找 sibling vhost\n- 把有用 hostname 加進 \u002Fetc\u002Fhosts\n- 先分辨 public app \u002F model service \u002F admin service\n\n## 2) 先把 ML 服務版本釘死\n- 抓 banner、頁尾、錯誤訊息、docker tag\n- 記錄精確版本，不要只寫產品名\n- 先查 auth issues，再查 serialization，再查 model loading\n- 看是否有預設帳密或半完成 setup\n\n## 3) 把上傳功能當成測試入口\n- 找 CSV \u002F JSON \u002F model \u002F archive upload\n- 問：parser 是誰？\n- 問：上傳後做什麼？train \u002F score \u002F import \u002F deserialize？\n- 查有沒有 Pickle、joblib、yaml、或自製 plugin 機制\n\n## 4) 反推合法 artifact 的結構\n- 先拆合法檔案，不要先寫惡意 payload\n- 記 module 名稱、import path、object graph\n- 對齊 Python 版本與依賴\n- 如果有 local helper module，就把那條路徑視為攻擊面\n\n## 5) 找提權的 writable code path\n- 查 cron、systemd timer、sudo wrapper、維運腳本\n- 找 privileged process 會讀的 writable directory\n- 特別注意 Python plugin 目錄與 import path\n- 能寫就代表能改行為，不只是改資料\n\n## 6) 寫報告時固定順序\n- Recon\n- vhost discovery\n- service fingerprinting\n- auth bypass \u002F initial access\n- payload construction\n- privilege escalation\n- lessons learned\n\n## 可重用欄位\n- Hostname:\n- Port:\n- Service:\n- Version:\n- Auth issue:\n- Upload surface:\n- Serialization format:\n- Writable code path:\n- Privilege boundary:\n- Final shell path:\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>這段模板我會留著下次直接改。它不是什麼神秘技巧，但很實用，因為它逼你先把邊界、版本、上傳、序列化、提權這幾層分開看，不會一開始就把自己搞暈。\u003C\u002Fp>\u003Cp>原始來源是 \u003Ca href=\"https:\u002F\u002F1337sheets.com\u002Fhack-the-box-htb-smarthire-writeup-medium-weekly-may-16th-2026\u002F\">https:\u002F\u002F1337sheets.com\u002Fhack-the-box-htb-smarthire-writeup-medium-weekly-may-16th-2026\u002F\u003C\u002Fa>，我這篇是根據那份 walkthrough 做方法論拆解；其中邏輯與模板是我重新整理的，技術脈絡則來自原文與我自己的實戰筆記。\u003C\u002Fp>","我拆 SmartHire 的 MLflow 繞過、Pickle RCE 和可寫 plugin 提權，最後整理成可直接抄的攻擊路徑。","1337sheets.com","https:\u002F\u002F1337sheets.com\u002Fhack-the-box-htb-smarthire-writeup-medium-weekly-may-16th-2026\u002F",null,"https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1779419808086-rps3.png","tools","zh","dc09f953-3375-49c8-aa00-ee2697de8b82",[17,18,19,20,21],"MLflow","Pickle","deserialization","privilege escalation","vhost",[23,24,25],"先把 public app 和 model service 分開看，別把整台機器當單一網站。","舊版 MLflow、CSV 上傳、Pickle 反序列化，通常是一條能串起來的攻擊鏈。","可寫的 Python plugin 目錄本質上就是可控程式碼執行，提權要先找這種路徑。",31,"2026-05-22T03:16:04.182767+00:00","2026-05-22T03:16:03.896+00:00","c3c88dd2-a940-438a-b359-0e5a24562273",{"tags":31,"relatedLang":34,"relatedPosts":38},[32],{"name":17,"slug":33},"mlflow",{"id":15,"slug":35,"title":36,"language":37},"smarthire-mlflow-bypass-rce-writeup-en","SmartHire turns MLflow into initial access","en",[39,45,51,57,63,69],{"id":40,"slug":41,"title":42,"cover_image":43,"image_url":43,"created_at":44,"category":13},"419deb6d-ea65-4fa7-9dd1-73763f373b53","bailian-token-plan-agent-credits-guide-zh","百炼Token Plan把Agent接入变简单","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1783929835818-cyp6.png","2026-07-13T08:03:24.024727+00:00",{"id":46,"slug":47,"title":48,"cover_image":49,"image_url":49,"created_at":50,"category":13},"5c5c6733-6f41-49ca-b61e-c0a53399c327","one-api-gateway-turns-six-ai-apis-into-one-zh","一個閘道把六個 AI API 收成一套","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1783883027640-gz6i.png","2026-07-12T19:03:22.171684+00:00",{"id":52,"slug":53,"title":54,"cover_image":55,"image_url":55,"created_at":56,"category":13},"953466bc-6d94-4ffe-944b-ac7728d09184","fde-playbook-fixes-broken-agent-projects-zh","FDE 讓烂尾 Agent 回正軌","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1783881221882-yw1n.png","2026-07-12T18:33:16.193979+00:00",{"id":58,"slug":59,"title":60,"cover_image":61,"image_url":61,"created_at":62,"category":13},"bd3b5d5c-02d9-49c4-8ca4-dcb6df373374","ai-zaobao-template-daily-to-reusable-report-zh","AI 早报拆成可复用周报","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1783879420413-rlwb.png","2026-07-12T18:03:11.617929+00:00",{"id":64,"slug":65,"title":66,"cover_image":67,"image_url":67,"created_at":68,"category":13},"33302498-49ec-4a00-8e2c-61b6f9fc3ece","claude-reflect-turns-usage-into-retention-zh","Claude Reflect 把使用變留存","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1783793005956-n1ea.png","2026-07-11T18:03:01.486301+00:00",{"id":70,"slug":71,"title":72,"cover_image":73,"image_url":73,"created_at":74,"category":13},"5f08bf54-0ddb-4884-b541-75e33ad21b30","midjourney-turns-prompt-ideas-into-art-zh","Midjourney 把提示詞變成可重用流程","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1783694003831-eilt.png","2026-07-10T14:32:55.765266+00:00",[76,81,86,91,96,101,106,111,116,121],{"id":77,"slug":78,"title":79,"created_at":80},"855cd52f-6fab-46cc-a7c1-42195e8a0de4","surepath-real-time-mcp-policy-controls-zh","SurePath 推出即時 MCP 政策控管","2026-03-26T07:57:40.77233+00:00",{"id":82,"slug":83,"title":84,"created_at":85},"9b19ab54-edef-4dbd-9ce4-a51e4bae4ebb","mcp-in-2026-the-ai-tool-layer-teams-use-zh","2026 年 MCP：團隊真的在用的 AI 工具層","2026-03-26T08:01:46.589694+00:00",{"id":87,"slug":88,"title":89,"created_at":90},"af9c46c3-7a28-410b-9f04-32b3de30a68c","prompting-in-2026-what-actually-works-zh","2026 提示工程，真正有用的是什麼","2026-03-26T08:08:12.453028+00:00",{"id":92,"slug":93,"title":94,"created_at":95},"05553086-6ed0-4758-81fd-6cab24b575e0","garry-tan-open-sources-claude-code-toolkit-zh","Garry Tan 開源 Claude Code 工具包","2026-03-26T08:26:20.068737+00:00",{"id":97,"slug":98,"title":99,"created_at":100},"042a73a2-18a2-433d-9e8f-9802b9559aac","github-ai-projects-to-watch-in-2026-zh","2026 必看 20 個 GitHub AI 專案","2026-03-26T08:28:09.619964+00:00",{"id":102,"slug":103,"title":104,"created_at":105},"a5f94120-ac0d-4483-9a8b-63590071ac6a","claude-code-vs-cursor-2026-zh","Claude Code 與 Cursor 深度對比：202…","2026-03-26T13:27:14.279193+00:00",{"id":107,"slug":108,"title":109,"created_at":110},"0975afa1-e0c7-4130-a20d-d890eaed995e","practical-github-guide-learning-ml-2026-zh","2026 機器學習入門 GitHub 實用指南","2026-03-27T01:16:49.712576+00:00",{"id":112,"slug":113,"title":114,"created_at":115},"bfdb467a-290f-4a80-b3a9-6f081afb6dff","aiml-2026-student-ai-ml-lab-repo-review-zh","AIML-2026：像課綱的學生實驗 Repo","2026-03-27T01:21:51.467798+00:00",{"id":117,"slug":118,"title":119,"created_at":120},"80cabc3e-09fc-4ff5-8f07-b8d68f5ae545","ai-trending-github-repos-and-research-feeds-zh","AI Trending：把 AI 資源收成一張表","2026-03-27T01:31:35.262183+00:00",{"id":122,"slug":123,"title":124,"created_at":125},"3ce6e6e2-bac5-463e-9f8d-45caabcc61f7","awesome-ai-for-science-research-tools-map-zh","AI 科研工具清單，開始像地圖了","2026-03-27T01:46:50.521945+00:00"]