分享一个wiki敏感信息扫描工具

阅读: 评论:0

分享⼀个wiki敏感信息扫描⼯具
背景
⽇常的安全运营中总是发现很多开发的同学将代码⽚段和⼀些技术⽂档在企业内部搭建的wiki中进⾏记录,其中经常会包含⼀些密码、数据库连接字符串、认证token之类的敏感信息。⽽这些⽂章往往是public的权限任何wiki普通⽤户都可以浏览到,因此带来了极⼤的内部安全风险。⼀旦⿊客获得其中⼀个员⼯的账号权限进⼊内⽹,wiki往往是获得⼤量可⽤敏感信息的⾸选途径,因此减少public权限的公开敏感信息就尤为重要。另外账号的暴露也不利于内部的安全审计,账户、⼝令被员⼯获取后恶意利⽤,进⾏未授权的访问,增加了企业的内部风险,⽽因为账号密码的泄漏往往会使安全事件的调查更加困难。
(2018.9.7 丰宁坝上草原)
开始吧
三岔湖长岛天堂洲际酒店
在此背景下,搜索了⽹上也没到针对wiki的审查⼯具,那么古语云“⼯欲善其事必先利其器”,既然没有现成的⼯具就⾃⼰new⼀个吧。
功能设计说明
wikiscan是根据password、key等关键词在企业内⽹搭建的confluence wiki平台审计相关敏感⽂件和内容暴露的扫描⼯具,其设计思路如下:
根据关键词在wiki中进⾏全局搜索,如(password、pwd、Authorization、密码),将搜索结果的页⾯路径信息去重整理得到搜索匹配的所有url集合;
正则匹配url集合中是否为数据⽂件或代码形式的后缀,如(txt、csv、xml、xsl、log、py、php、java、jsp、go),这些⽂件中包含密码等字段的关键字且本⾝就不太适合作为public权限的⽂档存在于wiki中,因此直接将该url作为风险结果保存;
不满⾜敏感后缀的url继续进⼊下⾯的检测逻辑,通过request遍历请求每⼀个wiki页⾯,正则匹配敏感关键字符合正则模式的放⼊风险结果中保存;
⽇常的⽤户进⾏wiki⽂章编辑会出现很多带有密码关键字的语句,很多实际并不是包含真正的密码或认证的凭证,需要通过正则减少误报量。
部分⽤户对⽂章中的密码关键字的value值有时会使⽤如 xxxxx、中⽂:密码、123456等进⾏掩码显⽰,根据企业中具体场景,可在正则中可对这些内容进⾏排除;
尽管正则尽量降低了搜索关键字带来的误报,仍然可能会有⼀些各种各样的特殊情况,我们可以通过⽩名单来排除这些实际上确认后没这么敏感的url;
我们并没有使⽤confluence官⽅提供的搜索接⼝,因为想到通过cookie虽然每次可能需要重新获得cookie值,但其实感觉更灵活些。
此外,我们通过参数可以⽀持两种扫描模式,全局扫描和单页扫描。全局扫描可以通过参数指定扫描搜索结果的url条数,单页扫描可以通过参数输⼊具体的wiki url来扫描这个页⾯是否包含敏感内容。
程序使⽤帮助
wikiscan v1.0 命令⾏参数⽅式执⾏:
USAGE:
-l  wiki url,singlepage scan mode use.
-c  Number of search results.
-h  Show help information.
-l:选填参数,单页扫描某个wiki url是否有敏感关键字;
-c:必填参数,⽤于全局模式设置扫描搜索的结果条数;
-h:帮助信息。
参数使⽤说明:-l 仅⽤于单页模式,-c 全局模式必填,单页模式⽆需填写
代码
#!/usr/bin/env python
#-*- coding:utf-8 -*-
#author:Darkpot
中国最美景点排行榜前十名
import requests
import json
import re国内海岛游
import yagmail
import argparse
class MyClass:
parser = argparse.ArgumentParser(description='wiki 敏感信息扫描')
parser.add_argument("-l",help="wiki url,singlepage scan mode use",type=str)
parser.add_argument("-c",help="Number of search results",type=int)广州动物园开放时间及门票
args = parser.parse_args()
input1 = args.l
count =  args.c
def globalScan(self,count):
try:
#请求参数头设置
keydict =['siteSearch+~+"password"','siteSearch+~+"密码"','siteSearch+~+"pwd"','siteSearch+~+"Authorization"']
url ='wiki/rest/searchv3/1.0/cqlSearch'
headers ={'cookie':'kie='}
alist =[]
keywords=[]
keywords=[]
keyword_suffix=[]
#⽩名单
whitelist=['/pages/viewpage.action?pageId=12345']
#根据关键词将搜索结果uri全部收集起来
for b in keydict:
params ={"cql":b,"start":0,"limit":count,"includeArchivedSpaces":"false"}
req = (url,params=params,headers=headers)
a =
middle = json.loads(a)
size = middle["size"]
for i in range(size):
href = middle["results"][i]["url"]
if href not in(alist+whitelist):
alist.append(href)
#将xml等数据格式的直接挑出来,其他的正则匹配关键字
#正则匹配样例:password= “”、password “”、password=12345、<password>123</password>
for q in alist:
url1='wiki'+q
houzui = re.findall(r"(\.txt|\.xml|\.csv|\.xsl|\.log|\.py|\.php|\.go|\.java|\.jsp)$",url1)
if houzui:
keyword_suffix.append(url1)
else:
req1 =(url1,headers=headers)
text =
password = re.findall(r"(?i)(password(s)?|pwd(s)?)\s*(={0,1}\s*(\"|')((?!密码|'|,)\S)+(\"|')|=\s*((?!密码|\")\S)+(,|\b))",text)
password1 = re.findall(r"(?i)\-p\s+(((?!密码|\"|123456)\S)+(,|\b)|(\"|')((?!密码|123456)\S)+(\"|'))",text)
password2 = re.findall(r"密码:((?!密码)\S)+(,|\b)",text)
password3 = re.findall(r"(?i)\<password(s)?\>((?!密码)\S)+\</password(s)?\>",text)
password6 = re.findall(r"\"\s*(password(s)?|pwd(s)?|Authorization)\s*\":\"\s*((?!密码)\w)+\s*\"",text)
password10 = re.findall(r"\s+(password(s)?|pwd(s)?|Authorization)\s*(:|:)\s*((?!密码|\")\S)+(,|\b)",text)
password12 = re.findall(r"\"(password(s)?|pwd(s)?)\"\s*(,\s*\[\"((?!密码)\S)+\"\]|=>\s*\"((?!密码)\S)+\",)",text )
if password:
keywords.append(url1)
elif password1:
keywords.append(url1)
elif password2:
keywords.append(url1)
elif password3:
keywords.append(url1)
elif password6:
keywords.append(url1)
elif password10:
keywords.append(url1)
elif password12:
keywords.append(url1)
yag = yagmail.SMTP(user ='You_email@163', password ='password', host ='smtp.163')
yag.send(to =['receiver@email'], subject ='wiki 敏感信息扫描', contents =['关键词正则匹配:\n',str(keywords),'关键词+数据⽂件后缀匹配:\n',str( keyword_suffix)])
except:
print("\n程序执⾏失败\n")
def singlePage(self,wiki):
try:
keywords0=[]
keyword_suffix0=[]
headers ={'cookie':'kie='}
houzhui = re.findall(r"(\.txt|\.xml|\.csv|\.xsl|\.log|\.py|\.php|\.go|\.java|\.jsp)$",wiki)
if houzhui:
keyword_suffix0.append(wiki)
else:
req0 =(wiki,headers=headers)
text0 =
password0 = re.findall(r"(?i)(password(s)?|pwd(s)?)\s*(={0,1}\s*(\"|')((?!密码|'|,)\S)+(\"|')|=\s*((?!密码|\")\S)+(,|\b))",text0)
password0 = re.findall(r"(?i)(password(s)?|pwd(s)?)\s*(={0,1}\s*(\"|')((?!密码|'|,)\S)+(\"|')|=\s*((?!密码|\")\S)+(,|\b))",text0)
password7 = re.findall(r"(?i)\-p\s+(((?!密码|\"|123456)\S)+(,|\b)|(\"|')((?!密码|123456)\S)+(\"|'))",text0)
password8 = re.findall(r"密码:((?!密码)\S)+(,|\b)",text0)
password9 = re.findall(r"(?i)\<password(s)?\>((?!密码)\S)+\</password(s)?\>",text0)
password5 = re.findall(r"\"\s*(password(s)?|pwd(s)?|Authorization)\s*\":\"\s*((?!密码)\w)+\s*\"",text0)
password4 = re.findall(r"\s+(password(s)?|pwd(s)?|Authorization)\s*(:|:)\s*((?!密码|\")\S)+(,|\b)",text0)
password11 = re.findall(r"\"(password(s)?|pwd(s)?)\"\s*(,\s*\[\"((?!密码)\S)+\"\]|=>\s*\"((?!密码)\S)+\",)",text0) if password0:
keywords0.append(wiki)
elif password7:
keywords0.append(wiki)
elif password8:
秋水广场音乐喷泉
keywords0.append(wiki)
elif password9:
keywords0.append(wiki)
elif password5:
keywords0.append(wiki)
elif password4:
keywords0.append(wiki)
elif password11:
keywords0.append(wiki)
print("关键词正则匹配:\n"+str(keywords0))
流溪河国家森林公园自驾游攻略print("关键词数据⽂件后缀匹配:\n"+str(keyword_suffix0))
except:
print("\n程序执⾏失败\n")
x = MyClass()
if x.input1:
x.singlePage(x.input1)
else:
x.unt)
结语

本文发布于:2023-06-19 09:06:49,感谢您对本站的认可!

本文链接:http://www.035400.com/whly/4/163797.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:扫描   搜索   正则   匹配   结果
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2024-2030 Comsenz Inc.Powered by © 文化旅游网 滇ICP备2022007236号-403 联系QQ:1103060800网站地图