21.14 Python 实现Web指纹识别

21.14 Python 实现Web指纹识别 处于当下的Web安全领域当中, 辨别目标站点的指纹属于渗透测试里常见的首个步骤指纹识别的目标在于明确目标站点所运用的技术体系和框架, 进而依据目标框架展开针对性的安全测评指纹识别的道理实际上挺简单, 当下主流的识别办法有下面这么一些。这些基于指纹的识别途径, 皆是借助剖析目标网站的特定表征或者行为, 于其中推导所运用的框架或者技术。它们能够助力渗透测试人员知悉目标网站的技术栈以及框架, 进而施行针对性的安全测试以及漏洞扫描。在本节内容当中, 我们会采用第二种方式, 也就是借助哈希鉴定去确定目标指纹信息, 此种办法需要具备完善的特征库, 这些特征库, 我们能自行寻觅制作, 也能够运用已有的库, 经由转换之后获取。要实现指纹识别, 在此之前, 须先尝试读取目标网站的标题信息, 该功能的实现堪称简易异常, 只需读入页面, 接着依次取出所需的“Date”, “”, “X--By”, “title”字段就行, 鉴于代码颇为简单, 所以在此处直接放出代码部分。import re,socket,threading,requests import argparse header {user-agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) LySharkTools} def GetIPAddress(domain): try: url str(domain.split(//)[1]) sock socket.getaddrinfo(url,None) result re.findall((?:[0-9]{1,3}\.){3}[0-9]{1,3}, str(sock[0][4])) return str(result[0]) except Exception: pass def GetServerTitle(url): try: address GetIPAddress(url) Respon requests.get(urlurl,headersheader,timeout5) print(-- * 80) print(url ,end) print(address , end) if Respon.status_code 200: RequestBody [item for item in Respon.headers] for item in [Date,Server,X-Powered-By]: if item in RequestBody: print(Respon.headers[item] ,end) title re.findall(.*, Respon.content.decode(utf-8)) print(title) except Exception: pass if __name__ __main__: parser argparse.ArgumentParser() parser.add_argument(-f,--file,destfile,help) args parser.parse_args() # 使用方法: main.py -f url.log if args.file: fp open(args.file,r) for item in fp.readlines(): url item.replace(\n,) thread threading.Thread(targetGetServerTitle,args(url,)) thread.start() else: parser.print_help()运行这段代码时, 读者要准备好所需获取的网站列表, 将其按照每行一列的方式放置到 url.log 文件里, 运行如下面图片所展示的命令, 就能依次读取到这些网站的服务器信息。我们持续达成指纹识别功能, 先是借助库把目标页面读取进字符串之中, 接着调用MD5算法算出该页面的HASH值并予以比对, 鉴于特定框架里总有一些页面不曾变动, 我们进而校准这些页面的HASH值, 便能达成对框架的识别, 代码颇为简易在此直接给出源代码。import requests import os,sys,hashlib import argparse headers {user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) LySharkTools} def CheckFinger(url,flag,keyworld): if flag 0: ret requests.get(urlurl,headersheaders,timeout1) text ret.text md5hashlib.md5() md5.update(text.encode(utf-8)) print(目标网页Hash值: {}.format(md5.hexdigest())) else: fp open(keyworld,r) for i in fp.readlines(): path url eval(i.replace(\n, ))[Path] hash eval(i.replace(\n, ))[Hash] web eval(i.replace(\n, ))[WebServer] ret requests.get(urlpath, headersheaders, timeout1) if ret.status_code 200: text ret.text md5 hashlib.md5() md5.update(text.encode(utf-8)) if md5.hexdigest() hash: print(目标Hash{} CMS页面类型{} .format(hash,web)) else: continue if __name__ __main__: parser argparse.ArgumentParser() parser.add_argument(--mode,destmode,help设置检查类型 [check/get]) parser.add_argument(-u,--url,desturl,help指定需要检测的网站地址) parser.add_argument(-f,--file,destfile,help指定字典数据库 data.json) args parser.parse_args() if args.mode get and args.url: CheckFinger(args.url,0,args.file) # 检测目标容器类型: main.py --modecheck -u https://www.xxx.com -f data.json elif args.mode check and args.url and args.file: CheckFinger(args.url,1,args.file) else: parser.print_help()执行如下命令, 这段代码就被用于通过使用get方法, 去获取特定页面的hash值, 比如说获取网站特定路径的hash值。当把这些特征给获取到手之后, 我们能够去新建一个.db文件, 接着把这些数据按照特定的格式来进行保存, 呈现的情况如下所示。{Path:/about/index.html,Hash: 9e69dd111c6cc873a1f915ca1a331b06,WebServer:hexo} {Path:/index.php,Hash: 2457dd111c6cc32461f915ca17789b06,WebServer:typecho} {Path:/index.html,Hash: 7530893af83150dc07461f4bc4cc0de6,WebServer:oss}若特征库处于完整状态,那么此刻可以通过使用 -f 去指定特征文档, 接着在循环之中获取是否与特征相匹配, 借由这样的方式进而判断 web 容器运用了哪一种容器组件。