土日の勉強ノート

AI、機械学習、最適化、Pythonなどについて、技術調査、技術書の理解した内容、ソフトウェア/ツール作成について書いていきます

HTTPを題材にtcpdumpの出力を理解する

前回 は、VirtualBox に ParrotOS の OVA をインストールして、Ubuntu と同じように使えるところまで、基本的な設定と、各ソフトウェアの設定を行いました。

今回は、「ハッキング・ラボのつくりかた 完全版 仮想環境におけるハッカー体験学習」に沿って、進めた内容を書きたいところでしたが、ネットワークのパケットのやり取りを見るための知識が不足していたため、今回は tcpdump の見方を正しく理解しようと思います。

特に、HTTP のやり取りを理解しておかないと先に進めにくいと感じたので、今回は、HTTP の内容についてもまとめようと思います。

それでは、やっていきます。

参考文献

はじめに

「セキュリティ」の記事一覧です。良かったら参考にしてください。

セキュリティの記事一覧

今回は、tcpdump の出力の見方を理解したいと思います。

使用している環境は、Windows10 の PC(ホスト)で、VirtualBox 7.0 + ParrotOS 6.1 です。

tcpdumpののインストール

tcpdump のインストールと、簡単な使い方については、以下の記事で書いたので、参考にしてください。

daisuke20240310.hatenablog.com

ちなみに、ParrotOS には、tcpdump、Wireshark の両方ともデフォルトでインストールされています。

tcpdumpの出力の見方

tcpdump のオプションは、-i(対象のネットワークインタフェース)、-t(タイムスタンプを表示しない)、-n(ホストアドレスを名前に変換しない)を使います。

データを表示しない場合

では、早速1つ目のサンプルを見ていきます。

次の tcpdump の実行結果は、別のターミナルで、Webサーバにアクセスした時の出力です(分かりやすいように改行を入れています)。

最初の2行は、ARP と、その応答です。IPアドレスでリクエストしたら、応答に MACアドレスが格納されています。

次の3行は、3ウェイハンドシェイクと呼ばれるもので、TCP のセッションを確立するための通信です。1行目は SYN パケットなので、Flags が [S](SYN の S)となっていて、length が 0です。2行目は SYN/ACK パケットなので、Flags が [S.](ACK は .)となっていて、やはり length が 0 です。3行目は ACK パケットなので、Flags が [.] となっていて、length は 0 です。クライアントから始まって、サーバ、クライアントの順になっています。

次の4行の最初は、クライアントが 80番ポートのWebサーバに、GET の要求を送信していて、次はその ACK です。次はサーバが応答を返していて、最後は、その ACK です。Flags が [P.](PUSH の P)で、PUSH はデータ送信という意味です。要求は 124byte であることに対して、応答は 1139byte と少し大きいですね。今回はデータを出力していないので、内容は分からないですが、HTML が返ってきてると思います。

最後の3行は、セッションの切断です。最初に、クライアントから FIN パケットを送信し、サーバも FIN パケットを送信しています。それぞれ、直後には相手からの ACK が送信されています。

$ sudo tcpdump -tn -i tap0
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tap0, link-type EN10MB (Ethernet), snapshot length 262144 bytes

ARP, Request who-has 10.0.2.16 tell 10.0.2.17, length 28
ARP, Reply 10.0.2.16 is-at 8e:02:d5:a1:04:fe, length 28

IP 10.0.2.16.50766 > 10.0.2.17.80: Flags [S], seq 2983610609, win 64240, options [mss 1460,sackOK,TS val 1394056006 ecr 0,nop,wscale 7], length 0
IP 10.0.2.17.80 > 10.0.2.16.50766: Flags [S.], seq 1869491964, ack 2983610610, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0
IP 10.0.2.16.50766 > 10.0.2.17.80: Flags [.], ack 1, win 502, length 0

IP 10.0.2.16.50766 > 10.0.2.17.80: Flags [P.], seq 1:125, ack 1, win 502, length 124: HTTP: GET / HTTP/1.1
IP 10.0.2.17.80 > 10.0.2.16.50766: Flags [.], ack 125, win 229, length 0
IP 10.0.2.17.80 > 10.0.2.16.50766: Flags [P.], seq 1:1140, ack 125, win 229, length 1139: HTTP: HTTP/1.1 200 OK
IP 10.0.2.16.50766 > 10.0.2.17.80: Flags [.], ack 1140, win 501, length 0

