-1

フレーム icmp を作成する方法 Python で不正なパケットをマークする

  1. import socket, struct, uuid, subprocess, fcntl, time,random

  2. リスト項目

from binascii import hexlify, unhexlify from datetime import datetime tarRed = raw_input('Ingrese nombre de Tarjeta de Red Utilizada: ') subprocess.call(['ifconfig', tarRed, 'promisc']) pt = 0x0800 s = socket.socket( socket.AF_PACKET, socket.SOCK_RAW, socket.htons(pt)) s.bind((tarRed, pt)) #GETCheck def getchecksum(ip_header,size): cksum = 0 pointer = 0 while size > 1: cksum += int ((str("%02x" % (ip_header[pointer],)) + str("%02x" % (ip_header[pointer+1],))), 16) サイズ -= 2 ポインター += 2 #if サイズ: #これはヘッダーが奇数である状況を説明します #cksum += int(ip_header[pointer]) cksum = (cksum >> 16) + (cksum & 0xffff) cksum += (cksum >>16) return (~cksum ) & 0xFFFF def _checksum(データ):#ヘッダーの合計を計算 ip_header_sum = sum(struct.unpack_from("6H", data)) #キャリーを追加 ip_header_sum = (ip_header_sum & 0xFFFF) + (ip_header_sum >> 8 & 0xFFFF) ip_header_sum = ~ip_header_sum & 0xFFFF return ip_header_sum def i_checksum (checksum_packet): total = 0 num_words = len(checksum_packet) / 2 for chunk in struct.unpack("!%sH" % num_words, checksum_packet[0:num_words*2]): total += chunk if len(checksum_packet) % 2: 合計 += ord(checksum_packet[-1]) << 8 合計 += 合計 >> 16 リターン (~合計 + 0xffff & 0xffff)0xFFFF) ip_header_sum = ~ip_header_sum & 0xFFFF return ip_header_sum def i_checksum(checksum_packet): total = 0 num_words = len(checksum_packet) / 2 for chunk in struct.unpack("!%sH" % num_words, checksum_packet[0:num_words*2] ): 合計 += チャンク if len(checksum_packet) % 2: 合計 += ord(checksum_packet[-1]) << 8 合計 += 合計 >> 16 戻り値 (~合計 + 0xffff & 0xffff)0xFFFF) ip_header_sum = ~ip_header_sum & 0xFFFF return ip_header_sum def i_checksum(checksum_packet): total = 0 num_words = len(checksum_packet) / 2 for chunk in struct.unpack("!%sH" % num_words, checksum_packet[0:num_words*2] ): 合計 += チャンク if len(checksum_packet) % 2: 合計 += ord(checksum_packet[-1]) << 8 合計 += 合計 >> 16 戻り値 (~合計 + 0xffff & 0xffff)16 リターン (~total + 0xffff & 0xffff)16 リターン (~total + 0xffff & 0xffff)

def checksum(source_string):    sum = 0     countTo =
(len(source_string)/2)*2    count = 0   while count<countTo:
            thisVal = ord(source_string[count + 1])*256 + ord(source_string[count])         sum = sum + thisVal         sum = sum &
0xffffffff
            count = count + 2   if countTo<len(source_string):      sum = sum + ord(source_string[len(source_string) - 1])      sum = sum &
0xffffffff  sum = (sum >> 16)  +  (sum & 0xffff)    sum = sum + (sum
>> 16)  answer = ~sum   answer = answer & 0xffff    #answer = answer >> 8 | (answer << 8 & 0xff00)  return answer def
checksuma(source_string):   sum = 0     countTo =
(len(source_string)/2)*2    count = 0   while count<countTo:
            thisVal = ord(source_string[count + 1])*256 + ord(source_string[count])         sum = sum + thisVal         sum = sum &
0xffffffff
            count = count + 2   if countTo<len(source_string):      sum = sum + ord(source_string[len(source_string) - 1])      sum = sum &
0xffffffff  sum = (sum >> 16)  +  (sum & 0xffff)    sum = sum + (sum
>> 16)  answer = ~sum   answer = answer & 0xffff    answer = answer >> 8 | (answer << 8 & 0xff00)   return answer def ultimo(str):
    csum = 0
    countTo = (len(str) / 2) * 2
    count = 0

    while count < countTo:
        thisVal = ord(str[count+1]) * 256 + ord(str[count])
        csum = csum + thisVal
        csum = csum & 0xffffffff
        count = count + 2

    if countTo < len(str):
        csum = csum + ord(str[len(str) - 1])
        csum = csum & 0xffffffff

    csum = (csum >> 16) + (csum & 0xffff)
    csum = csum + (csum >> 16)
    answer = ~csum
    answer = answer & 0xffff
    answer = answer >> 8 | (answer << 8 & 0xff00)
    return answer
