ホーム » 「nmap」タグがついた投稿
タグアーカイブ: nmap
ネットワークサービスとポートスキャン
外部からネットワーク接続を受けて、どういった処理を実行するようになっているのかを知るための方法を説明する。
ポート番号
ネットワーク通信では、通信する相手を指定するために IP アドレスが用いられるが、サーバでは、複数のプログラムが動いており、どのプログラムと接続するのかを指定するには、ポート番号を用いる。
IPアドレスを電話番号に例えるならば、ポート番号は内線電話番号に相当する。
特に、サーバではクライアントからの通信を待つために、このサービスならばこのポート番号を使うという標準番号が決まっている。
SSH = 22 # リモート接続(暗号化) TELNET = 23 # リモート接続 SMTP = 25 # メール送信 DNS = 53 # DNSサービス HTTP = 80 # Web サーバ POP = 109,110 # メール受信 IMAP = 143 # メール受信 HTTPS = 443 # Web サービス(暗号化) SMTPS = 465 # メール送信(暗号化) IMAPS = 993 # メール受信(暗号化) POPS = 995 # メール受信(暗号化)
ネットワークサービス
サーバでは、クライアントからの接続の受信を待つために、あらかじめプログラムを起動しておく必要がある。
こういうサーバプログラムは、Linux の世界では デーモン と呼ぶことも多い。
ネットワークサービスを起動する方式には、いくつかの方法がある。
スーパーサーバを使う場合
ネットワーク処理のプログラムは、複雑な処理を行うためそのプログラムを起動しておくと、メモリを大量に使用する。古いコンピュータでは、処理速度の低下となるため、利用頻度の低いサーバは、汎用的なサーバを起動しておき、必要に応じてプログラムを起動する。この方法には、inetd とか xinetd が用いられる。
$ vi /etc/inetd.conf echo stream tcp nowait tsaitoh コマンド名
上記の例では、echo=7番ポート に tcp で接続すると、ユーザ名 tsaitoh の権限で、コマンド名を実行してくれる。
デーモンを起動しておく場合
Linux では ランレベル という状態が決められている。
- シングルユーザモード(S) – 管理者が作業中で他のネットワーク接続とかを受け付けない状態
- システム停止(0) – 他の状態からシステム停止に移るための仮想的なランレベル
- マルチユーザモード(2) – 複数のユーザの接続ができる状態
- GUI環境付きのマルチユーザモード(5) – X11ディスプレイマネージャが動く状態
((( /etc/inittab の中に以下の記載がある ))) $ cat /etc/inittab : # The default runlevel. id:2:initdefault: : $ runlevel # 現在のランレベルを確認する方法 N 5
sysv-rc 方式
Linux では、ランレベルを変更する init コマンド(init 0 を実行すると、システムを停止できる)を実行すると、
- /etc/rc移行元ランレベル.d 配下のKで始まるプログラムをファイル名順に実行する。
- /etc/rc移行先ランレベル.d 配下のSで始まるプログラムをファイル名順に実行する。
$ ls /etc/rc2.d K01aprx S17sudo K01onedrive S17unattended-upgrades README S17uuidd S01lvm2-lvmpolld S18acpid S01pulseaudio-enable-autospawn S18amavis S14nfs-common $ sudo /etc/init.d/apache2 start # apache2のサーバ起動 $ sudo /etc/init.d/apache2 stop # 停止 $ sudo /etc/init.d/apache2 restart # 再起動
systemd 方式
上記の sysv-rc 方式は、プログラムの起動スクリプトが shell で書かれているので、(システムが単純な頃は)メンテナンスが容易だったが、(システムが複雑になると)起動処理に時間がかかるのが問題となった。このため、新しい Linux では、systemd というプログラムでサーバを起動する方式にかわった。
$ ls /etc/systemd journald.conf network pstore.conf sleep.conf system.conf user logind.conf networkd.conf resolved.conf system timesyncd.conf user.conf $ sudo systemctl list-units # systemd のユニット一覧 $ sudo systemctl list-sockets # 使用中のソケット一覧 $ sudo systemctl status apache2 # systemd で起動している特定のサーバの状態確認 $ sudo systemctl start apache2 # systemd でサーバ起動 $ sudo systemctl stop apache2 # systemd でサーバ停止 $ sudo systemctl restart apache2 # systemd でサーバ再起動
起動中のプログラムの確認
システムが通常状態で起動しているプログラムを確認するには、ps ax を用いる。
$ ps ax # a 全プロセス表示 x 端末を持たないプロセスも表示 PID TTY STAT TIME COMMAND 1 ? Ss 2:57 /sbin/init 2 ? S 0:00 [kthreadd] : 2229038 ? S 0:03 /usr/sbin/apache2 -k start :
PIDがプロセス番号、STATは、S:処理待ち状態、R:実行状態、TIME欄は、のべ実行時間を表す。
各プロセスの親プロセスと子プロセスの関係が知りたい場合には、pstree コマンドを用いる。
$ pstree systemd-+-/usr/sbin/amavi---2*[/usr/sbin/amavi] |-/usr/sbin/apach---11*[/usr/sbin/apach] |-ModemManager---2*[{ModemManager}] |-NetworkManager---2*[{NetworkManager}]
ここで、見たことのないプログラムが動いている様なら、システムの進入を受けた可能性を疑わないといけない。
ネットワーク通信で受信待ちのプログラムの確認
Linuxで開いているポートを確認するためには、netstat コマンドを用いる。
$ sudo netstat -ltup4 # -l Listenポート、-t TCP、-u UDP、-p ポートを開いている、-4 IPv4 稼働中のインターネット接続 (サーバのみ) Proto 受信-Q 送信-Q 内部アドレス 外部アドレス 状態 PID/Program name tcp 0 0 localhost:3551 0.0.0.0:* LISTEN 841/apcupsd tcp 0 0 0.0.0.0:imaps 0.0.0.0:* LISTEN 418280/dovecot :
nmap でポートスキャン
netstat コマンドは、対象コンピュータを使っている時には有効だが、他のコンピュータを調べるには、ポートスキャン専用の nmap を使うのが一般的。
ポートスキャンとは、相手のコンピュータに接続するポート番号を変更しながら、通信可能か調べること。
$ sudo nmap localhost Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-17 14:45 JST Nmap scan report for localhost (127.0.0.1) Host is up (0.0000090s latency). Other addresses for localhost (not scanned): ::1 Not shown: 982 closed ports PORT STATE SERVICE 22/tcp open ssh 25/tcp open smtp :
nmap で調べるための様々なオプション
$ sudo nmap -A localhost # OSなどを調べる $ sudo nmap -p 1-1023 localhost # 1〜1023 までのポート番号を調べる $ sudo nmap -sU localhost # UDPのポートスキャン $ sudo nmap -O localhost # OSの検出
攻撃を受けているのであれば、wireshark などのパケットキャプチャを使って、パケットの中身を調べる必要がある。
Capture The Flags 講座のアフターケア
子供が Capture The Flags の講座に参加したけど、簡単な説明後いきなりミニCTF大会だったので、さっぱり分からないだろうから、少し解き方の説明。
ドメインの秘密
ドメイン名とは、IPアドレスは覚えられないのでコンピュータにつけた名前。そのドメイン名とIPアドレスのデータベースがDNS。通常は、コンピュータ名からIPアドレスを調べる時に使う。unix や windows で DNS 情報を調べるコマンドが、nslookup。
最新の unix 環境では、nslookup ではなく、dig しか入っていないかもしれない。
その場合は、
$ sudo apt-get install dnsutils
((( 基本的使い方 ))) $ nslookup [オプション] ドメイン名 [DNSサーバ] ((( 問い合わせ例 ))) $ nslookup tsaitoh.net 8.8.8.8 # GoogleのDNSサーバに問い合わせる例(正引き) $ nslookup 64.33.3.150 8.8.8.8 # (逆引き=IPアドレスからドメイン名を調べる) $ nslookup -query=A tsaitoh.net # IPv4アドレスを調べる $ nslookup -query=AAAA www.yahoo.com # IPv6アドレスを調べる $ nslookup -query=MX tsaitoh.net 8.8.8.8 # メールサーバ情報を調べる $ nslookup -query=TXT tsaitoh.net 8.8.8.8 # SPF1というメールサーバの信頼性情報
我が家では、自宅専用のDNSサーバが動いている特殊な事例。インターネットのグローバルアドレス空間でどう見えているかを知りたい場合は、DNSサーバに 8.8.8.8 を使う。Google が、記憶しやすいIPアドレスで誰もが使っていい高速のDNSサーバを提供してくれている。
Webページを見つけろ
サーバとの通信では、IPアドレスで相手のコンピュータを見つけるけど、1台のコンピュータ内で複数のネットワークプログラムが動いていた時、どのプログラムと通信するのか区別する必要がある。そのための情報がポート番号。IPアドレスを電話番号に例えるなら、ポート番号は内線電話番号みたいなもの。
このポート番号は、プログラムによって番号は◯◯を使うべき…という値が決まっている(よく知られたポート番号)。Webサーバ(HTTP)は80番、Webサーバ暗号版(HTTPS)は443番、メールサーバ(SMTP)は25番….。
ポート番号で接続するサービスが決まるけど、学内だけで外に見せたくないWebサーバなどがある場合は、ファイアウォールで特定のポート番号を流通させないようにする場合もある。そういう場合には、通常のポート番号以外を使って通信することがある。
Webサーバに接続する時には、80番を使いたくない場合には、http://コンピュータ名:ポート番号/ と URL にポート番号付きで指定することもできる。
ポートスキャン
このポート番号が解らない時は、ポートスキャンというツールがある。ポート1番で通信してみる、ダメなら2番…という繰り返しをしてくれるツール。一番有名なツールが、nmap。ウィルスなどが仕掛けられて、外部からのネットワーク接続を受ける状態(バックドアが仕掛けられた状態)になったのを見つけるのが本来の使い方。
nmap は通常インストールされない(こんな危ないツール普通はシロートに使わせるものではない)。使いたい場合は、
$ sudo apt-get install nmap
((( 基本的使い方 ))) $ nmap [オプション] 接続先 $ sudo nmap tsaitoh.net # サーバ tsaitoh.net を調べる $ sudo nmap -A tsaitoh.net # ソフトの種類も調べてくれる。
ポート番号が解って、そのサーバソフトに接続してみる場合、telnet がよく使われる。
本来は、ネットワークの先のコンピュータを操作するためのソフト(リモート接続23番ポート)だけど、通信を暗号化しないため、セキュリティ的には危険なので、リモート接続用途で使うことは少ない。
Windowsでは、telnetは初期状態でインストールされない。unix で telnet を使いたい場合は、
$ sudo apt-get install telnet
((( 基本的使い方 ))) $ telnet コンピュータ名 [ポート番号] $ telnet tsaitoh.net 80 # 80番ポート(HTTP)に接続 GET / # トップページのHTMLが帰ってくる。 $ telnet tsaitoh.net 25 # 25番ポート(SMTP)に接続 QUIT # 接続を切る
隠れたデータ
ウィルスなどにコンピュータに感染させる場合、ファイル名などを偽っってあったりするので、ファイルの種別を調べたり、その中の命令を分析する必要がある。その場合によく用いる基本コマンド。
((( 基本的使い方 ))) $ file ファイル名 # 指定したファイルが何か簡単に調べてくれる。 $ file a.out # a.out の中身を調べる $ strings ファイル名 # ファイルの中身の文字として表示できるものを表示する。 $ strings a.out # a.out の中の文字情報を抽出 $ nm ファイル名 # オブジェクトファイルのシンボル(関数名や変数名)を表示 $ nm a.out # stripされたa.outでは抽出できない。
逆アセンブル
実行プログラムがどのような処理をしているのか内容を見たい場合は、逆アセンブル(機械語をアセンブリ言語に変換)する。ただし、一般的な実行プログラムでは、関数番地や変数名番地の情報が消されているので、OS の仕組みの知識が必要。
簡単に解析をするのであれば、objdump などを使うことが多い。ここでは、gdb を紹介する。
gdb(GNU Debugger)は、Cコンパイラ(gcc = GNU C Compiler)のためのデバッガ。linux だとプログラムが異常終了すると、coredump(実行時のメモリ内容を出力する機能) するので、この情報でプログラムの異常処理を探す時に使う。
デバッガは通常はインストールされないよな。
$ sudo apt-get install gdb
((( 基本的使い方 ))) a.out は、何らかのC言語のソースで事前に作っておくこと。 | // helloworld.c | #include <stdio.h> | int main() { | printf( "Hello World¥n" ) ; | return 0 ; | } $ gcc helloworld.c $ gdb a.out (gdb) break main # main にブレークポイントを設置 (gdb) run # プログラムを実行 (gdb) step 10 # 10行分処理を実行 (gdb) disas main # main 以降を逆アセンブル (gdb) quit ((( 異常処理とその場所を見つける ))) 異常終了するプログラムの例 | // segv.c | #include <stdio.h> | int main() { | *((int*)NULL) = 123 ; # 0番地にデータを書き込む | return 0 ; | } $ gcc -g segv.c # コンパイル時に名前情報を実行プログラムに埋め込む。 $ ulimit -c unlimited # coredump 機能を有効にする $ ./a.out Segmentation fault (コアダンプ) $ gdb a.out core # 異常終了した行が表示される