IP 10.0.2.16.50766 > 10.0.2.17.80: Flags [F.], seq 125, ack 1140, win 501, length 0
IP 10.0.2.17.80 > 10.0.2.16.50766: Flags [F.], seq 1140, ack 126, win 229, length 0
IP 10.0.2.16.50766 > 10.0.2.17.80: Flags [.], ack 1141, win 501, length 0

データも表示する場合(HTTPの詳細)

続いて、データも表示する場合です。追加で使用するオプションは、-X(パケットの内容と ASCII文字を出力する)だけです。

コマンドライン(curlコマンド)で、Webサーバに、HTTPリクエストを送ります。

見方は、行頭に > が付いてるところがクライアントからの GETリクエストで、< が付いているのがレスポンス(応答)です。少し長いので、HTTPリクエストとHTTPレスポンスに分けて表示します。

最初に > が付いてるところが、先頭行で、HTTP のリクエスト行になります。今回は GET リクエストで、要求するパスは /(ルート)で、HTTPバージョンは 1.1 です。この先頭行から空行まで(今回は4行と空行まで)がリクエストヘッダと呼ばれます。今回は、リクエストボディはありません(PUTリクエストとかはリクエストボディがある)。

2行目は、Hostヘッダと呼ばれ、URL のホスト名とポート番号(今回はデフォルトの80番なので省略されている?)が入ります。HTTP 1.1 では必須行です。

$ curl -vvv http://10.0.2.17
*   Trying 10.0.2.17:80...
* Connected to 10.0.2.17 (10.0.2.17) port 80
> GET / HTTP/1.1
> Host: 10.0.2.17
> User-Agent: curl/8.8.0
> Accept: */*
> 

続いて、HTTPレスポンスの内容です。< が付いているのが、HTTPレスポンスの1行目で、ステータス行です。プロトコルバージョン、ステータスコード、原因の3つから構成されます。この1行目から空行まで(10行と空行まで)が、レスポンスヘッダで、空行の後からがレスポンスボディとなります。

2行目はサーバのソフト名が入っており、nginx(エンジンエックス)が使われています。

6行目の Connection: keep-alive が重要です。HTTP/1.0 では、1つのリクエストに対して、1つのレスポンスを返すと TCP のコネクションを切断していました(ステートレスと呼ばれる)。HTTP/1.1 からは、1回の接続で、複数のリクエストとレスポンスを処理できるようになり、これが Keep-Alive の機能です。

空行の後はレスポンスボディで、HTML のデータが入っています。

* Request completely sent off
< HTTP/1.1 200 OK
< Server: nginx/1.15.7
< Date: Thu, 25 Jul 2024 13:39:01 GMT
< Content-Type: text/html
< Content-Length: 814
< Connection: keep-alive
< Vary: Accept-Encoding
< Last-Modified: Thursday, 25-Jul-2024 13:39:01 GMT
< Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0
< Accept-Ranges: bytes
< 
* Connection #0 to host 10.0.2.17 left intact
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"><meta http-equiv="pragma" content="no-cache"><link rel="icon" href="/favicon.ico"><title>Phoenix Contact - CHARX</title><script defer="defer" src="/js/chunk-vendors.6b7ab196.js"></script><script defer="defer" src="/js/app.813fc1cc.js"></script><link href="/css/chunk-vendors.6663084f.css" rel="stylesheet"><link href="/css/app.9f2662ac.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but charx doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>

続いて、tcpdump の出力です。内容は先ほどとだいたい同じはずなので、先ほどと同じ方法で分割します。

まずは、3ウェイハンドシェイクの部分です。先ほどの通信の部分に加えて、それぞれのデータが表示されています。

最初の SYN パケットのデータについて説明します。

45 から始まって、1行目の最後の 0a00 0210 が送信元 IPアドレスで、2行目の 0a00 0211 の送信先 IPアドレスまでが IPヘッダです。

その後の b5d6(46550)が送信元ポート番号で、その次の 0050(80)が送信先ポート番号で、3行目の 0000(緊急ポインタ)までが通常の TCPヘッダです。今回は、オプションで 20byte の追加の TCPヘッダがあるようです。

$ sudo tcpdump -tnX -i tap0
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tap0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
IP 10.0.2.16.46550 > 10.0.2.17.80: Flags [S], seq 413147170, win 64240, options [mss 1460,sackOK,TS val 1397046667 ecr 0,nop,wscale 7], length 0
    0x0000:  4500 003c b0f2 4000 4006 71a9 0a00 0210  E..<..@.@.q.....
    0x0010:  0a00 0211 b5d6 0050 18a0 2022 0000 0000  .......P..."....
    0x0020:  a002 faf0 184f 0000 0204 05b4 0402 080a  .....O..........
    0x0030:  5345 3d8b 0000 0000 0103 0307            SE=.........
IP 10.0.2.17.80 > 10.0.2.16.46550: Flags [S.], seq 992925710, ack 413147171, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0
    0x0000:  4500 0034 0000 4000 4006 22a4 0a00 0211  E..4..@.@.".....
    0x0010:  0a00 0210 0050 b5d6 3b2e d80e 18a0 2023  .....P..;......#
    0x0020:  8012 7210 1847 0000 0204 05b4 0101 0402  ..r..G..........
    0x0030:  0103 0307                                ....
IP 10.0.2.16.46550 > 10.0.2.17.80: Flags [.], ack 1, win 502, length 0
    0x0000:  4500 0028 b0f3 4000 4006 71bc 0a00 0210  E..(..@.@.q.....
    0x0010:  0a00 0211 b5d6 0050 18a0 2023 3b2e d80f  .......P...#;...
    0x0020:  5010 01f6 183b 0000                      P....;..

続いて、次の4パケットは、クライアントからの GETリクエストとその ACKパケット、サーバからの応答とその ACKパケットです。

サーバからの応答には HTML が入っています。

IP 10.0.2.16.46550 > 10.0.2.17.80: Flags [P.], seq 1:73, ack 1, win 502, length 72: HTTP: GET / HTTP/1.1
    0x0000:  4500 0070 b0f4 4000 4006 7173 0a00 0210  E..p..@.@.qs....
    0x0010:  0a00 0211 b5d6 0050 18a0 2023 3b2e d80f  .......P...#;...
    0x0020:  5018 01f6 1883 0000 4745 5420 2f20 4854  P.......GET./.HT
    0x0030:  5450 2f31 2e31 0d0a 486f 7374 3a20 3130  TP/1.1..Host:.10
    0x0040:  2e30 2e32 2e31 370d 0a55 7365 722d 4167  .0.2.17..User-Ag
    0x0050:  656e 743a 2063 7572 6c2f 382e 382e 300d  ent:.curl/8.8.0.
    0x0060:  0a41 6363 6570 743a 202a 2f2a 0d0a 0d0a  .Accept:.*/*....
