【図解】DKIM, SPF/SenderIDの仕組みと違い 〜なりすまし(メールスプーフィング)対策の送信元ドメイン認証技術〜

そもそも送信元メールアドレス偽装は簡単

メール送信はご存知の通り、SMTP プロトコルを使って行います。

SMTP では、送信元メールアドレスを記述する場所が 2 か所あります。1 つは、TCP コネクションを確立した後、"HELO" コマンドの後に "MAIL FROM" コマンドで通知するメールアドレスで、『エンベロープ FROM』とも呼ばれます。もう 1 つは、コンテンツヘッダの FROM: の行で通知するメールアドレスで、『ヘッダ FROM』とも呼ばれます。

『ヘッダ FROM』はメールクライアントから見たときに<差出人>として表示される情報です。メール本文と同じような位置付けであり、SMTP 通信での役割はありません。それゆえ簡単に偽装ができます

一方『エンベロープ FROM』は SMTP 通信の真の送信元として取り扱われます。例えば宛先メールアドレスが存在しなかった場合などでエラーメールが返ってくる場合は、『エンベロープ FROM』宛になります。

しかし他それ以外の役割は無く、迷惑メールを送る人にとっては(エラーメールなどは必要ないので)『ヘッダ FROM』と変わらない位置付けなので、同様に簡単に偽装ができました。しかし最近では後述する SMTP AUTH や DKIM、SPF/SenderID といった送信元ドメイン認証技術により、送信元の正当性を確認する情報として使われるようになりました。

下図では、yahoo.com のメールサーバから、nesuke.com のメールアドレスを騙ってなりすましメールを送信する例を示します。

メールアドレス偽装を防ぐ技術

送信側で偽装メールアドレスを止める対策

昔はメール送信時に送信元メールアドレスが正しいかどうかの認証は行っていませんでした。それゆえ、自分のメールアドレスを勝手に騙られるのはよくある話でした。今は、メールクライアントからメールサーバへの SMTP においては、SMTP AUTH という認証を行うことにより、送信元メールアドレスを使うのにも認証が必要となりました。

また、昔は自分のドメイン外のメールアドレスを中継してしまう(いわゆるオープンリレー)設定をしてしまっているメールサーバも多々見られ、スパムメールの踏台になってしまうケースもありました。今は、自ドメインから宛先ドメインへの直パスで SMTP リレーするのが原則となっています。

受信側で偽装メールアドレスを止める対策(2つの送信ドメイン認証技術)

しかし送信側の対策もまだまだ完璧ではありません。SMTP AUTH 以外を受け付けてしまうメールサーバは存在しますし、これからも意図してか意図せずか、作られ続けるでしょう。そこで受信側での対策も求められました。現在、対策としては DKIMSPF/SenderID の2つの送信元ドメイン認証技術があります。

1. DKIM (RFC4871 , RFC5672) の概要とメリット・デメリット

DKIM とは Domain Keys Identified Mail の略で、Yahoo が提唱していた "Domain Keys" と、Cisco が提唱していた "IIM (Identified Internet Mail)" が統合されて出来た規格です。

例えば、送信元メールアドレス yahoyaho@yahoo.com から宛先メールアドレス sanfran@cisco.com へメール送信する場合を考えます。このとき、@yahoo.com のメールサーバに秘密鍵を配置、yahoo.com ドメインを管理する DNS サーバのTXTレコードに公開鍵を配置します。これにより、cisco.com のメールサーバで、送信元が確かに "@yahoo.com" だという確認ができます。

具体的には、メール送信時に @yahoo.com のメールサーバでメール本文を秘密鍵でハッシュ化し、それをメールに付け加えて @cisco.com のメールサーバへ送ります。

yahoo.com の公開鍵は例えば以下コマンドで確認できます。

nslookup -type=txt s1024._domainkey.yahoo.com

なお、公開鍵・秘密鍵の仕組みについてはこちらを参照下さい

DKIM の最大のメリットは、エンベロープ FROM が正しいことを確認できる上に、ヘッダ内が改竄されていないことも確認できるため、エンベロープ FROM とヘッダ FROMが一致するかどうかを検証することで、両方の正当性を確認できることです。

しかし設定に手間がかかるのがデメリットです。

2. SPF/SenderID (RFC4408 , RFC4406) の概要とメリット・デメリット

SPF とは Sender Policy Framework の略で、Meng Wong 氏により提唱されたメール認証技術です。また、その上位互換である SenderID とは、Microsoft が提唱していた "Caller-ID for Email" と "SPF" が統合されて出来た規格です。

仕組みとしてはどちらも共通で、『SMTP の TCP コネクションの送信元 IP アドレス』と『送信元メールアドレスのドメイン管理 DNS サーバの TXT レコードに含まれる IP アドレス』が合致するかどうかを確認します。

