1

私は最近、生パケット用のプログラムに取り組んでいます。最近生パケットについての講義があったので、教授が私に言ったことを正確に学び、実行しようとしています. プログラムに問題があり、宛先アドレスが必要であるというエラーが表示されるため、エラーが修正されても socket.connect(destaddr) を実行したくありません。これが私のコードです: クラスと関数は次のとおりです:

#not real mac address to protect privacy also removed preamble
class packet(object):
    b = ""
    def __init__(self, payload):
        self.payload = payload

    def ether(self):
        #preamble = "55555555555555D5" 
        macdest = "123456789101" #my mac address - needed to remove colons 
        macsource = "123456789101" #router mac address without colons
        ethertype = "0800" #removed 0x because it is not needed
        fcs = "" #frame check sequence none so far
        frame = macdest+macsource+ethertype
        return frame

    def ip(self): #in hexadecimal
        version = "4" #ipv4 hex
        ihl = "5" #header length hex
        dscp = "00" #default
        ecn = "00" #default
        length = "36" #ether-24 + ip-20 + tcp-30 = 54 to hexa = 35
        idip="0000" #random id
        flags = "40" #dont fragment flag is 2 to hex is 4
        offset = "00" #space taker
        ttl = "40"#hex(64) = 40
        protocol = "06" #for tcp
        checksum = "0000"
        ipaddrfrom = "c0a8010a"
        ipaddrto =   "c0a80101"
        datagram = version+ihl+dscp+ecn+length+idip+flags+offset+ttl+protocol+checksum+ipaddrfrom+ipaddrto
        return datagram

    def tcp(self):
        portsrc = "15c0" #5568
        portdest = "0050" #80
        syn = "00000000" 
        ack = "00000000"
        nonce = "80"
        fin = "10"
        windowscale = "813b"
        checksum = "0000"
        segment = portsrc+portdest+syn+ack+nonce+fin+windowscale + checksum
        return segment

    def getpacket(self):
        frame = self.ether()
        datagram = self.ip()
        segment = self.tcp()
        payload = self.payload
        packet = frame+datagram+segment+payload

        a = 0
        b = ""
        for char in packet:
            a = a+1
            b = b + char
            if a == 4:
                b = b + " "
                a=0
        self.fmtpacket = b
        return packet

def raw():
    s = socket(AF_INET, SOCK_RAW, IPPROTO_IP)
    s.bind(('192.168.1.10', 0))
    pckt = packet("")
    netpacket = pckt.getpacket()
    print "Sending: " + pckt.fmtpacket
    print ""
    s.sendall(netpacket)
    data = s.recv(4096)
    print data
4

3 に答える 3

2

あなたの教授がそれでよければ、Python で raw パケットを作成する際にScapyを使用する方がはるかに簡単であることに気付くかもしれません。

彼らのウェブサイトから:

Scapy は、強力な対話型パケット操作プログラムです。さまざまなプロトコルのパケットを偽造またはデコードし、それらをネットワーク上で送信し、キャプチャし、要求と応答を一致させることができます。スキャン、トレースルーティング、プロービング、単体テスト、攻撃、ネットワーク検出などのほとんどの従来のタスクを簡単に処理できます (hping、nmap の 85%、arpspoof、arp-sk、arping、tcpdump、tethereal、p0f などを置き換えることができます)。

于 2012-08-31T20:13:45.783 に答える
1

「0.0.0.0」にバインドする理由はありますか? raw ソケットを作成するときは、それをインターフェイスにバインドする必要があります。

私が気づいたことの 1 つは、16 進数には '\x' プレフィックスが必要になることです。

今、文字をつなぎ合わせています。

たとえば、ip() では、バージョン + ihl = '45' です。これは文字列であり、16 進値ではありません。これを生のパケットとして送信すると、必要なバイトではなく 2 バイトになります。「45」ではなく「\x45」を送信します。

于 2012-08-31T19:21:04.133 に答える
1

送信されるパケットには、文字列ではなく実際のバイトが含まれている必要があります。

于 2013-06-21T11:09:00.743 に答える