自己动手打造Github代码泄露监控工具!再也不用担心代码泄露了!

0×00 为什么

自从小弟上次发布了《 自己动手打造Github代码泄露监控工具 》一文后,承蒙各位客官老爷捧场,阅读量已经好几十万了,Github也受到了一些大佬的关注。本着精益求精的黑客精神(其实是上次的工具版本存在许多不足),经过一段时间的运行后,确实工具存在一定精确性的问题,故有此文章

0×01 怎么改进

改进主要从以下几个方面入手:

1.搜索排序方式变更

上篇文章通过Github搜索排序Best Match来爬去前面6页来查找泄露信息, 优点在于 :可以匹配到最符合关键词的项目,比如匹配域名为baidu.com的相关代码。然后在最匹配的关键词中寻找payload,如password,username等; 缺点较为明显 :主关键词单一,虽然可以加入多个主关键词,但是匹配结果却不能收录最新的记录或代码。最为严重的问题是最新泄露的符合关键词的敏感信息可能无法获取到。

2.搜索方式变更

单一的域名关键词搜索内容有限,Github呈现的结果也非常多。另外Github的内部搜索算法的影响也会让搜索结果不尽人意。举个栗子,搜索baidu.com,Github呈现如下图:

自己动手打造Github代码泄露监控工具!再也不用担心代码泄露了!

看图可知,最匹配的代码结果其实可能没有包含我们想要的诸如password,username,database等敏感信息。有兴趣的童鞋可以自行搜索。细心的童鞋可能看到收录的时间五花八门,有6月29的,7月6号的等等。现在是11月了啊,这结果根本不是最新的,不准确性和非及时性的问题体现出来了。即便是搜索到几十页,上百页,也可能没有包含我们关注的信息泄露代码,所以必须改进。

3.存储方式和呈现效果变更

此前Github仓库的链接爬去后都通过excel来存储,Python处理这种IO还算性能不差。不过用excel来存储信息确实略显陈旧,新版本则采用sqlite来存储url和代码,这是存储方式的变更。另外在呈现效果虽然还是通过邮件来呈现,但是加入了代码部分的展现,关键词高亮显示,方便监控者阅读。具体效果如下:

自己动手打造Github代码泄露监控工具!再也不用担心代码泄露了!

接下来我们将针对提出的改进要点来修改监控工具~_~

0×02 具体改进方法

1.搜索排序方式改进

这个要点的变更,其实变更代码比较少,只是变更搜索代码的url即可:

https://github.com/search?o=desc&p=2&q=baidu.com&s=indexed&type=Code

通过变更排序方式,把最新收录的排在前面,这样就可以得到最新的代码收录信息。

对比先前版本url:

https://github.com/search?o=desc&q=baidu.com&s=&type=Code

2.搜索方式改进

搜索方式由单一关键词更改为关键词组合,例如,公司域名为:“example.com,需要查找的敏感关键词为:password,那么我们组合为:“example.com + password” 进行搜索。新的改进版本不仅会收录可能存在代码泄露仓库的url,同时也会收录简要代码部分。然后在后续加入到邮件报警和数据库代码中进行example 和 password进行匹配,如果两个关键词都存在,则再比对数据库中的基线里面是否存在对应代码的url,如果存在则不加入基线中,反之,加入到基线中。我来看代码部分:

def hunter(gUser,gPass,keywords):#根据关键词获取想要查询内容

global codes

global tUrls

try:

#代码搜索

s = login_github(gUser,gPass)

print('登陆成功,正在检索泄露信息.......')

sleep(1)

codes = []

tUrls = []

#新加入2条正则匹配,第一条匹配搜索出来的代码部分;第二条则进行高亮显示关键词

