->back to toppage

課題内容

自分の実験環境(端末)の使用/未使用ポート(ウェルノウンポート のみでok)を確認するポートスキャンプログラムを作成せよ。 さらに、任意のリモート端末の使用/未使用ポートを確認するように 改良せよ(加点ポイント)。なお、スクリプトを使って内部で'netstat -l' コマンドを実行し、その結果を利用するのは不可とする (ソケットプログラムを作成すること)。


作成したポートスキャンプログラム

portscan.cは、引数で指定されたホストの ウェルノウンポートをスキャンするプログラムである。 引数は複数指定可能で、それぞれのホストに順番にポートスキャンを行い、 使用されているポート(接続できたポート)とその合計数を表示する。 全てのホストへのポートスキャンを終了したら、指定されたホスト数、 スキャンを実行したホスト数、見つからなかったホスト数を 表示して終了する。

図2は、このプログラムが実行している ポートスキャンをイメージ化したものである。
このプログラムではポートに接続できるかどうかを確認するために connect()関数を複数回利用して全ポートに総当たりを行っている。

実行結果では、ホスト133.13.54.209とホストnw0439.st.ie.u-ryukyu.ac.jp (同一ホスト)は合計4つのポートが接続可能である事がわかる。
また、ホストmokeQは存在しないアドレスのため、ホストが見つからない。
この例で接続可能なホストとそのポートが対応するサービスは以下の通りである。
ポートとそれに対応するサービス(括弧内は関連するMacのサービス)

Port 22 -> SSH Remote Login Protocol(リモートログイン)
Port 80 -> World Wide Web HTTP(パーソナルWeb共有)
Port 427 -> Server Location(パーソナルWeb共有、パーソナルファイル共有)
Port 548 -> AFP over TCP(パーソナルファイル共有)

ポートスキャンプログラムとは、対象ホストのポート(こっこでは0〜1023 のウェルノウンポート)の接続の可不可を確認するプログラムである。 netstatコマンドで言えば、stateが“LISTEN”になっているポートは 接続可能なポートになる。
この作業で脆弱なポートを発見したりすると、そこから不正侵入 を受ける事もある。また、接続できないポートを突破して侵入される 場合もある。システム管理者は、このプログラムを利用して 管理しているシステムの弱点などを調べる事もできる。

表示すると情報量が大幅に増えるのでコメントアウトしてあるが、 接続不可能なポートを表示する機能も一応付加してある。 (ソース78行目〜82行目)

-> portscan.c
-> portscan.c -file
->ポートスキャンイメージ
->実行結果


portscan.c
01: /******************************************************
02:  *
03:  *    PortScan program
04:  *
05:  * auther : Yuichiro Tomoyose
06:  *   file : portscan.c
07:  *   date : 2006/01/26
08:  *  usage : ./portscan address [address address ...]
09:  *
10:  *****************************************************/
11:
12: #include <stdio.h>
13: #include <ctype.h>
14: #include <string.h>
15: #include <sys/types.h>
16: #include <sys/socket.h>
17: #include <netinet/in.h>
18: #include <netdb.h>
19:
20: int main( int argc, char *argv[] )
21: {
22:   int    SocketNumber;        /* Socket descripter */
23:   int    usedport;            /* Used port count */
24:   int    i;                   /* argument count */
25:   int    nconnect = 0;        /* cannot connected hosts count */
26:   struct hostent *HostEntry;  /* host entry */
27:   struct sockaddr_in sin;     /* Socket Entry */
28:  
29:   /* Set protocol family name */
30:   sin.sin_family = AF_INET;
31:  
32:   /* Argument check */
33:   if( argc == 1 )
34:     {
35:       printf("usage: ./portscan address [address address ...]\n");
36:       exit(1);
37:     }
38:  
39:   /* Arguments (Host-Name) loop */
40:   for( i = 1 ; i <= (argc - 1) ; i++ )
41:     {
42:       usedport = 0;
43:       
44:       printf("----- %s -----\n",argv[i]);
45:      
46:       /* Host check & Get Host Entry by Host-Name */
47:       if((struct hostent *)NULL == (HostEntry = gethostbyname(argv[i])))
48:     {
49:       printf("\7No Hosts.\n\n");
50:       nconnect++;
51:     }else
52:     {
53:	  
54:       bcopy(HostEntry->h_addr,&sin.sin_addr.s_addr,HostEntry->h_length);
55: 	  
56:       /* Connect Wellknown Port */
57:       unsigned short count;
58:       int useport;
59:       for( count = 0 ; count < 1023 ; count++ )
60:         {
61:	      
62:           /* Make Socket */
63:           if(0 > (SocketNumber = (socket(AF_INET,SOCK_STREAM,0))))
64:             {
65:               printf("\7Cannot get Socket.\n");
66:               exit(1);
67:             }
68:
69:           /* PortNumber set */
70:           sin.sin_port = htons(count);
71:
72:           /* Try Connect */
73:           if( 0 == connect(SocketNumber, (struct sockaddr *)(&sin), sizeof(sin)))
74:             {
75:               printf("--Port No.%d used.\n",count);
76:               usedport++;
77:             }
78:           //else
79:           //{
80:           //  printf("--Port No.%d not used.\n",count);
81:           //}
82:
83:           /* Close Socket */
84:           close(SocketNumber);
85:
86:         }
87:	  
88:       /* Result print */
89:       printf("%d port is used\n\n",usedport);
90:	  
91:       }
92:     }
93:  
94:   printf("Total %d hosts.\n",(argc - 1));
95:   printf("  %d hosts portscan end.\n",((argc - 1) - nconnect));
96:   printf("  %d hosts can't find.\n\n",nconnect);
97:   
98: }

図2:ポートスキャン作業のイメージ


実行結果
[nw0439]% ./portscan
usage: ./portscan adress [address address ...]
[nw0439]% ./portscan 133.13.54.209 nw0439.st.ie.u-ryukyu.ac.jp mokeQ
----- 133.13.54.209 -----
--Port No.22 used.
--Port No.80 used.
--Port No.427 used.
--Port No.548 used.
4 port is used

----- nw0439.st.ie.u-ryukyu.ac.jp -----
--Port No.22 used.
--Port No.80 used.
--Port No.427 used.
--Port No.548 used.
4 port is used


----- mokeQ -----
No Hosts.

Total 3 hosts.
  2 hosts portscan end.
  1 hosts can't find.

[nw0439]%

参考URL

「YUNET」
「ソケットプログラミング」
「Structure」
「Brief guide to UNIX Network programming」

->previous problem
->go to toppage
-> next problem