技術の犬小屋

Webプログラミングを餌に生きる犬のメモ帳

Posts in the セキュリティ/認証 category

C言語で発生し得るバッファオーバーフローと呼ばれる脆弱性について調べたのでまとめてみる。
 

バッファオーバーフローとは

読んで字の如く,バッファ(メモリ上に確保された領域)からデータがオーバーフロー(あふれる)ことである。
バッファオーバーフローは,入力データを検査しないプログラムの脆弱性によって,バッファ領域として設定されているアドレス範囲を超えたメモリが上書きされ,誤動作が引き起こされる。バッファオーバーフローが起きた場合,通常は該当プログラムの動作が不安定になったり停止したりする。しかし,そのようなバグを含むプログラムに対して,意図的に悪意のあるデータを与えることにより,コンピュータの動作を乗っ取ってしまえる可能性が問題となる。
 

バッファオーバーフローが起きる原因

C言語の標準入出力関数であるgets関数はバッファ長のチェックを行わないで標準入力をバッファに書き込むので,この関数を使う全てのプログラムには,バッファオーバーフローによる不正動作の危険性がある。また使い方が分かりやすいという理由でC言語初心者向けの入門プログラミングでしばしば用いられるscanf関数も書式指定を誤った場合は同じ危険性を持っている。これらの関数を実用的なプログラムで用いる場合には注意が必要である。
 

具体的な例

  1. メールアドレスは200文字を超えないだろうと予想して200文字分の領域をバッファとして(char型の変数とかで)用意する。
  2. ユーザが200文字より長いメールアドレスを入力する。
  3. プログラムがバッファの大きさをチェックせずに入力データを書き込む。
  4. バッファとして確保した領域をはみだしてデータが書き込まれてしまう。

 
これがバッファオーバーフローである。具体的な対策方法としては,コード上でバッファの大きさをチェックして入力データが収まるかどうかを判定してあげるか,そもそもC言語のようなバッファオーバーフローが起こる可能性のある標準入出力関数を持つプログラミング言語を使わないか,といったところである。
 
 
以上
 
 
参考
バッファオーバーラン – Wikipedia

久々にAmazon EC2のAmazon Linuxにvsftpをセットアップしようとしたところ、手順を忘れかけていたのでメモを残しておく。
 

vsftpのセットアップ手順

Amazon Linuxへvsftpをセットアップするには、以下の手順に沿って行う。

  1. yumコマンドでvsftpをインストールする
  2. 使われていないポートを確認する
  3. vsftpを設定する
  4. ユーザを作成する
  5. vsftpの起動設定を行う
  6. vsftpを起動する
  7. Amazon EC2のSecurity Groupsを設定する

 
以下より、手順ごとに解説する。
 

yumコマンドでvsftpをインストールする

以下のコマンドを実行し、vsftpをインストールする。

sudo yum install vsftpd

 

使われていないポートを確認する

以下のコマンドを実行し,使われていないコマンドを確認する。

cat /proc/sys/net/ipv4/ip_local_port_range

 
以下のようなレスポンスが返ってきた場合,32768~61000までが空いていることが分かる。

32768   61000

 

vsftpを設定する

vsftp.confを編集する

以下のコマンドを実行し,vsftpの設定ファイルの編集を行う。

sudo vi /etc/vsftpd/vsftpd.conf

 
以下の表にvsftpd.confの変更内容を示す。
 

