Поиск по блогу

вторник, 27 мая 2014 г.

Ссылки на видео и код "[Python] Simple network Sniffer"

Понравилось все 6 роликов (но разрешение плохое)Python Simple network Sniffer. Здесь на всякий случай копирую исходный код, чтобы разобрать пример позже.
У этого же автора есть еще ролики Downloading and Parsing possibilities of Python. As an example website was taken http://xkcd.com/
3:30 press Shift+Ctrl+Enter (not Shift+Alt+Enter) in order to open any program in administrator mode.

4:46 IP header is 32 x 5 = 160 bits = 20 bytes. Each line has 32 bits.

This tutorial shows how to write a simple network sniffer that can capture an IP packet, parse it and print it on the screen in the human readable form.

Raw sockets - http://docs.python.org/library/socket...
Struct module - http://docs.python.org/library/struct...
IP header - http://www.networksorcery.com/enp/pro...
Regular expressions - http://gskinner.com/RegExr/

Network sniffer code - http://pastebin.com/e8iGvVZR
In []:
from socket import *
import struct
import sys
import re
 
# receive a datagram
def receiveData(s):
    data = ''
    try:
        data = s.recvfrom(65565)
    except timeout:
        data = ''
    except:
        print "An error happened: "
        sys.exc_info()
    return data[0]
 
# get Type of Service: 8 bits
def getTOS(data):
    precedence = {0: "Routine", 1: "Priority", 2: "Immediate", 3: "Flash", 4: "Flash override", 5: "CRITIC/ECP",
                  6: "Internetwork control", 7: "Network control"}
    delay = {0: "Normal delay", 1: "Low delay"}
    throughput = {0: "Normal throughput", 1: "High throughput"}
    reliability = {0: "Normal reliability", 1: "High reliability"}
    cost = {0: "Normal monetary cost", 1: "Minimize monetary cost"}
 
#   get the 3rd bit and shift right
    D = data & 0x10
    D >>= 4
#   get the 4th bit and shift right
    T = data & 0x8
    T >>= 3
#   get the 5th bit and shift right
    R = data & 0x4
    R >>= 2
#   get the 6th bit and shift right
    M = data & 0x2
    M >>= 1
#   the 7th bit is empty and shouldn't be analyzed
 
    tabs = '\n\t\t\t'
    TOS = precedence[data >> 5] + tabs + delay[D] + tabs + throughput[T] + tabs + \
            reliability[R] + tabs + cost[M]
    return TOS
 
# get Flags: 3 bits
def getFlags(data):
    flagR = {0: "0 - Reserved bit"}
    flagDF = {0: "0 - Fragment if necessary", 1: "1 - Do not fragment"}
    flagMF = {0: "0 - Last fragment", 1: "1 - More fragments"}
 
#   get the 1st bit and shift right
    R = data & 0x8000
    R >>= 15
#   get the 2nd bit and shift right
    DF = data & 0x4000
    DF >>= 14
#   get the 3rd bit and shift right
    MF = data & 0x2000
    MF >>= 13
 
    tabs = '\n\t\t\t'
    flags = flagR[R] + tabs + flagDF[DF] + tabs + flagMF[MF]
    return flags
 
# get protocol: 8 bits
def getProtocol(protocolNr):
    protocolFile = open('Protocol.txt', 'r')
    protocolData = protocolFile.read()
    protocol = re.findall(r'\n' + str(protocolNr) + ' (?:.)+\n', protocolData)
    if protocol:
        protocol = protocol[0]
        protocol = protocol.replace("\n", "")
        protocol = protocol.replace(str(protocolNr), "")
        protocol = protocol.lstrip()
        return protocol
 
    else:
        return 'No such protocol.'
 
# the public network interface
HOST = gethostbyname(gethostname())
 
# create a raw socket and bind it to the public interface
s = socket(AF_INET, SOCK_RAW, IPPROTO_IP)
s.bind((HOST, 0))
 
# Include IP headers
s.setsockopt(IPPROTO_IP, IP_HDRINCL, 1)
s.ioctl(SIO_RCVALL, RCVALL_ON)
data = receiveData(s)
 
# get the IP header (the first 20 bytes) and unpack them
# B - unsigned char (1)
# H - unsigned short (2)
# s - string
unpackedData = struct.unpack('!BBHHHBBH4s4s' , data[:20])
 
version_IHL = unpackedData[0]
version = version_IHL >> 4                  # version of the IP
IHL = version_IHL & 0xF                     # internet header length
TOS = unpackedData[1]                       # type of service
totalLength = unpackedData[2]
ID = unpackedData[3]                        # identification
flags = unpackedData[4]
fragmentOffset = unpackedData[4] & 0x1FFF
TTL = unpackedData[5]                       # time to live
protocolNr = unpackedData[6]
checksum = unpackedData[7]
sourceAddress = inet_ntoa(unpackedData[8])
destinationAddress = inet_ntoa(unpackedData[9])
 
 
print "An IP packet with the size %i was captured." % (unpackedData[2])
print "Raw data: " + data
print "\nParsed data"
print "Version:\t\t" + str(version)
print "Header Length:\t\t" + str(IHL*4) + " bytes"
print "Type of Service:\t" + getTOS(TOS)
print "Length:\t\t\t" + str(totalLength)
print "ID:\t\t\t" + str(hex(ID)) + " (" + str(ID) + ")"
print "Flags:\t\t\t" + getFlags(flags)
print "Fragment offset:\t" + str(fragmentOffset)
print "TTL:\t\t\t" + str(TTL)
print "Protocol:\t\t" + getProtocol(protocolNr)
print "Checksum:\t\t" + str(checksum)
print "Source:\t\t\t" + sourceAddress
print "Destination:\t\t" + destinationAddress
print "Payload:\n" + data[20:]
# disabled promiscuous mode
s.ioctl(SIO_RCVALL, RCVALL_OFF)
In []:
from socket import *
import struct
import sys
import re

# receive a datagram
def receiveData(s):
    data = ''
    try:
        data = s.recvfrom(65565)
    except timeout:
        data = ''
    except:
        print "An error happened: "
        sys.exc_info()
    return data[0]

# get Type of Service: 8 bits
def getTOS(data):
    precedence = {0: "Routine", 1: "Priority", 2: "Immediate", 3: "Flash", 4: "Flash override", 5: "CRITIC/ECP",
                  6: "Internetwork control", 7: "Network control"}
    delay = {0: "Normal delay", 1: "Low delay"}
    throughput = {0: "Normal throughput", 1: "High throughput"}
    reliability = {0: "Normal reliability", 1: "High reliability"}
    cost = {0: "Normal monetary cost", 1: "Minimize monetary cost"}

#   get the 3rd bit and shift right
    D = data & 0x10
    D >>= 4
#   get the 4th bit and shift right
    T = data & 0x8
    T >>= 3
#   get the 5th bit and shift right
    R = data & 0x4
    R >>= 2
#   get the 6th bit and shift right
    M = data & 0x2
    M >>= 1
#   the 7th bit is empty and shouldn't be analyzed

    tabs = '\n\t\t\t'
    TOS = precedence[data >> 5] + tabs + delay[D] + tabs + throughput[T] + tabs + \
            reliability[R] + tabs + cost[M]
    return TOS

# get Flags: 3 bits
def getFlags(data):
    flagR = {0: "0 - Reserved bit"}
    flagDF = {0: "0 - Fragment if necessary", 1: "1 - Do not fragment"}
    flagMF = {0: "0 - Last fragment", 1: "1 - More fragments"}

#   get the 1st bit and shift right
    R = data & 0x8000
    R >>= 15
#   get the 2nd bit and shift right
    DF = data & 0x4000
    DF >>= 14
#   get the 3rd bit and shift right
    MF = data & 0x2000
    MF >>= 13

    tabs = '\n\t\t\t'
    flags = flagR[R] + tabs + flagDF[DF] + tabs + flagMF[MF]
    return flags

# get protocol: 8 bits
def getProtocol(protocolNr):
    protocolFile = open('Protocol.txt', 'r')
    protocolData = protocolFile.read()
    protocol = re.findall(r'\n' + str(protocolNr) + ' (?:.)+\n', protocolData)
    if protocol:
        protocol = protocol[0]
        protocol = protocol.replace("\n", "")
        protocol = protocol.replace(str(protocolNr), "")
        protocol = protocol.lstrip()
        return protocol

    else:
        return 'No such protocol.'

