Feitian U2F NFC 和 macOS 上面 U2F 的現狀

最近取得一個 Feitian (廠牌)製造的 U2F Key ,除了拿來當作線上帳號二階認證的因子之外我還想要研究一下能不能拿它來登入 MacOS 、放我的 ssh key,研究了很久才發現 U2F 和放 ssh key 完全是兩個不同的功能。

有三個常見相關的功能:

  • U2F: challenge-response 式的二階認證標準
  • CCID: 可以產生和儲存 RSA 或是 Elliptic curve key 的智慧卡,這就是儲存 ssh key 或是 PGP key 需要的功能
  • TOTP: 用對稱式金鑰產生 one time password 的協定

像是 Yubikey 4 有標示支援 OpenGPG,應該就表示支援 CCID ,Yubikey 也要靠他們出的軟體來切換 U2F/CCID/TOTP 模式。

另外我原本擔心我的 Feitian U2F key 有沒有受到之前 Infineon 晶片有爆出 RSA key generation 弱點的影響,查了之後才知道這個弱點不影響 U2F 的安全性,只會影響智慧卡(CCID)的部分。

U2F

U2F 除了可以拿來登入線上服務之外也可以拿來登入作業系統,通常是透過安裝和設定 pam-u2f ,這個網路上教學很多這邊就先不寫。

相關專案:

CCID

有幾個和 CCID 相關的專案:

其他

Feitian U2F key 似乎可以切換成 CCID 模式,只是要用他們家奇怪的 windows 應用程式,現在手邊沒有 windows 所以就沒有測試。

然後雖然現在已經 Firefox 60 了,Google 帳號還是不支援在 Firefox 上面使用硬體金鑰當作第二階段認證因子…… fuck you google

參考

Using Alt+Arrow keys in vim inside tmux

tmux seems to send different key sequences to vim, so I had to add both to vimrc:

nmap :tabprev
" Alt+left arrow inside tmux
nmap ^[[1;3D :tabprev
" Alt+left arrow outside tmux
nmap ^[[1;9D :tabprev
nmap :tabnext
" Alt+right arrow inside tmux
nmap ^[[1;3C :tabnext
" Alt+right arrow outside tmux
nmap ^[[1;9C :tabnext

 

You’ll need to use Ctrl+v to input the keys to vimrc, see this article.

And iTerm2 needs to be configured, Left Alt Key (or right if you want) = Esc+

Relevant articles (not sure what their relations are):

也來罵臉書好了

最近罵 facebook 很夯,而且不斷來到新高點,隨便找幾篇:

不過類似的評論已經出現很久了,去年九月就有了這篇: Facebook’s war on free will

然後還有衛報最新力作 Revealed: 50 million Facebook profiles harvested for Cambridge Analytica in major data breach

各方終於要開始表示擔憂調查跳船(後來又澄清說不跳)啦。

我反而認為有些描述和理解過於誇大了,現在所報導關於臉書的大部分負面新聞,不過是臉書本來的運作方式罷了,人們只是現在才開始關心。

以最新的 Cambridge Analytica 消息來說,他們不過是利用了一個應用程式,向使用者詢問能不能取得他們的資料,然後真的取得了他們的資料。碰巧,早期臉書的 API 允許開發商拿到授權使用者的朋友的資料, CA 就拿這些資料來分析。(當然有另一個合理說法是說臉書故意不關閉這個 API 來吸引開發者)這樣的資料使用模式,怎麼會是報導中所稱的「Data breach 資料外洩」呢?一點都沒有外洩,反而是使用者自己同意釋出這些資料的。

當然,在這個案例當中,臉書仍然有錯,錯在並未詳細說明使用者同意第三方開發者使用資料之後可能的風險。(但使用者知識也大概低落至於壓根不知道什麼叫做「授權第三方開發者取得個人資料」吧,從台灣的新聞報導,講得好像開心農場是臉書的一部分一樣)

現今的使用者仍然對這樣的資料請求缺乏戒心,更缺乏理解,科技公司不斷說「相信我們!提供你的個資,我們會好好保護,為你帶來方便!」,然後使用者就按同意了。

我覺得以這個使用者使用科技前不詳加瞭解的模式,未來還是會在同樣的模式下被科技公司所剝削。

不過我想,這是大眾運作的常態,在接觸新科技的時候,從來不會去瞭解背後的原理,只想著新科技的方便,等到大家開始發現新科技的負面影響、剝削人的一面的時候,科技公司早就賺飽飽了。

我從以前就不喜歡 Facebook ,然而原因與現在的人們不同,我反而覺得,現在人們反對臉書的原因,是因為他們現在才開始意識到這個商業模式真正的運作方式,這個商業模式是內稟的、天生的,這個公司(或者說產業)從誕生至今就是以這個模式運作的,本身並沒有錯,錯、該罵的地方在於關於這項科技的商業模式和運作原理,公司從來沒有投入足夠的資源去說明(甚至惡意不公開),讓人們充分理解他們選擇使用的後果,然而使用者們也沒有投入適當的心力去設法瞭解這個商業模式和運作原理。

我會說,科技的使用者應該要負起更多的責任去瞭解他們所使用的科技,而不是一開始什麼都沒有想,為了開心農場就加入,然後現在再來抱怨臉書侵犯他們的個人隱私。我瞭解現在的狀況並非如此,甚至反而是歷史上大多數科技普及進程中自然進行的模式,並且人性也不是這樣的,大多數人不會去思考自己的選擇,就算他們要開始思考自己的選擇,在科技領域來說,相關資訊還是非常的不透明,也缺乏普及、一般人能夠瞭解的說明來源(例如科普媒體)。

在這個科技普及進程裡面,科技公司也缺乏誘因去仔細說明他們的科技,更別說教導人們「恰當」使用科技,畢竟,如果跟使用者說「在使用我們產品以前請仔細考慮以下事項」,誰還會想要使用你的產品啊。現在的「創新創業」模式講求的破壞性創新、早期的高成長,被產業和大眾視為理所當然,然而這樣的高成長,我認為必須要仰賴這種使用者對底層科技的不瞭解(而這些不瞭解造成了剝削)才能達成。那些使用者條款、設定選項,對於新創企業的用途也都只是在於使用者抱怨,或是受到批評的時候,讓他們可以說「哦我們有提供這個選項啊」、「我們的條款裡面已經有寫了,請使用者使用前詳細閱讀條款再決定是否使用」。

然而,在這個一方想要賺錢,另一方不求甚解的狀況下,主要會蒙受損害、被剝削的,只有使用者而已。使用者若不自己多花一點心力去瞭解所使用的科技,會受害的也只是自己而已。

使用者從頭到尾並未仔細思考自己註冊、提供資料所帶來的後果,一開始什麼都沒想就加入臉書,現在則是發現臉書使用資料的方式跟自己想像的不同,然後就開始抵制。這次大家開始意識到臉書某種程度上是惡意的而開始離開,這是件好事,但我總覺得使用者如果持續在使用科技的時候不多加思考,以後還是會以同樣的模式被其他科技公司「背叛」。

以現在大眾傳播的模式,我猜臉書又會成為千古罪人,沒有人會注意到 Instagram, Google, Whatsapp, Apple 等等,這一堆科技公司都是使用同樣的模式在賺錢和運作的—— data exploitation 。

還看到有人開了競賽說要建一個更好的臉書替代品,我覺得有點諷刺,現在使用者們從來不想要像是 email 這樣的開放系統,只想要一個最大的公司,信任他們,給他們所有的資料,可以提供他們最好最方便的服務,而且當然要是免費的。或者說,使用者永遠都是要又要馬兒跑得快又要馬兒不吃草,然而這本來就是不可能的事情嘛,唯一達到「馬兒跑得快又不吃草」的方法,就只有欺騙使用者囉。

現在有篇廣泛流傳的文章《如何防止臉書偷走我們的一切》,我想要指出文中一些與原始報導有出入的地方:

事件爆發後越來越多新的進展曝光,包括將臉書用戶數據賣給Cambridge Analytica的其實是臉書總部裡的心理醫生Joseph Chancellor,而Facebook的一名員工Parakilas也向衛報爆料他的主管如何下封口令,以掩蓋這起醜聞。

這段文字讀起來像是臉書公司自己將用戶資料賣給 CA,然而其實不是,在衛報的原始報導中是這麼說的:

Joseph Chancellor was one of two founding directors of Global Science Research (GSR), the company that harvested Facebook data using a personality app under the guise of academic research and later shared the data with Cambridge Analytica.

He was hired to work at Facebook as a quantitative social psychologist around November 2015, roughly two months after leaving GSR, which had by then acquired data on millions of Facebook users.

Chancellor is still working as a researcher at Facebook’s Menlo Park headquarters in California, where psychologists frequently conduct research and experiments using the company’s vast trove of data on more than 2 billion users.

所以說,收集資料的是 GSR 公司,收集的方式是利用他們開發的 thisisyourdigitallife 臉書第三方應用程式,並且告知使用者將會把他們的資料用於「學術用途」。後來將資料賣給 CA 的不是臉書,而是 GSR ,而這個資料販賣已經違反臉書的平臺條款,然而臉書也並沒有去進行查核,事實上一旦使用者授權第三方從臉書伺服器取得他們的用戶資料,資料一傳輸到第三方伺服器,臉書就幾乎沒有辦法檢核資料是否被合理使用,即使在發現違反平臺條款的使用的時候,也沒有什麼方法可以防止用戶的資料外洩。從衛報原文中也看不出來 GSR 把資料賣給 CA 是在 Joseph 離開前還是離開後。總之 Joseph 離開後就去臉書工作了。所以整件事應該是說「臉書的員工之前所創辦的公司把該公司收集到的使用者資料賣給了 CA」。

再來,Joseph Chancellor 是劍橋大學心理系的博士後研究助理,有社會心理學博士學位,但是以台灣的標準而言不算是「心理醫生」,但中文作者翻譯誤將有 Ph.D 的 Dr. 翻譯為「心理醫生」。

然後,我也找不到「Facebook的一名員工Parakilas也向衛報爆料他的主管如何下封口令,以掩蓋這起醜聞」在任何報導中的相關文句,最接近的是 Parakilas 在華盛頓郵報的投書

Here’s an example of how an investigation into one such issue played out during my time at the company: In late 2011, it was revealed that an app called Klout was creating “ghost” profiles of children. These public profiles were not created or authorized by the children and were reportedly based on friend data from adults who had authorized the Klout app. As the lead for platform data protection issues, I had to call the leadership of Klout and ask whether it was violating any Facebook policies, because we couldn’t see what it was actually doing with the data. The leadership swore it was not in violation. I reiterated the importance of following the policies, and that was the end of our call. Facebook took no further action, and Klout continued to access Facebook data, though it turned off the ghost profiles feature.

While Klout was an unusual case because the alleged violation was publicly visible, other less visible data protection issues happened regularly during my tenure. Facebook had the following tools to deal with these cases: It could call the developer and demand answers; it could demand an audit of the developer’s application and associated data storage, a right granted in the platform policies; it could ban the developer from the platform; it could sue the developer for breach of the policies, or it could do some combination of the above. During my 16 months at Facebook, I called many developers and demanded compliance, but I don’t recall the company conducting a single audit of a developer where the company inspected the developer’s data storage. Lawsuits and outright bans were also very rare. I believe the reason for lax enforcement was simple: Facebook didn’t want to make the public aware of huge weaknesses in its data security.

Concerned about the lack of protection for users, in 2012 I created a PowerPoint presentation that outlined the ways that data vulnerabilities on Facebook Platform exposed people to harm, and the various ways the company was trying to protect that data. There were many gaps that left users exposed. I also called out potential bad actors, including data brokers and foreign state actors. I sent the document to senior executives at the company but got little to no response. I had no dedicated engineers assigned to help resolve known issues, and no budget for external vendors. Facebook’s users were being protected by whatever external partnerships I was able to strike without having to pay those partners. The only time my team got any attention was when negative articles appeared in the press.

簡單來說,臉書的上層主管只是冷處理了這件事情,並沒有「下封口令」,以當時的狀況來說,他所回報的東西其實都是相對小事,像臉書這樣的公司根本不會去處理。

參考資料

反編譯、分析、閱讀 Android 應用程式原始碼,以 17直播為例

有些 Android 應用程式會要求過多的權限,如果不給它的話還不讓你使用應用程式,但明明這權限就很不合理啊。

以 17 直播為例,看個直播幹嘛要存取我的檔案?

https://dl2.pushbulletusercontent.com/N86YBB9oAlvoEPmGO6QyO9NJvSDoFD9c/Screenshot_20180225-141150.png

看了就很不爽,就是這樣的應用程式訓練出毫不眨眼就隨便給出權限的使用者,所以今天拿它來開刀。

找出顯示中的 Activity

首先用 adb shell dumpsys activity 瞭解一下目前是哪一個 activity :

ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
  Stack #1:
    Task id #7379
    * TaskRecord{b876752 #7379 A=com.machipopo.media17 U=0 sz=1}
      userId=0 effectiveUid=u0a204 mCallingUid=u0a204 mCallingPackage=com.machipopo.media17
      affinity=com.machipopo.media17
      intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.machipopo
.media17/.StartActivity bnds=[48,156][126,234]}
      realActivity=com.machipopo.media17/.StartActivity
      autoRemoveRecents=false isPersistable=true numFullscreen=1 taskType=0 mTaskToReturnTo=1
      rootWasReset=true mNeverRelinquishIdentity=true mReuseTask=false mLockTaskAuth=LOCK_TASK_AUTH_PINNABLE
      Activities=[ActivityRecord{822c1b8 u0 com.machipopo.media17/.activity.MenuActivity_V2 t7379}]
      askedCompatMode=false inRecents=true isAvailable=true
      lastThumbnail=android.graphics.Bitmap@80a2cec lastThumbnailFile=/data/system/recent_images/7379_task_thumbnail
.png
      stackId=1
      hasBeenVisible=true mResizeable=false firstActiveTime=1519539613444 lastActiveTime=1519539613444 (inactive for
 26s)

主要是看 Activities= 那一行,就知道目前的 activity 是什麼。

反編譯取得原始碼

我已經裝好了 Mobile Security Framework ,直接上傳 APK 檔案就可以反組譯,還會順便做一些其他分析。

到安裝 MobSF 的目錄底下有個 uploads 資料夾, APK 的 checksum 就是資料夾名稱,進去之後會看到幾個資料夾:

接下來的重點就是看 java_sourcesmali_source 這兩個資料夾了。

閱讀 Java 原始碼

打開 MenuActivity_V2.java ,往下捲一下很快就看到:

顯然就是檢查有沒有寫入外部儲存空間權限的函式,我猜測它的行為如下:

  1. 呼叫 android.support.v4 API ,檢查使用者是否已經授權存取外部儲存空間(269 行)
  2. 如果沒有授權的話,把字串 android.permission.WRITE_EXTERNAL_STORAGE 加進 arrayList 。也就是說,arrayList 裡面的字串代表應用程式還需要的權限。
  3. arrayList 的長度,設為 n2 ,然後回傳。

再找一下 F() 它的 caller 有誰,搜尋了一下,只有這個函式:

在 1410 行的 if 檢查了 this.F() 是不是回傳零,也就是「應用程式所需要的權限數量是不是零」,如果不是零的話,執行 1411~1414 this.n 的相關操作。

看到它在 1411 行檢查了 this.n 是否為空,如果不為空的話呼叫 this.n.dismiss() ,初步猜測 this.n 就是上面截圖中對話框的控制 class ,而 1411~1412 則是在檢查目前有沒有已經開啟的對話框,如果有的話,把它關閉 (dismiss) 。

在檔案開始處 MenuActivity_V2 class 的屬性型別宣告證實了我的猜想:

從 207 行,我們得知 this.n 的型別是 com.machipopo.media17.fragment.dialog.e ,看起來就是個對話框 (dialog) 。

至於對話框 class 要怎麼操作,現階段不是很重要,畢竟我們只需要把對話關掉(應該說是完全不要呼叫顯示對話框的函式)就好了。

關掉對話框有很多種方法,但由於我們實際上要修改應用程式的行為光是改 java code 是沒用的,需要修改 smali code ,因此我想還是先看看它的 smali code 長什麼樣子,再思考要怎麼修改比較方便。

閱讀 smali 原始碼

一樣在 uploads 資料夾裡面,可以找到 smali_source/com/machipopo/media17/activity/MenuActivity_V2.smali 這個檔案,也就是對應 MenuActivity_V2.java 的 smali 原始碼。

首先我們需要先找到 F() 的 caller ,也就是 onStart()

雖然說我根本就沒學過 smali (應該只有研究 Java VM 的人才需要瞭解 smali 吧),但稍微看了整個 smali 原始碼,還是可以看到一些規律,加上一些背景知識就可以看懂一段 smali code 的行為。

smali 看來還是蠻高階的東西,簡單搜尋了一下 onStart 字串,就找到這一段:

什麼 Singleton , AppLogic 的,跟 Java code 裡面的名字一樣,因此確定從 5621 行就是 onStart() 沒錯。

往下到 5648 行,就看到呼叫 F() 的指令:

5649 行的行為,猜測大概就是呼叫 F() ,而 F 會回傳一個整數 (I) ,這個回傳值會放在 {p0} 裡面。

5651 行把 {p0} 裡面的結果移動到 v0

5653 行是重點,判斷 v0 是否為零 (equal to zero, eqz) ,如果是的話 jump 到 :cond_81 ,如果不是的話繼續執行

以上 5649~5653 這段 smali code ,對應的 Java code 是 1410 行 if (this.F() != 0 && Build.VERSION.SDK_INT >= 23) { && 前面的東西。

瞭解了以上行為之後,看得出來,如果在使用者有給出所有權限的狀況下:

  1. F() 會回傳零
  2. 在 5653 的判斷會成功,直接跳到 :cond_81

因此 :cond_81 之後就是我們想要的行為(回歸正常操作),而 5653 ~ :cond_81 這段則會跳出對話框,不斷阻擋我們操作。

看一下 :cond_81 會做什麼:

5768~5772 對應到 Java code 1416 的 com.machipopo.media17.business.AppLogic.a().o((Context)this);

最後的 goto 則是 1418 行 if (com.machipopo.media17.business.AppLogic.a().b(.......

綜合以上判斷,我們需要修改的地方,就是把 5648 ~ :cond_81 這段行為,完全刪除,如此一來,無論 F() 的回傳值為何, 1416 行檢查權限成功之後的行為都會照常執行。

重新組裝 APK

關於整個反編譯和重新 build apk 的流程,可以參考 Huli 的這篇《人人都會的 apk 反編譯》。

用 apktool 反編譯原始碼(其實直接用 MobSF 反編譯出來的應該也可以用,但為了避免 apktool 沒辦法把 MobSF 反編譯的原始碼包回去,省點 debug 的力氣,還是就另外用一次 apktool),然後照著剛剛的規劃,刪掉 5648 ~ :cond_81 的東西。需要特別注意的是,用 apktool 反編譯出來的原始碼會跟 MobSF 的有點不一樣,主要是 symbol 名稱不同,像是 cond_81 可能會是其他數字,但程式碼的結構會是一樣的,修改的時候注意一下就可以。

修改過 smali code 之後,用 apktool b xxx -o new_17.apk 它包回 apk 檔案,

然後它就發生了錯誤…:

I: Using Apktool 2.2.3
I: Checking whether sources has changed...
I: Smaling smali folder into classes.dex...
base/smali/com/machipopo/media17/activity/MenuActivity_V2.smali[5659,0] Cannot get the location of a label that hasn't been placed yet.
Exception in thread "main" brut.androlib.AndrolibException: Could not smali file: com/machipopo/media17/activity/MenuActivity_V2.smali

不確定是什麼原因(畢竟我不是很懂 smali),我猜大概是中間刪掉的 code 有什麼重要意義,所以導致後面呼叫錯誤,但沒關係,還有其他方法可以修改行為:

直接在 5651 行它把結果存入 v0 之後,把 v0 覆蓋為零(5653 行是我加入的),至於問我我怎麼知道 const/4 v0, 0x0 這種寫法?我是往上稍微捲一下, 5637 行就有這種指令,我直接改了寫上 5653 行。

解決這問題之後,使用 apktool b 的時候還有遇到另一個錯誤,照著連結中的解法,成功封裝起來了。

接下來的步驟是 zipalign 打包好的 apk,然後用 apksigner 簽章(產生 keystore 的方法見這裡),方法可以直接參考 Google 的文件

安裝問題

接下來我就把 apk 放進手機裡,然後點開安裝,它卻只會跳出「套件剖析錯誤」的提示,從 adb logcat 看詳細錯誤看到: Parse error when parsing manifest. Discontinuing installation

查了一下,照著這篇改用 adb install 安裝就可以了。

成功

https://dl2.pushbulletusercontent.com/BxEUwLrfTKMNj8HUojseWOQgRLD2rRh9/Screenshot_20180225-225223.png

再也不會有惱人的提示框啦!

參考

學習 smali 語法: http://blog.csdn.net/wdaming1986/article/details/8299996

來龍去脈

其實 17 的 app 在更早以前的版本不只會要外部儲存空間的權限,應用程式一打開,就會向你要求麥克風、相機和簡訊的存取權限,這個是 2017 年 7 月左右版本的原始碼:

當時看這個 app 我就更不爽了,應用程式一打開什麼功能都還沒開始用就跟你要一大堆權限,不給權限的話還整個不給你用,真的是非常不負責任的開發者行為。

TabHide 之後的分頁群組插件調查

Firefox 59.0a1 之後新增了大家等待已久的 TabHide 功能,所以我就來重新調查一次有什麼插件是符合我需求的了。我的希望是儘量能夠逼近 Quicksaver 原版 Tab Groups 的功能。

Conex

Conex 好像是 addons.mozilla.org 上面蠻熱門的類 Tab groups 插件,但我實測之後發現:

  1. 他的每一個分頁群組會存在一個 contextualIdentities 容器 (container) 裡面,這不合我的用途,因為
    1. 我已經把我的不同用途的 cookie store 放到不同的 Firefox 的 profile 裡面了,我希望我的所有分頁群組共用一個 cookie store。
    2. 這行為和本來 Quicksaver 的版本不一樣。
    3. 而且 contextualIdentities 我之前檢閱完之後就覺得是個設計、模組化不良的 API
  2. 似乎是因為用了 containers 的關係,建立新容器、改名容器需要到 Firefox 的設定頁面裡面手動改。

Simple Tab Groups

  1. 切換不同群組的時候,不在顯示中的群組裡面的分頁會被卸載

後來我研究了一下,發現這個插件切換分頁群組的功能完全是使用 tabs.remove() 來達成的,也就是切換的時候會把分頁關掉,換回來的時候再打開。目前他們有個 issue 是要實作切換群組的時候分頁不會被卸載

Panorama View

這個插件目前最接近我的需求,不同分頁群組使用同一個 cookie store 和 Quicksaver 的版本相比,缺少幾個功能:

  1. 清單(專屬的清單頁面或是 context menu )顯示分頁群組和群組中的分頁:正在開發中
  2. 在不同群組之間顯示一樣的釘選分頁:有 PR

另外幾個是我覺得可以加的功能,我有空研究的話可以加加看:

  1. 指定不同分頁群組的顏色,這樣會達到類似 containers 的顯示效果,但是仍然共用 cookie store 。可能可以重複利用 VivaldiFox 這個插件的程式碼來作出不同顏色。

其他

另外,閒逛的時候還發現了幾個有趣的插件:

  • Social Fixer: 各種 Facebook 延伸功能,可以過濾貼文、標示貼文為已讀、移除特定區塊等等。但可惜不是開源的。
  • Auto Tab Discard : 簡單的定時 unload 分頁套件,我在 57 前就有用其他類似的插件。

更新 2/10

我發現 Simple Tab Groups 雖然缺少最重要的功能,但是程式庫、國際化和 UI 比 Panorama View 完整。

 

OpenVPN server settings in Asuswrt-Merlin

By default username/password authentication doesn’t seem to be enabled, choose Advanced Settings in the VPN server tab:

Down below, the Cipher Negotiation default will need to be disabled to work with OpenVPN clients <2.4.0 , which are quite common (Ubuntu 16.04 LTS still has OpenVPN 2.3.10 in package repo).

By default the VPN server also does not push routes, i.e. connection will be established but the client won’t change their default route to the tunnel interface created. This action could be added in the client ovpn file redirect-gateway def1, or the settings may be “pushed" by the server to the client by adding this server directive: push "redirect-gateway def1"

Update: I didn’t notice before, the “Direct clients to redirect Internet traffic” directive seems to do just that.

這艘船載了什麼貨物呢?

在 Hacker News 上面看到這個專案: https://github.com/marcdacosta/ambient-shipping

可以查到過美國海關每一艘船上面的貨物資料,覺得很酷,一時興起來研究了一下台灣有沒有辦法這樣搞。

總之最重要的目標就是要可以查到提單 (bill of lading) 內容,引用自關務署的說明:

大提單屬有價證券,一般商業習慣均稱為提單,係由運送人所簽發,為運送契約之證明文件,是運送人或船長收受貨物之收據,也是確認貨物所有權之權利證券。大提單之格式或有差異,但大同小異,一般記載有託運人之姓名或名稱、受貨人、受通知人、貨物名稱、件數或重量,或其包裝之種類、個數及標誌、裝載港及卸貨港、運費交付、填發之年月日等事項。

試了一下之後發現有時候是真的可以查到貨物內容的:

  1. 先去 MarineTraffic 網站挑一艘你想查的船,記住船名。

  2. 海關通關號碼(原船隻掛號)查詢 (GB330) ,以船名搜尋,就可以搜尋到每個航次的海關通關號碼(原船隻掛號),還有船公司代碼、出口裝船關別(基隆、六堵等等)

  3. 再去 海運進口艙單資料查詢(GB326) 的查詢一,輸入 2 的資訊,然後勾「查詢艙單資料」,就可以搜尋到艙單號碼主提單號

  4. 再去查詢二,用艙單號碼或是主提單號就可以搜尋到報單號碼,可以拿去查這批貨物通關的時間,中間是否有被要求補件等等。但查不到我想要的提單內容。

提單在通關的時候並不是必備的文件,但海關可以要求廠商提供,但台灣關務署收到了之後看來並不會把它變成公開資料。

幸運的是我後來找到一個網站可以方便查詢各大航運公司的提單內容,但全世界的運輸公司太多,所以有很多這個網站查不到的。

在 GB236 查到的主提單號可能會有兩種格式,一種前面包含 SCAC code (像是 HPHCB17003515 ),另一種前面不包含 SCAC code (像是 0317540166 ),查提單的時候就要自己猜是哪一家公司。

SCAC code 是美國某個運輸協會管理的全世界的運輸公司的代號,每個運輸公司會有自己獨有的代號。

部分的 SCAC code 可以從這份文件裡面查到: https://gist.github.com/allada/c10ca4a5751b6546dbec ,但我試過像是 HPHC 就查不到。

有時候運氣好的話就真的可以查到貨櫃內容: