Python實(shí)現(xiàn)Web指紋識(shí)別實(shí)例
web主流的識(shí)別方式
在當(dāng)今的Web安全行業(yè)中,識(shí)別目標(biāo)網(wǎng)站的指紋是滲透測(cè)試的常見(jiàn)第一步。指紋識(shí)別的目的是了解目標(biāo)網(wǎng)站所使用的技術(shù)棧和框架,從而進(jìn)一步根據(jù)目標(biāo)框架進(jìn)行針對(duì)性的安全測(cè)試,指紋識(shí)別的原理其實(shí)很簡(jiǎn)單,目前主流的識(shí)別方式有下面這幾種。
- 識(shí)別特定網(wǎng)頁(yè)中的關(guān)鍵字,比對(duì)關(guān)鍵字識(shí)別框架:這種方式通過(guò)在目標(biāo)網(wǎng)頁(yè)的HTML、CSS、JavaScript代碼中搜索特定的關(guān)鍵字或標(biāo)識(shí),比對(duì)這些關(guān)鍵字與已知框架的特征進(jìn)行識(shí)別。例如,如果在網(wǎng)頁(yè)中發(fā)現(xiàn)了特定的JavaScript函數(shù)、CSS類名或HTML標(biāo)簽,可以推斷目標(biāo)網(wǎng)站所使用的框架或庫(kù),如jQuery、AngularJS等。
- 通過(guò)計(jì)算特定的相對(duì)獨(dú)立頁(yè)面的哈希值,比對(duì)實(shí)現(xiàn)鑒別:這種方式將目標(biāo)網(wǎng)頁(yè)的內(nèi)容進(jìn)行哈希計(jì)算,生成一個(gè)唯一的哈希值,并與已知框架的頁(yè)面哈希值進(jìn)行比對(duì)。如果目標(biāo)網(wǎng)頁(yè)的哈希值與某個(gè)框架的哈希值匹配,則可以推斷目標(biāo)網(wǎng)站所使用的框架。這種方法適用于那些在不同頁(yè)面間保持相對(duì)穩(wěn)定的框架,例如單頁(yè)應(yīng)用(SPA)。
- 通過(guò)指定URL的TAG模式,鑒別目標(biāo)容器類型:這種方式通過(guò)分析目標(biāo)網(wǎng)站的URL結(jié)構(gòu)或特定的URL參數(shù),來(lái)推斷目標(biāo)網(wǎng)站所使用的容器類型或框架。例如,如果URL中包含特定的路徑或參數(shù),可以推斷目標(biāo)網(wǎng)站可能是基于某個(gè)特定容器,如WordPress、Drupal等。這種方式常用于識(shí)別內(nèi)容管理系統(tǒng)(CMS)或其他特定的應(yīng)用程序。
這些指紋識(shí)別方式都是通過(guò)分析目標(biāo)網(wǎng)站的特定特征或行為,從中推斷所使用的框架或技術(shù)。它們可以幫助滲透測(cè)試人員了解目標(biāo)網(wǎng)站的技術(shù)棧和框架,從而進(jìn)行針對(duì)性的安全測(cè)試和漏洞掃描。本節(jié)內(nèi)容中我們將采用第二種方式通過(guò)哈希鑒定來(lái)確定目標(biāo)指紋信息,此種方法需要有完善的特征庫(kù),這些庫(kù)我們可以自行尋找制作,也可以使用已有的庫(kù)經(jīng)過(guò)轉(zhuǎn)換后獲取。
讀取到該目標(biāo)網(wǎng)站的標(biāo)題信息
在實(shí)現(xiàn)指紋識(shí)別之前,我們先要嘗試讀取到該目標(biāo)網(wǎng)站的標(biāo)題信息,該功能實(shí)現(xiàn)非常簡(jiǎn)單,只需要讀入頁(yè)面,并依次取出所需要的"Date","Server","X-Powered-By","title"字段即可,由于代碼較為簡(jiǎn)單此處就直接放出代碼部分。
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("http://")[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(url=url,headers=header,timeout=5)
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("<title>.*</title>", Respon.content.decode("utf-8"))
print(title)
except Exception:
pass
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-f","--file",dest="file",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(target=GetServerTitle,args=(url,))
thread.start()
else:
parser.print_help()這段代碼在運(yùn)行時(shí)讀者需要準(zhǔn)備好需要獲取的網(wǎng)站列表,并每行一列放入url.log文件中,通過(guò)運(yùn)行如下圖所示的命令即可依次讀取到這些網(wǎng)站的服務(wù)器信息;

調(diào)用MD5算法計(jì)算出該頁(yè)面的HASH值并比對(duì)
我們繼續(xù)實(shí)現(xiàn)指紋識(shí)別功能,首先利用Requests庫(kù)將目標(biāo)頁(yè)面讀入到字符串中,然后調(diào)用MD5算法計(jì)算出該頁(yè)面的HASH值并比對(duì),由于特定框架中總是有些頁(yè)面不會(huì)變動(dòng),我們則去校驗(yàn)這些頁(yè)面的HASH值,即可實(shí)現(xiàn)對(duì)框架的識(shí)別,代碼很簡(jiǎn)單這里就直接放出源代碼。
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(url=url,headers=headers,timeout=1)
text = ret.text
md5=hashlib.md5()
md5.update(text.encode('utf-8'))
print("目標(biāo)網(wǎng)頁(yè)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(url=path, headers=headers, timeout=1)
if ret.status_code == 200:
text = ret.text
md5 = hashlib.md5()
md5.update(text.encode('utf-8'))
if md5.hexdigest() == hash:
print("目標(biāo)Hash:{} CMS頁(yè)面類型:{} ".format(hash,web))
else:
continue
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--mode",dest="mode",help="設(shè)置檢查類型 [check/get]")
parser.add_argument("-u","--url",dest="url",help="指定需要檢測(cè)的網(wǎng)站地址")
parser.add_argument("-f","--file",dest="file",help="指定字典數(shù)據(jù)庫(kù) data.json")
args = parser.parse_args()
if args.mode == "get" and args.url:
CheckFinger(args.url,0,args.file)
# 檢測(cè)目標(biāo)容器類型: main.py --mode=check -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()這段代碼通過(guò)使用get方法可獲取到特定頁(yè)面的hash值,例如獲取www.lyshark.com網(wǎng)站特定路徑的hash值,則可以執(zhí)行如下命令;

當(dāng)獲取到這些特征后,我們就可以新建database.db文件,并將這些數(shù)據(jù)保存為特定的格式,如下所示;
{"Path":"/about/index.html","Hash": "9e69dd111c6cc873a1f915ca1a331b06","WebServer":"hexo"}
{"Path":"/index.php","Hash": "2457dd111c6cc32461f915ca17789b06","WebServer":"typecho"}
{"Path":"/index.html","Hash": "7530893af83150dc07461f4bc4cc0de6","WebServer":"oss"}
當(dāng)特征庫(kù)完整時(shí),即可使用-f指定特征文件,循環(huán)獲取是否匹配特征,從而判斷web容器使用了那種容器。

以上就是 Python 實(shí)現(xiàn)Web指紋識(shí)別的詳細(xì)內(nèi)容,更多關(guān)于 Python Web指紋識(shí)別的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
好的Python培訓(xùn)機(jī)構(gòu)應(yīng)該具備哪些條件
python是現(xiàn)在開(kāi)發(fā)的熱潮,大家應(yīng)該如何學(xué)習(xí)呢?許多人選擇自學(xué),還有人會(huì)選擇去培訓(xùn)結(jié)構(gòu)學(xué)習(xí),那么好的培訓(xùn)機(jī)構(gòu)的標(biāo)準(zhǔn)是什么樣的呢?下面跟隨腳本之家小編一起通過(guò)本文學(xué)習(xí)吧2018-05-05
python繪制散點(diǎn)圖詳細(xì)步驟(從0到1必會(huì))
這篇文章主要介紹了如何使用Python繪制散點(diǎn)圖,包括導(dǎo)入包、準(zhǔn)備數(shù)據(jù)、繪制圖像、修飾圖像(添加標(biāo)題、坐標(biāo)軸標(biāo)簽、顏色圖例)以及整合所有代碼,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-12-12