vsftp.confの変更内容
分類 内容 意味
修正 anonymous_enable=NO 匿名ユーザーのログインは許可しない。
修正 dirmessage_enable=NO ユーザが新しいディレクトリに初めて移動したとしてもメッセージは表示しない。
修正 ascii_upload_enable=YES アスキーモードのアップロードを有効にする。
修正 ascii_download_enable=YES アスキーモードのダウンロードを有効にする。
修正 chroot_local_user=YES ローカルユーザーのルートを各自のホームに変更する。
修正 chroot_list_enable=YES chroot_listを有効にする。ファイルはデフォルト(chroot_list_file=/etc/vsftpd/chroot_list)になる。
修正 tcp_wrappers=NO ホストへのアクセスを制御しない。(EC2のSecurity Groupsで設定する方がよい)
修正 connect_from_port_20=NO ActiveFTPを無効にする。
修正 xferlog_std_format=NO wu-ftpdではなく,vsftpdログ形式でログを記録する。
追加 pasv_enable=YES PASV FTPを有効にする。
追加 pasv_addr_resolve=YES PASVモード接続先IPアドレスをホスト名から取得する。
追加 pasv_address=固定IP Elestic IPを設定する。(インスタンスのPublic DNSを指定するとPASVモードでの接続はできない。バージョン2.0.4以降であれば、IPが固定でなくても pasv_addressにDDNSを書くことで動的なIPに対応できる。)
追加 pasv_min_port=60001 PASVモード接続時の最小ポート番号を設定する。(確認した空きポートの範囲で設定)
追加 pasv_max_port=60010 PASVモード接続時の最大ポート番号を設定する。(確認した空きポートの範囲で設定)
追加 use_localtime=YES ローカルタイムを使用する。(デフォルトはGMT)
追加 force_dot_files=YES .(ドット)で始まるファイルを隠さない。

 

chroot_listを編集する

続いて,chroot_listファイルを作成し,ルートを変更しないユーザーを指定する。ここで指定されたユーザは,ルートディレクトリにアクセスできるようになるので,rootなど特別なユーザーのみ指定する。とりあえず,空にしておいても問題ない。

sudo vi /etc/vsftpd/chroot_list

 

ユーザを作成する

FTPサーバに接続するためのユーザを作成する。デフォルトのec2-userでは,FTPサーバへの接続を行うことができないので,FTPサーバ接続用のユーザを作成する必要が生じる。
 
ユーザを作成するには,以下のコマンドを入力する。

sudo adduser ユーザ名

 
ユーザにパスワードを設定するには,以下のコマンドを入力する。

sudo passwd ユーザ名

 

vsftpの起動設定を行う

vsftpの起動設定を行う。これを行うことでシステムを再起動した場合でも,自動的にvsftpが起動するようになる。
以下のコマンドを入力し,vsftpの起動設定を行う。

sudo chkconfig vsftpd on

 
vsftpdの起動設定を正常に行うことができたかを確認する。以下のコマンドを入力する。

sudo chkconfig

 
vsftpdの項目が以下のように表示されれば,設定が成功している。

vsftpd          0:off   1:off   2:on    3:on    4:on    5:on    6:off

 

vsftpを起動する

以下のコマンドを入力し,vsftpを起動する。

sudo service vsftpd start

 

Amazon EC2のSecurity Groupsを設定する

vsftpはAmazon EC2のインスタンス上で稼働しているが,そのインスタンスが使用しているSecurity Groupの設定を変更する。Security Groupを選択して、21番ポート(FTPがデフォルトで使用)と、60001-60010番ポート(FTPのPASVモード時に使用)を外部からアクセスできるように設定する。
 
これでFTPの設定が一通り完了した。あとはFTP接続クライアントを用いて,接続の確認を行うことになる。
 
 
以上
 
 
参考
道はなくても進むのだ: Amazon EC2 (Amazon Linux) での vsftpd インストールと設定

Linuxにおけるファイルのアクセス権について,再勉強したのでまとめておく。
 

アクセス権とは

アクセス権とは,ユーザやグループがファイルやディレクトリに対して,アクセスするための権限のことである。
Linuxは1つのシステムを複数のユーザーで共有できる,マルチユーザー型のシステムなので,システム上のデータをどのユーザーでも自由に操作可能であると,セキュリティ上に問題がある。そこで,ファイルやディレクトリに対して,どういう操作を許可するのかというアクセス権を設定する。
 
ファイルやディレクトリは,ファイルの形式,アクセス権限,所有者,所有グループ,最終更新日時などの属性を持っている。ls -lコマンドによって,これらの属性を確認する事ができる。左から順番に,パーミッション,ファイルの所有者,ファイルの所有グループ,ファイルサイズ,最終更新日時,ファイル名となっている。
 
permission_type
 
アクセス権には「読み取り権」,「書き込み権」,「実行権」の3種類がある。ファイルやディレクトリに対して,設定可能な3種類の権限について,以下の表にまとめる。
 

