鹿色のIT雑記

エンジニアの鹿色がIT技術を追いかけていくブログです

NICTERからダークネットを眺めてみる

皆さん、ダークネットはご存知でしょうか?

なんとなく心をくすぐられる響きですよね。

今回は、ダークネットを眺めてみようということで、記事を書いています。

 

 

ダークネットとは?

ダークネットとは、未使用の到達可能なグローバルIPで、どこにも割り当てられていないものを指すようです。

どういうこと?という感じですが、自分の理解では以下のようになります。

  • 通常、サーバの住所としてグローバルIPが割り当てられており、そこに対してユーザからのリクエストが来ることで、サーバが何かしらの応答を返す
    • みんな何かしらの意思を持ってアクセスしにくる
  • ダークネットは、未使用なグローバルIPなので、誰も応答しない空き地に対してあえてリクエストを送信する
    • 空き地にアクセスしにくるの怖くね…?
    • というので、意思を持たず無差別にアクセスするようなサイバー攻撃用のBotからのリクエストが届く

空き地に攻撃するウイルスのイメージをBingに書いてもらいました。

ダークウェブと何か違うの?

ちなみに、 "ダークウェブ" というものもあるのですが、こちらはダークネットとは別物のようなので、混同しないようにするのが良さそうです。

ただし、似たような言葉なので混同して使われることもあるようで、読む際は文脈を理解する必要がありそうです。

 

実際に眺めてみる

NICTが以下のようなダークネットを観測するサイトを提供しています。

www.nicter.jp

 

Atlasは地球儀に上に攻撃パケットをプロットするような形で攻撃パケットを可視化されています。

めちゃくちゃ矢が飛んできていて面白いですね。

また、TCP/UDP/ICMPが色分けられているんですが、いわゆるpingのICMPの白色のパケットはあまり飛んで来ないんだなぁと思いました。

 

Top10は、なんか見ているとああ…という感じになりますね。

あとは、意外とTCP通信の宛先ポートに偏りがないんだなと思いました。23番が6%なのはやっぱりtelnetは突きやすかったりするんですかね?

3389番はなんだろうと思ったらリモートデスクトップ用のポートでなるほどなと思いました。

 

感想

空き地をあらかじめ見ておくことにどれだけ意味があるのかわかっていませんが、普段見えないところに攻撃パケットが飛んでいると思うとなかなか恐ろしいですね…

自宅サーバなど始める場合はもちろん、DLNAみたいに、外から家のテレビレコーダーに繋げるような設定をする場合にも、脆弱性には注意しておかないといけませんね。

SSLとTLSって何が違う?

またまた、よく使っているけどあまりちゃんと理解していないシリーズです。

今回はSSLTLSって何が違うのか?について調べてまとめました。

 

 

ざっくりした結論

どちらも通信を暗号化するもので、SSLの種々の脆弱性に対応していく中で、名称がTLSに変化していった。

 

そもそもSSLTLSって…?

ホームページにアクセスすると、「保護されていない通信」のような警告が出ることがあると思います。

その場合に、そのホームページはHTTPSに対応しておらず、接続が暗号化されていないので、「保護されていない通信」となります。

このHTTPSで暗号化した通信を行うために、SSL/TLSが重要になります。

歴史

元々は、SSL2.0というのが初期バージョンとして公開されたようですが、脆弱性がありSSL3.0が公開されました。

そのSSL3.0を元にSSL3.0の脆弱性を解消したのがTLS1.0で、以降TLSが利用されるようです。

現在はTLS1.3が最新バージョンとなるようです。

TLSが動作するイメージ

ブラウザとサーバが、お互い本人であることを確認して握手してから通信を始めるというのが雑な解釈です笑

図はBingのImageCreatorに書いてもらいました。

 

握手する際に、通信で利用する共通の鍵を交換することで、その後の通信を暗号化していくようなイメージです。

ちなみに、TLS1.3ではお互い本人であることを確認するタイミング(証明書の交換)で、既に暗号化された通信で行うことで安全に本人確認もしているようです。

この本人確認のタイミングで暗号化された通信を行うにはDH法を利用して、秘密情報を交換することで行なっているようです。

DH法の詳細な計算方法はWikiを見ていただきたいのですが、賢いこと考えますよね…

 

感想

