質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

0回答

2767閲覧

Scapyで複数パケットを受信する方法について

kusomi

総合スコア4

CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/11/15 06:01

編集2019/11/15 08:04

前提・実現したいこと

Scapyを使用して、HTTP通信を行うためのスクリプトを作成しています。
試験通信ではWEBサーバ側からFINを送る必要があるため、HTTPリクエストを送信した後、
HTTPレスポンス×2パケット(MSSを超えるため)とFINの3パケットを受信します。
クローズシーケンスを完了させるため、FINのシーケンス番号を確認して、
+1をack番号としたACKを送信したいと考えています。

発生している問題・エラーメッセージ

複数パケットを受信する場合はsr()を使用する必要があると理解していますが、
最初の1パケットしか受信できていません。
パケットキャプチャより、3WayハンドシェイクおよびHTTPリクエスト&レスポンス、
WEBサーバからのFINが正常に送られていることは確認済みです。
その上で、sr()を実行したところ27packetsを受信したメッセージが表示されました。
このパケット数は毎回変わるため、このソケット外の通信も含まれている(?)と
想定しています。これについても、もし理由が分かれば教えていただきたいです。

>>> ans=sr(http,multi=1,timeout=1) Begin emission: Finished sending 1 packets. .*......................... Received 27 packets, got 1 answers, remaining 0 packets

パケット受信後、sr()ではtuple型になるため、例えばans.seqのような
取得方法はできないと考えています。
print(ans)とすると以下のようになりました。

>>> print(ans) (<Results: TCP:1 UDP:0 ICMP:0 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>)

ans[0][0]で1つ目の受信パケットが表示できました。

>>> print(ans[0][0]) (<IP frag=0 proto=tcp dst=10.x.x.x |<TCP sport=50000 dport=http seq=101 ack=4290404129 flags=A |<Raw load='GET /2k.txt HTTP/1.1\r\nHost: xxx.yyy.zzz\r\nConnection: Close\r\n\r\n' |>>>, <IP version=4 ihl=5 tos=0x0 len=576 id=24220 flags=DF frag=0 ttl=254 proto=tcp chksum=0xc594 src=10.x.x.x dst=10.y.y.y |<TCP sport=http dport=50000 seq=4290404129 ack=163 dataofs=5 reserved=0 flags=A window=5422 chksum=0xad6f urgptr=0 |<Raw load='HTTP/1.1 200 OK\r\nDate: Fri, 15 Nov 2019 05:32:30 GMT\r\nServer: Apache/2.2.15 (CentOS)\r\nLast-Modified: Wed, 05 Jun 2019 05:50:37 GMT\r\nETag: "8430b-7d1-58a8d2d3c0ac9"\r\nAccept-Ranges: bytes\r\nContent-Length: 2001\r\nSet-Cookie: JSESSIONID=111\r\nConnection: close\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' |>>>)

ans[0][1]とすることで後続の受信パケットが表示できるかと思ったのですが、
"list index out of range"エラーが表示されるため、これ以外のパケットは
受信できていないようです。

>>> print(ans[0][1]) Traceback (most recent call last): File "<console>", line 1, in <module> File "/usr/local/lib/python3.6/site-packages/scapy/plist.py", line 118, in __getitem__ return self.res.__getitem__(item) IndexError: list index out of range

実際にはHTTPレスポンスが2パケット、その後にFINが送られています。
Scapyでは最初のパケットのみ受信しているように見えます。

http://python.zombie-hunting-club.com/entry/2018/04/18/112124#sr

上記URLを拝見したところ、sr()ではHTTPレスポンスのみしか受信しないようにも読めますが、
それにしてもHTTPレスポンスの1パケット目しか受信できていない理由が分かりません。

該当のソースコード

from scapy.all import * args=sys.argv dstip=args[1] dstport=int(args[2]) sourceport=50000 seqnum=100 ###3way handshake### ip=IP(dst=dstip) tcp=TCP(sport=sourceport,dport=dstport,seq=seqnum) tcp.flags = 'S' SYN=ip/tcp SYNACK=sr1(SYN) tcp.seq += 1 tcp.ack = SYNACK.seq + 1 tcp.flags = 'A' ack=ip/tcp send(ack) ### http request ### get='GET /2k.txt HTTP/1.1\r\nHost: xxx.yyy.zzz\r\nConnection: Close\r\n\r\n' http=ip/tcp/get ans=sr(http,multi=1,timeout=1) print(ans[0][0]) print(ans[0][1])

###質問

・HTTPレスポンスとFINを同時に受信する方法を教えてください。

・FINが受信できた後、ACKを送信するためにFINのシーケンス番号を取得したいと考えています。
tuple型の変数からシーケンス番号を取得する方法を教えてください。

どちらかの回答だけでもいただけると大変助かります。
よろしくお願いします。

環境

CentOS Linux release 7.2.1511 (Core)

Python 3.6.8

Scapy2.4.3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問