我试图向google.com发送HTTP GET请求,但得到的答案是ACK,而不是HTML文件。这是代码:
def Make_Get():
synR = IP(dst = 'www.google.com', ttl = 64)/TCP(dport = 80,sport = randint(1024,65535), flags = 'S')
synAckAN = sr1(synR)
req = (IP(dst='www.google.com') / TCP(dport=80, sport=synAckAN[TCP].dport, seq=synAckAN[TCP].ack, ack=synAckAN[TCP].seq + 1, flags='A')/"GET / HTTP/1.0 nn")
ans, a = sr(req)
return ans
这是我从这个函数中得到的两个数据包:
###[ IP ]### version = 4 ihl = None tos = 0x0 len = None id = 1 flags = frag = 0 ttl = 64 proto = tcp chksum = None src = 192.168.233.128 dst = 216.58.214.100 options ###[ TCP ]### sport = 35534 dport = http seq = 1 ack = 1964930533 dataofs = None reserved = 0 flags = A window = 8192 chksum = None urgptr = 0 options = {} ###[ Raw ]### load = 'GET / HTTP/1.0 nn' None ###[ IP ]### version = 4L ihl = 5L tos = 0x0 len = 40 id = 32226 flags = frag = 0L ttl = 128 proto = tcp chksum = 0x6425 src = 216.58.214.100 dst = 192.168.233.128 options ###[ TCP ]### sport = http dport = 35534 seq = 1964930533 ack = 18 dataofs = 5L reserved = 0L flags = A window = 64240 chksum = 0xe5e6 urgptr = 0 options = {} ###[ Padding ]### load = 'x00x00x00x00x00x00' None
当我在发送这个数据包时嗅探流量时,我得到了这个:
###[ Ethernet ]###
dst= 00:0c:29:bb:8e:79
src= 00:50:56:e9:b8:b1
type= 0x800
###[ IP ]###
version= 4L
ihl= 5L
tos= 0x0
len= 517
id= 32136
flags=
frag= 0L
ttl= 128
proto= tcp
chksum= 0x5004
src= 172.217.20.100
dst= 192.168.233.128
options
###[ TCP ]###
sport= http
dport= 1928
seq= 1828330545
ack= 18
dataofs= 5L
reserved= 0L
flags= FPA
window= 64240
chksum= 0x8b5f
urgptr= 0
options= []
###[ HTTP ]###
###[ HTTP Response ]###
Status-Line= u'HTTP/1.0 302 Found'
Accept-Ranges= None
Age= None
E-Tag= None
Location= u'http://www.google.co.il/?gfe_rd=cr&ei=9fiTV6P6FuWg8weei7rQDA'
Proxy-Authenticate= None
Retry-After= None
Server= None
Vary= None
WWW-Authenticate= None
Cache-Control= u'private'
Connection= None
Date= u'Sat, 23 Jul 2016 23:08:37 GMT'
Pragma= None
Trailer= None
Transfer-Encoding= None
Upgrade= None
Via= None
Warning= None
Keep-Alive= None
Allow= None
Content-Encoding= None
Content-Language= None
Content-Length= u'261'
Content-Location= None
Content-MD5= None
Content-Range= None
Content-Type= u'text/html; charset=UTF-8'
Expires= None
Last-Modified= None
Headers= u'Date: Sat, 23 Jul 2016 23:08:37 GMTrnContent-Length: 261rnContent-Type: text/html; charset=UTF-8rnLocation: http://www.google.co.il/?gfe_rd=cr&ei=9fiTV6P6FuWg8weei7rQDArnCache-Control: private'
Additional-Headers= None
###[ Raw ]###
load= '<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">n<TITLE>302 Moved</TITLE></HEAD><BODY>n<H1>302 Moved</H1>nThe document has movedn<A HREF="http://www.google.co.il/?gfe_rd=cr&ei=9fiTV6P6FuWg8weei7rQDA">here</A>.rn</BODY></HTML>rn'
正如您所看到的,这一层的最后一层包含了我需要的代码。
我的问题是:
为什么我不能获得带有sr()
的数据包,以及如何获得它来收集HTML代码?
编辑:
对函数的调用:
print Make_Get('www.google.com')[0][Raw]
功能:
def Make_Get(ipp):
ip = DNS_Req(ipp)
synR = IP(dst = ip)/TCP(dport = 80,sport = randint(1024,65535), flags = 'S')
syn_ack = sr1(synR)
getStr = "GET / HTTP/1.1rnHost: {}rnrn".format(ip)
request = (IP(dst= ip) / TCP(dport=80, sport=syn_ack[TCP].dport, seq=syn_ack[TCP].ack, ack=syn_ack[TCP].seq + 1, flags='A')/getStr)
an = sr(request)
return an
结果:
Begin emission: .Finished to send 1 packets. * Received 2 packets, got 1 answers, remaining 0 packets Begin emission: *Finished to send 1 packets. Received 1 packets, got 1 answers, remaining 0 packets []
首先,在HTTP中,正确的换行符是"\r\n",而不是"\n"。
第二,你使用HTTP/1.0而不是HTTP/1.1有什么原因吗?如果没有,您应该将请求更改为:
GET / HTTP/1.1rn
Host: www.google.comrn
rn
第三,您收到的ACK通常是在发送实际HTTP响应之前由服务器发送的,以更快地确认您的请求。然后,第二个段与HTTP响应一起发送。您在第一个show()
示例中缺少此示例。
看看这里。
要捕获该段,可以使用sr()
函数及其参数timeout
和multi
:
ans, unans = sr(request, timeout=2, multi=True)
for c, s in ans:
if s.haslayer(Raw):
print b[Raw]
print("-----------") # just a delimiter
timeout
用于确保sr()
将停止(值2是任意的)。multi
的意思是"接受同一刺激的多个答案",除非存在,否则sr()
将在发送一个请求答案后停止嗅探。