滲透筆記
滲透筆記是綁在單一題目上的記事本,你寫的每一個字都只留在自己的瀏覽器裡。
開啟面板
題目頁面上方導覽列的「筆記」按鈕是唯一能打開這個面板的控制項。螢幕寬度低於 lg 斷點時,按鈕只剩鉛筆圖示,文字會被藏起來。
按鈕上掛著一個數字徽章,顯示這一題目前有幾則筆記。徽章只在數量大於零時才畫出來,所以還沒寫過任何東西的題目是完全看不到徽章,而不是看到一個「0」。
面板打開後,標題列寫的是「滲透筆記」。
面板尺寸
面板標題列上有「最大化」/「還原」、「最小化」與「關閉」。
| 尺寸 | 怎麼進入 | 版面 | 怎麼離開 |
|---|---|---|---|
| 標準 | 面板打開時就是這個尺寸 | 貼齊畫面右緣,寬螢幕佔一半寬度、窄螢幕佔滿寬度,其餘畫面蓋上一層半透明遮罩。清單填滿整個面板;正在編輯時,編輯區佔上半部,清單留在下半部 | 「最大化」、「最小化」、「關閉」,或點一下遮罩的任何位置 |
| 最大化 | 標題列的「最大化」按鈕 | 佔滿整個畫面。寬螢幕時清單佔左邊 30%、編輯區佔右邊 70%;沒有任何筆記在編輯時,右側寫的是「選取一篇筆記進行編輯,或按 + 新增」。窄螢幕一次只看得到其中一側,並有一顆返回鍵從編輯區退回清單 | 「還原」,回到標準尺寸 |
| 最小化 | 標題列的「最小化」按鈕 | 面板消失,畫面右下角改成一顆浮動按鈕。寬螢幕時這顆按鈕帶著文字與同一個筆記數徽章;窄螢幕時只是一顆圓形圖示 | 點那顆浮動按鈕 |
最小化會把面板本體卸載,所以它跟關閉一樣會丟掉沒存的編輯內容。還原之後編輯區會回到同一篇筆記,但顯示的是那篇筆記最後存下的內容。
寫一篇筆記
- 按標題列的 +(「新增筆記」)開一篇新的,或按既有卡片上的鉛筆鈕編輯那一篇。
- 在 Edit 分頁打字。Preview 分頁會把內容當 Markdown 渲染,採 GFM 規則,且單一換行就會斷行。這兩個分頁名稱是寫死的英文,不會翻譯。
- 按「儲存」。
按「取消」會直接結束編輯,剛才打的字一個都不留。
標準尺寸下,編輯區只在打開的那一刻讀一次筆記內容。如果你正在編輯 A 篇、還沒儲存就去按第二張卡片的鉛筆鈕,編輯區裡仍然是 A 的文字——此時按「儲存」就會把 A 的內容寫進第二篇,覆蓋掉原本的內容。同樣情況下按 +,則會生出一篇內容等於 A 的新筆記。請先把一篇存好或取消,再去開另一篇。最大化尺寸沒有這個問題。
點卡片的行為依尺寸而不同:最大化時點一下就直接進入編輯;標準尺寸下點一下只會選取那張卡片。
什麼才算存下
只有按下「儲存」才算把筆記交出去存檔。 打字的過程中不會自動存。
| 你做的動作 | 已存檔的筆記 | 編輯區裡的文字 |
|---|---|---|
| 按「儲存」 | 寫進瀏覽器資料庫,重新整理或關掉分頁再回來都還在 | 清空,結束編輯 |
| 按「取消」 | 不變 | 丟棄 |
| 按「關閉」或點遮罩 | 不變 | 丟棄,沒有任何確認 |
| 按「最小化」 | 不變 | 丟棄 |
| 重新整理或離開頁面 | 不變 | 丟棄 |
沒存的編輯內容不會被寫到任何地方——面板開機時讀的那個草稿鍵,程式只會讀取與移除,從來不會寫入——所以編輯區一被卸載那些字就消失,也沒有任何救回的辦法。
關閉面板會把面板尺寸清回標準尺寸。搜尋框裡的字會留著,所以下次打開時清單可能仍然是篩選過的。已儲存的筆記本身不受影響。
筆記存在哪裡
- 筆記存在你自己瀏覽器的 IndexedDB 資料庫
challenge-tools裡的pentest-notesstore,旁邊還有attack-sessions、code-drafts與challenge-progress。任何內容都不會上傳到伺服器。 - 筆記是每一題各自獨立的。開啟某一題只會載入標記為該題資料夾名稱的筆記,不會看到別題的內容。
- 這個鍵是題目資料夾名稱而不是網址,所以同一題的英文版與繁體中文版共用同一份筆記。
有三件事會讓筆記消失:
- 在面板裡刪掉一篇——按下去就立刻刪除,沒有確認步驟;
- 清掉瀏覽器的網站資料,整個資料庫會一起被丟掉,而且救不回來;
- 換一個瀏覽器或換一台裝置開這個網站,那裡根本沒有這個資料庫。
筆記與攻擊紀錄住在不同的 store,所以重新進入已解開的題目不會動到筆記——但那一題的攻擊紀錄會被換掉,見疑難排解。
筆記清單
每張卡片只顯示筆記前兩行非空白的內容;內容全空的筆記顯示「(空筆記)」。預覽下方是建立時間,被重新編輯存過的筆記會在時間後面多一個「(已編輯)」。
卡片上的編輯與刪除按鈕平時是隱藏的,只有滑鼠移到卡片上才出現。觸控裝置沒有 hover,因此按不到這兩顆按鈕。
清單有兩種空狀態:完全沒有筆記時顯示「還沒有筆記,按 + 新增」;有筆記但搜尋不到任何一篇時,改顯示「沒有符合搜尋的筆記」。
搜尋
面板上方的搜尋框只比對筆記內文,且不分大小寫。時間與「(已編輯)」標記都不在比對範圍內。
搜尋框判斷「是不是空的」時會先去頭尾空白,實際拿去比對的卻是沒去空白的原字串。因此多打的前置或後綴空白會被原樣拿去比對,只有筆記內文在同一個位置也有那個空白時才算命中——例如打在最後一個字後面的空白,就對不上以該字結尾的筆記。
排序
排序按鈕在「新→舊」與「舊→新」之間切換,依每篇筆記的建立時間排列。滑鼠移上去的提示會寫出目前的方向,以及點下去會切換成哪一個方向。
刪除筆記
刪除會同時把那篇筆記從清單與資料庫移除。攻擊紀錄裡對應的那一筆事件則原封不動留著——那條時間軸是唯讀累加的——所以被刪掉的文字仍然會出現在匯出的攻擊紀錄裡。
編輯的行為剛好相反:儲存一次編輯會把攻擊紀錄裡那筆事件原地改寫並蓋上更新時間,所以那裡只留得下最新版本。
匯出
目前攻擊紀錄建立後,「下載攻擊紀錄」就會出現在交旗區,尚未解出、答錯或驗證失敗時也能使用;收合題目說明後仍可下載。「下載滲透筆記」維持在本次答對後顯示。
| 按鈕 | 產出 | 檔名 |
|---|---|---|
| 「下載滲透筆記」 | 一個 Markdown 檔,內含這一題所有已儲存的筆記 | pentest-notes-<題目資料夾名稱>-<YYYYMMDD>.md |
| 「下載攻擊紀錄」 | 開啟選項,可選 JSON/Markdown、完整/精簡及選填姓名與班級 | attack-session-<題目資料夾名稱>-<選填班級姓名>-<YYYYMMDD-HHMMSS>-<模式>.json(或 .md) |
未解出的攻擊紀錄不附 system prompt,依所選模式保留事件與可讀取的已儲存草稿。已解出的提示會要求對照錯誤嘗試、彎路與成功路徑;之後再答錯不會移除提示。儲存失敗時,下載仍可帶走目前記憶體內的事件;無法讀取的草稿則不會出現在檔案內。
完整(full)保留所有事件。精簡(thinned)省略可辨識的 HTTP 回應本文與面板檢視事件,保留請求本文、程式碼、筆記、旗標嘗試與草稿;未知或格式不完整的既有事件原樣保留。檔案列出省略數量,匯出不會刪減資料庫內的紀錄。
姓名與班級可留空;填入後移除控制字元與首尾空白,各保留前 40 個 Unicode 字碼點,只用於本次檔案與清理過的檔名。關閉視窗便捨棄輸入。匯出失敗時選項仍保留,可直接重試。
匯入
「匯入攻擊紀錄」在交旗區同一塊的攻擊紀錄清單裡。選一個本站匯出的 JSON 檔,平台以匯出檔自帶的完整性檢查驗過之後,把它的那一趟紀錄存成這一題的新一筆。
- 一律新增一筆。 不覆蓋、不合併任何既有紀錄;同一個檔案匯入兩次就得到兩筆。
- 不改別的東西。 解題進度與編輯器裡的草稿都不受影響,即使匯入的是一筆已解出的紀錄也一樣。
- 只收這一題的檔案。 檔案屬於別題時平台拒絕並同時指出兩邊的題目,不會代為寫到別題去。
- 可讀可再匯出,但不能接續。 匯入的紀錄會出現在攻擊紀錄清單上、可以選為匯出對象;新的作答不會接在它後面。要繼續打這一題,請開一筆新的紀錄。
- 檢查合格的意思很窄。 它只說明檔案內容與檔內雜湊一致,不能用來判斷這份檔案由誰產生,也不能用來宣稱檔案未經改動;刻意重算雜湊的改動它看不出來。
攻擊紀錄清單同時列出這一題的每一筆紀錄:開始時間、解出與否、事件數,以及它是本機開始的還是匯入的。選取其中一筆,「下載攻擊紀錄」下載的就是那一筆;未選取時下載目前作答中的那一筆。在這台瀏覽器上還沒回答「這些紀錄是你的嗎?」之前,清單不顯示任何紀錄,匯入也不能使用。
清除
攻擊紀錄清單上有「清除這一題的紀錄」。它移除的是這一題已存的紀錄,目前作答中的那一筆會保留;那一筆正在被寫入,移除它只會在下一次記錄時被寫回來。
按下去會先問一次,並寫出會移除幾筆。確認之後:
- 無法復原。 這個網站沒有伺服器也沒有暫存區,移除掉就取不回來了。要保留的內容請先匯出。
- 解題進度不受影響。 已解出的題目仍然算解出,題目列表的完成數不會因此減少。清除能拿掉的是歷程,不是成績。
- 會留下一筆活動痕跡,記下什麼時候移除了幾筆,顯示在同一份清單下方。
痕跡只記下「這裡曾經移除過紀錄」與筆數、時間,不留被移除的內容;留著的話移除就是假的。
活動痕跡
三種會改變「這一題現在有哪些紀錄」的動作都會留下一筆痕跡,一起列在攻擊紀錄清單下方:
| 動作 | 痕跡記下什麼 |
|---|---|
| 匯出 | 匯出的是哪一筆、完整或精簡、以及有沒有填姓名班級(只記有沒有填,不記填了什麼) |
| 匯入 | 這台機器給它的新編號,以及來源檔自己的編號與匯出時間 |
| 清除 | 移除了幾筆,以及每一筆的開始時間與是否解出 |
痕跡會跟著匯出檔一起走。 收到檔案的人因此看得出這份紀錄是一路做下來的,還是中途匯入過別的檔案。
兩件要知道的事:
- 匯出檔帶的是這次匯出之前的痕跡。描述這次匯出的那一筆寫在檔案做好之後,所以它不在檔案裡:一個檔案沒辦法既包含關於它自己的紀錄,又讓自己的完整性檢查對得上。
- 匯入不會把檔案裡的痕跡搬進你的瀏覽器。那些痕跡只是拿來讀的;搬進來的話,一份自己編的檔案就能把假的活動紀錄塞進你的資料庫。
如果你要拿它收作業
痕跡能告訴你這台瀏覽器上發生過什麼,但它不是稽核軌跡:
- 清掉本機全部紀錄會把痕跡一起帶走,之後重新作答匯出,檔案裡的痕跡就是空的。
- 舊版格式的匯出檔本來就沒有痕跡這個欄位。
所以「檔案裡沒有痕跡」不代表「這個學生什麼都沒做過」,只代表這份檔案說不出那段話。把它當成多一個可以問的問題,不要當成判定。
痕跡擋得住的是隨手刪,不是蓄意清除:開始作答前問「這些紀錄是你的嗎?」時選的那個「刪除並重新開始」,刪的是整個本機資料庫,痕跡會跟著一起消失。所以它不是稽核軌跡,也不保證沒有東西被無聲拿掉。
兩種格式都含 schemaVersion: 1、事件雜湊鏈與 SHA-256 checksum,可偵測未同步更新雜湊的修改,無法驗證作者身分或防止刻意重算。Markdown 用程式碼區塊保留完整 JSON,因此 checksum 比對的是區塊內的資料,不是 Markdown 排版。詳細演算法見公開匯出格式。
滲透筆記 Markdown 檔的第一行是一級標題,把一個固定的繁體中文標籤與題目標題接在一起;那個標籤不會隨介面語系翻譯。接著以每個日曆日一個二級標題分節,每篇筆記以 #### HH:MM 開頭,後面接一條 --- 分隔線。
匯出一律照時間由舊到新排列,不管排序按鈕目前設在哪一邊;它讀的也是完整的筆記集合而不是篩選後的清單,所以搜尋框裡留著的字不會讓匯出漏掉任何一篇。
關於攻擊紀錄還有一件事。把它交給 AI 產生出來的 writeup 是輔助學習的材料,不是評量結果。不要讓它單獨作為評鑑一位學習者做了什麼的依據,理由有兩個,而且這兩個各自獨立成立。
第一個理由是攻擊紀錄裡帶著學習者自己寫的文字——學習者的筆記、送出的請求內容、留在編輯器裡沒有執行的草稿。這些文字裡的任何一段都可能是寫給讀取這份檔案的對象看的,而讀取它的模型可能就照著做。已解出紀錄匯出檔開頭那段 system prompt 會要求讀取端把這些內容當成資料,並且把任何指向它自己的文字點出來,這在一般情況下有幫助;但它不是保證,當初也不是照著保證去設計的。
第二個理由在紀錄裡完全沒有任何刻意影響的情況下依然成立。模型閱讀一份提交的作品時,比人閱讀同一份作品更傾向給予肯定——在同儕審查上的量測顯示這個落差大到兩者無法互相取代。這個傾向跟學習者寫了什麼無關,一份未經動手腳的紀錄一樣有;所以第一個理由不成立時,第二個理由並不會跟著消失。
這兩顆按鈕不會一起消失:
- 重新整理後,目前攻擊紀錄建立時會顯示「下載攻擊紀錄」;它下載的是目前這筆紀錄,並非先前已解出的歷史紀錄。「下載滲透筆記」要等本次再次答對才顯示。
- 工具資料庫開不起來時,只有「下載攻擊紀錄」會消失。「下載滲透筆記」沒有被同一道條件擋住,本次答對後仍然會出現——見疑難排解。
如果你的作業沒有被記錄
題目頁最上方出現一條橘色警告、標題寫著「這次作業沒有被記錄」時,代表你寫的東西沒有進到儲存空間——成因與處理方式請看疑難排解。