scapy學習(一)

scapy像一把瑞士軍刀一樣,可以用過網絡分析的多種場景,主要用於網絡報文分析、捕獲及自定義協議報文等。

我們可以通過命令行或是python腳本兩種方式來使用scapy。

scapy的安裝知道參考:https://scapy.readthedocs.io/en/latest/

1. scapy命令:

ls(): 列出scapy所支持的所有協議

>>> ls()
AH         : AH
AKMSuite   : AKM suite
ARP        : ARP
ASN1P_INTEGER : None
ASN1P_OID  : None
ASN1P_PRIVSEQ : None
ASN1_Packet : None
ATT_Error_Response : Error Response
ATT_Exchange_MTU_Request : Exchange MTU Request
ATT_Exchange_MTU_Response : Exchange MTU Response
ATT_Execute_Write_Request : Execute Write Request
ATT_Execute_Write_Response : Execute Write Response
ATT_Find_By_Type_Value_Request : Find By Type Value Request
ATT_Find_By_Type_Value_Response : Find By Type Value Response

lsc(): 列出scapy所支持的命令和功能

>>> lsc()
					
IPID_count          : Identify IP id values classes in a list of packets
arpcachepoison      : Poison target's cache with (your MAC,victim's IP) couple
arping              : Send ARP who-has requests to determine which hosts are up
arpleak             : Exploit ARP leak flaws, like NetBSD-SA2017-002.
bind_layers         : Bind 2 layers on some specific fields' values.
bridge_and_sniff    : Forward traffic between interfaces if1 and if2, sniff and return
chexdump            : Build a per byte hexadecimal representation
computeNIGroupAddr  : Compute the NI group Address. Can take a FQDN as input parameter
corrupt_bits        : Flip a given percentage or number of bits from a string
corrupt_bytes       : Corrupt a given percentage or number of bytes from a string
defrag              : defrag(plist) -> ([not fragmented], [defragmented],
defragment          : defragment(plist) -> plist defragmented as much as possible 
dhcp_request        : Send a DHCP discover request and return the answer
dyndns_add          : Send a DNS add message to a nameserver for "name" to have a new "rdata"
dyndns_del          : Send a DNS delete message to a nameserver for "name"

conf:列出所有的配置選項

>>> conf
					
ASN1_default_codec = <ASN1Codec BER[1]>
AS_resolver = <scapy.as_resolvers.AS_resolver_multi object at 0x0000029009D3...
BTsocket   = <BluetoothRFCommSocket: read/write packets on a connected L2CAP...
L2listen   = <L2pcapListenSocket: read packets at layer 2 using libpcap>
L2socket   = <L2pcapSocket: read/write packets at layer 2 using only libpcap>
L3socket   = <L3pcapSocket: read/write packets at layer 3 using only libpcap>
L3socket6  = functools.partial(<L3pcapSocket: read/write packets at layer 3 ...
USBsocket  = None
auto_crop_tables = True
auto_fragment = True
bufsize    = 65536
cache_iflist = {'\\Device\\NPF_{A7D888CC-A2FE-40C2-8A59-C340127ACF3E}': ('Nd...
checkIPID  = False
checkIPaddr = True
checkIPinIP = True
checkIPsrc = True
check_TCPerror_seqack = False

help():列出一個具體命令的幫助命令,例如,help(sniff)

>>> help(sniff)
			 
Help on function sniff in module scapy.sendrecv:

sniff(*args, **kwargs)
    Sniff packets and return a list of packets.
    
    Args:
        count: number of packets to capture. 0 means infinity.
        store: whether to store sniffed packets or discard them
        prn: function to apply to each packet. If something is returned, it
             is displayed.
             --Ex: prn = lambda x: x.summary()
        session: a session = a flow decoder used to handle stream of packets.
                 e.g: IPSession (to defragment on-the-flow) or NetflowSession
        filter: BPF filter to apply.
        lfilter: Python function applied to each packet to determine if
                 further action may be done.
                 --Ex: lfilter = lambda x: x.haslayer(Padding)
        offline: PCAP file (or list of PCAP files) to read packets from,

show():列出一個具體報文的詳細信息,例如,Newpacket.show()

scapy支持大約300種網絡協議。可以在ls()命令參數種指定查看具體的協議細節。例如:

ls(TCP):

>>> ls(TCP)
					
sport      : ShortEnumField                      = (20)
dport      : ShortEnumField                      = (80)
seq        : IntField                            = (0)
ack        : IntField                            = (0)
dataofs    : BitField (4 bits)                   = (None)
reserved   : BitField (3 bits)                   = (0)
flags      : FlagsField (9 bits)                 = (<Flag 2 (S)>)
window     : ShortField                          = (8192)
chksum     : XShortField                         = (None)
urgptr     : ShortField                          = (0)
options    : TCPOptionsField                     = (b'')

scapy可以創建TCP/IP協議中的任何一層的包。下面這張圖是scapy管理的層結構圖:

scapy中通常一個層代表一種協議,一個網絡報文包含多個層。網絡報文必須是符合標準協議的。

默認的,IP層配置的目的IP是127.0.0.1,代表本地機器。如果我們想要發送到另一個IP,我們需要配置一些IP層。以下面例子說明:

創建一個IP和ICMP層報文:

>>> icmp = IP(dst='google.com')/ICMP()

創建其他層報文:

>>>tcp=IP(dst='google.com')/TCP(dport=80)
>>> packet = Ether()/IP(dst='google.com')/ICMP()/"ABCD"

我麼可以通過show和show2功能來查看發送的報文,通過ls來查看報文結構:

>>> packet.show()
			 
###[ Ethernet ]### 
  dst       = ff:ff:ff:ff:ff:ff
  src       = 10:5b:ad:a2:20:bd
  type      = IPv4
###[ IP ]### 
     version   = 4
     ihl       = None
     tos       = 0x0
     len       = None
     id        = 1
     flags     = 
     frag      = 0
     ttl       = 64
     proto     = icmp
     chksum    = None
     src       = 192.168.0.106
     dst       = Net('google.com')
     \options   \
###[ ICMP ]### 
        type      = echo-request
        code      = 0
        chksum    = None
        id        = 0x0
        seq       = 0x0
###[ Raw ]### 
           load      = 'ABCD'


>>> ls(packet)
			 
dst        : DestMACField                        = 'ff:ff:ff:ff:ff:ff' (None)
src        : SourceMACField                      = '10:5b:ad:a2:20:bd' (None)
type       : XShortEnumField                     = 2048            (36864)
--
version    : BitField (4 bits)                   = 4               (4)
ihl        : BitField (4 bits)                   = None            (None)
tos        : XByteField                          = 0               (0)
len        : ShortField                          = None            (None)
id         : ShortField                          = 1               (1)
flags      : FlagsField (3 bits)                 = <Flag 0 ()>     (<Flag 0 ()>)
frag       : BitField (13 bits)                  = 0               (0)
ttl        : ByteField                           = 64              (64)
proto      : ByteEnumField                       = 1               (0)
chksum     : XShortField                         = None            (None)
src        : SourceIPField                       = '192.168.0.106' (None)
dst        : DestIPField                         = Net('google.com') (None)
options    : PacketListField                     = []              ([])
--
type       : ByteEnumField                       = 8               (8)
code       : MultiEnumField (Depends on type)    = 0               (0)
chksum     : XShortField                         = None            (None)
id         : XShortField (Cond)                  = 0               (0)
seq        : XShortField (Cond)                  = 0               (0)
ts_ori     : ICMPTimeStampField (Cond)           = 7774012         (7774012)
ts_rx      : ICMPTimeStampField (Cond)           = 7774012         (7774012)
ts_tx      : ICMPTimeStampField (Cond)           = 7774012         (7774012)
gw         : IPField (Cond)                      = '0.0.0.0'       ('0.0.0.0')
ptr        : ByteField (Cond)                    = 0               (0)
reserved   : ByteField (Cond)                    = 0               (0)
length     : ByteField (Cond)                    = 0               (0)
addr_mask  : IPField (Cond)                      = '0.0.0.0'       ('0.0.0.0')
nexthopmtu : ShortField (Cond)                   = 0               (0)
unused     : ShortField (Cond)                   = 0               (0)
unused     : IntField (Cond)                     = 0               (0)
--
load       : StrField                            = b'ABCD'         (b'')


scapy一層一層的來創建及分析報文。scapy中的報文是字典形式,因此每個包都是一個嵌套字典,每一層是上一層的一個孩子字典。通過summary()方法能夠查看每個包的各個層的細節。

>>> packet[0].summary()
			 
"Ether / IP / ICMP 192.168.0.106 > Net('google.com') echo-request 0 / Raw"
>>> packet[1].summary()
			 
"IP / ICMP 192.168.0.106 > Net('google.com') echo-request 0 / Raw"
>>> packet[2].summary()
			 
"ICMP 192.168.0.106 > Net('google.com') echo-request 0 / Raw"
>>> packet[3].summary()
			 
'Raw'

2. scapy報文發送:

scapy中發送報文,有兩種方法:

1)send(): 發送三層報文

2)sendp():發送二層報文

send命令的主要參數整理如下:

iface:發送報文的接口

Inter:兩個報文之間的發送間隔(秒數)

loop:如果需要一直髮送下去,設置該項爲1. 否則設置0

packet:待發送的報文列表

verbose:允許我們改變log級別或者完成不使能log(設置爲0)

例如:裏面的packet報文,三層發送爲send(packet),而對於二層發送可以指定以太網接口。二層接口和三層功能類似,不同的是報文不會經過路由,只在本地網絡內通信。

上述兩個接口都是隻管發送報文,而不能接受應答。爲了接收應答可以通過下面的接口來實現:

sr(...):發送並接收報文。接口等待直到所有發送的報文都收到響應。這個接口是工作在三層。如果沒有期待的路由,報文是不    能被髮送的。

sr1(...):這個功能與sr接口一樣,除了這個接口指捕獲第一個返回的響應報文,忽略其他的。

srp(...):功能與sr相似,不過這個接口工作在二層。它允許我們通過一個指定的網卡來發送,即使沒有需要的路由,報文仍能被髮送。

srp1(...):功能通sr1,只不過工作在二層。

srbt(...):通過藍牙連接發送。

srloop(...):允許我們發送和接收報文N次。一個報文發送三次,我們將對應收到三個響應。這個接口允許我們指定當報文接收到或者無響應時的行爲。

srploop(...):功能通srloop,只不過工作在二層。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章