パーミッションの種類
意味 アルファベットでの表記 数字での表記 説明
※パーミッション表記の一番左側に付けられる「d」や「c」などのアルファベットはファイルの種類を表している。「d」はディレクトリ,「c」は特殊ファイルとなる。
読み取り r 4 ディレクトリ内の一覧表示が可能
書き込み w 2 ディレクトリ内でファイルの作成/変更/削除が可能
実行 x 1 ディレクトリ内のファイルにアクセスが可能

 

パーミッションのアルファベット表記について

パーミッションのアルファベット表記は,ls -lコマンドでファイルのパーミッションを表示した際に使用される。
 
file_permission_a
 
上記画像では,赤枠で囲った部分がファイルのパーミッションである。これは,各アルファベットと-を3つずつに区切り,左から「所有者の権限」,「所有グループの権限」,「その他のユーザーの権限」と解釈する。
 
permission_detail
 

パーミッションの数値表記について

パーミッションの数値表記は,chmodコマンドでファイルのパーミッションを変更する際に使用される。
chmodを使って,ファイルやディレクトリのパーミッションを変更する際の書式は以下のようになる。
 

chmod -c パーミッション ファイル名

 
記述例としては,以下のようになる。
 

chmod 764 smokydog.txt 

 
「764」は数値表記のパーミッションである。数値表記のパーミッションは,所有者に与えられた権限が「rwx」(アルファベット表記)の場合,「4」+「2」+「1」=「7」となる。同様に「rw-」の場合は「4」+「2」=「6」,「r–」の場合は「4」となる。つまり,パーミッションの数値表記は,パーミッションの内容が足し算によって表される。
 

アクセス権の変更方法について

既に上記でも紹介したが,改めてchmodコマンドについて説明する。chmodコマンドは,ファイルやディレクトリのアクセス権を変更する際に使用する。
chmodコマンドの書式は,以下のようになる。
 

chmod オプション アクセス権 ファイル名

 
「オプション」には,代表的なものとして-Rがあるが,これはディレクトリのパーミッションを変更する際に,ディレクトリに含まれる全てのファイルのパーミッションを一緒に変更するオプションである。「アクセス権」の指定は,「対象ユーザー」,「操作」,「権限」の3つを指定することができる。
「アクセス権」に指定できる「対象ユーザー」,「操作」,「権限」の種類を,以下の表に示す。
 

対象ユーザー
対象ユーザー 内容
u 所有者
g 所有グループに属するユーザー
o その他のユーザー
a 全てのユーザー

 

操作
操作 内容
+ 権限を追加する
- 権限を削除する
= 権限を指定する

 

権限
権限 内容
r 読み取り権限
w 書き込み権限
x 実行権限
s SUID,またはSGID
t スティッキービット

 
記述例としては,以下のようになる。
 

#a.txtに,その他のユーザーの読み取り権限を追加
chmod o+r a.txt

#a.txtから,所有者及び,所有グループに属するユーザーの実行権限を削除
chmod ug-x a.txt

 

デフォルトのアクセス権について

ファイルやディレクトリを作成したときに設定されるデフォルトのアクセス権は,umask値で決定される。umask値は3桁の数値で,ファイルは「666」,ディレクトリは「777」からumask値を引いた値が,デフォルトのアクセス権となる。umask値はユーザーごとに設定される。
umask値を設定する際の書式は,以下のようになる。
 

umask マスク値

 
具体的な記述例としては,以下のようになる。
 

umask 022

 

SUIDについて

SUID(Set User ID)とは,特殊なパーミッション(アクセス権)の一つで,実行可能ファイルに対して設定することができる。ファイルのパーミッションには「読み取り権」,「書き込み権」,「実行権」が存在するが,このうちの「実行権」に対して,RootユーザのユーザIDをセットすることができる。RootユーザのユーザIDがセットできることによって,Rootユーザにしか実行権限がなかったファイルに対して編集などが可能になる。
例えば,/etc/passwdファイルは,ユーザー名やパスワードなどのユーザーアカウント情報を格納するファイルであるが,このファイルはパーミッションが「rw-r–r–」となっており,所有者である「root」以外は書き込みができないようになっている。しかし,一般ユーザがpasswdコマンドで自身のパスワードを変更すると,新しいパスワードは/etc/passwdファイルに保存される。何故このようなことが可能かというと,passwdコマンドには特殊なパーミッションであるSUIDが設定されており,実行時にroot権限に切り替わるからである。
SUIDを設定する際の書式は以下のようになる。
 

