巡风源码阅读与分析---Aider.py

之前写过一遍Aider.py,但只是跟着代码一顿阅读没有灵魂,所以重新对它阅读并重新写一遍。

描述

文件位置:aider/aider.py 是用来辅助验证的脚本

官方描述就一句话

代码阅读分析

这个脚本会监听8088端口、以及DNS监听53端口。可以将所有请求的dns请求记录下来辅助验证某处是否存在漏洞。

源代码:

import socket,thread,datetime,time
query_history = []
url_history = []
def web_server():
    web = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    web.bind(('0.0.0.0',8088))
    web.listen(10)
    while True:
        try:
            conn,addr = web.accept()
            data = conn.recv(4096)
            req_line = data.split("\r\n")[0]
            path = req_line.split()[1]
            route_list = path.split('/')
            html = "NO"
            if len(route_list) == 3:
                if route_list[1] == 'add':
                    if route_list[2] not in url_history:
                        url_history.append(route_list[2])
                elif route_list[1] == 'check':
                    if route_list[2] in url_history:
                        url_history.remove(route_list[2])
                        html = 'YES'
            else:
                query_str = route_list[1]
                for query_raw in query_history:
                    if query_str in query_raw:
                        query_history.remove(query_raw)
                        html = "YES"
            print datetime.datetime.now().strftime('%m-%d %H:%M:%S') + " " + str(addr[0]) +' web query: ' + path
            raw = "HTTP/1.0 200 OK\r\nContent-Type: application/json; charset=utf-8\r\nContent-Length: %d\r\nConnection: close\r\n\r\n%s" %(len(html),html)
            conn.send(raw)
            conn.close()
        except:
            pass
if __name__=="__main__":
    dns = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    dns.bind(('0.0.0.0',53))
    thread.start_new_thread(web_server,())
    while True:
        try:
            recv,addr = dns.recvfrom(1024)
            if recv not in query_history:query_history.append(recv)
            print datetime.datetime.now().strftime('%m-%d %H:%M:%S') + " " +str(addr[0]) +' Dns Query: ' + recv
        except Exception,e:
            print e
            continue
dns = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

UDP建立socket连接,然后绑定53端口。

if recv not in query_history:query_history.append(recv)

将请求添加到query_history数组中。

web_server()

监听8088端口并且接收消息,取第一行,然后分割。 取到url 将url按/分割,然后判断分割的数据是否等于3,第二个数字是等于add还是check

如果是add:则判断第三个数组是否在url_history里,没有的话则添加进去

如果是check:则判断第三个数组是否在url_history里,有的话从url_history移除。

如果数组长度不等于3 ,则判断第二个数组的值是否在query_history里。有的话从query_history移除。

也就是说利用漏洞请求http://ip:8088/add/randomstrnslookup randomstr IP ,ip就是巡风的地址。
然后验证 http://ip:8088/randomstrhttp://ip:8088/check/randomstr是否返回了'yes',是的话就存在漏洞。

用个例子来说明,如Apache Tika中的命令注入(CVE-2018-1335)漏洞。该漏洞无回显,所以写巡风验证POC十分困难。但利用该辅助功能就很方便了。

搭建环境过程在这里:https://github.com/zhengjim/loophole/tree/master/CVE-2018-1335

我们首先利用漏洞命令执行nslookup zhengjim_test 127.0.0.1(zhengjim_test自行取名,127.0.0.1为巡风地址)。

然后我们只要验证http://127.0.0.1:8088/zhengjim_test是否返回YES就行了

误判率还低,因为首先地址是自己定义的,而且返回完YES后则移除了,保存不会重复。

与https://github.com/LandGrey/dnstricker功能类似

dnstricker监听本地53/udp端口,用以模拟解析/响应dns请求,导引流量;可以将所有请求自己子域名的dns请求记录下来,用来确定某处是否存在漏洞;

总结

该功能适用于那些无回显的漏洞,如无回显的代码执行漏洞,无回显的命令执行漏洞,无回显的sql注入漏洞,无回显的XML实体注入,与dnslog功能相似。使我们更好的写POC。感谢ysrc开源~

posted @ 2019-03-18 15:55  Zhengjim  阅读(757)  评论(0编辑  收藏  举报