2012-06-12 43 views
13

Tôi đang làm việc tích hợp scapy với twisted, nhưng tôi chạy vào lỗi này rất lạ trên OSX mà tôi không thể có vẻ để tìm ra.Ổ cắm nguyên và sendto trong python

Về cơ bản tôi không thể gửi gói TCP hợp lệ (bao gồm tiêu đề IP) qua ổ cắm thô. Đây là những gì tôi đang làm:

import socket 
from scapy.all import IP, TCP 
pkt = IP(src='0.0.0.0', dst='127.0.0.1')/TCP() 
spkt1 = str(pkt) 
outs = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW) 
outs.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1) 
outs.sendto(spkt1, ('127.0.0.1', 0)) 

Khi tôi chạy này, tôi nhận được lỗi sau:

outs.sendto(spkt1, ('127.0.0.1', 0)) socket.error: [Errno 22] Invalid argument

Trong trường hợp bạn không có scapy trên không muốn sử dụng nó này là base64 gói mã hóa:

import base64 
spkt1 = base64.b64decode("RQAAKAABAABABvvOAAAAAH8AAAEAFABQAAAAAAAAAABQAiAAEH4AAA==") 

điều rất lạ là một gói tin đó là gần như giống hệt dường như được gửi đúng:

spkt2 = base64.b64decode("RQBAAAWwAAACBgAAAAAAAH8AAAEAyAOEAAAAAAAAAACwAgDIAHsAAAIEBbQBAwMBAQEICk3PUjMAAAAABAIAAA==") 

Đây là cách hai gói trông giống như:

SPKT1 
0000 45 00 00 28 00 01 00 00 40 06 FB CE 00 00 00 00 E..([email protected] 
0010 7F 00 00 01 00 14 00 50 00 00 00 00 00 00 00 00 .......P........ 
0020 50 02 20 00 10 7E 00 00       P. ..~.. 
SPKT2 
0000 45 00 40 00 05 B0 00 00 02 06 00 00 00 00 00 00 [email protected] 
0010 7F 00 00 01 00 C8 03 84 00 00 00 00 00 00 00 00 ................ 
0020 B0 02 00 C8 00 7B 00 00 02 04 05 B4 01 03 03 01 .....{.......... 
0030 01 01 08 0A 4D CF 52 33 00 00 00 00 04 02 00 00 ....M.R3........ 

Bằng cách kiểm tra chúng ra trong Wireshark họ chỉ khác nhau ở phần TCP.

Tôi đã thực hiện rất nhiều thử nghiệm khác nhau và cuối cùng tôi có thể thiết lập một số tùy chọn TCP cụ thể để gửi gói, nhưng không có nghĩa là gói đó không hoạt động.

Có ai có ý tưởng tại sao điều này có thể xảy ra không?

EDIT:

gói này không xuất hiện để làm việc:

pkt = IP(len=16384, src='0.0.0.0', dst='127.0.0.1', 
    id=RandShort(), ttl=2)/TCP(sport=255, 
     dport=900, flags="S", window=200, 
     options=[('MSS', 1460), ('WScale', 2)]) 
spkt = bytes(pkt) 
spkt += '\x00'*20 

Nếu bạn không thêm số không nó không hoạt động.

+0

Bạn có thể sửa 'nhập' trong đoạn mã đầu tiên của mình không? (Ngoài ra, thực tế thú vị trong khi tôi đọc qua yêu cầu của câu hỏi của bạn: bạn có thể sử dụng '" ... ".decode (" base64 ")' và '" ... ".encode (" base64 ")' thay vì 'import base64') . Ok, xin lỗi, không thể giúp với cái này. Nhưng bạn có upvote của tôi. –

+0

có, đã khắc phục việc nhập. –

+0

FWIW, tôi gặp lỗi tương tự trên mã của bạn. –

Trả lời

3

Tôi đã quyết định rằng Ổ cắm thô chỉ bị lỗi để có thể sử dụng được. Đặc biệt là vì phần mềm này cần phải được nền tảng chéo, quirks cho OSX có thể không được áp dụng cho các hệ điều hành khác.

Hiện tại, tôi chỉ đơn giản là gói "ổ cắm" được cung cấp bởi scapy. Trong tương lai tôi sẽ viết một cái gì đó mà chỉ phụ thuộc vào libdnet (vì đó là những gì scapy không viết khung nguyên bản).

Bạn có thể tìm thấy điều này được thực hiện ở đây:

https://github.com/hellais/txscapy

0

0.0.0.0 không giống như địa chỉ nguồn IP hợp lệ với tôi. Việc thay đổi điều này thành bất kỳ giá trị nào khác có tạo nên sự khác biệt nào không?

+0

Có vẻ như nó không tạo ra sự khác biệt. –

+0

không, nó không tạo ra bất kỳ sự khác biệt nào. Ví dụ, gói này đủ để làm việc: pkt = IP (len = 16384, src = '0.0.0.0', dst = '127.0.0.1', id = RandShort(), ttl = 2)/TCP (thể thao = 255, dport = 900, cờ = "S", cửa sổ = 200, tùy chọn = [('MSS', 1460), ('WScale', 2)]) spkt = bytes (pkt) spkt + = '\ x00' * 20 Nếu bạn không thêm 20 số không, nó sẽ không giống như số khác. (thêm gói vào bài đăng được định dạng đúng) –

+0

Lạ. Dunno. Suy nghĩ tiếp theo của tôi là hạt nhân OS X có đầy đủ các lỗi không rõ ràng như thế này. ;) –

0
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53) 
[GCC 4.5.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import socket 
>>> from scapy.all import IP, TCP 
WARNING: No route found for IPv6 destination :: (no default route?) 
>>> pkt = IP(src='0.0.0.0', dst='127.0.0.1')/TCP() 
>>> spkt1 = str(pkt) 
>>> 
>>> outs = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW) 
>>> outs.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1) 
>>> outs.sendto(spkt1, ('127.0.0.1', 0)) 
40 

