{{category Network,nolink}}telnetを使ってアクセスしてみる。 <<注意:必ず利用する資格を持ったサーバで行うこと。>>利用する資格がないのに接続を行えば不正利用となります。また、認証処理を何度も間違えるとトラブルの原因になりますので注意してください。 !!!telnetでブラウジング telnetコマンドで、webサーバ(ポート80番)にアクセスしてみる。 !!実行手順 webサーバに接続したら、以下のようにGETコマンドでファイルを取得する。引数には取得するファイルのパスとプロトコルのバージョンを指定する。その後リクエストヘッダを必要に応じて送信し、空の行(改行のみ)を送信すると、レスポンスヘッダと空行をはさんでデータが返ってくる。 GET /index.html HTTP/1.0 Host: www.example.com User-Agent: Telnet [ja] (Linux) ※プロトコルバージョンで「HTTP/1.0」の場合は特にリクエストヘッダは必要ないが、「HTTP/1.1」の場合は「Host」を送信する必要がある。''ちなみに、Hostを送らないとバーチャルホストで動いてるサイトには接続できない (出来なかったはず)。'' !!実行結果 - GET (適当に改竄してます) GETコマンドでファイルを取得する。 $ telnet www.example.com 80 Trying 192.0.2.1... Connected to www.example.com. Escape character is '^]'. GET /index.html HTTP/1.0 Host: www.example.com User-Agent: Telnet [ja] (Linux) HTTP/1.1 200 OK Date: Sat, 28 Jun 2008 00:00:00 GMT Server: Apache/1.3.xx (Unix) mod_ssl/2.8.xx OpenSSL/0.9.xg Last-Modified: Sat, 28 Jun 2008 00:00:00 GMT ETag: "6ad4cbccf11eb2d22401db4155cf8bba6e26ea06" Accept-Ranges: bytes Content-Length: 942 Connection: close Content-Type: text/html : 中略 Connection closed by foreign host. $ !!実行結果 - HEAD (適当に改竄してます) HEADコマンドでレスポンスヘッダのみを取得する。 $ telnet www.example.com 80 Trying 192.0.2.1... Connected to www.example.com. Escape character is '^]'. HEAD /index.html HTTP/1.0 HTTP/1.1 200 OK Date: Sat, 28 Jun 2008 00:00:00 GMT Server: Apache/1.3.xx (Unix) mod_ssl/2.8.xx OpenSSL/0.9.xg Last-Modified: Sat, 28 Jun 2008 00:00:00 GMT ETag: "6ad4cbccf11eb2d22401db4155cf8bba6e26ea06" Accept-Ranges: bytes Content-Length: 942 Connection: close Content-Type: text/html Connection closed by foreign host. $ !!実行結果 - POST (適当に改竄してます) POSTコマンドでデータを送信する。 ヘッダで Content-Length を設定して。空行を挟んだ後、指定した長さ(バイト数)分データを書けばよかった気がする。 !!!telnetでブラウジング(AUTH対応) telnetコマンドで、webサーバ(ポート80番)にアクセスしてみる。 web (HTTP) における認証には、「Basic 認証 (基本認証)」と「Digest 認証 (ダイジェスト認証)」の2種類の方法がある。Basic の方がシンプルであり、ほぼすべてのサーバ・ブラウザに実装されている。その反面、セキュリティ面で不安が残る(ID/PWが単に符号化されているだけ)。今時のサーバ・ブラウザであれば、Digest も対応されている(ただし、IE6にはクエリ付きの時のバグがある)。 認証が必要な場合、および、認証が成功していない場合以下のように応答が返ってくる。 *レスポンスコードが、「401 Authorization Required」といった内容になる(コード値:401)。 *レスポンスヘッダに「WWW-Authenticate: Basic realm="Auth Name"」といったヘッダが含まれる。 *レスポンスボディが、認証が必要といった内容(ブラウザでキャンセルした場合に表示される内容)になっている。 認証が必要なページをリクエストする場合は、Authorization ヘッダに認証方法や認証情報を付けてリクエストする。 認証は、ログイン・ログアウトではなく、リクエストのたびに認証情報(Authorization ヘッダ)を送信する必要がある。つまり、Webサーバは、認証が必要なページへのリクエストに Authorization ヘッダがあり、そのユーザ名とパスワードが正しい場合に、そのページの内容を返す。それ以外は 401 を返す。 !!実行手順 - Basic 認証 認証が必要なページにアクセスした場合に、WWW-Authenticate ヘッダがあり、値が「Basic 」で始まる場合は、Basic 認証を要求している。Basic 認証のページにアクセスする場合は、リクエストヘッダに Authorization を追加して、値に「Basic 認証文字列」を指定する。 GET /index.html HTTP/1.0 User-Agent: Telnet [ja] (Linux) Host: www.example.com Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ= Basic 認証での認証情報は、ユーザ名とパスワードをコロンで連結した物をBASE64でエンコードしたも。ユーザ名が 'username'でパスワードが'password'の場合、'aG9nZTpmdWdh'となる。 例えば、perl (と MIME::Base64 モジュール)を使用して求める場合の例: $ perl -MMIME::Base64 -e 'print encode_base64("username:password");' dXNlcm5hbWU6cGFzc3dvcmQ= $ !!実行手順 - Digest 認証 認証情報が必要なページにアクセスした場合に、WWW-Authenticate ヘッダがあり、値が「Digest 」で始まる場合は、Digest 認証を要求している。 Digest 認証は、サーバ側で作成される乱数(ランダム文字列)、ユーザ名とパスワード、クライアント側で作成した乱数(ランダム文字列)といった内容のハッシュ値を求める必要があります。乱数はリクエストのたびに変わる。 !!!telnetでファイル転送? telnetコマンドで、ftpサーバ(ポート21番)にアクセスしてみる。ただ、telnetではファイル転送は(簡単には)出来ないので、==ユーザ認証== PASVモードで一覧取得までです。 !!実行手順 ftpサーバに接続したら、以下のようにUSERコマンドでユーザ名をPASSコマンドでパスワードを送信する。何も出来ないのでQUITコマンドで終了する。 USER anonymous PASS anonymous@example.com QUIT ※アノニマスユーザでログインしたのでパスワードは慣例としてメールアドレスを入力する。 !!実行結果 (適当に改竄してます) $ telnet ftp.example.com 21 Trying 192.0.2.1... Connected to ftp.example.com. Escape character is '^]'. 220 ftp.example.com FTP server (Version wu-2.x.x(MAFFIN) Wed Jal 12 00:00:00 GMT 2000) ready. USER anonymous 331 Guest login ok, send your complete e-mail address as password. PASS anonymous@example.com 230- 230- ####################################### 230- # Welcome to the FTP service. # 230- ####################################### 230- 230 Guest login ok, access restrictions apply. QUIT 221-You have transferred 0 bytes in 0 files. 221-Total traffic for this session was 596 bytes in 0 transfers. 221-Thank you for using the FTP service on ftp.example.com. 221 Goodbye. Connection closed by foreign host. $ !!実行手順(PASVモードで一覧取得) ログインまでの手順は同じ、PASVコマンドを送りデータコネクションの情報を取得する。もう一つ telnet を起動して取得した情報で接続を行う。そして、LISTコマンドを送り一覧を送ってもらう。 USER guest PASS guest PASV LIST QUIT !!実行結果(PASVモードで一覧取得) (適当に改竄してます) ※ STOR と RETR による送信と受信はおまけ $ telnet ftp.example.com 21 220 ftp.example.com FTP server (Version 5.60) ready. USER guest 331 Password required for guest. PASS guest 230 User guest logged in. PASV 227 Entering Passive Mode (192,0,2,1,171,132) LIST 150 Opening ASCII mode data connection for /bin/ls. 226 Transfer complete. PASV 227 Entering Passive Mode (192,0,2,1,171,133) STOR ftptest.txt 150 Opening ASCII mode data connection for ftptest.txt. 226 Transfer complete. PASV 227 Entering Passive Mode (192,0,2,1,171,134) RETR ftptest.txt 150 Opening ASCII mode data connection for ftptest.txt (34 bytes). 226 Transfer complete. QUIT 221 Goodbye. $ telnet 192.0.2.1 43908 /bin/ls の内容 $ telnet 192.0.2.1 43909 ftptest.txt の内容を書く(その後終了させる) $ telnet 192.0.2.1 43910 ftptest.txt の内容 !!!telnetでメール送信 telnetコマンドで、smtpサーバ(ポート25番)にアクセスしてみる。 !!実行手順 smtpサーバに接続したら、HELO コマンドで接続を確立し、MAIL および RCPT で発信者と送信者を指定、DATA でメールの内容(ヘッダと本文)を送り、QUIT で接続を切る。 また、HELO コマンドではなく、EHLO コマンドを利用して接続を確立することによって、サーバがESMTPをサポートしているかの確認、ESMTPをサポートしていれば利用できる拡張機能のリストが取得できる。 メールの内容は、DATA コマンドを送信して開始を伝える、その後、Fromなどのヘッダを、続いて本文を記述。最後に"." (ピリオド)だけの行を送ると入力が終了する。 HELO localhost.example.com MAIL FROM: admin@example.com RCPT TO: user@example.com DATA From: admin@example.com To: user@example.com Subjet: test mail Hello world. . QUIT !!実行結果 (適当に改竄してます) $ telnet smtp.example.com 25 Trying 192.0.2.1... Connected to smtp.example.com. Escape character is '^]'. 220 smtp.example.com ESMTP Sendmail 8.xx.y/8.xx.y; Wed, 2 Jul 2000 00:00:00 +0000 (UTC) HELO localhost.example.com 250 smtp.example.com Hello localhost.example.com [192.0.2.1], pleased to meet you MAIL FROM: admin@example.com 250 2.1.0 admin@example.com... Sender ok RCPT TO: user@example.com 250 2.1.5 user@example.comt... Recipient ok DATA 354 Enter mail, end with "." on a line by itself From: admin@example.com To: user@example.com Subjet: test mail Hello world. . 250 2.0.0 m61F95Dm001664 Message accepted for delivery QUIT 221 2.0.0 smtp.example.com closing connection Connection closed by foreign host. $ !!!telnetでメール送信(SMTP-AUTH対応) telnetコマンドで、SMTP-AUTH対応された smtpサーバ にサブミッションポート(ポート587番)でアクセスしてみる。 最近は、迷惑メール対策として POP before SMTP (PbS), SMTP-AUTH や Outbound Port 25 Blocking (OP25B) などが行われている。PbS は、先にPOP3の接続をして認証を先に行う。OP25B に関しては、指定するポートを25番からサブミッションポートの587番などを指定する。 あとは SMTP-AUTH で、次のようにする。EHLO で接続した際に、サーバから認証が可能な方式が返ってくるので、そのあと、AUTH コマンドで認証処理をする。認証が完了すれば、送信の処理は通常と同じ。 !!実行手順 - PLAIN とりあえずは、一番シンプルな PLAIN 方式での認証手続き。EHLO コマンドで接続を確立後、使用できる認証方式(AUTHの行)が返されてくるので、その一覧の中に"PLAIN"があることを確認する(ない場合は対応していない)。確認できたら、AUTH コマンドで、引数に認証方式と認証文字列を送信する。 EHLO localhost.example.com AUTH PLAIN dXNlcm5hbWUAdXNlcm5hbWUAcGFzc3dvcmQ= QUIT PLAINでの認証文字列は、ユーザ名2回とパスワードをヌル文字で連結したものをBASE64でエンコードしたものになる。ユーザ名が 'username'でパスワードが'password'の場合、'dXNlcm5hbWUAdXNlcm5hbWUAcGFzc3dvcmQ='となる。 例えば、perl (と MIME::Base64 モジュール)を使用して求める場合の例: $ perl -MMIME::Base64 -e 'print encode_base64("username\0username\0password");' dXNlcm5hbWUAdXNlcm5hbWUAcGFzc3dvcmQ= $ !!実行結果 (適当に改竄してます) $ telnet smtp.example.com 587 Trying 192.0.2.1... Connected to smtp.example.com. Escape character is '^]'. 220 smtp.example.com ESMTP EHLO localhost.example.com 250-smtp.example.com 250-AUTH LOGIN CRAM-MD5 PLAIN 250-AUTH=LOGIN CRAM-MD5 PLAIN 250-PIPELINING 250 8BITMIME AUTH PLAIN dXNlcm5hbWUAdXNlcm5hbWUAcGFzc3dvcmQ= 235 ok, go ahead (#2.0.0) QUIT 221 smtp.example.com Connection closed by foreign host. $ !!実行手順 - LOGIN unix の logoin と同じようにユーザ名とパスワードを聞かれるのでそれに答える感じで応答を返す。ただし、要求も応答も平文ではなく、BASE64でエンコードされたものになる。 auth login 334 VXNlcm5hbWU6 # 'Username:' dXNlcm5hbWU= # "username" 334 UGFzc3dvcmQ6 # 'Password:' cGFzc3dvcmQ= # "password" !!実行手順 - CRAM-MD5 サーバから送られてくるキーとパスワードを組み合わせて、MD5ダイジェストを作成しそれにユーザを名を付加してBase64でエンコードする !!実行手順 - DIGEST-MD5 !!おまけ:OP25Bによるブロック (適当に改竄してます) $ telnet smtp.example.com 25 Trying 192.0.2.1... telnet: connect to address 192.0.2.1: Connection timed out $ !!おまけ:SMTP-AUTH認証失敗 (適当に改竄してます) $ telnet smtp.example.com 587 Trying 192.0.2.1... Connected to smtp.example.com. Escape character is '^]'. 220 smtp.example.com ESMTP EHLO localhost.example.com 250-smtp.example.com 250-AUTH LOGIN CRAM-MD5 PLAIN 250-AUTH=LOGIN CRAM-MD5 PLAIN 250-PIPELINING 250 8BITMIME AUTH PLAIN dXNlcm5hbWUAdXNlcm5hbWUAcGFzc3dvcmO= 535 authorization failed (#5.7.0) Connection closed by foreign host. $ !!!telnetでメール受信 telnetコマンドで、pop3サーバ(ポート110番)にアクセスしてみる。 !!実行手順 popサーバに接続したら、USER, PASS コマンドでユーザ認証を行う。認証されたら、LIST コマンドでメールの一覧を受け取り、各メールを RETR, DELE コマンドで受信および削除を行う。最後に QUIT コマンドで終了する。 USER username PASS password STAT LIST RETR 1 DELE 1 LIST QUIT !!実行結果 (適当に改竄してます) $ telnet pop3.example.com 110 Trying 192.0.2.1... Connected to pop3.example.com. Escape character is '^]'. +OK USER username +OK PASS password +OK STAT +OK 1 614 LIST +OK 1 614 . RETR 1 +OK Received: from smtp.example.com (username@smtp.example.com [192.0.2.1]) by smtp.example.com (8.13.x/8.13.x) with SMTP id xxxxxxxxxxxxxx for username@smtp.example.com; Sun, 6 Jul 2008 hh:mm:ss +0900 (JST) Date: Sun, 6 Jul 2008 hh:mm:ss +0900 (JST) Message-Id: <200807060000.xxxxxxxxxxxxxx@smtp.example.com> From: admin@example.com To: user@example.com Subjet: test mail Hello world. . DELE 1 +OK LIST +OK . QUIT $ !!実行手順 - APOP POPの認証はパスワードを平文で送信する。そのため、パスワード漏洩を防止するために、APOP方式が考案された。 APOP に対応している場合、以下のように接続時に '''<12345.1234567890@pop3.example.com>''' といったタイムスタンプが返される。 $ telnet pop3.example.com 110 Trying 192.0.2.1... Connected to pop3.example.com. Escape character is '^]'. +OK <12345.1234567890@pop3.example.com> そして認証の USER, PASS コマンドの代わりに、APOP コマンドを使用し、引数にユーザ名とタイムスタンプとパスワードを連結した文字列のMD5を送信する。 例えば、ユーザ名が 'username' でパスワードが 'password' の場合で、上記の接続の後とき 'a61edf36edd16a1e76fbc8ecef89171b' が認証のコードとなる。 APOP username a61edf36edd16a1e76fbc8ecef89171b 例えば、md5 コマンドを使用して求める場合の例: $ md5 -s '<12345.1234567890@pop3.example.com>password' MD5 ("<12345.1234567890@pop3.example.com>password") = a61edf36edd16a1e76fbc8ecef89171b APOP方式の認証は、あくまでもパスワードをネットワーク上に平文で流さないだけであり、本文などは平文のままになる。また、原理上サーバ側に生パスワードを保存しておく必要がある。さらに、APOP方式の脆弱性も見つかっている。