eBPFでゲストのCPUIDをトレースする
これはMCC Advent Caleandar 20日目の記事です.
前日はUm6ra1さんによるMediBang Paintのmdpファイルを解析してみたでした.
はじめに
eBPFのチュートリアルとして,KVMゲストによるCPUID Instructionの実行をホスト側でeBPF(とTracepoints)を使ってトレースしてみる.ここでは,eBPFはBCCを使って書く.BCCのサンプルソースには kvm_hypercall.py
というのがあり,このサンプルの動きは以下のようになっている.
kvm_exit
,kvm_entry
,kvm_hypercall
をフックする.kvm_exit
のフックにおいて,VMExit ReasonがVMCALLによるものであったら,eBPF Mapにフラグを立ててprintする.kvm_hypercall
のフックにおいて,eBPF Mapにフラグが立っていれば,args->nr
(VCPU_REGS_RAX
) をprintする.kvm_entry
のフックにおいて,eBPF Mapのフラグを0にし,args->vcpi_id
をprintする.
例えば,ゲストで適当にVMCALL Instructionを実行すると以下のようなトレースが取れる.
$ sudo python kvm_hypercall.py TIME(s) COMM PID EVENT 15163.410112000 qemu-system-x86 9819 KVM_EXIT exit_reason : 18 15163.410130000 qemu-system-x86 9819 HYPERCALL nr : 114514 15163.410132000 qemu-system-x86 9819 KVM_ENTRY vcpu_id : 0
今回はこのサンプルをVMExit ReasonがCPUIDによるものかどうかのチェックに改変し,さらに kvm_cpuid
をフックする.args
で取れる値については /sys/kernel/debug/tracing/events/kvm/kvm_xxx(イベント名)/format
(TracepointsかつKVMイベントの場合) 辺りを見るとわかる.
環境
ホスト
- OS : Ubuntu 18.04.1 LTS
- Linux Kernel : 4.15.0-39-generic
- CPU : Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz
- Memory : 32GB
- QEMU-KVM : 2.11.1
- Python : 2.7.15rc1
- libbcc : 0.7.0-1
- bcc-tools : 0.7.0-1
ゲスト
コード
ホスト
ゲスト
CPUID Instructionのコードを適当に書いた. gist.github.com
結果
$ sudo python kvm_cpuid.py TIME(s) COMM PID EVENT 20422.473108000 qemu-system-x86 9819 KVM_EXIT exit_reason : 0xa 20422.473128000 qemu-system-x86 9819 KVM_CPUID rax : 0xd, rbx : 0x756e6547, rcx : 0x6c65746e 20422.473132000 qemu-system-x86 9819 KVM_ENTRY vcpu_id : 0x0 20422.473142000 qemu-system-x86 9819 KVM_EXIT exit_reason : 0xa 20422.473144000 qemu-system-x86 9819 KVM_CPUID rax : 0x663, rbx : 0x800, rcx : 0x80202021 20422.473146000 qemu-system-x86 9819 KVM_ENTRY vcpu_id : 0x0 20422.473149000 qemu-system-x86 9819 KVM_EXIT exit_reason : 0xa 20422.473151000 qemu-system-x86 9819 KVM_CPUID rax : 0x0, rbx : 0x0, rcx : 0x0 20422.473153000 qemu-system-x86 9819 KVM_ENTRY vcpu_id : 0x0 20422.473688000 qemu-system-x86 9819 KVM_EXIT exit_reason : 0xa 20422.473702000 qemu-system-x86 9819 KVM_CPUID rax : 0x1, rbx : 0x0, rcx : 0x4d 20422.473704000 qemu-system-x86 9819 KVM_ENTRY vcpu_id : 0x0 20422.473714000 qemu-system-x86 9819 KVM_EXIT exit_reason : 0xa 20422.473718000 qemu-system-x86 9819 KVM_CPUID rax : 0x1, rbx : 0x0, rcx : 0x4d 20422.473719000 qemu-system-x86 9819 KVM_ENTRY vcpu_id : 0x0 20422.473722000 qemu-system-x86 9819 KVM_EXIT exit_reason : 0xa 20422.473725000 qemu-system-x86 9819 KVM_CPUID rax : 0x121, rbx : 0x1c0003f, rcx : 0x3f 20422.473726000 qemu-system-x86 9819 KVM_ENTRY vcpu_id : 0x0 20422.473729000 qemu-system-x86 9819 KVM_EXIT exit_reason : 0xa 20422.473731000 qemu-system-x86 9819 KVM_CPUID rax : 0x122, rbx : 0x1c0003f, rcx : 0x3f 20422.473733000 qemu-system-x86 9819 KVM_ENTRY vcpu_id : 0x0 20422.473735000 qemu-system-x86 9819 KVM_EXIT exit_reason : 0xa 20422.473738000 qemu-system-x86 9819 KVM_CPUID rax : 0x143, rbx : 0x3c0003f, rcx : 0xfff 20422.473742000 qemu-system-x86 9819 KVM_ENTRY vcpu_id : 0x0 20422.473747000 qemu-system-x86 9819 KVM_EXIT exit_reason : 0xa 20422.473750000 qemu-system-x86 9819 KVM_CPUID rax : 0x163, rbx : 0x3c0003f, rcx : 0x3fff 20422.473751000 qemu-system-x86 9819 KVM_ENTRY vcpu_id : 0x0 20422.473760000 qemu-system-x86 9819 KVM_EXIT exit_reason : 0xa 20422.473763000 qemu-system-x86 9819 KVM_CPUID rax : 0xd, rbx : 0x756e6547, rcx : 0x6c65746e 20422.473764000 qemu-system-x86 9819 KVM_ENTRY vcpu_id : 0x0 20422.979395000 qemu-system-x86 9819 KVM_EXIT exit_reason : 0xa 20422.979412000 qemu-system-x86 9819 KVM_CPUID rax : 0x663, rbx : 0x800, rcx : 0x80202021 20422.979414000 qemu-system-x86 9819 KVM_ENTRY vcpu_id : 0x0 20422.979453000 qemu-system-x86 9819 KVM_EXIT exit_reason : 0xa 20422.979460000 qemu-system-x86 9819 KVM_CPUID rax : 0x663, rbx : 0x800, rcx : 0x80202021 20422.979462000 qemu-system-x86 9819 KVM_ENTRY vcpu_id : 0x0
参考
声でドローンを動かす
これはMCC Advent Calendar 2018 10日目の記事です。
昨日はid:nullnumaさんによる、Wacomのペンタブレットを分解してみたでした。
学園祭のコンテンツ関連のエントリを書いている人が誰もいなかったので、学園祭関連の話をします。
概要
学園祭で展示するコンテンツとして、声で操作するドローンのプログラムを書いた。 対象のドローンはParrot Rolling Spiderで重量55gのミニドローンとなっている。
本来はスマートフォンとRolling SpiderをBluetoothで繋いで操作して遊ぶおもちゃなのだが、 BLEでの制御部分の実装がNodeJSで使用可能なライブラリとして公開されているのでこれを使った。
声の取得について、当初はGoogle Cloud Speech API を使って取得していたが、ネットワーク環境が必要なことから(学園祭の部屋のネットワーク環境が最悪だった)断念し、ローカル内にJuliusサーバを構築し、ある程度高速に音声認識結果を取得できるようにした。
結果
Juliusは、Dictation KitのDNNを使ったものを動かしていたが、雑音の入った会場内では認識がかなり難しかった。
Rolling Spiderへの制御命令は、ドローン自体の物理的な動作を含めると、前回の命令から時間をあけて(〜5秒程度)送信する必要があり、 コントロールするのは中々難しかった。さらに、会場が狭く、実際に飛ばすと危険だったので、Rolling Spiderは飛ばないように机に括り付けてデモをやった。悲しい。
反省
Rolling Spiderがミニドローンということもあり飛行時間が5〜10分程度なので換えの予備バッテリーを複数買っておいた方が良かった。Rolling Spider自体、学園祭で使うというより安価で遊べそうだったので買ったわけだが、もう少し金を出して、Wi-Fi接続可能なドローンを買った方が遊びごたえがありそうだった。
コード
おわりに
同じ部屋で展示を行っていたこちらが大変人気があり面白いコンテンツだったので、いつか解説エントリが出ることを願いつつ終わりにします。
学祭で自作ゲーム展示します よろしくお願いします pic.twitter.com/KCQbVsliM8
— アマゾン川の逆襲 (@sasamijp) November 8, 2018
DLLインジェクションの検証
これはMCC Advent Calendar10日目の記事です.
前回はUm6ra1(@v1ru5) さんによる,LinuxのUSBドライバを書いてみよう ~RTL2832uでLチカ~でした.
はじめに
本記事では,DLLインジェクションを実際に実装・検証していきます.DLLインジェクションとは,Windowsにおいて,プロセスに意図しないDLL(Dynamic Link Library)を埋め込む攻撃手法です.この手法はUser Mode Rootkit等のマルウェアでよく用いられるテクニックでもあります.
環境
以下の環境で検証を行いました.実装はC++を使用しました.
OS Windows10 Pro x86-64 Visual Studio Community 2015 Version 14.025431.01 Update 3
手順
基本方針としては,DLLパスを攻撃対象プロセスの仮想アドレス空間のメモリ領域に書き込み,リモートスレッドを生成する形でDLLコードを実行します.具体的には以下の手順で攻撃対象へDLLインジェクションを行います.
1. プロセスへのアタッチ -> OpenProcess()
HANDLE OpenProcess( DWORD dwDesiredAccess, // アクセスフラグ BOOL bInheritHandle, // ハンドルの継承オプション DWORD dwProcessId // プロセス識別子 );
https://msdn.microsoft.com/ja-jp/library/cc429278.aspx
2. プロセスの仮想アドレス空間内のメモリ領域確保 -> VirtualAllocEx()
LPVOID VirtualAllocEx( HANDLE hProcess, // 割り当てたいメモリを保持するプロセス LPVOID lpAddress, // 割り当てたい開始アドレス DWORD dwSize, // 割り当てたい領域のバイト単位のサイズ DWORD flAllocationType, // 割り当てのタイプ DWORD flProtect // アクセス保護のタイプ );
https://msdn.microsoft.com/ja-jp/library/cc430225.aspx
3. 確保済みメモリ領域へDLLパスのコピー -> WriteProcessMemory()
BOOL WriteProcessMemory( HANDLE hProcess, // プロセスのハンドル LPVOID lpBaseAddress, // 書き込み開始アドレス LPVOID lpBuffer, // データバッファ DWORD nSize, // 書き込みたいバイト数 LPDWORD lpNumberOfBytesWritten // 実際に書き込まれたバイト数 );
https://msdn.microsoft.com/ja-jp/library/cc429067.aspx
4. リモートスレッドの生成(DLLコードの実行) -> CreateRemoteThread()
HANDLE CreateRemoteThread( HANDLE hProcess, // 新しいスレッドを稼働させるプロセスを識別するハンドル LPSECURITY_ATTRIBUTES lpThreadAttributes, // スレッドのセキュリティ属性へのポインタ DWORD dwStackSize, // 初期のスタックサイズ (バイト数) LPTHREAD_START_ROUTINE lpStartAddress, // スレッド関数へのポインタ LPVOID lpParameter, // 新しいスレッドの引数へのポインタ DWORD dwCreationFlags, // 作成フラグ LPDWORD lpThreadId // 取得したスレッド識別子へのポインタ );
https://msdn.microsoft.com/ja-jp/library/cc429075.aspx
CreateRemoteThread関数の実行において,lpStartAddressにLoadLibraryのアドレス,lpParameterにプロセスの仮想アドレス空間のメモリ領域に書き込まれたDLLパスのアドレスを指定するようにします.こうすることでリモートスレッドのエントリポイントがLoadLibraryによってロードされたDLLのDllMain関数となります.
HMODULE LoadLibrary( LPCTSTR lpFileName // モジュールのファイル名 );
https://msdn.microsoft.com/ja-jp/library/cc429241.aspx
今回は検証用DLL(dllexample.dll)をメモ帳(notepad.exe)にインジェクションします.検証用DLLのDllMain関数部分は以下の通りです.
gist.github.com
また,インジェクション実行のプログラム(injector.cpp)は以下の通りです.
gist.github.com
以上のプログラムを実行すると以下のような結果になり,メモ帳に対してDLLインジェクションが成功したことが確認できました.
参考
- Open Security Research: Windows DLL Injection Basics
- 64ビット対応のDLLインジェクション - SIN@SAPPOROWORKSの覚書
- CreateRemoteThread関数によるDLLインジェクションをやってみる - ももいろテクノロジー
おわりに
DLLインジェクションの攻撃手法自体は以前から知っていましたが,手を動かして検証したことがなかったのでやってみました.
次回はsasamijpさんによる,街中謎解きゲームの話です.
今年は某先輩専用のAdvent Calendarが開催されなかったことが残念でなりません.
セキュリティ・ミニキャンプ in やまなし 2017 に参加してきた
9月24日に開催されたセキュリティ・ミニキャンプ in やまなし の専門講座にチューターとして参加してきた.ミニキャンプは23日に一般講座も開催していたがその時は専門講座の会場設営などを行っていた(実際は電車を乗り過ごして一番遅く着いたのでほとんど設営は終わっていた).今回は専門講座で行われた技術的な内容について書いていく.
1. 手作りパケットでWebサーバと通信しよう
Scapyでhttp通信を行うプログラムを書いた.事前課題ではコネクション確立,コネクション確立後の通信,コネクションの切断の際のシーケンス番号(seq),応答確認番号(ack)の変化について調べる課題とNetcat,PythonのSocketに関して基本的な操作方法を覚えてくる課題が出された.講義では最終的にコネクション確立,確立後のHTTPリクエスト,コネクション切断までの一連の流れを書き,tcpdumpやwiresharkを使用しながら実際にパケットの流れの観測と検証を行った.
(www.example.comというのは今回記事として書く上での適当なホスト名であり講義で実際に使用したわけではない)
TCPのシーケンス番号,応答確認番号については,個人的にはこの辺りの説明がわかりやすいと思う.TCPの機能は正直あまり理解していない部分が多いのでRFCを読もうと思う.ちなみに知り合いのとあるイケメンパケリストはRFCの文書->疑似言語->プログラミング言語みたいな感じで翻訳していけばTCPのプロトコルスタックが実装しやすいと言っていた気がする.
OSがRSTパケット(RST/ACK)を送信してしまう
これはカーネルのTCPスタックがSYNを認知していない状態でサーバからのSYN/ACKを受けるため.TCPスタックがはじめのSYNを認知できないのはScapyがRawSocket経由でパケットの送信を行っているためである.ということでScapyで3ウェイハンドシェイクを行うためにはiptablesでRSTをDROPする必要がある.
$ sudo iptables -I OUTPUT -p tcp --tcp-flags RST RST -j DROP
2. ローカルプロキシで遊ぼう
講師の先生が自作したローカルプロキシ(Nodejs製)を使って与えられた課題を解決するようにプロキシのプログラムを改変した.課題は以下の通り.
必須課題
1. レスポンスがHTMLだった場合,"Bad"という文字列を"Good"に置換して返却する. 2. Basic認証を常に突破できるようにする.(userid/passwordは知っている状態)
1はヘッダのContent-Type
行がtext/html
だった場合にボディ中の"Bad"を"Good"に書き換える.2は通常時のBasic認証のHTTPを観察し,Authorization
行を常にヘッダに追加するようにすればよい. これはわかっていてもJavaScriptがわからず沼にはまっている人が多く私もJavaScriptの経験が浅いので結構沼にはまった. JavaScriptやっていきたい.
ちなみにこれらは必須課題で任意課題(発展課題)もある.そちらの方はまだ検証中なので追々追記していく.ジャバスクリプト何もわからん
— e_no (@epcnt19) 2017年9月24日
感想
初めてチュータを経験したが参加者とは違った側面の面白さや学びがあった.セキュリティ・キャンプは全国大会・地方大会含め参加者として何度かお世話になったので今後は新たな参加者の方をサポートしていく立場に回れればと思う.(一般 | 専門)講座参加者・講師・チュータの皆様,開催にあたり支援して下さった皆様,お疲れ様でした.
exitmap
はじめに
TorがOnionRoutingという仕組みで秘匿性を保っていることは既に皆さんご存知かと思います.そしてOnionRoutingにおいて,Torネットワークからクリアネット(非Torネットワーク)への架け橋となる出口ノード(ExitNode)の存在は非常に重要で,エンドtoエンドでの暗号化通信を行っていない場合,ExitNodeにはクライアントの通信内容が筒抜けになります.Torネットワークの各ノード(EntryNode,BridgeNode,RelayNode,ExitNode)は誰でもなることができるため,悪意をもって盗聴や改ざんを行うExitNodeの存在が非常に脅威となります.そこで,今回は悪意のあるExitNodeや,そういった疑いのあるExitNodeを探索するツールであるexitmapについて紹介します.
exitmap
exitmapはスウェーデンのカールスタード大学 PriSecグループとオーストリアのSBA Researchの共同研究によって2014年に開発されたもののようです. Pythonベースのプログラムになっており,内部的にStemを使用しているため,Tor本体をインストールしておく必要があります.
https://www.cs.kau.se/philwint/spoiled_onions/ github.com
イメージとしては,exitmap内でモジュール(例えば,ファイルのダウンロード・Webサーバへの接続等を行うモジュール)が評価対象のExitNodeを通じて実行され,その実行結果からNegative/Positiveを判定する感じです.モジュールは各自で開発することもできます.
使ってみる
環境
$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=16.10 DISTRIB_CODENAME=yakkety DISTRIB_DESCRIPTION="Ubuntu 16.10"
$ uname -mr 4.8.0-52-generic x86_64
インストール
$ git clone https://github.com/NullHypothesis/exitmap $ cd exitmap $ pip install -r requirements.txt $ cd ..
使い方
$ ./exitmap/bin/exitmap (モジュール名)
のように指定します.デフォルトで入っているモジュールには以下のようなものがあります.
checktest
- https://check.torproject.org/に接続し,Torと判定されるかチェックする.(ExitNodeがプロキシを刺しているかチェックする)
testfds
- 単純なWebページの内容を取得できるかチェックする.(ExitNodeのファイルディスクリプタが正しく機能しているかチェックする)
dnspoison
- 名前解決を行い,受信したAレコードと予想されるAレコードの比較を行う.(ExitNodeがDNSスプーフィングを行っているかチェックする)
dnssec
- ExitNodeがDNSSECを検証するかどうかチェックする.
patchingCheck
- ファイルのダウンロードを行い,改ざんをチェックする.
cloudflared
- https://www.cloudflare.com/に接続し,CAPTCHAが受信できるかチェックする.
rtt
- RTTをチェックする.
正直なところ,各モジュールの役割についてはソースコードを読んだ方が早いです.モジュールは./exitmap/src/modules/
以下に配置されています.
また,exitmap本体にもいくつかのオプションがあります.詳細はhelpオプションで確認できるので,ここではいくつかの重要なオプションについて紹介します.
--country [Country Code]
- ExitNodeの国を指定するオプションです.日本であれば
JP
のように指定します.
- ExitNodeの国を指定するオプションです.日本であれば
--first-hop [FingerPrint]
- EntryNode(first hop)を20バイトのフィンガープリントで指定します.
--exit [FingerPrint]
- ExitNodeを20バイトのフィンガープリントで指定します.
--build-delay [Seconds]
- Torのサーキットを生成する際に任意の秒数間休止します.
以下の例は全ての出口ノードに対してdnspoisonモジュールを実行した例です.今回はDNSスプーフィングの疑いのあるExitNodeは発見できませんでした.
https://gist.github.com/epcnt19/84d753545ac715a569e31cc44fed883f#file-exitmap
おわりに
悪意のあるExitNodeを発見するためには,exitmapによる継続的なスキャンや,モジュールの拡張・自作を行う必要がありそうです.ただし,継続的なスキャンという点に関してはスキャンがTorネットワークへ負荷を与えているという点に注意する必要があります.
独り言
全出口ノード数は800〜900程度だそうですが,案外少なくないですか(調べてみたら,ここ数年で結構減少してるっぽい)
https://metrics.torproject.org/relayflags.html
Torの全出口ノード数800って意外に少ないな
— e_no (@epcnt19) 2017年6月3日
全体の10%程度であれば月10〜20万くらいで運用可能では
DECAFのセットアップ
DECAFの環境を構築したので,再度構築する時のための自分用メモ.
github.com
環境
- ホストOS Ubuntu16.10(LTS) 64bit
- ゲストOS① Ubuntu14.04(LTS) 64bit
- ゲストOS② Windows XP 32bit
ホストOSの上でゲストOS①を動作させ(Virtualbox),その上でゲストOS②を動作させる(DECAF(QEMU)). ホストOS上で直接DECAFを動作させなかったのは、Ubuntu16.10上でのビルドが上手く行かなかったためで,現在原因調査中.
パッケージのインストール
$ sudo apt-get update $ sudo apt-get install qemu binutils-dev libboost-all-dev $ sudo apt-get build-dep qemu $ sudo apt-get -y install build-essential linux-headers-$(uname -r) $ sudo apt-get install zlib1g-dev libssl-dev libncurses5-dev $ sudo apt-get install libcurl4-openssl-dev libexpat1-dev libreadline-gplv2-dev $ sudo apt-get install uuid-dev libfuse-dev bzip2 libbz2-dev git $ sudo apt-get -y install automake1.9 autoconf libtool $ git clone https://github.com/sycurelab/DECAF $ cd DECAF/decaf $ ./configure $ make $ cd ..
イメージの作成
- WindowsXP(modernIE)のVMware用イメージをダウンロードした.
- VMWare用イメージ(vmdk)をqcow2イメージに変換したものでDECAFを起動しようとしたところ,
No bootable device
と出てしまい,ブートできなかった.原因調査中. - qcow2イメージではなく,rawイメージに変換したものを使用したところ,問題なく起動できた.
DECAFでqcow2(vmdk->qcow2のconvert)だとNo bootable deviceになるけどrawを直接指定したらとりあえず動いた
— e_no (@epcnt19) 2017年4月30日
$ unzip IE8.XP.For.Windows.VMware.zip $ qemu-img convert -f vmdk -O raw IE8_-_WinXP-disk1.vmdk winxp.img $ ./decaf/i386-softmmu/qemu-system-i386 -monitor stdio -drive file=./winxp.img
さいごに
今後は以下を参考にプラグイン開発をやっていく予定.
追記
https://groups.google.com/forum/#!topic/decaf-platform-discuss/iLw8E7p559w
参考
- poppycompass.hatenablog.jp
- tsunpoko.hatenablog.com
- GitHub - ntddk/geteip: tiny DECAF plugin
- GitHub - ntddk/blue: Some anti QEMU trick used by in-the-wild malware.
- DECAFによるマルウェア自動解析 | 一生あとで読んでろ
- セキュリティキャンプ講義「仮想化技術を用いたマルウェア解析」にチャレンジしてみた(プラグイン開発編) - 拾い物のコンパス
- ミニキャンプ沖縄・仮想化技術を用いたマルウェア解析-Revenge(プラグイン開発編) - /var/log/tsun
記念撮影
onionアドレスの生成
TorのHiddenServiceの識別子として用いられるonionドメインのアドレス(以下,onionアドレス)ですが,どのように生成されるのか気になったので調べました.
仕組み
知りたかったことは以下の記事にほとんど載っていました.
- doc/HiddenServiceNames – Tor Bug Tracker & Wiki
- https://timtaubert.de/blog/2014/11/using-the-webcrypto-api-to-generate-onion-names-for-tor-hidden-services
上記の記事によると,
- RSA(1024bit)の公開鍵と秘密鍵のキーペアを作成する.
- 公開鍵をDERエンコードする.
- DERエンコードされた公開鍵からSHA1ハッシュ(160bit)を生成する.
- 生成したハッシュ値の前半半分(80bit)を取り出し,Base32エンコードする.
という手順で生成しているようです.Base32は40bitを8文字に変換するエンコード方式で,80bitのハッシュ値から16文字の文字列にエンコードされ,これがonionアドレスとなるようです.一般的な手順でHiddenServiceの設定を行った場合,Tor側が自動でonionアドレスと秘密鍵を生成してくれます.ちなみにこれらはtorrcのHiddenServiceDir項目で指定したパスの配下にhostname,private_keyという名前で生成されます.
任意の文字列をonionアドレスにしたい
例えば,facebookcorewwwi.onion(FacebookのHiddenService)のように任意の文字列をonionアドレスに指定するための方法ですが,指定したパターンが出現するまでキーペアを生成し続ける(ブルートフォース)作業を行うことによって実現できます.そのようなツールは既にいくつも存在して,Shallotやscallionが有名なようです.
試しにShallotでアドレスを生成してみたところ,1-5文字程度であればある程度高速にonionアドレスを算出できました.ちなみに,facebookcorewwwi.onionは8文字ですから一般的なマシンでのブルートフォースではまず不可能でしょう.
おわりに
TorのHiddenService,RelayNode,ExitNodeの設定方法をブログに書いていなかったのでそのうち書きます.とはいえ,HiddenService,RelayNodeに関しては以下のページに基本的な設定方法がある程度説明されているので,自分のメモ用程度にしか需要はないと思いますが.
Hidden Service - Hideki Saito Wiki Japanese
Linuxに安全にtorリレーをインストールする方法 - Qiita
Ubuntu14/CentOS6xにtor入れてrelayサーバーにする - Qiita