Tôi dường như không có lỗi khi viết tập hợp gói cụ thể đó - tôi đang sử dụng x86_64 với hạt nhân 2.6.38- * Gnu/Linux.

Có lẽ sự cố của bạn liên quan đến một số tổn hại não Mac OS X với ổ cắm thô?

0

Một vấn đề khác có liên quan. Mô-đun Python impacketping.py tập lệnh cho máy chủ ping.Trên Mac OS X Lion Tôi gặp lỗi khi sử dụng tập lệnh này:

Traceback (most recent call last): 
    File "/private/var/www/env/bin/ping.py", line 73, in <module> 
    s.sendto(ip.get_packet(), (dst, 0)) 
socket.error: [Errno 22] Invalid argument 

Nhưng trên mọi thứ Ubuntu hoạt động tốt và tôi nhận được thư trả lời từ máy chủ.

0

Tôi không có bằng chứng cứng, nhưng tôi nghĩ điều này có thể liên quan đến kích thước tải trọng tối thiểu của ethernet.

Từ wikipedia:

The minimum payload is 42 octets when 802.1Q tag is present and 46 octets when absent.

dụ gói đầu tiên của bạn là chỉ có 40 byte, vì vậy nó muốn được dưới giới hạn trong cả hai trường hợp. Bạn có thể thử nghiệm với việc thay đổi padding từ 20 byte thành các giá trị đó để xác minh rằng nó ngừng hoạt động ở một trong các giới hạn.

Nếu có, hành vi sẽ có ý nghĩa hoàn hảo; hệ điều hành từ chối gói vì bạn không cung cấp đủ dữ liệu để xây dựng một gói hợp lệ.

1

Cần có tiêu đề IP để có nhiều giá trị 32 bit hợp lệ. Và cũng có một khu vực đệm ở cuối.

Vì vậy, tùy thuộc vào các tùy chọn IP được đặt trong tiêu đề - chiếm một số lượng bit thay đổi - bạn cần đếm số bit đệm.

Có vẻ như các hệ điều hành khác nhau xử lý sự khác biệt này. Người ta có thể xem xét rằng một hệ điều hành thông minh sẽ làm điều này padding cho bạn.