chmod u+s ファイル名

 
SUIDを設定するには,chmodコマンドで所有者「u」に対して権限「s」を追加する。SUIDが設定されたファイルのパーミッションの数値表記は,3桁の数値表記に「4000」を加えたものになり,「4777」のように書き表される。
 

SGIDについて

SGID(Set Group ID)とは,特殊なパーミッション(アクセス権)の一つで,実行可能ファイルおよびディレクトリに対して設定することができる。SGIDは,SUIDと機能的にはほとんど同じで,ファイルの「実行権」に対して,GroupのグループIDをセットすることができる。ディレクトリに対してSGIDを設定すると,そのディレクトリ内に作成されたファイルやディレクトリの所有グループが,ディレクトリ自体の所有グループに設定される。
SGIDを設定する際の書式は以下のようになる。
 

chmod g+s ファイル名

 
SGIDを設定するには,chmodコマンドで所有グループに属するユーザー「g」に対して,権限「s」を追加する。SGIDが設定されたファイルのパーミッションの数値表記は,3桁の数値表記に「2000」を加えたものになり,「2777」のように書き表される。
 

スティッキービットについて

スティッキービットとは,特殊なパーミッション(アクセス権)の一つで,ディレクトリに対して設定することができる。スティッキービットが設定されたディレクトリでは,書き込み権限はあっても,自分以外のユーザーが所有するファイルを削除することはできない。これはファイルのパーミッションを「777」に設定したいが,ファイル自体は他のユーザーに削除されたくない場合に使用する。
スティッキービットを設定する際の書式は以下のようになる。
 

chmod o+t ファイル名

 
スティッキービットを設定するには,chmodコマンドでその他のユーザー「o」に対して,権限「t」を追加する。スティッキービットが設定されたファイルのパーミッションの数値表記は,3桁の数値表記に「1000」を加えたものになり,「1777」のように書き表される。
 

ファイルの拡張属性について

ext2やext3といったファイルシステムでは,通常の属性(パーミッションや更新日時など)のほかに,拡張属性を設定することができる。ファイルの拡張属性を変更するには,chattrコマンドを使用する。
chattrコマンドの書式は,以下のようになる。
 

chattr オプション 拡張属性 ファイル名

 
拡張属性の指定は,「操作」,「属性」の2つを指定する。
「属性」に指定できる「操作」,「属性」の種類を,以下の表に示す。
 

操作
操作 内容
+ 属性を追加する
- 属性を削除する
= 属性を指定する

 

属性
属性 内容
i 変更不可
d dumpコマンド実行時にバックアップの対象にしない

 
具体的な記述例としては,以下のようになる。例では,ファイル「test.txt」に変更不可の属性を設定している。
 

chattr +i test.txt

 
また,拡張属性を確認するには,lsattrコマンドを使用する。
lsattrコマンドの書式は以下のようになる。
 

lsattr ファイル名

 
 
以上
 
 
参考
かんたん!アクセス権 | ウナのLinux講座 | ウナのIT資格一問一答

Amazon EC2のMicroインスタンスに設置したApacheを使ってBasic認証を設定してみたので手順をメモしておく。
 

Basic認証とは

Webサイトの閲覧に使うプロトコル「HTTP」が備える、最も基本的なユーザ認証方式。アクセスの制限されたWebページにアクセスしようとすると、Webブラウザでユーザ名とパスワードの入力を求め、サーバでアクセスを許可しているユーザに一致すると、ページを閲覧することができる。
 

Basic認証を設置する方法

Basic認証を行う方法について,以下より,手順ごとに説明する。
 

.htpasswdを作成する

.htpasswdとは,Basic認証に使用される,ユーザ名とパスワードが記述されたファイルである。ファイルの書式は,ユーザ名:パスワードとなる。加えて,ファイルの記述ルールとして,パスワードは必ず符号化・暗号化することが求められる。パスワードの符号化・暗号化には,BASE64,MD5,cript()などを使用することが出来る。今回はLinuxのhtpasswdというプログラムを使って,.htpasswdファイルを作成する。
 
Linuxのhtpasswdプログラムで.htpasswdファイルを生成したい場合,以下の書式でコマンドを入力する。
 

htpasswd -c ファイル名 ユーザ名

 
書式に沿った具体例としては,以下のようになる。
 

htpasswd -c .htpasswd dog

 
上記のコマンドを入力後は,以下のようにシェルとの対話によってパスワードを設定することができる。
 
htpasswd
 
ちなみに,.htpasswdファイルの中身は以下のように記述されている。
 

dog:tB1Qybq7RtMNo

 
もっと簡単な.htpasswdの作成方法として,こちらのサイトで提供されている.htpasswdの作成ツールを用いる方法もあるが,セキュリティ上の観点で見ると推奨は出来ない。
 

.htaccessを作成する

.htaccessとは,Webサーバで使用できる、Webサーバの動作をディレクトリ単位で制御するためのファイルである。今回はBasic認証を行うために使用する。
以下,Basic認証を設置する際の.htaccessの記述例である。
 

<Files ~ "^\.(htaccess|htpasswd)$">
deny from all
</Files>
AuthUserFile /var/www/html/.htpasswd
AuthGroupFile /dev/null
AuthName "Please enter your ID and password";
AuthType Basic
require valid-user 
order deny,allow

 
<Files ~ "^\.(htaccess|htpasswd)$">deny from all</Files>では,正規表現を用いて,.htaccessと.htpasswdへのアクセスを制限している。これは,他人に.htaccessと.htpasswdが見られないようにするための処置である。
 
AuthUserFile /var/www/html/.htpasswdでは,認証に使用するための.htpasswdファイルの場所を指定している。
 
AuthGroupFile /dev/nullは,グループごとに認証を行う必要がある場合に指定する。今回はその必要は無いので,/dev/nullを指定している。/dev/nullとは,プロセスの不要な出力ストリームを捨てるのに使うか、入力ストリームのための空のファイルとして使うスペシャルファイルである。
 
AuthName "Please enter your ID and password"では,認証時に表示するメッセージを指定している。
 
AuthType Basicでは,認証方式を指定している。
 
require valid-userでは,アクセスを許可するユーザを指定する。全てのユーザを許可する場合は今回のようにvalid-userを指定する。
 
order deny,allowでは,アクセスの「許可」と「拒否」の順番を指定している。orderを使うことで拒否と許可の順番の指定を行うことができる。denyが拒否,allowが許可なので,今回の場合は「拒否してから許可」と指定している。
 

httpd.confを編集する

httpd.confには,.htaccessファイルを使用するように設定する必要がある。
httpd.confファイルのAllowOverrideを,以下のようにNone指定からAll指定に変更する。
 

#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be &quot;All&quot;, &quot;None&quot;, or any combination of the keywords:
#   Options FileInfo AuthConfig Limit
#
    # AllowOverride None
    
    # NoneをAllに変更すると.htaccessの設定が有効になる。
    AllowOverride All

 

Apacheを再起動する

以下のコマンドを実行し,Apacheを再起動することでhttpd.confへの変更が反映される。
 

sudo service httpd restart

 
これでBasic認証を設定することができた。
 
 
以上
 
 
参考
.htaccessでベーシック認証 | バシャログ。
ベーシック認証を設定する(AuthType) – アクセス制限 – Apache入門
BASIC認証とは 〔 ベーシック認証 〕 〔 基本認証 〕 – 意味/解説/説明/定義 : IT用語辞典
.htaccessとは – 意味/解説/説明/定義 : IT用語辞典

XSS脆弱性への対策方法について勉強した。サニタイズ言うなキャンペーンにも目を通した。Webアプリケーションのセキュリティに詳しい,高木浩光先生や徳丸浩先生の考え方を含めながら,まとめてみる。
 

XSSとは

ソフトウェアのセキュリティホールの一つで,Webサイトの訪問者の入力をそのまま画面に表示する掲示板などのプログラムが,悪意のあるコードを訪問者のブラウザに送ってしまう脆弱性のこと。
悪意を持ったユーザがフォームなどを通してJavaScriptなどのスクリプトコードを入力した時に,プログラム側に適切なチェック機構がないと,そのスクリプト内容がそのままHTMLに埋め込まれ,ページを閲覧したコンピュータでスクリプトが実行されてしまうことがある。
 

サニタイズとは

Webサイトの入力フォームへの入力データから,HTMLタグ,JavaScript,SQL文などを検出し,それらを他の文字列に置き換える操作のこと。「無害化」とも呼ばれ,サニタイジング操作により,入力データ中に含まれる悪意のあるHTMLタグ,JavaScript,SQL文などが解釈・実行されることを防ぐ。
 

サニタイズはするべきではない

ここまで見て,まず考えるのが「XSS対策としてサニタイズすれば良いのではないか」ということであるが,サニタイズはXSS対策の保険的なものであり,本来,サニタイズは推奨されない。
 
日本における「サニタイズ」という言葉の持つ意味やニュアンスを厳密に定義すると「入力処理で受け取ったデータに含まれる有害(別のリテラルで解釈可能)なメタ文字に対して,エスケープ処理を行うこと」となる。
ここで注意したいのは,「サニタイズ」は「バリデーション」とは全く異なるという点である。バリデーションを行うことは一般的なので,ここでは深く説明はしないが,「バリデーション」という言葉の定義は「入力処理で受け取ったデータに対して,データの妥当性をチェックすること」であり,サニタイズとは異なる。
 
では,何故サニタイズをしてはいけないのか,ということについての理由を説明する。まず,大前提として「サニタイズ」は間違った習慣が根付いてしまったものであり,本来は推奨されるべきではない,ということを念頭に置いてほしい。
 
サニタイズが推奨されないことには,以下の2つの理由がある。

  • プログラマの都合で,ユーザーが入力した内容を勝手に改変するべきではない
  • サニタイズが行われると,システムが汚染される

以下,それぞれの理由について説明する。
 

プログラマの都合で,ユーザーが入力した内容を勝手に改変するべきではない

いくらセキュリティ上の危険があるからといって,ユーザーが入力した内容を勝手に改変してよい理由はない。もし,メタ文字のエスケープが必要になる入力が行われたとしたら,それは本来はエラーにするべきである。
 

サニタイズが行われると,システムが汚染される

サニタイズは「スクリプトで受け取ったデータに含まれる,<>&"といったメタ文字を,JavaScriptのリテラルとして解釈できてしまう」という問題への付け焼刃的な対策方法である。だが,必ずしもXSSへの対策にサニタイズを行う必要はなく,出力処理で適切にエスケープ処理を行うことで,XSS脆弱性を回避することが可能である。
ここで大切なのは「サニタイズ」という言葉の定義を正しく理解することである。「サニタイズ」とは「入力処理で有害なメタ文字をエスケープ処理すること」である。「出力処理で有害なメタ文字をエスケープすること」を「サニタイズ」とは呼ばない。
 
ここで,どうして「入力処理」ではなく,「出力処理」でメタ文字をエスケープすることにこだわるのか,ということについて説明する。その理由は,メタ文字のエスケープ処理がシステムにもたらす「汚染」とも呼ぶべき影響範囲をなるべく小さくするためである。
 
ここでの「汚染」とは,入力データがエスケープ処理によって,本来のデータとは異なるデータに書き換えられることによって発生する,システムへの害のことを指す。
もし,入力処理でメタ文字のエスケープ処理を行った場合,エスケープ処理の影響は,システム内部やDBにまで波及する。つまり,システム内部やDBにて,エスケープ処理されたデータを,本来のデータに戻すための2次3次的な変更が発生することになる。
一方,出力処理でメタ文字のエスケープ処理を行った場合,エスケープ処理の影響はシステム内のどこにも波及することはない。
 
以上の理由から,XSS対策に,サニタイズ(入力処理でのメタ文字のエスケープ処理)は推奨されない。XSS対策には,出力処理でのメタ文字のエスケープ処理を行うべきである。
 

まとめ

  • サニタイズとは,「入力処理でメタ文字をエスケープすること」である
  • XSS脆弱性対策には,サニタイズは行わず,出力処理で適切にエスケープ処理を行う

 
 
以上
 
 
参考
クロスサイトスクリプティングとは 【 XSS 】 【 Cross Site Scripting 】 – 意味/解説/説明/定義 : IT用語辞典
サニタイジングとは 【 sanitizing 】 〔 サニタイズ 〕 – 意味/解説/説明/定義 : IT用語辞典
高木浩光@自宅の日記 – WASF Times版「サニタイズ言うな!」
XSS再入門
XSS: 今こそXSS対策についてまとめよう – 徳丸浩の日記(2008-08-22)