# the public network interface
HOST = gethostbyname(gethostname())

# create a raw socket and bind it to the public interface
s = socket(AF_INET, SOCK_RAW, IPPROTO_IP)
s.bind((HOST, 0))

# Include IP headers
s.setsockopt(IPPROTO_IP, IP_HDRINCL, 1)
s.ioctl(SIO_RCVALL, RCVALL_ON)
data = receiveData(s)

# get the IP header (the first 20 bytes) and unpack them
# B - unsigned char (1)
# H - unsigned short (2)
# s - string
unpackedData = struct.unpack('!BBHHHBBH4s4s' , data[:20])

version_IHL = unpackedData[0]
version = version_IHL >> 4                  # version of the IP
IHL = version_IHL & 0xF                     # internet header length
TOS = unpackedData[1]                       # type of service
totalLength = unpackedData[2]
ID = unpackedData[3]                        # identification
flags = unpackedData[4]
fragmentOffset = unpackedData[4] & 0x1FFF
TTL = unpackedData[5]                       # time to live
protocolNr = unpackedData[6]
checksum = unpackedData[7]
sourceAddress = inet_ntoa(unpackedData[8])
destinationAddress = inet_ntoa(unpackedData[9])


print "An IP packet with the size %i was captured." % (unpackedData[2])
print "Raw data: " + data
print "\nParsed data"
print "Version:\t\t" + str(version)
print "Header Length:\t\t" + str(IHL*4) + " bytes"
print "Type of Service:\t" + getTOS(TOS)
print "Length:\t\t\t" + str(totalLength)
print "ID:\t\t\t" + str(hex(ID)) + " (" + str(ID) + ")"
print "Flags:\t\t\t" + getFlags(flags)
print "Fragment offset:\t" + str(fragmentOffset)
print "TTL:\t\t\t" + str(TTL)
print "Protocol:\t\t" + getProtocol(protocolNr)
print "Checksum:\t\t" + str(checksum)
print "Source:\t\t\t" + sourceAddress
print "Destination:\t\t" + destinationAddress
print "Payload:\n" + data[20:]
# disabled promiscuous mode
s.ioctl(SIO_RCVALL, RCVALL_OFF)


Посты чуть ниже также могут вас заинтересовать

4 комментария:

  1. Надо бы написать пост о туннелях, но рановато, введение в туннели у меня уже есть, а реализовать вот такую идею хотелось бы, но некогда, потому записываю для памяти
    Вам понадобится самый дешевый VPS, например здесь. На нем вы поднимите SSH на портах, которые доступны через ваш прокси. Например у меня открыты стандартные порты 80 и 443. На работе вы запускаете putty, в качестве хоста подключения указав ваш VPS, в Connection -> Proxy указав адрес и порт вашего прокси, а в Connection -> SSH -> Tunnels добавив Source port 1080 с опцией Dynamic. В браузере вместо своего рабочего прокси сервера вы укажите адрес localhost, порт 1080, тип прокси - SOCKS.

    Таким образом, putty установит защищенное соединение (туннель) по разрешенному порту с вашим VPS. А ваш браузер станет отправлять запросы в это защищенное соединение, которое не сможет анализироваться и фильтроваться рабочим прокси. В браузерах с помощью плагинов можно настроить одновременно несколько прокси. На все адреса вы будете ходить через рабочий, а на какие-то определенные через туннель. Например для Chrome есть плагин SwitchySharp.

    ОтветитьУдалить
    Ответы
    1. Чуть не забыл ... вот первоисточник http://python.su/forum/topic/20603/

      Удалить
  2. Перечислим здесь альтернативы тяжелым снифферам...
    Putty - есть telnet, должно быть видео в большом количестве...
    Netcat (NetDog) - Linux only? Текстовые браузеры с возможностями управления заголовками и прокси-подключениями...
    Curl !!! -простой интерфейс командной строки, для нее есть обертка - grab
    Плагин для Firefox - http://doc.scrapy.org/en/latest/topics/firefox.html

    ОтветитьУдалить
    Ответы
    1. Для полноты картины:
      забыл про связку telnetlib - telnet

      Удалить