名前が変わっていっただけで、やりたいことは同じということがわかって良かったです。

ただ、暗号化の話を読むにつれ、数学に強い人はやっぱりすごいなと感心するばかりですね。

賢い人が生み出したものを有難く使わせてもらうことにします。

DB関係でよく見かけるけどあまり理解していない単語たち

皆さんはデータベースを触られることはありますか?

自分はRDBをよく使ってきたのですが、あまり意味をわかっていない状態で挙動だけなんとなくわかったようになっているものが多いので、今回単語帳を作っておこうと思い立ちました。

 

 

RDB

RDBはリレーショナルデータベースのことで、MySQLなどが有名ですね。

 

NoSQL

NoSQLはRDB以外のDBのことのようです。

MongoDBなどが有名どころのようですが、思ったより細分化されているようでした。

とはいえ、データ構造が自由であることが特徴というところだけ押さえておけば良いのかなと思っています。

スケーラビリティも高いようですが、検索の効率を上げるためのインデックスの貼り方はどのようになっているのかは気になるところです。

 

ストアドプロシージャ

RDBに対するSQLをまとめておいたり、あらかじめ命令を格納しておくことで高速化するもののようです。

 

そもそも、プロシージャとは何か?というと、戻り値のない関数のようなイメージとのことです。

参考)ストアドプロシージャとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典

 

プリペアドステートメント

あらかじめSQL文の中に置き換え対象となる文字(プレースホルダ)を用意しておくことで、後から変数を代入することができるものです。

これによって型を間違えることがなくなったり、SQLインジェクションの対策になったりします。

この時、String型はどのように判断するんだろう?と思っていたのですが、プリペアドステートメントではプレースホルダに入力された値はSQLの構文としては解釈しないようになるので、攻撃文字列が入っていても無視されるようです。

例)

ユーザからの入力値をINPUT_VALUEとした時に、単にシングルクォートで囲っていると、以下のようになります。

select * from sample_table where id = 'INPUT_VALUE';

ここで、入力値が ' OR 1 = 1 のような文字列だった場合、DBの全情報が出てしまいます。

そもそも、*でデータを取得するのも良くないとは思いますが…

select * from sample_table where id = '' OR 1 = 1';

 

こんな時に、プリペアドステートメントを利用していれば、以下のようになります。

select * from sample_table where id = ?;

この時、?に対してユーザの入力値を入れるのですが、あくまで文字列として扱われるため、「' OR 1 = 1」というidが検索されるので安全ということのようでした。

 

これは便利ですね。

Joinのチートシート

Joinも何が何か忘れがちなので残しておきます。

SQL Joins CheatSheet - Active Webdezign

 

感想

こう考えると、NoSQLに関して全くわかっていなかったので、今度しっかりと調べてみようと考えています。

ファイル名に騙されるな!

戦前の日本は右から左に文字が印刷されていたようですが、現代人からするとすごく違和感のある書き方ですよね。

逆に、違和感が無くなることを利用してウイルスを実行させようという人もいるんですね。

というわけで、今回はファイル名の偽装に関する話題です。

 

 

何を言ってるの?

例えば、こちらのファイル名を見られたときに、皆さんはどのように感じますか?

happy.txt.exe

明らかにウイルスが実行されそうなファイルですよね。

では、こちらのファイル名はどうでしょうか?

happy.exe.txt

ちょっと怪しいですが、テキストファイルっぽく見えますよね?

このファイル、場合によっては実行ファイルなことがあります。

 

どういうこと?という感じですよね。

からくりとしては、Unicodeの制御文字でRLO(U+202E)というものがあり、この制御文字以降の文字を右から左に書くようになります。

制御文字自体は不可視なので、一見txtファイルに見えるこのファイルも、exeファイルであり、実行可能なファイルな恐れがあるということです。

なので、上記の例で言うと、こんな状態になっているということです。

happy.RLOexe.txt

怖いですね…

 

実際のところ

詳細なコマンドはあまり書くと良くないと思うので伏せておきますが、Macでechoコマンドを利用して制御文字をいれて実行したところ、添付画像のように?で表示されるため、騙せないようになっているのかなと思います。

実際にRLOが必要な言語だとどうなるのかはわかっていませんが、その場合は逆順表記が普通なので違和感はないのかなと思います。

