被漂移拖垮的高 SF | No Name on the Door | GaianSpace CTF 2026
🌐 English version: English
系列第六篇。上一篇〈Two Voices〉衛星還用標準的 SF9,這題它則是被陌生人改了下行設定,變成隱式標頭 + 每個封包不同的 SF,而且高 SF 的符號很長、都卜勒/時鐘漂移會讓解碼在中段開始出錯,這是解調器被逼到要加漂移修正的一篇
系列其他篇:Channel Hop、True Color Is a Lie、Isodata Seven、Subsidy Claim、Hopscotch
題目在講什麼

01:40。陌生人還在對 GAIAN-723 說話,衛星每隔幾分鐘回應一次,但每個回應都用地面站數據機「拒絕聽」的聲音。GAIAN-723 改變了說話方式:封包不再標示長度,而且每個封包聽起來都和上一個略有不同。地面站記錄在 01:31 有一行:DL CFG CHANGED BY TC — NOT FROM MOC
目標:找出衛星在 01:37 確認陌生人指令時回報的二氧化碳讀數,以及它說自己已經醒著多久。
Flag 格式 GAIANSPACE{[CO2 in ppm]_[uptime in seconds]}。
每個封包的 SF 都不一樣
記錄顯示下行設定在 01:31 被遙控指令改掉,之後「標頭不見、長度不明」也就是 隱式標頭
這份錄波是 01:36 滾動後的新片段,起點 01:36:45,所以 01:37 在錄波的第 15 秒之後。
量各頻段能量,找出 8 個衛星封包,然後用前導碼峰值對 SF 7–12 做搜尋,結果每個封包的 SF 都不一樣(SF7、8、9、10 輪流),這應該就是對應到題目說的「每個聽起來都略有不同」
| 開始(s) | 長度 | SF |
|---|---|---|
| 7.50 | 0.84 s | 10 |
| 13.07 | 0.57 s | 8 |
| 34.88 | 0.84 s | 10 |
| … | … | … |
陌生人的指令是短而強的脈衝(SF7、BW250k)。錄波起點 01:36:45 + 34.65 s ≈ 01:37:19,所以那個指令之後最近的衛星封包(34.88 s、SF10)就是題目要的 ACK
高 SF 的漂移修正
這題最難的封包是 SF10,SF(Spreading Factor,展頻因子)越大,每個符號就越長,像是 SF10 一個符號要 4096 個Sample(SF7 才 512),所以符號拖得越久,下面這個問題就越致命。
什麼是漂移? 衛星在天上以每秒好幾公里的速度飛,收發兩邊的頻率會因為都卜勒效應(就像救護車經過時音調會變)而持續偏移;再加上兩邊石英振盪器本身的時鐘誤差,整段訊號的頻率不是固定偏一格,而是一路慢慢滑動,符號越長,一個封包之內滑掉的量就越明顯。
它怎麼影響到解碼? 回憶一下解調骨架:每個符號 dechirp 後會得到一個 FFT 峰值,峰值落在哪個整數 bin 就是這個符號的值。
但漂移會讓峰值不是剛好落在整數格上,而是帶一個小數(例如落在第 100.2、100.35、100.5 格……),而且這個小數部分會隨時間一路變大
我量到它從 −0.2 慢慢漂到 −0.5,再翻到 +0.5。
一開始偏 0.2 格,四捨五入還能進對格子;可是漂到接近 0.5 時,四捨五入就會跳錯一格,於是封包前半段解得對、後半段從 CO2= 附近開始變成亂碼,這就是「只用一個固定偏移會在中段崩掉」的原因~
所以要先確認問題純粹來自漂移:這個 ACK 封包的頻譜圖是乾淨的 chirp,中途沒有跳頻、沒有被干擾:

修正法分三步:
- 把每個符號峰值的小數部分抓出來,沿時間排成一條曲線;
- 因為小數到 ±0.5 會「繞一圈」跳回去,先用
np.unwrap把這種跳接補成連續的曲線; - 用一條二次多項式去擬合它(漂移是平滑的,二次就夠),再把這條擬合曲線從每個符號的 bin 裡扣掉,峰值就乖乖回到整數格。
左圖是符號峰值的漂移(藍點)與二次擬合(紅線),右圖是封包與指令的時間表:

扣掉漂移後整個封包就解乾淨了。這封包結尾還帶一個 CRC-16(*18FC),我用 CCITT 參數重算完全吻合,等於幫「解對了」再蓋一個章
結果
1 | TM,ACK,1,GET HK,HK,V=4.51,I=0.1,T=21.82,P=996.24,CO2=432,UP=132*18FC |
題目要 CO2 與 UP(開機秒數):CO2=432、UP=132。這裡有個陷阱:01:36:52 那次也有一筆幾乎一樣的 ACK(CO2=424,UP=105),只能靠時間區分,先把錄波起點換算成實際時間,才對得到 01:37 那一筆。兩次的 UP 相差 27 秒,跟兩次回應的時間差吻合,可以交叉驗證
Flag
1 | GAIANSPACE{432_132} |
心得
- 「每個封包都不一樣」往往就是 SF 或 BW 在跳。 先對每個封包獨立做參數搜尋,別假設前一個封包的參數可以沿用。
- 隱式標頭沒有長度也沒有 CR:長度用在空中的符號數推,CR 用「哪一個能解出乾淨文字或通過 CRC」決定。 開頭幾位元組對得上但後面亂碼,常常是 CR 或漂移的問題,不是整個方向錯了。
- 高 SF 符號很長、對漂移非常敏感。 畫出符號峰值小數部分的走勢,一眼就能看出漂移,用解纏繞 + 多項式擬合修正。
- 兩個外觀一樣的 ACK 只靠時間區分。 要先把錄波起點換算成實際 UTC,再對應題目說的時刻,才不會拿錯那一筆。下一篇〈Hopscotch〉衛星更進一步——改成在多個頻率之間跳(FHSS),解調器得先把跳頻序列拼回來才能解。


