本来是自己研究扫描器的一天,结果D和小白把公司比赛要用到的那个钓鱼网站文件发我。基于大数据的安全比赛,基本很多做大数据的公司都参加。我负责筛选出这一批文件里可能是钓鱼网站的文件以及url。
比赛给的东西如下:
一个文本文档,存了经过bmh(白帽汇),hash的文件名,对应的url
1000个以hash命名的文件,其实都是html文件,里面的内容有钓鱼网站的,有其他的网站的,而我的任务就是搞出那些钓鱼网站的文件。
文件名做了哈希加密的,所以批量起来还是小麻烦。既然是处理大数据,那么肯定要用大数据的处理方法。手工岂不是太落下乘了: )
首先处理这类的文档思路是:获取特征->获取文件内容对比特征->筛选出含特征的文件->获取文件名,对文件名进行操作等。
但是,实际上这个没有这么简单,在实践的流程还是踩了不少坑的。
00x1 采集特征
我们筛选的方法有两种,白名单和黑名单。在安全攻防中这个思想是常用的,可能你们认为白名单比黑名单安全,但是这个仅仅针对防御,具体的问题要具体讨论。
抛开讨论,我们先采集一批特征。
存在的特征:
Apple ID AliCloud iCould 95568 iPhone 中银E贷 APPLE 銀行 ICBC 银行 苹果 lounge 95566 娱乐城 ---------------
不存在的特征:
7e.hk 访问线路 建设中 无法找到该页 运行时错误 404
这里解释下,繁体中文和简体中文的的字符集是不一样的,特别是转化成unicode编码,所以要区分开来。
采集之后又轮到我们抉择了,到底是要用白名单还是黑名单。
白名单:准确性高,但是你采集到的特征可能不全。容易遗失一些文件(站点)。
黑名单:找到存在这些内容的站点,将这些站点过滤,剩下的就是我们想要的,但是有可能错杀。找到的有可能不是我们想要的,就是所谓的误差~
00x2: 白名单采集
来公司之后老大给的理念就是细心细心,然后精准。
无脑的选择了白名单~
由于老大看不起我,先给了我1000个文件,所以我给出如下的代码:
# encoding:utf-8
import os
import re
def file_name(file_dir):
result = open("result.txt","w")
for files in os.walk(file_dir):
for file in files:
try:
for i in range(1000):
nowfile_old = files[2][i]
nowfile= open(nowfile_old)
for line in nowfile.readlines():
if re.search("IPhone",line) or re.search("Apple ID",line) or re.search("AliCloud",line) or re.search("iCould",line) or re.search("95568",line) or re.search("Apple ID",line) or re.search("Apple ID",line) or re.search(u"\u4e2d\u94f6\u0045\u8d37",line) or re.search(u"\u94f6\u884c",line) or re.search(u"\u82f9\u679c",line) or re.search(u"\u9280\u884c ",line) or re.search("bank",line) or re.search("ICBC",line) or re.search("lounge",line) or re.search("95566",line):
result.writelines(nowfile_old+"\n")
break
except Exception,e:
print e
result.close()
dir = os.getcwd()
file_name(dir)
采用了正则来匹配,将中文的特征转化成url编码,其实这段代码有坑,让小白笑了下。=-=,这样我们就获取到我们存在这些白名单特征的文件名。
但是比赛的要求是获取到文件名之后,还要将不相关的文件删除,并且我们获取到这些hash值是不对的,要将hash值和url对应起来。
我们再借助个小脚本:
#encoding: utf-8
file_begin= open("url.txt","r")
file_result = open("result.txt","r")
file_ok = open("ok.txt","w")
def first():
file1 = []
for datas in file_begin.readlines():
file1.append(datas)
return file1
def second():
file2 = []
for datas in file_result.readlines():
file2.append(datas)
return file2
datas = first()
results = second()
for data in datas:
d = 0
bmh,key,url = data.split(",")
for result in results:
if key==result.strip():
d+=1
if d==1:
file_ok.writelines(bmh+",")
file_ok.writelines(key+",")
file_ok.writelines(url)
讲url.txt与我们获取到的这些result做对比,如果存在就输出一个类似url.txt格式的文档。其实这段代码我也碰到坑,坑就在,result.strip()这边。我上一个脚本获取文件名是这样写的,result.writelines(nowfile_old+"\n")。然后就把自己坑惨了,为什么输出的ok.txt一直是0kb???擦,百思不得其解,后面小白说下个断电试试,果然老司机!
下了断点就发现多了一个回车符,我们肉眼看不到看不到,将它strip过滤一下就ok了。
第三步,就是获取到这些存在特征的文件。
同样一个脚本搞定:
#!python
# -*- coding:utf8 -*-
import os
import os.path
import shutil
filePath = os.getcwd()
destDir = "D:/xiaobaibai"
def write(filename,content):
a = open(filename,"a")
a.write(content)
a.close()
def loadlist():
r = []
with open("ok.txt") as content:
for temp in content:
r.append(temp)
return r
dellist = []
l = loadlist()
for fl in l:
bmh, fn, url = fl.split(",")
destPath = destDir + os.path.sep + fn
rcPath = filePath+os.path.sep+fn
shutil.copy(srcPath, destPath)
这里我们不对文件进行删除,将它们复制到D盘的小白白。
ok了。有四百多个文件,刚要叫D过来交差,D说:这咋整滴,怎么会ze么sao。哈哈哈 ,最近学他普通话都不标zun了。
不过,1000多个文件,我搞出了400多个你要我怎么办,迷茫,无助...
00x3 黑名单
后面刚不住他就用了黑名单的方法。
其实黑名单更简单,只需要改部分代码,获取文件名的正则那个改成(也可以不用正则):
if re.search("7e.hk",line) or ("访问线路" in line) or("建设中" in line) or ("无法找到该页" in line) or (
"404" in line) or ("运行时错误" in line):
第二个脚本照旧,第三个脚本就改成了:
#!python
# -*- coding:utf8 -*-
import os
import os.path
import shutil
filePath = os.getcwd()
files = os.listdir(filePath)
def write(filename,content):
a = open(filename,"a")
a.write(content)
a.close()
def loadlist():
r = []
with open("ok.txt") as content:
for temp in content:
r.append(temp)
return r
dellist = []
l = loadlist()
for fl in l:
bmh, fn, url = fl.split(",")
for file in files:
if file == fn:
os.remove(fn)
删除文件的脚本,将黑名单对应的删除。
ok,执行完就有500多个文件了。不过我想问有差么...
这篇文章主要还是想说一下这类比赛的一个解题的思路和我在python中遇到的坑。好了,不要喷,然后赞助给点飞机票吧。