发送低级原始tcp包python

时间:2012-08-31 19:10:35

标签: python

我最近一直在为一个原始数据包工作。我们最近有一个关于原始数据包的讲座,所以我一直在努力学习并完成我教授告诉我的内容。我有一个问题,我的程序出现了一个错误,说明所需的目标地址,它的原始,所以我不想做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

3 个答案:

答案 0 :(得分:2)

如果您的教授对此感到满意,您可能会发现Scapy更容易在python中创建原始数据包。

从他们的网站:

  

Scapy是一个功能强大的交互式数据包操作程序。它能够伪造或解码大量协议的数据包,通过线路发送,捕获它们,匹配请求和回复等等。它可以轻松处理大多数经典任务,如扫描,跟踪路由,探测,单元测试,攻击或网络发现(它可以取代hping,85%的nmap,arpspoof,arp-sk,arping,tcpdump,tethereal,p0f等)< / p>

答案 1 :(得分:1)

是否有理由绑定到'0.0.0.0'?创建原始套接字时,您需要将其绑定到接口。

我注意到的一件事是你需要十六进制的'\ x'前缀。

现在,你正在把字符串起来。

例如,在ip()中,版本+ ihl ='45'。那是一个字符串,而不是十六进制值。当您将其作为原始数据包发送时,这是两个字节而不是您想要的字节。你想发送'\ x45',而不是'45'。

答案 2 :(得分:1)

要发送的数据包应包含实际字节而不是字符串。