ブラジル、Undead Secによるフィッシング攻撃等で使われるIDNホモグラフアタックむけのドメイン名生成ツール。
※悪用は厳禁です。
元記事タイトル: EvilURL - An Unicode Domain Phishing Generator for IDN Homograph Attack
元記事URL: http://www.kitploit.com/2017/11/evilurl-unicode-domain-phishing.html
EvilURLのgithubページ https://github.com/UndeadSec/EvilURL
Undead Secのgithubページ https://github.com/UndeadSec
こういうツールは悪用すると本当に危険で違法行為に繋がりうるわけだけど、こういった手法をしっかりと知り、対策を考えることがとても重要。
IDNホモグラフアタック is 何?
ホモグラフ攻撃(ホモグラフこうげき)は、URLのホスト名の文字として、真正なサイトに酷似した、異なる文字( = 見た目の形が紛らわしい文字)を用いて偽装し、偽のサイトに誘導するスプーフィング攻撃の一種で、同形異字語攻撃ともいう。
「IDN」とはInternationalized Domain Nameのことで、ドメイン名にASCII文字(0-9、a-z、-など)以外を使うことができる仕組み。身近なところでいうと日本語ドメインがIDNのひとつ。
実際には、これまで使われてきたアルファベットや数字のASCII文字とUnicode文字を変換するための標準化された規格がこの仕組みを支えており、この変換の方式をPunycodeという。
攻撃を監視するうえで気にすべきなのは、誰がこの変換を行うのか。DNSクエリとしてUnicodeが飛び交うのか、というところだが、実際にはユーザーエージェントの実装に依存する仕組みなので、ブラウザがPunycode変換を行い、実際に飛び交うDNSクエリは変換後のドメイン名、ということでしょう。
Punycode
Punycodeはエンコード方式であり、可逆性がある(エンコードして、デコードすると、戻る)。そりゃそうだ。また、ドメイン名なわけなので、重複があってはいけない。 Punycode変換後のドメイン名は先頭に「xn--」という接頭辞がつく
具体的な変換手順などのむづかしいはなしについてはWikipediaやRFCへどうぞ
- Wikipedia:Punycode
- RFC3492:Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)
実際どのように変換されるかを簡単に見たい場合は、ブラウザのアドレスバーに打ち込んでみれば良い。
(価格.comという日本語ドメインを入力してアクセスしようとしているさま)
名前解決できていないが、このアドレスバーに打ち込んだ部分を再度メモ帳などにコピペすると変換結果がわかる。
(Punycode変換後の文字列があらわれているさま)
ただ不審なサイトの調査で実際にアクセスしてしまうのは危険なので、そういったケースではブラウザではなくコンバートツールやPythonを使うこと。
Pythonで日本語ドメインからPunycodeに変換するにはstrクラスのencodeメソッドでエンコード方式「idna」を使う。 encodeメソッドが返すオブジェクトはbytesオブジェクトなのでstrにするにはdecodeも追加する。(文字列だと思ってあれこれしようとすると思わぬ例外が発生しますからね)
In [4]: "価格.com".encode("idna").decode("utf-8")
Out[4]: 'xn--1sqt31d.com'
In [5]: type("価格.com".encode("idna"))
Out[5]: bytes
逆にPunycode文字列を戻すには、逆のことをすれば良い。
In [21]: "xn--1sqt31d.com".encode("utf-8").decode("idna")
Out[21]: '価格.com'
Python3ではstrオブジェクトはdecodeメソッドを持っていないため文字列からいきなりdecodeしようとするとエラーになる。いったんutf-8等でencodeしてbytesオブジェクトに変換し、そこからデコードする。これ豆な。
IDNホモグラフアタック
このIDN(Punycode)の仕組みを悪用したフィッシング攻撃がIDNホモグラフアタック。要は見間違えやすい文字で攻撃のターゲットの人が見た時の「おかしくね?」をバイパスしようとする。
ホモグラフアタックといえば、例えばFacebookのドメイン名
facebook.com
これに似た文字列で、たとえば小文字のオー(o)を、数字のゼロにする(0)
faceb00k.com
ちょっと目立っちゃうので全部大文字にしちゃうとか。
FACEB00K.COM
これフォントにもよるけどほぼわからないよねと。
IDNの仕組みを使うとさらに巧妙になり、たとえばロシア語キリル文字の「а, с, е, о, р, х, у」は、英字アルファベットの「a, c, e, o, p, x, y」と見た目が酷似している。 ordでUnicodeのコードポイントを見てみると「а」は1072、「a」は97であることがわかる。
In [27]: ord("a")
Out[27]: 97
In [26]: ord("а")
Out[26]: 1072
さてこの「а」を活用したIDNを作ると、こうなる。
fаcebook.com
はいわからない。こりゃわからない。それではこれをPunycodeで変換してみると・・・
In [29]: "fаcebook.com".encode("idna")
Out[29]: b'xn--fcebook-2fg.com'
xn--が先頭に、そしてfcebookと「a」だと思っていた部分がなくなっており、末尾に"2fg"として付与されていることがわかる。
Evil URL
前置きがだいぶ長くなったけど、この仕組みを活用した「フィッシング用ドメイン名生成ツール」が今回紹介するEvil URL。 ソースコードを見ると実に単純で、アルファベットのA、C、E、O、P、S、D、Q、Wがあった場合、「酷似した別の文字」に置換しているだけ。
(EvilURLでフィッシングに使えてしまうドメインを生成しているさま)
Punycodeも見れた方が便利では?ということで追記。
57c57
< print('\n{2}[*] Char replaced: %s\n[*] Using Unicode: %s\n[*] Unicode number: %s\n{0}[*] Evil url: %s%s{1}\n-------------------------------'.format(GREEN, END, YELLOW) % (char, unicd, uninum, newurl, end))
---
> print('\n{2}[*] Char replaced: %s\n[*] Using Unicode: %s\n[*] Unicode number: %s\n[*] Punycode: %s\n{0}[*] Evil url: %s%s{1}\n-------------------------------'.format(GREEN, END, YELLOW) % (char, unicd, uninum, newurl.encode("idna").decode("utf-8"), newurl, end))
(Punycodeも出力されているさま)
対策
フィッシングサイトへの誘導等のためにこういった手法についてどうすべきか考えると、「そもそもIDN、Unicode文字の含まれたドメインへのアクセスって業務上必要だっけ?」という観点で考えると、ごく一部のケースでしか使われていないのでは、と思う。また、日本語についていえば日本語ドメインは取得はわりとされているようだが実際に活用されているケースは殆ど見かけないし、大手企業等でも取得はしていても結局本家のASCII文字ドメインへのリダイレクトのみ、なんていうこともある。そこで、ちょっと乱暴かもしれないけど、DNSサーバーでxn--で始まる名前は解決しないようにするよう設定してしまえば、このIDNホモグラフアタックの被害を受けることはない。
また、xn--で始まるDNSクエリはログを記録し、モニタリングしておく、等ということができれば、「こんなフィッシング攻撃が来ているかもしれない」ということに気付くことができそうだ。 「うちGmail使えないんですよー」というのと同じ感覚で「うち日本語ドメインサイトにアクセスできないんですよー」、ということで、いいんじゃないかな。
前置きが長かったわりに話としては「こういう手口もあることだから、xn--ドメインアクセス拒否しちゃっておいても良いかもね」というだけ。 重要なのは、「こういうドメインブロックしたいな」と思った時に、サラッとできる仕組みをあらかじめ作っておくことなんだねぇ
まとめ: 日本語ドメイン いらなくない?