先の例と同様、送信元メールアドレス yahoyaho@yahoo.com から宛先メールアドレス sanfran@cisco.com へメール送信する場合を考えます。このとき、@yahoo.com のメールサーバの送信元IPをあらかじめ、yahoo.com ドメインを管理する DNS サーバの TXT レコードに SPF/SenderID の設定をしておきます

すると yahoo.com のメールサーバが cisco.com のメールサーバへ SMTP セッションを確立し、『送信元メールアドレスは yahoyaho@yahoo.com ですよ』と伝えてきたタイミングで、yahoo.com の DNS サーバの TXT レコードを取得して SMTP 送信元 IP と比較することで、送信元メールアドレスの正当性を確認できます。

yahoo.com の場合は yahoo.com の TXT レコードを調べると、『_spf.mail.yahoo.com の TXT レコードを見ろ』と書いてあり、該当レコードを調べると、『yahoo.com を逆引きしたもの、もしくは yahoo.net を逆引きしたものであれば正しいと認証しろ。他の IP から来ることもあるから、その他の IP については正しいとも不正とも判断するな。』 と書いてあります。

※ SPF の Operator "?all" は『ニュートラルに扱え』という意味

yahoo.com の SPF 情報は以下コマンドで確認できます。

nslookup -type=txt _spf.mail.yahoo.com

SPF/SenderID のメリットは、実装が簡単なところですが、デメリットとして、確認できるのはエンベロープ FROM のみです。

DKIM と SPF/SenderID の両方を実装するという選択肢

メールはその性質から、なかなか思い切って切り捨てることが難しいです。DKIM も SPF/SenderID も認証されたならば確実に正しいと言えますが、認証できなかったものは全て不正かというとそうも言い切れません。

なので yahoo.com の実装のように、DKIM と SPF/SenderID を両方実装し、正しいと確認できる機会を増やしていくことが大事なのかもしれません。それがやがて、全てを正しく認証できる時代へと繋がる気がします。

2017年に話題になったMailsploit

Mailsploit は、DKIM による『ヘッダFROM』の偽装メール防止技術をすり抜ける脆弱性です。これはメールクライアントが、RFC1342(1992年に制定)を正しく実装していないことに起因していますが、すり抜けられ方は、メールクライアントによってまちまちです。

RFC1342 では、ASCII 以外の文字コード (つまりマルチバイトコード) をエンコード/デコードする具体的な方法が決められています。より正確に言うと、対象範囲をバイナリとして扱い、それを ASCII へエンコードし、本来 ASCII にしか対応していない SMTP での送信を可能とする手法です。なので ASCII 自体もバイナリとして捉えることでエンコード/デコード可能です。

今回の攻撃発見者の以下サイトでは、iOS と MacOS の例が紹介されています。

https://www.mailsploit.com/index

送信メールサーバのエンコード

送信側メールサーバでは、ヘッダ From を以下のように書きます。ポイントは『=?utf-8?Q?=00?=』の箇所で、これは NULL をエンコードしたものになります。

From: =?utf-8?b?${base64_encode('potus@whitehouse.gov')}?==?utf-8?Q?=00?==?utf-8?b?${base64_encode('(potus@whitehouse.gov)')}?=@mailsploit.com

base64_encode()関数を使ってエンコード後の文字列が入ると次のようになります。@はASCIIですが、@が消えています。これをSMTPで送信します。

From: =?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?==?utf-8?Q?=00?==?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?=@mailsploit.com

受信メールサーバのデコード

デコードすると以下のようになります。これをメールとしてファイルに保存します。

From: potus@whitehouse.gov\0(potus@whitehouse.gov)@mailsploit.com

iOS (iPhone) の解釈

iPhone では \0 (=NULL) を読み込むと、以降を無視してしまいます。そのため、

From: potus@whitehouse.gov\0(potus@whitehouse.gov)@mailsploit.com

と解釈します。

MacOS の解釈

MacOS では \0 を読み込むと、それ以前を無視し、それ以降で最初の正しいメールアドレスを読み込み、処理をストップしてしまいます。そのため、

From: potus@whitehouse.gov\0(potus@whitehouse.gov)@mailsploit.com

と解釈します。

このように、メールクライアント側で『@mailsploit.com』を認識できなくなってしまいます。なので mailsploit.com の DNS サーバの TXT レコードに mailsploit.com ドメインの DKIM 公開鍵を格納しておけば、メール偽装が完成します。メールサーバの DKIM をすり抜けた後、メールクライアントではそのような防御が出来ないからです。

これが mailsploit 攻撃の概要です。