背景
最近调研了一些开源的白盒的代码安全扫描器,其中就包括了之前比较出名的cobra项目。看了下这个项目的情况,该项目最近一次更新是在2年前,目前项目基本已不维护。仅支持PHP的AST分析和基于此的一些策略,其他语言的规则完全靠正则表达式匹配关键词,误报率较高。看了下网上很多文章说创宇的404大佬重写了 cobra AST部分,新的项目是cobra-w,cobra-w的误报率会比之前的老项目有不少优化。但是cobra-w可能由于作者的技术栈和侧重,完全去掉了java相关的规则。由于我司的语言技术栈没有php,java呢也只占了一部分,所以看起来可以借鉴的地方就不是很多。不过既然了解了这个项目的一些情况也不妨搭建起来先测试下再说。
(2015.12 泰国·卡塔海滩)
开始测试
下载安装
具体的项目安装使用方法直接看cobra的手册,介绍的就比较详细了。
http://cobra.feei.cn/
我在本地搭建安装Cobra服务,直接启用GUI 模式(支持API)
扫描
在配置文件中填写自己的git secret ,然后直接填写git仓库的地址即可立即开始扫描。
稍等一会即可看到扫描报告结果。
测试结果
经对git仓库一些项目进行扫描测试,该项目中的默认规则中,敏感信息及风险文件的扫描相对比较准确,这类风险正则就可以满足检测。而sql注入等检测规则非常少,且因为不支持跨文件的dataflow的检测,误报还是较多的。
规则数量,如下图,去除php语言规则,剩下的通用规则包括java规则仅21条,全部基于正则。其中CVI-19开头的策略是cve匹配版本号的SCA规则,因为目前公司已经有SCA就未关注这类规则。
优化了下硬编码检测规则
经过测试因为硬编码的检测基本都是依靠正则匹配,cobra检测的规则默认支持一些常见的password、mysql等,但是还是有一定的误报率,这里我自己做了一些正则的调整,将误报率进一步降低。
这里正则分成两块
- conf类检测
只对conf类文件进行扫描规则(这里也在原有的conf配置文件后缀基础上进行了补充,包括:.properties、.conf、.ini、.cfg、.yml、.xml、.iml、.spf、.manifest、.gradle、.npmrc、.arcconfig)
1)<![CDATA[(?i)(?:PASSWORD|email|password|passwd|mysql|appsecretkey|appsecret|accessKeySecret|APP_SECRET|pass|pwd|secret|secret_key)\w*\s*(?:=)\s*(?!\$\{.*\})]]>
2)<![CDATA[(?i)(?:email|password|passwd|mysql|appsecretkey|appsecret|accessKeySecret|APP_SECRET|pass|pwd|secret|secret_key)\w*\s*('|"){0,1}(?::)\s*('|"){0,1}(.*)]]>
- 除去js的代码文件检测
包括.java、.go等
1)<![CDATA[(?i)(?:email|password|passwd|mysql|appsecretkey|appsecret|accessKeySecret|APP_SECRET|pwd|secret|secret_key|access.key|secret.key)\w*\s*('|"){0,1}(?:(=|:))\s*("|').*("|')]]>
2)第一行<match mode="regex-only-match"><![CDATA[(?i)(?:BASIC_AUTH)\w*\s*(?:=)\s*.*(\{)?]]></match>
匹配第一行后,在同一代码段中包含:<match2 block="in-function-down"><![CDATA[\w*\s*(?::)\s*(\()?.*(\))?]]></match2>
实现自动化扫描
cobra本身提供了扫描全部git仓库的自动化脚本git_projects.py,但由于项目是18年最后更新的,调用的git还是v3的api接口,目前我们使用的gitlab 接口是v4。另外由于项目数量巨大,想去掉未扫描出结果的项目,只关注扫描出的问题,就自己写了一个自动化的脚本。
cobra的官方提供的脚本:https://github.com/WhaleShark-Team/cobra/blob/master/git_projects.py
#!/usr/bin/env python
#-*- coding:utf-8 -*-
#author:Darkpot
import requests
import json
import time
#import csv
def reqWebSite():
success = True
while success:
try:
#请求git地址仓库接口,拉取全部的代码仓库中的项目地址
#请替换你的git中的请求accesstoken
headers = {"PRIVATE-TOKEN":"YOUR_ACCESSTOKEN"}
git = []
#range 中的最大数,取决于/api/v4/projects接口查询你的页数,per_page为每页显示条数,page参数为第几页
for b in range(1,500):
#请求的git api 地址要根据当前的git版本查看git api手册自行调整
url = 'https://YOUR_GITLAB/api/v4/projects?simple=yes&per_page=50&page='+str(b)
req = requests.get(url,headers=headers)
response = req.json()
for num in range(len(response)):
i=response[num]["http_url_to_repo"]
if i not in git:
git.append(i)
'''
可导出project列表到csv
with open('git.csv', 'w') as f:
writer = csv.writer(f)
for val in git:
writer.writerow([val])
'''
#将爬取的git仓库地址逐一发送给cobra白盒扫描器进行扫描,/api/add 为添加扫描任务接口,status为查询任务状态接口
url2 = 'http://127.0.0.1:8888/api/add'
url3 = 'http://127.0.0.1:8888/api/status'
headers2 = {"Content-Type":"application/json"}
sids=[]
#将扫描出有漏洞的任务id sid保存到如下文件
file = r'/YOUR_Dircetory/git.txt'
for giturl in git:
# CoBRA 任务添加接口的参数配置,key需要在cobra目录中的config进行自定义配置;rule 为本次扫描启用的规则
data = '{"key":"YOU_COBRA_KEY","target":"'+giturl+':master","rule": "cvi-130003,cvi-130004,cvi-130001,cvi-130002,cvi-130005,cvi-130006"}'
req2 =requests.post(url2, data=data, headers=headers2)
response2 = req2.text
json_result2 = json.loads(response2)
sid2 = json_result2["result"]["sid"]
while 1:
time.sleep(3)
# 添加完任务后,每隔3s请求一次任务状态,查看是否完成
data2 = '{"key":"YOU_COBRA_KEY","sid":"'+sid2+'"}'
req3 = requests.post(url3, data=data2, headers=headers2)
response3 = req3.text
json_result3 = json.loads(response3)
print(json_result3)
status =json_result3["result"]["status"]
if status=='running':
continue
else:
#如果任务完成间隔60s,再查看下任务状态,因为cobra扫描结果生成需要时间,当任务状态第一次变成done时可能结果会全部显示为0,容易产生漏报。
time.sleep(60)
req4 = requests.post(url3, data=data2, headers=headers2)
response4 = req4.text
json_result4 = json.loads(response4)
#将查询状态响应中返回的高中低危漏洞个数进行比较,只要其中有一个大于0则记录下来
high=json_result4["result"]["statistic"]["high"]
medium=json_result4["result"]["statistic"]["medium"]
critical=json_result4["result"]["statistic"]["critical"]
low=json_result4["result"]["statistic"]["low"]
if high!=0:
sids.append(sid2)
with open(file, 'a+') as f:
f.write(sid2+'\n')
break
elif medium!=0:
sids.append(sid2)
with open(file, 'a+') as f:
f.write(sid2+'\n')
break
elif critical!=0:
sids.append(sid2)
with open(file, 'a+') as f:
f.write(sid2+'\n')
break
elif low!=0:
sids.append(sid2)
with open(file, 'a+') as f:
f.write(sid2+'\n')
break
else:
break
print(sids)
except Exception as e:
print("出现如下异常%s"%e)
reqWebSite()
结语
本次测试,虽然未直接找到一款非常适用于公司环境的白盒扫描工具,但是也了解到了一款非常不错的开源工具 cobra。也学习了LoRexxar 大佬写的一系列白盒审计的文章,获益颇多。建议感兴趣的朋友可以去认真读一下,贴出大佬的github:https://github.com/LoRexxar。后续也会陆续发一些我最近在调研白盒方案的一些文章和心得,欢迎大家相互交流。
上文所贴的自动化脚本 github:https://github.com/hashwormer/cobra_automulit_scan.git