最近项目支撑,需要针对各类ms漏洞、webshell、k8等工具编写防御规则,我们统一把恶意工具下载到本地,在本地开一个web服务。每针对一个工具开发一条规则,就需要捕获一个数据包,而且必须是经过过滤处理的单独的数据包。希望能有一个工具简化抓包过程。
思路1:本地开启web服务,如果是开启wireshark,然后批量爬虫的话,会得到包含多个追踪流的数据包,如果借助scapy进行拆包,要处理的异常情况太多。放弃。
思路2:使用sniffer抓包。缺陷是存在漏包,访问了某个地址之后,产生的流量没有被sniffer抓到。
思路3:使用tcpdump。缺陷是每次工作都得开个虚拟机,并且不便于移植到同事的电脑上。
思路4:使用windump,一个windows版本的tcpdump。缺陷是:我物理机下不能运行,虚拟机运行时,过滤器与保存文件的操作不能同时使用,工具的奇怪bug太多。
思路5:使用tshark实现windows下抓包,代替tcpdump
tshark相当于是命令行版的wireshark,不需要额外安装,在安装wireshark的时候就会安装上这个工具。那么,先开启tshark抓包,然后python爬取一个目标路径,最后tshark停止抓包,并将抓取的内容写入到电脑上。这里最大的问题是如何停止抓包,我是用的方法是设置抓包时间,让它到时间就停止。
关于tshark:
tshark.exe -D
命令查看电脑上有哪些网卡。\Device\NPF_{FA29BC17-7BFC-4CE8-BB48-71174A6BDA54}
即可指定抓取的网卡是以太网\Device\NPF_{FA29BC17-7BFC-4CE8-BB48-71174A6BDA54}
我一开始设计的是windump,tshark的代码是同事做的,这里介绍的是tshark,使用中有些注意事项:
工具总共涉及到3个文件:脚本、脚本配置文件、目标url地址。
只需修改配置文件和目标url地址即可,脚本无需修改(注意安装相关库文件),可以直接运行。
cfg.yaml
# tshark 路径
tshark_path: "D:\\Program Files\\Wireshark\\tshark.exe"
# 网卡名称(tshark -D 查看网卡)
iface: r"\Device\NPF_{FA29BC17-7BFC-4CE8-BB48-71174A6BDA54}"
# 本机ip地址
localhost: "10.71.35.238"
# 服务器IP
serverIP: "10.8.144.32"
# 服务器端口
port: "8085"
item.txt
cfg.yaml
中的服务器IP进行拼接/webtrojan/web-malware-collection-13-06-2012/PHP/SyRiAn.Sh3ll.v7.txt
/webtrojan/web-malware-collection-13-06-2012/PHP/ugdevil.v2.0.txt
/webtrojan/web-malware-collection-13-06-2012/PHP/up.php
/webtrojan/web-malware-collection-13-06-2012/PHP/uploader.txt
import threading
import time
import requests
import os
import yaml
from subprocess import PIPE, Popen
# 导入配置文件
def load_cfg():
with open('cfg.yaml', 'r', encoding='utf-8') as f:
con = f.read()
cfg = yaml.safe_load(con)
# print(cfg['tshark_path'])
return cfg
# 爬虫批量访问指定url
def request_url(url):
url = 'http://' + url
try:
res = requests.get(url=url, timeout=5)
except:
print('failed to get' + url)
return False
if res.status_code == 200:
return True
else:
print('访问失败,请重试:' + url)
# 使用tshark抓包
def tshark_cap(filename):
# 提取url中最后一个斜线后面的内容作为文件名。如果文件名存在空格,就进行替换
filename = filename.replace(' ', '_') # 默认是一个空格,如果文件名中存在多个空格,请手动更改url或者修改代码
filename = filename + '.pcap' # 拼接出文件名
file_path = 'pcaps/' # 抓包的包放在pcaps文件夹下。pcaps是与脚本在同一路径下
file = file_path + filename # 拼接出文件的绝对路径
cfg = load_cfg()
tshark_path = cfg['tshark_path']
tshark_path = tshark_path.strip()
iface = cfg['iface']
iface = iface.strip()
localhost = cfg['localhost']
localhost = localhost.strip()
serverIP = cfg['serverIP']
serverIP = serverIP.strip()
filt = '"host ' + localhost + ' and host ' + serverIP + '"' # 拼接出过滤器,用来过滤数据包
command = tshark_path + ' -i ' + iface + ' -f ' + filt + ' -a duration:2 -w ' # 设定tshark抓包2秒,2秒之后自动关闭
# command = r'"C:\\Program Files\\Wireshark\\tshark.exe" -i \Device\NPF_{144EC01C-9E64-43EC-AFA0-531860514A37} -f "host 10.71.35.157 and host 10.253.251.97" -a duration:3 -w '
command = command + file
# print(command)
p = Popen(command, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()
def main():
if not os.path.exists('pcaps'):
os.mkdir('pcaps')
print("请创建 item.txt 文件,并将表格中的内容粘贴进文件中....")
os.system("pause")
print('running....')
with open('item.txt', 'rb') as f:
contents = f.read()
filenames = contents.decode('utf-8')
filenames = filenames.split('\r\n')
host = load_cfg()['serverIP'] + ":" + load_cfg()['port']
for filename in filenames:
if len(filename) < 1:
continue
filename = filename.strip()
url = host + filename
pname = filename.split('/')[-1]
req = threading.Thread(target=request_url, name='request', args=(url,))
cat = threading.Thread(target=tshark_cap, name='catpcap', args=(pname,))
cat.start()
# 请注意,休眠时间不足的话,会导致抓到的数据包是空包
# 不同的电脑上,此时的休眠时间不同。我同事是2秒就行,我的是5秒才行.
# 你需要通过输入不同的休眠时间来测试,究竟休眠多少时间才能抓到数据包
time.sleep(5)
req.start()
req.join()
cat.join()
# time.sleep(1)
if __name__ == '__main__':
print('''
本工具为批量抓包工具,访问一次指定地址,抓一次数据包。
==============================================================
使用说明:
安装wireshark时会默认安装“tshark.exe”(一个命令行版的wireshark),
你可以使用everything搜索出其位置,在终端中运行它,如“.\tshark.exe -D”获取本地网卡,选择你像抓取的网卡编号
脚本使用GET方法每访问一次目标地址,就会调用tshark抓一次包
数据包会导出在与脚本同目录下的“pcaps”文件夹下
1. 使用方法:python 批量抓包-1112项目专用.py
2. 注意:使用前请先配置 cfg.yaml(此文件需要与脚本位于同一目录下)
3. 在“item.txt”中输入你要访问的url地址(此文件需要与脚本位于同一目录下)
''')
main()
print('enjoy it :)')
# os.system("pause")