facetime packet capture

facetimeはSIPを使っている。そしてオマケにSTUNでNAT超えもするという素敵機能がデフォルトで発動している。デフォルトでMac/iPhone間で通話がサクットできる。簡単にfacetimeのパケットを見てみる。

■ 環境
Macbook Pro(LAN内) iPhone5(KDDI)
ここでMacbook Proの方でWireSharkを使ってキャプチャをする。
ちなみに、MacのFacetimeのバージョンは3.0で、iOS 7.1.2。

■ 結果.1 STUNのパケット
キャプチャをしたらWireSharkのFilterの所にstunと入れるとこんな感じで見れる。

stun

Binding Requestとか良い感じに綺麗に見れますね。184.50.86.131はAkamaiのアドレスですねぇ。まぁ、ただの穴あけ機だから何でも良いんだろうけど。

■ 結果.2 SIPのパケット
STUNでMac-iPhone間が直接UDPで通信可能になったら、次はSIPですね。同じくFilterの所にsipと入れると中身がごっそり見れる。暗号化は一つもしていない男前っぷりというか、Appleにしては思い切ったことしてますね。

黒いところはMac側のGlobal IPが入っているので塗りつぶしています。INVITE/100 Trying/180 Ringing/200 OK/ACK/BYE/200 OKといった感じで基本的なSIPのプロトコルの流れが見れますね。106.128.94.223というIPはKDDIのLTEの所にあるnatterのIPですね。そこの16402に対してUDPのパケットを投げると、直接通信が出来るというUDP Holepunchingの仕組み。

■ 結果.3 SDPを見る
INVITEのbody部にはSDPが入っているけど、そのままだと見れない。さっきのINVITEのヘッダを見てみると、”e: deflate” と書いてある…そう、SDP部分は圧縮されている。そこで、次のようにしてSDP部分は見る。

まず最初にSDP部分のデータをローカルか何かに保存する。こんな感じで。

とりあえずここではsdp.datとして保存した。次にPHPのスクリプト(別にPHPじゃなくてもuncompressできれば何でも)で保存したデータをuncompressする。こんな感じで。

$filename = "./sdp.dat";
$handle = fopen($filename, "rb");
$contents = fread($handle, filesize($filename));
fclose($handle);
$uncompressed = gzuncompress($contents);
echo $uncompressed;

すると、次のようなSDPの中身が見れると思う。

v=0
o=GKVoiceChatService 0 0 IN IP4 210.172.128.230
s=niisato
c=IN IP4 [IPアドレス]
b=AS:2000
t=0 0
a=FLS;VRA:0;MVRA:0;RVRA1:1;RVRA2:1;AS:2;MS:-1;LF:-1;LTR;CABAC;CR:3;PR;AR:8/5,2/3;XR;
a=DMBR
a=CAP
m=audio 37338 RTP/AVP 104 105 106 9 0 124 122 121
a=rtcp:37338
a=fmtp:AAC SamplesPerBlock 480
a=rtpID:3398691976
a=au:67072
a=fmtp:104 sbr;block 480
a=fmtp:105 sbr;block 480
a=fmtp:106 sec;sbr;block 480
a=fmtp:122 sec
a=fmtp:121 sec
m=video 37338 RTP/AVP 126
a=rtcp:37338
a=rtpID:1321803278
a=rtpmap:126 X-H264/90000
a=fmtp:126 imagesize 0 rules 15:320:240:320:240:15
a=imageattr:126 send [x=320,y=240,fps=30] [x=480,y=368,fps=30] [x=640,y=480,fps=30] [x=1280,y=720,fps=30] recv [x=320,y=240,fps=30] [x=480,y=368,fps=30] [x=640,y=480,fps=30] [x=1280,y=720,fps=30]

セッション名(s=niisato)の所にオイラのMac上のアカウント名が見れちゃってるんだけど、まぁ別にこれくらいなら良いか…わりとイヤな感じがするけど…あと、IPアドレスの所はMacが居るLANのGlobal側IPが入ってくる。
ここでサクッと分かるのは、RTCPのポートは37338、オーディオ(m=audio)にはPCMU、G.722、AACとか。ビデオはH264ですね。

■ 結果.4 RTPを見る。
RTPはSIPでセッションが確立した後に利用されるプロトコルで、実際に話していたり、ビデオ通話しているデータが流れている。これも特に暗号化されていないで丸っと見れるので、確認するにはとっても便利。

まず最初にセッション確立後にRTPのポートに流れいるUDPのパケットを調べる。

次に、このUDPのパケットをRTPにして見る。Decode Asを選択して…

RTPをポチっと。

すると一覧で見れるようになる。

Appleの所に書いてあった感じだとSRTPでエンドtoエンドで暗号化されるとかってあったと思うけど、メディアデータの所は単純にこのパケットから再生しても再生できない。つまり、メディアの所は暗号化(AES-256)の所っすかね。パケットを詳しくは見ていないから分かんないけど、STUNでend-to-endで接続の時か、他の所で何かTCPでサーバと話している所もあったりして、まぁどっかで鍵は渡してるんでしょうね。

メディア暗号化の所以外は、STUN-SIP/SDP-RTPの部分は確認できるんで(平文だし)、興味があったら見てみても良いと思われ。

「facetime packet capture」への2件のフィードバック

  1. お疲れ様でした。しかし、SDPの中で、imageattrの使い方が間違ってます。
    あれはRFC6236で定義されてますがfps=30のようなのは使えないんです。

    1. あくまでfacetimeのSDPをキャプチャした内容なので、僕は手を加えていません。SIP/SDP自体、RFCにきっかりしている物以外に、方言や独自仕様が沢山あると思っているので。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください