情報工学実験2「TCP/IPプログラミング」


学籍番号:055704J
氏 名 :伊志嶺拓人


■課題1:telnetコマンドによるWWWサーバへのアクセス

telnetコマンドを使って任意のWWWサーバにアクセスし、任意のURLのページデータ(htmlソースプログラム)を画面に表示せよ。(報告書にはそのURLとページデータの先頭の20行程度を添付せよ)


・情報工学科のWWWサーバ(www.ie.u-ryukyu.ac.jp)にtelnetアクセスして、j05004のページ(~j05004/index.html)のページデー  タを取得した。
 結果を以下に示す。
~[2006:Dec:02:Sat:12:34]%telnet www.ie.u-ryukyu.ac.jp 80

Trying 133.13.48.8...
Connected to shongane.ie.u-ryukyu.ac.jp.
Escape character is '^]'.
GET /~j05004/index.html HTTP/1.0

HTTP/1.1 200 OK
Date: Sat, 02 Dec 2006 03:34:51 GMT
Server: Apache/2.0.55 (Unix) mod_ssl/2.0.55 OpenSSL/0.9.7i PHP/5.1.2
Last-Modified: Sat, 02 Dec 2006 02:43:02 GMT
ETag: "3c03d6-2b6-1341f980"
Accept-Ranges: bytes
Content-Length: 694
Cache-Control: max-age=60
Expires: Sat, 02 Dec 2006 03:35:51 GMT
Connection: close
Content-Type: text/html




<HTML>
 <HEAD>
   <META http-equiv="Content-Type" content="text/html; charset=EUC-JP">
  <TITLE>
  j05004 HomePage
  </TITLE>
 </HEAD>
<body bgcolor="#333333">
 <BODY>
<font size="3" color="#FFFFFF">
<h2> TAKUTOのページ</h2>
<hr>
<a href="./kadai.html"><font size="3" color="#FFFFFF">課題のページ</a><br>
<br>
<a href="./fun.html"><font size="3" color="#FFFFFF">趣味のページ</a><br>
<br>
<a href="./gnuplot.html"><font size="3" color="#FFFFFF">Gnuplotのページ</a><br>
<br>
<a href="j05004.sxi.zip"><font size="3" color="#FFFFFF">わたしのプレゼンファイル</a><br>
<br>
<a href="http://www.ie.u-ryukyu.ac.jp"><font size="3" color="#FF00FF">琉球大学情報工学科のページ</a>
 </BODY>
</HTML>
Connection closed by foreign host.
~[2006:Dec:02:Sat:12:34]%

■課題2:inetdを使用するサーバプログラムの作成

サンプルプログラム(1)を自分の実験環境で動作するようにし、実行結果を示すとともに、プログラムの中で使われている関数(Connect,Disconnect, Send Data, Recv Dataなど)の動作を説明し、サーバ・クライアント動作全体をフローを示して説明せよ。

実行結果を以下に示す。

tcp[2006:Dec:08:Fri:12:37]%./client
Connected.
Input Keyword = warning: this program uses gets(), which is unsafe.
yama
Keyword = [yama] / Data = [kawa]

Input Keyword = 123
Keyword = [123] / Data = [456]

Input Keyword = hoge
Keyword = [hoge] / Data = []

Input Keyword = 
Disocnnected.
tcp[2006:Dec:08:Fri:12:37]%

●関数の動作説明

Connect() :サーバにコネクションする関数
Disconnect() :接続を解除する関数
SendData() :サーバにデータを送る関数
RecvData() :セーバからデータを受け取る関数
GetLineFromPeer() : クライアントからデータを受け取る関数
GetKeywordData() : 入力された文字に対応する文字列を返す関数

動作の流れを以下のフロー図に示す。
tcp.jpg

■課題3:inetdを使用しないサーバプログラムの作成

サンプルプログラム(1)のサーバプログラム(server.c)はinetdから起動するものであるが、inetdを使用せずに同じ動作をするデーモン型のサーバプログラムを作成し、実行結果を示すとともに、inetdを使用するサーバプログラムとそうでないものとの実装上の違いを説明せよ。

dclient.c
dserver.c
ターミナル1
%dserver
now waiting for client connect
ターミナル2
%dclient
Connected.
Input Keyword = warning: this program uses gets(), which is unsafe.
yama
Keyword = [yama] / Data = [kawa]

Input Keyword = shiro
Keyword = [shiro] / Data = [kuro]

Input Keyword = xxxx
Keyword = [xxxx] / Data = [yyyy]

Input Keyword = 
Disocnnected.
%
ターミナル1
%dserver
now waiting for client connect
Connected from 127.0.0.1
%
・inetdを使った場合では、クライアントが要求する度にサーバを立ち上げるのでシステムリソースは減少するが、レスポンスが遅くなる。 inetdを使わない場合では、サーバは常に接続されているのでレスポンスは速くなるがシステムリソースは増加する。

■課題4:HTTPクライアントの作成

ソケットおよびHTMLを使ってWWWサーバから任意のURLのページを取得し、標準出力に出力するプログラムを作成せよ。

httpclient.c
琉球大学情報工学科のページを取得した。
結果を以下に示す。

%./http-client http://www.ie.u-ryukyu.ac.jp/
http://www.ie.u-ryukyu.ac.jp/ を取得します。

HTTP/1.1 400 Bad Request
Date: Mon, 11 Dec 2006 05:58:51 GMT
Server: Apache/2.0.55 (Unix) mod_ssl/2.0.55 OpenSSL/0.9.7i PHP/5.1.2
Content-Length: 356
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
<hr>
 〜省略〜

■課題5:ポートスキャンの実験

自分の実験環境(端末)の使用/未使用ポート(ウェルノウンポートのみでok)を確認するポートスキャンプログラムを作成せよ。さらに、任意のリモート端末の使用/未使用ポートを確認するように改良せよ(加点ポイント)。

portscan.c
実行結果を以下に示す。
]%portscan
Address = "127.0.0.1" Portscan started..
Open TCP Port:   80
Open TCP Port:  427
Open TCP Port:  548
Open TCP Port:  631
Portscan find them.
%

■課題6:バッファオーバーフローの実験

サンプルプログラム(2)を実行せよ。このプログラムはgets()関数を用いて、標準入力からの入力をバッファにデータを読み込むものであるが、結果を見ると、プログラム中で操作していないバッファdmy[]に値が入ることがある。この原因を考察し、解決策を示せ。

bufovf.cのBUFLEN 200をBUFLEN 10にして、pwで実行した。
実行結果を以下に示す。
% bufovf
before
buf(Len:0) = 
dmy(Len:0) = 
12345678901234567890
after
buf(Len:20) = 12345678901234567890
dmy(Len:4) = 7890
% 
実行結果より、bufサイズを超えたデータはdmyに書き込まれていることが確認できる。
これは gets()関数によるもので、gets()関数はバッファの長さを指定することができないので、配列以上の文字を入力してしまい、dmyに も書き込まれってしまった。
解決策として、gets()関数ではなく、fgets()関数を使う方法がある。fgets()関数はバッファのサイズを指定することができるので、配列以上の文字を入力するのを防いでくれる。

以下にfgets()関数を使ったプログラムの実行結果を示す。プログラムソース(bufovf.c)
% bufovf
before
buf(Len:0) = 
dmy(Len:0) = 
12345678901234567890
after
buf(Len:19) = 1234567890123456789
dmy(Len:0) = 
% 
結果からも分かるように、
バッファサイズを10に指定しているため、それを超える文字は書き込まれないようになっている。

この問題によって引き起こされるTCP/IP通信におけるセキュリティ上の欠陥はどのようなものが考えられるか、具体例を挙げて述べよ。

 バッファオーバーフーローとは、確保したメモリ領域(バッファ)を超えてデータが入力された場合に、データがあふれてプログラムが暴走してしまうことである。
 
これを利用して バッファに対して許容量を超えるデータを送り付けてシステムを機能停止にしたり、意図的にバッファをオーバーフローさせ、あふれ出たデータを実行させてしまう事ができる。

 バッファオーバーフローは最も代表的なセキュリティ・ホールであり、昔からさまざまなOSやアプリケーションに多く存在している問題である。現在OSで見つかっているセキュリティ・ホールの半数以上はバッファオーバーフローによるものといわれている。

■参考文献

●IT用語辞典 e-Words :http://e-words.jp/
●YUNET: http://yunet.2.pro.tok2.com/index.html
●とほほのWWW入門: http://www.tohoho-web.com/www.html
●C/C++ リファレンス: http://www.cppll.jp/cppreference/
●68user's page: http://x68000.q-e-d.net/~68user/
●TCP/IPプログラミング: http://research.nii.ac.jp/~ichiro/syspro98/index.html