逆に、LRO(U+202D)という制御文字もあるようなので、そのような言語圏の人にはそちらが攻撃用文字列になるんでしょうね。

 

ちなみに、Ubuntuで実行したところしっかりと制御文字が適用されて反転しました。

また、制御文字が入ったファイルをmvさせようとした際にも入力文字が逆に進んでいくので少し面白かったですが、このような文字が入っているファイルの扱いは面倒ですね。

このように、UTF-8の表示を止めることで制御文字が入っているかを見ることもできるようです(制御文字部分は伏せ字にしています)。

$ LANG="C" ls -1
happy.exe.txt
'happy.'$'\xxx\xxx\xxx''txt.exe'

 

感想

攻撃する人も色々なこと考えるんだなあと感心してしまいました。

ただ、最近の環境だとセキュリティも考えられているので、ある程度安心して利用できるようになっているんだなと思いました。

とはいえ騙されないように知識を獲得していくのも重要だなというところで、引き続き学習を進めていこうと考えています。

MacでZIPファイルにパスワードをかけたら解凍できなくて困った話

非常に前時代的な話なのですが、 ZIP ファイルにパスワードをかけたいことがあるかと思います。

その用事に対応するために、Macを利用して ZIP ファイルを作った時にパスワードをかけたのですが、なぜか解凍できなくて困ったので ここに残しておきます。

 

 

結論

MacでZIPファイルにパスワードをかける際には、zipcloakを利用せずに、ターミナルでファイルを圧縮する必要があります。

"zip -e" でやっておくのが安全です。

ただし、解凍できるパターンもあるので、もしかしたら最新のMacOSだとCRCエラーを無視して解凍するようになっているのかもしれません。

 

何が起こった?

"mac zip パスワード" などで検索するとzipcloakを利用する方法が上がってくるかと思います。

このzipcloakを利用して、「ファインダーで右クリックして圧縮した」zipファイルにパスワードをかけると解凍できなくなる。という問題が起こりました。

$ for t in a b c d e;do echo $t > $t.txt; done

選択して右クリックから圧縮

$ zipcloak アーカイブ.zip

Enter password:

Verify password:

encrypting: a.txt

zipcloak warning: Local Entry CRC does not match CD: a.txt

encrypting: b.txt

zipcloak warning: Local Entry CRC does not match CD: b.txt

encrypting: c.txt

zipcloak warning: Local Entry CRC does not match CD: c.txt

encrypting: d.txt

zipcloak warning: Local Entry CRC does not match CD: d.txt

encrypting: e.txt

zipcloak warning: Local Entry CRC does not match CD: e.txt

 

ただ、よくわからないのが、このテスト用のファイルだとうまく解凍できてしまうというところですね…

巷の記事では、「Local Entry CRC does not match CD」というエラーそのものが解凍不可能な条件のように書かれています。

 

追加で調査してみた

ディレクトリを含む場合

よくよく考えると、ディレクトリを含む場合に解凍に失敗していた気がするので、条件を変更します。

$ for t in a b c d e;do echo $t > $t.txt; done     

$ for t in a b c d e;do echo $t > ziptest/$t.txt; done

右クリックで圧縮

$ zipcloak アーカイブ.zip                             

Enter password:

Verify password:

encrypting: a.txt

zipcloak warning: Local Entry CRC does not match CD: a.txt

encrypting: b.txt

zipcloak warning: Local Entry CRC does not match CD: b.txt

encrypting: c.txt

zipcloak warning: Local Entry CRC does not match CD: c.txt

encrypting: d.txt

zipcloak warning: Local Entry CRC does not match CD: d.txt

encrypting: e.txt

zipcloak warning: Local Entry CRC does not match CD: e.txt

encrypting: ziptest/

encrypting: ziptest/c.txt

zipcloak warning: Local Entry CRC does not match CD: ziptest/c.txt

encrypting: ziptest/b.txt

zipcloak warning: Local Entry CRC does not match CD: ziptest/b.txt

encrypting: ziptest/a.txt

zipcloak warning: Local Entry CRC does not match CD: ziptest/a.txt

encrypting: ziptest/e.txt

zipcloak warning: Local Entry CRC does not match CD: ziptest/e.txt

encrypting: ziptest/d.txt

zipcloak warning: Local Entry CRC does not match CD: ziptest/d.txt

これでも解凍できる…