pattern_code = re.compile( r'

Box blob-wrapper">(.*?)
',re.S)

pattern_sub = re.compile( r'',re.S)

for keyword in keywords:

for page in tqdm(range(1,7)):

#更改搜索排序方式的url,收录可能存在泄漏的url还是使用xpath解析

search_code = ' https://github.com/search?o=desc&p= ' + str(page) + '&q=' + keyword +'&s=indexed&type=Code'

resp = s.get(search_code)

results_code = resp.text

dom_tree_code = etree.HTML(results_code)

#获取存在信息泄露的链接地址

Urls = dom_tree_code.xpath( '//div[@class="flex-auto min-width-0 col-10"]/a[2]/@href')

for url in Urls:

url = ' https://github.com ' + url

tUrls.append(url)

#获取代码部分,先获得整个包含泄露代码的最上层DIV对象,再把对象进行字符化,便于使用正则进行匹配泄露代码部分的div

results = dom_tree_code.xpath( '//div[@class="code-list-item col-12 py-4 code-list-item-public "]')

for div in results:

result = etree.tostring(div,pretty_print=True,method= "html")

code = str(result,encoding='utf-8')

#如果存在

Box blob-wrapper">此标签则匹配泄露的关键代码部分,不存在则为空。

if '

Box blob-wrapper">' in code:

data = pattern_code.findall(code)

codes.append(pattern_sub.sub( '

else:

codes.append(' ')

return tUrls,codes

except Exception as e:

#如发生错误,则写入文件并且打印出来

error_Record(str(e),traceback. format_exc())

print(e)

正如代码中的注释所讲,获取泄露地址的url还是采用xpath的解析。然而在泄露的代码部分,使用的是正则。

为什么使用正则,第一,为了把包含泄露代码的table获取下来以便发送邮件发送邮件时只需要简单加入css样式即可);第二,这样避免利用xpath去解析table下的行,这样做稍显麻烦。

其实在考虑这部分逻辑的时候遇到一个坑,那就是有些可能存在泄漏的仓库,有url,却没有代码部分,没有代码部分就不会存在’

’ 这个div,这样获取的url和代码就不能一一对应,会发现url和代码错位了,根本就不准确。所以要先获取
‘ 的父div即’
’,然后判断是否存在代码部分,如果不存在则泄露代码的列表当前位置为空或空格,存在则搜索代码泄露部分加入到列表中。这样避免了有url没有code的问题。

自己动手打造Github代码泄露监控工具!再也不用担心代码泄露了!

同时,在加入泄露代码的列表时,通过正则匹配进行css的替换把获取的table标签中的标签替换为。这样以后发送的邮件正文中关键词则被标红。

最后在异常处理部分加入了出现异常就写入文件,并且把trackback一并写入文件,以后排查错误时可以更准确方便。

3.存储方式和呈现方式改进

存储方式变更为数据库存储采用sqlite3,简单易用,小型存储需求可以满足。创建了Baseline表,包含url和code两个字段。如图所示:

自己动手打造Github代码泄露监控工具!再也不用担心代码泄露了!

数据库主要用于对比去重,基线建立,如数据库中不存在泄露的url则加入其中,然后通过邮件发预警。反之则不发送邮件预警。代码如下:

def insert_DB(url,code):
 try:
 conn = sqlite3.connect( 'hunter.db')
 cursor = conn.cursor()
 cursor.execute('CREATE TABLE IF NOT EXISTS Baseline (url varchar(1000) primary key,code varchar(10000))' )
 cursor.execute('INSERT OR REPLACE INTO Baseline (url,code) values (?,?)',(url,code))
 cursor.close
 conn.commit()
 conn.close()
 except Exception as e:
 print("数据库操作失败!
 ")
 error_Record(str(e),traceback. format_exc())
 print(e)
def compare_DB_Url(url ):
 try:
 con = sqlite3.connect( 'hunter.db')
 cur = con.cursor()
 cur.execute('SELECT url from Baseline where url = ?',))
 results = cur.fetchall()
 cur.close()
 con.commit()
 con.close()
 return results
 except Exception as e:
 error_Record(str(e),traceback. format_exc())
 print(e)
呈现方式还是采用邮件预警,邮件格式采用html方便插入table并且设置css。邮件发送代码如下:
def send_mail(host,password,sender,receivers,message):
 def _format_addr( s):
 name,addr = parseaddr(s)
 return formataddr(( Header(name,'utf-8').encode(),addr))
 msg = MIMEText(message,'html','utf-8')
 subject = 'Github信息泄露监控通知'
 msg['Subject'] = Header(subject,'utf-8') .encode()
 msg['From'] = _format_addr('Github信息泄露监控<%s>' % sender)
 msg['To'] = ','.join(receivers)
 try:
 smtp_obj = smtplib.SMTP(host,25)
 smtp_obj.login(username,password)
 smtp_obj.sendmail(sender,msg.as_string ())
 print('邮件发送成功!')
 smtp_obj.close()
 except Exception as err:
 error_Record(str(err),traceback. format_exc())
 print(err)

0×03 预警逻辑和基线建立

预警逻辑和基线建立代码都放在了主函数中,读取配置文件与之前Github信息泄露监控工具无异。而在关键词和payload读取时则进行了改动,搜索关键词由原来的单一,变为组合型关键词,即keyword + payload。搜索代码中存在的关键词和payload又将两者拆分,这样就保证了监控者关注的关键词和payload 100%存在于Github新收录的条目中,关键代码如下:

if __name__ == '__main__' :
 config = configparser.ConfigParser()
 config.read('info.ini')
 g_User = config['Github' ]['user']
 g_Pass = config['Github' ]['password']
 host = config['EMAIL' ]['host']
 m_User = config['EMAIL' ]['user']
 m_Pass = config['EMAIL' ]['password']
 m_sender = config['SENDER' ]['sender']
 receivers = []
 for k in config ['RECEIVER']:
 receivers.append(config['RECEIVER'][k])
 keywords = []
 #组合关键词,keyword + payload,两者之间加入“+”号,符合Github搜索语法
 for keyword in config ['KEYWORD']:
 for payload in config ['PAYLOADS']:
 keywords.append(config['KEYWORD'][keyword] + '+' + config[ 'PAYLOADS'][payload])
 message = 'Dear all

未发现任何新增敏感信息!' tUrls,codes= hunter(g_User,g_Pass,keywords) target_codes = [] #第一次运行会查找是否存在数据文件,如果不存在则新建,存在则进行新增条目查找 if os.path.exists( 'hunter.db'): print("存在数据库文件,进行新增数据查找......") #拆分关键词,在泄露的代码中查找关键词和payload.如果两者都存在则进行下一步数据库查找 for keyword in keywords: payload = keyword.split( '+') for i in range(0,len(tUrls)) : if (payload[0 ] in codes[i ]) and (payload[1 ] in codes[i ]): #如果数据库中返回的值为空,则说明该条目在数据库中不存在,那么添加到target_codes里面用户发送邮件,并且添加数据库中 if not compare_DB_Url(tUrls[i]): target_codes.append('


' + '链接:' + tUrls[i] + '

') target_codes.append('简要代码如下:
' ) insert_DB(tUrls[i],codes[i]) else: print("未发现数据库文件,创建并建立基线......") for keyword in keywords: payload = keyword.split( '+') for i in range(0,len(tUrls)) : #关键词和payload同时存在则加入到target_codes,并写入数据库 if (payload[0 ] in codes[i ]) and (payload[1 ] in codes[i ]): target_codes.append('


' + '链接:' + tUrls[i] + '

') target_codes.append('简要代码如下:
' ) insert_DB(tUrls[i],codes[i]) #当target_codes有数据时,则进行邮件预警 if target_codes: warning = ''. join(target_codes) result = 'Dear all

发现信息泄露! ' + '一共发现{}条'.format (int(len(target_codes)/ 2)) + warning send_mail(host,m_User,m_Pass,m_sender,result) else: send_mail(host,message)

首先进行数据库文件查找,如果是首次运行,那么会在程序目录下生成一个db文件名称为hunter。然后进行keyword和payload查找,当keyword和payload都存在于爬下来的泄露代码中,那么则加入到target_codes中用于邮件预警,最后进行数据库写入操作创建基线;如果数据库存在则说明基线存在,那么则进行新增数据查找。同理,当keyword和payload存在泄漏代码中,并且还必须满足获取的泄露地址url不存在于数据库Baseline表中则加入到target_codes,最后写入表中。在加入target_codes时还写入了换行符,css样式等,具体可参考上面代码。程序最后发送预警邮件,如target_codes有数据,那么进行预警。如果不存在数据则进行通知

0×04 效果呈现

具体效果如下图所示:

自己动手打造Github代码泄露监控工具!再也不用担心代码泄露了!

图中被抹去的是关键词,keyword和payload都以红色显示。根据自己需求进行修改即可。

0×05 总结

所谓人无完人,程序也是一样,只有通过不断改进,才能达到近乎完美得到自己想要的效果。我觉得最重要的是改进的过程,在这个过程会遇到各种问题,各种难题,我们要做的是去一个个克服,不能半途而废。只有这样才能不断的提升自己,提高自己的各项技能水平。安全之路还长,吾将上下而求索!谢谢各位客官老爷耐心读完!最新完整代码还是那个地址:

https://github.com/Hell0W0rld0/Github-Hunter

自己动手打造系列下期预告:自己动手打造自动化安全扫描平台

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


我最近重新拾起了计算机视觉,借助Python的opencv还有face_recognition库写了个简单的图像识别demo,额外定制了一些内容,原本想打包成exe然后发给朋友,不过在这当中遇到了许多小问题,都解决了,记录一下踩过的坑。 1、Pyinstaller打包过程当中出现warning,跟d
说到Pooling,相信学习过CNN的朋友们都不会感到陌生。Pooling在中文当中的意思是“池化”,在神经网络当中非常常见,通常用的比较多的一种是Max Pooling,具体操作如下图: 结合图像理解,相信你也会大概明白其中的本意。不过Pooling并不是只可以选取2x2的窗口大小,即便是3x3,
记得大一学Python的时候,有一个题目是判断一个数是否是复数。当时觉得比较复杂不好写,就琢磨了一个偷懒的好办法,用异常处理的手段便可以大大程度帮助你简短代码(偷懒)。以下是判断整数和复数的两段小代码: 相信看到这里,你也有所顿悟,能拓展出更多有意思的方法~
文章目录 3 直方图Histogramplot1. 基本直方图的绘制 Basic histogram2. 数据分布与密度信息显示 Control rug and density on seaborn histogram3. 带箱形图的直方图 Histogram with a boxplot on t
文章目录 5 小提琴图Violinplot1. 基础小提琴图绘制 Basic violinplot2. 小提琴图样式自定义 Custom seaborn violinplot3. 小提琴图颜色自定义 Control color of seaborn violinplot4. 分组小提琴图 Group
文章目录 4 核密度图Densityplot1. 基础核密度图绘制 Basic density plot2. 核密度图的区间控制 Control bandwidth of density plot3. 多个变量的核密度图绘制 Density plot of several variables4. 边
首先 import tensorflow as tf tf.argmax(tenso,n)函数会返回tensor中参数指定的维度中的最大值的索引或者向量。当tensor为矩阵返回向量,tensor为向量返回索引号。其中n表示具体参数的维度。 以实际例子为说明: import tensorflow a
seaborn学习笔记章节 seaborn是一个基于matplotlib的Python数据可视化库。seaborn是matplotlib的高级封装,可以绘制有吸引力且信息丰富的统计图形。相对于matplotlib,seaborn语法更简洁,两者关系类似于numpy和pandas之间的关系,seabo
Python ConfigParser教程显示了如何使用ConfigParser在Python中使用配置文件。 文章目录 1 介绍1.1 Python ConfigParser读取文件1.2 Python ConfigParser中的节1.3 Python ConfigParser从字符串中读取数据
1. 处理Excel 电子表格笔记(第12章)(代码下载) 本文主要介绍openpyxl 的2.5.12版处理excel电子表格,原书是2.1.4 版,OpenPyXL 团队会经常发布新版本。不过不用担心,新版本应该在相当长的时间内向后兼容。如果你有新版本,想看看它提供了什么新功能,可以查看Open
1. 发送电子邮件和短信笔记(第16章)(代码下载) 1.1 发送电子邮件 简单邮件传输协议(SMTP)是用于发送电子邮件的协议。SMTP 规定电子邮件应该如何格式化、加密、在邮件服务器之间传递,以及在你点击发送后,计算机要处理的所有其他细节。。但是,你并不需要知道这些技术细节,因为Python 的
文章目录 12 绘图实例(4) Drawing example(4)1. Scatterplot with varying point sizes and hues(relplot)2. Scatterplot with categorical variables(swarmplot)3. Scat
文章目录 10 绘图实例(2) Drawing example(2)1. Grouped violinplots with split violins(violinplot)2. Annotated heatmaps(heatmap)3. Hexbin plot with marginal dist
文章目录 9 绘图实例(1) Drawing example(1)1. Anscombe’s quartet(lmplot)2. Color palette choices(barplot)3. Different cubehelix palettes(kdeplot)4. Distribution
Python装饰器教程展示了如何在Python中使用装饰器基本功能。 文章目录 1 使用教程1.1 Python装饰器简单示例1.2 带@符号的Python装饰器1.3 用参数修饰函数1.4 Python装饰器修改数据1.5 Python多层装饰器1.6 Python装饰器计时示例 2 参考 1 使
1. 用GUI 自动化控制键盘和鼠标第18章 (代码下载) pyautogui模块可以向Windows、OS X 和Linux 发送虚拟按键和鼠标点击。根据使用的操作系统,在安装pyautogui之前,可能需要安装一些其他模块。 Windows: 不需要安装其他模块。OS X: sudo pip3
文章目录 生成文件目录结构多图合并找出文件夹中相似图像 生成文件目录结构 生成文件夹或文件的目录结构,并保存结果。可选是否滤除目录,特定文件以及可以设定最大查找文件结构深度。效果如下: root:[z:/] |--a.py |--image | |--cat1.jpg | |--cat2.jpg |
文章目录 VENN DIAGRAM(维恩图)1. 具有2个分组的基本的维恩图 Venn diagram with 2 groups2. 具有3个组的基本维恩图 Venn diagram with 3 groups3. 自定义维恩图 Custom Venn diagram4. 精致的维恩图 Elabo
mxnet60分钟入门Gluon教程代码下载,适合做过深度学习的人使用。入门教程地址: https://beta.mxnet.io/guide/getting-started/crash-course/index.html mxnet安装方法:pip install mxnet 1 在mxnet中使
文章目录 1 安装2 快速入门2.1 基本用法2.2 输出图像格式2.3 图像style设置2.4 属性2.5 子图和聚类 3 实例4 如何进一步使用python graphviz Graphviz是一款能够自动排版的流程图绘图软件。python graphviz则是graphviz的python实