IP 10.0.2.17.80 > 10.0.2.16.46550: Flags [.], ack 73, win 229, length 0
    0x0000:  4500 0028 369c 4000 4006 ec13 0a00 0211  E..(6.@.@.......
    0x0010:  0a00 0210 0050 b5d6 3b2e d80f 18a0 206b  .....P..;......k
    0x0020:  5010 00e5 183b 0000                      P....;..
IP 10.0.2.17.80 > 10.0.2.16.46550: Flags [P.], seq 1:1140, ack 73, win 229, length 1139: HTTP: HTTP/1.1 200 OK
    0x0000:  4500 049b 369d 4000 4006 e79f 0a00 0211  E...6.@.@.......
    0x0010:  0a00 0210 0050 b5d6 3b2e d80f 18a0 206b  .....P..;......k
    0x0020:  5018 00e5 1cae 0000 4854 5450 2f31 2e31  P.......HTTP/1.1
    0x0030:  2032 3030 204f 4b0d 0a53 6572 7665 723a  .200.OK..Server:
    0x0040:  206e 6769 6e78 2f31 2e31 352e 370d 0a44  .nginx/1.15.7..D
    0x0050:  6174 653a 2054 6875 2c20 3235 204a 756c  ate:.Thu,.25.Jul
    0x0060:  2032 3032 3420 3133 3a33 393a 3031 2047  .2024.13:39:01.G
    0x0070:  4d54 0d0a 436f 6e74 656e 742d 5479 7065  MT..Content-Type
    0x0080:  3a20 7465 7874 2f68 746d 6c0d 0a43 6f6e  :.text/html..Con
    0x0090:  7465 6e74 2d4c 656e 6774 683a 2038 3134  tent-Length:.814
    0x00a0:  0d0a 436f 6e6e 6563 7469 6f6e 3a20 6b65  ..Connection:.ke
    0x00b0:  6570 2d61 6c69 7665 0d0a 5661 7279 3a20  ep-alive..Vary:.
    0x00c0:  4163 6365 7074 2d45 6e63 6f64 696e 670d  Accept-Encoding.
    0x00d0:  0a4c 6173 742d 4d6f 6469 6669 6564 3a20  .Last-Modified:.
    0x00e0:  5468 7572 7364 6179 2c20 3235 2d4a 756c  Thursday,.25-Jul
    0x00f0:  2d32 3032 3420 3133 3a33 393a 3031 2047  -2024.13:39:01.G
    0x0100:  4d54 0d0a 4361 6368 652d 436f 6e74 726f  MT..Cache-Contro
    0x0110:  6c3a 206e 6f2d 7374 6f72 652c 206e 6f2d  l:.no-store,.no-
    0x0120:  6361 6368 652c 206d 7573 742d 7265 7661  cache,.must-reva
    0x0130:  6c69 6461 7465 2c20 7072 6f78 792d 7265  lidate,.proxy-re
    0x0140:  7661 6c69 6461 7465 2c20 6d61 782d 6167  validate,.max-ag
    0x0150:  653d 300d 0a41 6363 6570 742d 5261 6e67  e=0..Accept-Rang
    0x0160:  6573 3a20 6279 7465 730d 0a0d 0a3c 2164  es:.bytes....<!d
    0x0170:  6f63 7479 7065 2068 746d 6c3e 3c68 746d  octype.html><htm
    0x0180:  6c20 6c61 6e67 3d22 656e 223e 3c68 6561  l.lang="en"><hea
    0x0190:  643e 3c6d 6574 6120 6368 6172 7365 743d  d><meta.charset=
    0x01a0:  2275 7466 2d38 223e 3c6d 6574 6120 6874  "utf-8"><meta.ht
    0x01b0:  7470 2d65 7175 6976 3d22 582d 5541 2d43  tp-equiv="X-UA-C
    0x01c0:  6f6d 7061 7469 626c 6522 2063 6f6e 7465  ompatible".conte
    0x01d0:  6e74 3d22 4945 3d65 6467 6522 3e3c 6d65  nt="IE=edge"><me
    0x01e0:  7461 206e 616d 653d 2276 6965 7770 6f72  ta.name="viewpor
    0x01f0:  7422 2063 6f6e 7465 6e74 3d22 7769 6474  t".content="widt
    0x0200:  683d 6465 7669 6365 2d77 6964 7468 2c69  h=device-width,i
    0x0210:  6e69 7469 616c 2d73 6361 6c65 3d31 223e  nitial-scale=1">
    0x0220:  3c6d 6574 6120 6874 7470 2d65 7175 6976  <meta.http-equiv
    0x0230:  3d22 6361 6368 652d 636f 6e74 726f 6c22  ="cache-control"
    0x0240:  2063 6f6e 7465 6e74 3d22 6e6f 2d63 6163  .content="no-cac
    0x0250:  6865 223e 3c6d 6574 6120 6874 7470 2d65  he"><meta.http-e
    0x0260:  7175 6976 3d22 6578 7069 7265 7322 2063  quiv="expires".c
    0x0270:  6f6e 7465 6e74 3d22 3022 3e3c 6d65 7461  ontent="0"><meta
    0x0280:  2068 7474 702d 6571 7569 763d 2270 7261  .http-equiv="pra
    0x0290:  676d 6122 2063 6f6e 7465 6e74 3d22 6e6f  gma".content="no
    0x02a0:  2d63 6163 6865 223e 3c6c 696e 6b20 7265  -cache"><link.re
    0x02b0:  6c3d 2269 636f 6e22 2068 7265 663d 222f  l="icon".href="/
    0x02c0:  6661 7669 636f 6e2e 6963 6f22 3e3c 7469  favicon.ico"><ti
    0x02d0:  746c 653e 5068 6f65 6e69 7820 436f 6e74  tle>Phoenix.Cont
    0x02e0:  6163 7420 2d20 4348 4152 583c 2f74 6974  act.-.CHARX</tit
    0x02f0:  6c65 3e3c 7363 7269 7074 2064 6566 6572  le><script.defer
    0x0300:  3d22 6465 6665 7222 2073 7263 3d22 2f6a  ="defer".src="/j
    0x0310:  732f 6368 756e 6b2d 7665 6e64 6f72 732e  s/chunk-vendors.
    0x0320:  3662 3761 6231 3936 2e6a 7322 3e3c 2f73  6b7ab196.js"></s
    0x0330:  6372 6970 743e 3c73 6372 6970 7420 6465  cript><script.de
    0x0340:  6665 723d 2264 6566 6572 2220 7372 633d  fer="defer".src=
    0x0350:  222f 6a73 2f61 7070 2e38 3133 6663 3163  "/js/app.813fc1c
    0x0360:  632e 6a73 223e 3c2f 7363 7269 7074 3e3c  c.js"></script><
    0x0370:  6c69 6e6b 2068 7265 663d 222f 6373 732f  link.href="/css/
    0x0380:  6368 756e 6b2d 7665 6e64 6f72 732e 3636  chunk-vendors.66
    0x0390:  3633 3038 3466 2e63 7373 2220 7265 6c3d  63084f.css".rel=
    0x03a0:  2273 7479 6c65 7368 6565 7422 3e3c 6c69  "stylesheet"><li
    0x03b0:  6e6b 2068 7265 663d 222f 6373 732f 6170  nk.href="/css/ap
    0x03c0:  702e 3966 3236 3632 6163 2e63 7373 2220  p.9f2662ac.css".
    0x03d0:  7265 6c3d 2273 7479 6c65 7368 6565 7422  rel="stylesheet"
    0x03e0:  3e3c 2f68 6561 643e 3c62 6f64 793e 3c6e  ></head><body><n
    0x03f0:  6f73 6372 6970 743e 3c73 7472 6f6e 673e  oscript><strong>
    0x0400:  5765 2772 6520 736f 7272 7920 6275 7420  We're.sorry.but.
    0x0410:  6368 6172 7820 646f 6573 6e27 7420 776f  charx.doesn't.wo
    0x0420:  726b 2070 726f 7065 726c 7920 7769 7468  rk.properly.with
    0x0430:  6f75 7420 4a61 7661 5363 7269 7074 2065  out.JavaScript.e
    0x0440:  6e61 626c 6564 2e20 506c 6561 7365 2065  nabled..Please.e
    0x0450:  6e61 626c 6520 6974 2074 6f20 636f 6e74  nable.it.to.cont
    0x0460:  696e 7565 2e3c 2f73 7472 6f6e 673e 3c2f  inue.</strong></
    0x0470:  6e6f 7363 7269 7074 3e3c 6469 7620 6964  noscript><div.id
    0x0480:  3d22 6170 7022 3e3c 2f64 6976 3e3c 2f62  ="app"></div></b
    0x0490:  6f64 793e 3c2f 6874 6d6c 3e              ody></html>
IP 10.0.2.16.46550 > 10.0.2.17.80: Flags [.], ack 1140, win 501, length 0
    0x0000:  4500 0028 b0f5 4000 4006 71ba 0a00 0210  E..(..@.@.q.....
    0x0010:  0a00 0211 b5d6 0050 18a0 206b 3b2e dc82  .......P...k;...
    0x0020:  5010 01f5 183b 0000                      P....;..

最後に、コネクションの切断です。クライアントからの FINパケット、サーバからの FINパケットと、その ACKパケットです。

IP 10.0.2.16.46550 > 10.0.2.17.80: Flags [F.], seq 73, ack 1140, win 501, length 0
    0x0000:  4500 0028 b0f6 4000 4006 71b9 0a00 0210  E..(..@.@.q.....
    0x0010:  0a00 0211 b5d6 0050 18a0 206b 3b2e dc82  .......P...k;...
    0x0020:  5011 01f5 183b 0000                      P....;..
IP 10.0.2.17.80 > 10.0.2.16.46550: Flags [F.], seq 1140, ack 74, win 229, length 0
    0x0000:  4500 0028 369e 4000 4006 ec11 0a00 0211  E..(6.@.@.......
    0x0010:  0a00 0210 0050 b5d6 3b2e dc82 18a0 206c  .....P..;......l
    0x0020:  5011 00e5 183b 0000                      P....;..
IP 10.0.2.16.46550 > 10.0.2.17.80: Flags [.], ack 1141, win 501, length 0
    0x0000:  4500 0028 b0f7 4000 4006 71b8 0a00 0210  E..(..@.@.q.....
    0x0010:  0a00 0211 b5d6 0050 18a0 206c 3b2e dc83  .......P...l;...
    0x0020:  5010 01f5 183b 0000                      P....;..
^C
10 packets captured
10 packets received by filter
0 packets dropped by kernel

おわりに

今回は、ハッキング・ラボのつくりかた 完全版 仮想環境におけるハッカー体験学習 を読むにあたり、必須の知識であるネットワークの通信を理解しました。

最後になりましたが、エンジニアグループのランキングに参加中です。

気楽にポチッとよろしくお願いいたします🙇

今回は以上です!

最後までお読みいただき、ありがとうございました。