エラーメッセージの意味を理解する

誤り訂正に利用するCRCのエラーのようですが、CDに関する情報が全く見当たらず、なんの略なのかわからないですね…

大文字2文字で略さないでほしいですね。

ZipArchiveから頑張って辿ってどうやらCentral Directoryではないかというところでアタリをつけています。

間違っていたらコメントなどでご指摘ください。

Minizip 2.8.6 by Coeur · Pull Request #509 · ZipArchive/ZipArchive · GitHub

Do not write central directory header if central directory is 0 bytes… · zlib-ng/minizip-ng@64faa25 · GitHub

 

ZIP (file format) - Wikipedia にもCentral Directoryの記載があるのでおそらく合っていると思うのですが、このどこからどこまでが1ファイルの領域かという部分が壊れてしまって不整合になっているということなんですかね?

 

ひとまず、不整合が起こる条件になってしまっているということのようです。

 

どう対策する

"zip -e"コマンドを使ってパスワードを付与するのが無難なようです。

$ zip -e archive.zip *.txt                    

Enter password:

Verify password:

  adding: a.txt (stored 0%)

  adding: b.txt (stored 0%)

  adding: c.txt (stored 0%)

  adding: d.txt (stored 0%)

  adding: e.txt (stored 0%)

$ unzip -t archive.zip

Archive:  archive.zip

[archive.zip] a.txt password:

    testing: a.txt                    OK

    testing: b.txt                    OK

    testing: c.txt                    OK

    testing: d.txt                    OK

    testing: e.txt                    OK

No errors detected in compressed data of archive.zip.

感想

うまく解凍できたりできなかったりしてややこしいのですが、ひとまずコマンドを使っておこうと思いました。

本筋とは異なりますが、英語を大文字で略記するのはトラブルシューティングがしづらいのでやめてほしいですね…

虹をかけられないようにソルトをパラパラと振りかける

よくわからないポエムみたいなタイトルで始まりましたが、DBに格納しているパスワードをどうやって守るかという話題です。

趣味のサーバを運用する際に、「ソルト」という単語はよく目にしていたのですが、あまりしっかりと意味をわかっていなかったので、まとめておきます。

 

 

そもそも何の話?

色々なWebサービスを利用する際に、IDやパスワードを登録することがあると思います。

それらを利用して、ログインをするわけですが、そのためにはどのIDがどのパスワードを利用しているのか、どこかに記憶しておく必要があります。

その際に、人間であれば脳の記憶を覗かれることは今のところないはずなので、「山と聞かれたら川と返す」みたいに、パスワードはそのままの言葉を覚えておけば良いのですが、コンピュータは記憶を覗かれる恐れがあります。

そのため、パスワードはそのままの言葉(平文)で記録しないことが望ましいです。

 

その記憶を覗く攻撃と、それに対する防御策をまとめるような話になります。

 

本題

対策ってどのようなものがあるの?

一般的にはパスワードをそのまま記憶するのではなく、ハッシュ関数をかけて難読化することが行われるようです。

例えば、 "exampleshikapassword" というパスワードにMD5関数でハッシュをかけると、以下のようなハッシュ値が得られます。

$ echo -n "exampleshikapassword" | md5sum
b91bb005b8360a26f06914e2515d72db  -

そこで、データベースには "312386ed265cfda1b1e7a76a1d8b0ad3" という文字列を登録しておくことで、仮に記憶が取られても元々のパスワードがそのまま見られることがありません。

ログインする際にも、入力されたパスワードにMD5関数をかけることで照合します。

どうやって攻撃してくる?

ここで、攻撃者がどのように考えるかというと、このハッシュ値から元のパスワードを推測しようとします。

その際に、「レインボーテーブル」という本記事のタイトルの虹に相当するものを作るようです。

レインボーテーブルの説明は若干ややこしいのですが、おおよそ以下のようなイメージ と思っておりますが、誤りなどありましたらコメントなどでご指摘いただければと思います。

  • 「元となるキーワード」となる単語を用意する
  • このキーワードをハッシュ化して、ハッシュ値を得る
  • ハッシュ値と解読したいパスワードのハッシュ値が一致するかを確認する
  • 一致しなければ
    • ハッシュ値に対して「還元関数」を適用して新たな「キーワード」を生成する
  • 一致すれば
    • キーワードが解読したいパスワードなので、解読成功
  • これを繰り返して、「元となるキーワード」から生成される大量のハッシュ値を生成する