#GETCheck
#MACs adst='ffffffffffff' mac_destino = unhexlify(adst) ma = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) info =
fcntl.ioctl(ma.fileno(), 0x8927,  struct.pack('256s', tarRed[:15]))
asrc = ''.join(['%02x:' % ord(char) for char in info[18:24]])[:-1]
sd = asrc.split(':') asrc = sd[0]+sd[1]+sd[2]+sd[3]+sd[4]+sd[5]
mac_origen = unhexlify(asrc)
#MACs cabEther = struct.pack('!6s6sh',mac_destino,mac_origen,pt)
#datosIP
#version = '4'
#IHL = '5' tipoServicio = unhexlify('00') longitudT = struct.pack('!BB',00,24) identificador = struct.pack('!BB',00,01)
flag_Pos = 0x4000 tiempoVida = 05 ptIP = unhexlify('01') SCC = 0
#IPs ip = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) ipO= str( socket.inet_ntoa(fcntl.ioctl(ip.fileno(),0x8915,struct.pack('256s',
tarRed[:15]))[20:24])) ipO1 = ipO.split('.') ipOr =
struct.pack("!BBBB",int(ipO1[0]),int(ipO1[1]),int(ipO1[2]),int(ipO1[3]))
ipD = raw_input('Ingrese la direccion IP destino:  ') ipD1 =
ipD.split('.') ipDest =
struct.pack("!BBBB",int(ipD1[0]),int(ipD1[1]),int(ipD1[2]),int(ipD1[3]))
#IPs
#datosIP cabIP = struct.pack('!1s1s2s2shB1sH4s4s',unhexlify('45'),tipoServicio,longitudT,identificador,flag_Pos,tiempoVida,ptIP,SCC,ipOr,ipDest)
SCC = checksum(cabIP) cabIP =
struct.pack('!1s1s2s2shB1sH4s4s',unhexlify('45'),tipoServicio,longitudT,identificador,flag_Pos,tiempoVida,ptIP,socket.htons(SCC),ipOr,ipDest)
#datosIcmp tipo = 8 codigo = 0x00 check = 0x0000 identificador = int((id(1) * random.random()) % 65535) secuencia = 0x0000
#datos = 'qwertyasdfghzxcvbn0102030405060708091011121314151617181920' datos =
1 * 'Q'
#datosIcmp cabIcmp = struct.pack('!bbHHh',tipo,0,0,identificador,1) my_checksum = ultimo(cabIcmp + datos) cabIcmp =
struct.pack('!bbHHh',tipo,0,socket.htons(my_checksum),identificador,1)
cabIcmp = cabIcmp + datos tiempo = datetime.now() print tiempo for i
in range(15):   s.send(cabEther + cabIP + cabIcmp,0)
4

1 に答える 1

4

あなたの質問はほとんど理解できません。リストされたコードで作成しているパケットがシステムによって不正な形式であると報告されているため、ICMP ECHO パケットを作成する方法を尋ねているようです。コードが機能しない理由に答えようとします。

まず、使用しているソケットの種類が正しくありません。タイプ 8 ではなく、タイプ 1 が必要です。これは、3 番目のパラメーターで十分に簡単に行うことができます。

s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)

(この呼び出しを行うには、ルート権限または管理者権限が必要です。)

次に、ソケットを作成した後、ICMP ヘッダーを作成する必要があります。ICMP ヘッダーは、次の構造で構成されます。

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 0 |     Type      |     Code      |          Checksum             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 4 |                         REST OF HEADER                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

2 番目の 4 バイト「REST OF HEADER」に注意してください。この 4 バイトの 2 番目のセットは、最初の 2 バイトの TYPE/CODE によって異なります。たとえば、TYPE が 0 で CODE が 0 の場合、エコー応答を扱っていることを意味し、そのため、2 番目の 4 バイトは、オフセット 4 から始まる2 バイトの識別子フィールドと 2 バイトのシーケンス番号フィールドになります。図が示すように、オフセット 7 で終了します。

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 0 |     Type      |     Code      |          Checksum             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 4 |           Identifier          |        Sequence Number        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 8 |     Data ...
   +-+-+-+-+-

このヘッダーを作成するには、タイプ 8 のエコー リクエスト構造をそのまま使用します (この作成のバイト 4 ~ 5 および 6 ~ 7 は説明のためのものであり、通常、これはゼロ以外の異なる値になることに注意してください)。 :

icmp = struct.pack(">BBHHH", 8, 0, 0, 0, 0)

このヘッダーの最初の作成では、チェックサムはゼロです。ここで必要なのは、実際にチェックサムを (このゼロ値で) 計算し、次に、この新しいチェックサム値でヘッダーを再作成することです。

icmp = struct.pack(">BBHHH", 8, 0, cksum(icmp), 0, 0)

しかし、これはあなたのコードが再び間違っているところです。の実装i_checksum()が間違っています。修正するには、あなたに任せます。チェックサムは 1 の補数と呼ばれ、それに関する多数のオンライン記事や、それを実装する Linux システム上の C コードがあります。

ヘッダーとその正しいチェックサムを取得したら (システムが間違っているとパケットを送信しないため重要です)、次の場所に送信するだけです。

s.sendto(icmp, (SOME_REMOTE_HOST, 0))

そして、もしあれば返信を受け取ります:

s.recvfrom(1500)

(IP フレームの MTU である 1500 バイトを選択したことに注意してください。したがって、応答がこれよりも大きくなる可能性は低いですが、それは確かに可能です。)

そして、この時点で、あなたのコードは完全に失敗します-最後の2つのステップを実行するコードがなく、返信とヘッダーフィールドの構造解析を処理する追加のコードは言うまでもありません。

あなたが定義した他の 2 つの関数に関しては、それらは奇妙です。そのうちの 1 つは、リンク層フィールドを扱っていることを暗示しているようです (ソケットは IP 層以上のみを扱うため、ソケットには当てはまりません)。もう 1 つは、チェックサムを計算しようとしているように見えますが、正しくはありません。 (また)。

要するに、abarnertが暗示しているように、コードと質問を明確にしてください (さらに追加してください)。

于 2014-03-17T16:38:17.133 に答える