攻撃者目線での利点は、「元となるキーワード」からハッシュ値を大量に生成できるので、パスワード解読用のテーブルを圧縮できるところのようです。

 

ハッシュ値からまた新たなキーワードを生むという発想はよくやるなぁと思いますね。

 

虹をかけられないようにするには?

ここでソルトが活躍してきます。

ソルトとは、塩みたいにサーバ側でパスワードに対してランダムな文字を振ることでハッシュ値を変更するものです。

$ echo -n "salt_exampleshikapassword" | md5sum
d8dd9e126af8ebe4d3c2d902455dcc15  -

このソルトは、何種類か用意しておくことで同じパスワードでも異なるハッシュ値を生成することができます。

$ echo -n "salt1_exampleshikapassword" | md5sum
cb07656ef73ef021ae72906a2fd0b83b  -
$ echo -n "salt2_exampleshikapassword" | md5sum
9d348d4fb73b96d8e72fb3926a1eb823  -

$ echo -n "salt3_exampleshikapassword" | md5sum
bed92fbe5a7fe9c07e6ea451149f7a40  -

これにより先ほどのレインボーテーブルなどの攻撃用データベースの容量を増加させることができるため、攻撃が成功しづらくなるようです。

 

ただし、このソルトはIDごとに異なるものを利用するなどしておかないと、ソルト自体が解読されてしまってソルトの効果が薄くなってしまうようです。

お塩とはいえ、それぞれの人に合った味つけをしてあげることが重要ということですね。

 

感想

ソルトがどのような働きをしているのかあまりわかっていませんでしたが、意外と重要なものなのだなと感じました。

最近は多要素認証など、パスワード以外でもアカウントが保護されることが多く、もしかしたらそこまで重要ではない知識なのかもしれませんが、こういった基礎的なことを知っておくのも良いですね。

自宅の機器がボットネットに利用されないために

過去の記事にもあるように、自分はSwitchBotを利用しています。

shikairo.hatenablog.com

 

セキュリティ周りのことを勉強するにあたって、ボットネットという単語を見かけたので、対策をしっかりしておかないといけないなぁと思い、記事を書いています。

 

 

ボットネットとは?

攻撃者がインターネットに接続されている機器を利用して、C&Cサーバ(Command & Controlサーバ)から指令を出すような攻撃方法があるようです。

この攻撃用のネットワークのことをボットネットと呼ぶようです。

過去には、Miraiというボットネットが攻撃を仕掛けることがあったようでした。

参考)Miraiボットネット?大規模なDDoS攻撃を仕掛けるその仕組みとは | サイバーセキュリティ情報局

Miraiボットネットは主にIoT機器を対象にしたもので、自分が利用しているSwitchBotの機器が狙われることがあるかもしれません。

軽く調べたところ、SwitchBotで脆弱性を利用された事例はなさそうでしたが、用心するに越したことはなさそうです。

 

どう用心する?

アップデートする

やはり、ファームウェアやソフトウェアのアップデートを定期的に実施するのが一番かと思います。

ただし、SwitchBotはファームウエアを自動更新することができないので、自身で定期的にアプリを開いて、それぞれのデバイスにアップデートがあるか確認しないといけないのが不便ですね…

 

Matter対応なども嬉しいですが、セキュリテイ的な部分でのユーザビリティ向上も期待したいですね。

もしかしたらできるのかもしれませんが、ファームウェアアップデートが必要な機器があればプッシュ通知してくれるとか…

 

トラフィックを監視する

次点としては、自宅の回線のトラフィックを監視するのが良さそうです。

自分はGoogle Nest Wifiを利用しているので、接続している機器のトラフィックの状況がGoogle Homeアプリから見られます。

 

時々見ておいて、異常な通信がないかをチェックできているとよさそうです。

一番いいのはゲートウェイサーバを運用してそこで検知するか、ルータにその機能が組み込まれていることだと思いますが、そこまでするのは流石に大変ですね…

 

感想

結局、対策としては一般的なことをちゃんとしましょうということになるのかなと思いました。

が、IoT機器を選択する際には、セキュリティアップデートのしやすさも1つの導入の判断基準として入れても良いのかもしれませんね。