0x01 工具
1.1 Wireshark
Wireshark
是一个图形化的网络协议分析工具,提供了用户友好的界面,可以实时捕获和分析网络流量。Wireshark
支持多种协议的解析和分析,包括以太网、TCP/IP
、HTTP
、DNS
等。它能够以图形界面的方式展示数据包的详细信息,以及根据特定过滤条件来筛选和分析数据包。Wireshark
适合需要直观的可视化和交互式分析的场景。
1.2 Tshark
TShark
是Wireshark
的命令行版本,它提供了与Wireshark
类似的功能,但是通过命令行接口进行操作。TShark
可以在终端窗口中运行,适用于需要批量处理或自动化分析的情况。您可以使用TShark
来捕获和分析网络流量,也可以将其与脚本和其他工具集成,以便更灵活地处理数据包。
使用方法如下:
tshark -r file -T fields —Y 指定过滤器 -e 提取的内容 > 指定输出的附件
1.3 Aircrack-ng
Aircrack-ng
是一个用于无线网络安全评估和渗透测试的套件,主要用于测试和分析WiFi
网络的安全性。它提供了多种工具和功能,用于捕获、分析和破解无线网络的数据流,以检测可能的漏洞和攻击。
利用Aircrack-ng
进行流量包密码爆破。
aircrack-ng -w [字典] ctf.pcap
aircrack-ng -w /usr/share/dirb/wordlists/others/best1050.txt ctf.pcap
利用Aircrack-ng
进行流量包解密。
airdecap-ng ctf.pcap -e [爆破出来的WPA值] -p [爆破出来的密码]
airdecap-ng ctf.pcap -e ctf -p password1
0x02 常见题型
2.1 SQL 布尔盲注
流量分析题中一个常见题型为SQL
布尔盲注,如下图所示,红框包含的内容表示逐位判断flag
的内容,显然如果判断错误就继续判断,判断正常就对下一位进行判断。蓝框包含的内容表示flag
的第一位字符的ASCII
等于102
,即字母f
,然后对第二位进行判断,我们就可以通过判断flag
每一位的最后一个payload
来获取正确的flag
。或者可以通过响应包的长度来进行判断,这里flag
猜解正确时可以看到响应包的长度为978
,不正确时为994
,也可通过该特征进行判断。
可以使用tshark
快速导出http
请求的所有uri
。
tshark -r input.pcap -Y "http.request" -T fields -e http.request.uri > output.txt
然后可以写一个简单的脚本,正则提取猜解的flag
位数以及ASCII
码,保存最后一次猜解正确的ASCII
码。最后输出flag
。
import re
flag_ascii = dict()
with open("output.txt", "r") as f:
data = f.readlines()
for i in data:
# 在date 中搜索符合正则表达的字符串并 将匹配的字符串存入变量 match 中
match = re.search(r'from%20t),(.*?),d))=(.*?)--+', i)
if match:
key = int(match.group(1)) # 取变量match中的第一个括号里的内容 (也就是上条语句中的 (.*?)中的内容)并转为10进制
value = chr(int(match.group(2))) # 取变量match中的第二个括号里的内容,并转为对应的字符
flag_ascii[key] = value # 使用字典,保存最后一次猜解正确的ascii码
for i in flag_ascii:
print(flag_ascii[i], end='')
2.2 流量包导出文件
通常在抓取流量的时候,会抓取到一些包含了文件传输的流量,我们可以通过wireshark
的导出对象功能,将传输的文件直接导出,步骤如下图所示:文件 -> 导出对象 ->HTTP(DICOM、IMF、SMB、TFTP)
。
如下图,可以看到流量包中包含了多个文件,我们可以选择导出单个文件,也可以全部导出。
也可使用foremost
全部导出。
2.3 USB流量
USB
流量指的是USB
设备接口的流量,攻击者能够通过监听USB
接口流量获取键盘敲击键、鼠标移动与点击、存储设备的明文传输通信、USB
无线网卡网络传输内容等等。在CTF
中,USB
流量分析主要以键盘和鼠标流量为主。
tshark
把cap data
提取出来:
tshark -r usb.pcap -T fields -e usb.capdata > usbdata.txt
Linux
下提取并去除空行:
tshark -r usb.pcap -T fields -e usb.capdata | sed '/^s*$/d' > usbdata.txt
完成后得到下图所示的数据。
键盘流量
数据包的数据字段有的是Leftover Capture Data
。
也有的是HID DATA
。使用tshark -r usb.pcap -T fields -e usbhid.capdata > usbdata.txt
进行导出。
键盘流量长度一般是八个字节。第1个字节的作用主要是判断是否按下
Shift
,Alt
,Control
等键,第2个字节是保留位,第3~8个字节是普通按键,但击键信息集中在第 3 个字节。(如果遇到多个按键一起按的情况,这个时候3~8字节可能会被利用起来。)键位映射关系参考:《USB键盘协议中键码》中的HID Usage ID[1]。
因此我们只需要将Leftover Capture Data
或HID DATA
字段的数据提取保存下来,然后将第三个字节的数据通过键位映射进行对照保存即可得到键盘输入的数据。
USB
键盘流量脚本如下,将pcap_file_path
变量修改为流量包的路径即可。
import sys
import os
presses = []
normalKeys = {"04": "a", "05": "b", "06": "c", "07": "d", "08": "e", "09": "f", "0a": "g", "0b": "h", "0c": "i",
"0d": "j", "0e": "k", "0f": "l", "10": "m", "11": "n", "12": "o", "13": "p", "14": "q", "15": "r",
"16": "s", "17": "t", "18": "u", "19": "v", "1a": "w", "1b": "x", "1c": "y", "1d": "z", "1e": "1",
"1f": "2", "20": "3", "21": "4", "22": "5", "23": "6", "24": "7", "25": "8", "26": "9", "27": "0",
"28": "<RET>", "29": "<ESC>", "2a": "<DEL>", "2b": "t", "2c": "<SPACE>", "2d": "-", "2e": "=", "2f": "[",
"30": "]", "31": "\", "32": "<NON>", "33": ";", "34": "'", "35": "<GA>", "36": ",", "37": ".", "38": "/",
"39": "<CAP>", "3a": "<F1>", "3b": "<F2>", "3c": "<F3>", "3d": "<F4>", "3e": "<F5>", "3f": "<F6>",
"40": "<F7>", "41": "<F8>", "42": "<F9>", "43": "<F10>", "44": "<F11>", "45": "<F12>"}
shiftKeys = {"04": "A", "05": "B", "06": "C", "07": "D", "08": "E", "09": "F", "0a": "G", "0b": "H", "0c": "I",
"0d": "J", "0e": "K", "0f": "L", "10": "M", "11": "N", "12": "O", "13": "P", "14": "Q", "15": "R",
"16": "S", "17": "T", "18": "U", "19": "V", "1a": "W", "1b": "X", "1c": "Y", "1d": "Z", "1e": "!",
"1f": "@", "20": "#", "21": "$", "22": "%", "23": "^", "24": "&", "25": "*", "26": "(", "27": ")",
"28": "<RET>", "29": "<ESC>", "2a": "<DEL>", "2b": "t", "2c": "<SPACE>", "2d": "_", "2e": "+", "2f": "{",
"30": "}", "31": "|", "32": "<NON>", "33": ":", "34": """, "35": "<GA>", "36": "<", "37": ">", "38": "?",
"39": "<CAP>", "3a": "<F1>", "3b": "<F2>", "3c": "<F3>", "3d": "<F4>", "3e": "<F5>", "3f": "<F6>",
"40": "<F7>", "41": "<F8>", "42": "<F9>", "43": "<F10>", "44": "<F11>", "45": "<F12>"}
def main():
# 文件路径参数
pcap_file_path = "E:\temp\usbdata"
data_file_name = "usb.dat"
# 通过流量包获取数据
os.system("tshark -r %s -T fields -e usb.capdata > %s" % (pcap_file_path, data_file_name))
# 读取数据
with open(data_file_name, "r") as f:
for line in f:
presses.append(line[0:-1])
# 数据处理
result = ""
for press in presses:
if press == '':
continue
# 对有冒号和无冒号两种情况进行区分
if ':' in press:
bytes_data = press.split(":")
else:
bytes_data = [press[i:i + 2] for i in range(0, len(press), 2)]
if bytes_data[0] == "00":
if bytes_data[2] != "00" and normalKeys.get(bytes_data[2]):
result += normalKeys[bytes_data[2]]
elif int(bytes_data[0], 16) & 0b10 or int(bytes_data[0], 16) & 0b100000: # 按下 shift 键
if bytes_data[2] != "00" and normalKeys.get(bytes_data[2]):
result += shiftKeys[bytes_data[2]]
else:
print("[-] Unknow Key : %s" % (bytes_data[0]))
print("[+] Found : %s" % result)
# clean the temp data
os.system("del %s /F" % data_file_name)
if __name__ == "__main__":
main()
鼠标流量
鼠标数据包的数据长度为4个字节,第一个字节代表按键,当取0x00
时,代表没有按键、为0x01
时,代表按左键,为0x02
时,代表当前按键为右键。第二个字节可以看成是一个signed byte
类型,其最高位为符号位,当这个值为正时,代表鼠标水平右移多少像素,为负时,代表水平左移多少像素。第三个字节与第二字节类似,代表垂直上下移动的偏移。
每一个数据包的数据区一般情况下有四个字节,第一个字节代表按键, 当取 0x00 时,代表没有按键;当取 0x01 时,代表按键为左键;当取 0x02 时,代表按键为右键。第二个字节可以看成是一个
signed byte
类型,其最高位为符号位,当这个值为正(小于127)时,代表鼠标水平右移多少像素,为负(补码负数,大于127小于255)时,代表水平左移多少像素。第三个字节与第二字节类似,代表垂直上下移动的偏移。第四个字节是拓展字节,代表滚轮数据 0 – 没有滚轮运动 ;1 – 垂直向上滚动一下 ;0xFF – 垂直向下滚动一下 2 – 水平滚动右键一次 ;0xFE – 水平滚动左键单击一下
这里数据包的数据字段HID Data
是六字节而不是四字节,在蓝牙鼠标设备的流量中,数据段的长度可能因不同的因素而变化,可能是四字节或六字节。这取决于设备的类型、协议和通信方式。需要我们去判断其中哪个字节产生作用。
这里对应的起作用的字节是2、3、4字节,因此x
是int(line[4:6], 16)
,y
是int(line[6:8], 16)
,鼠标键是int(line[2:4], 16)
。
import os
os.system("tshark -r test2.pcapng -T fields -e usbhid.data > usbdata.txt")
nums = []
keys = open('usbdata.txt', 'r')
result = open('result.txt', 'w')
posx = 0
posy = 0
for line in keys:
if len(line) == 0: # 忽略空行
continue
x = int(line[4:6], 16)
y = int(line[6:8], 16)
if x > 127:
x -= 256
if y > 120: # 这个参数控制单个字符的高度,如果高度过大导致字符过瘦,请调大
y -= 264 # 这个参数控制字符串的倾斜程度,如果向下倾斜就调高,如果向上倾斜就调低
posx += x
posy += y
btn_flag = int(line[2:4], 16) # 1 for left , 2 for right , 0 for nothing
if btn_flag == 1:
result.write(str(posx) + ' ' + str(-posy) + 'n')
print(result)
keys.close()
result.close()
os.system("gnuplot.exe -e "plot 'result.txt'" -p")
没有装gnuplot
的也可以到kali
里进行绘图。
2.4 WebShell流量
蚁剑流量
蚁剑(AntSword
)是一款开源的跨平台网站管理工具,用于进行渗透测试和网络攻击的测试。它具有图形化界面和多种功能,可以用于管理网站、执行命令、获取信息等。蚁剑在一些安全研究和渗透测试场景中被使用。
蚁剑流量如下图,传入的hack
参数值为@eval(@base64_decode($_POST[_0xf99a118e8e8a9]));
,接收POST
传入的参数_0xf99a118e8e8a9
进行base64
解码然后当做代码执行,这里hack
就是一句话木马连接的密码。
我们将参数_0xf99a118e8e8a9
的值进行解码,得到一系列PHP
代码,这里@ini_set("display_errors", "0");@set_time_limit(0);
就是蚁剑一个明显的流量特征。
2.5 协议
DNS协议
DNS
隧道是一种利用DNS
协议进行隐秘通信的技术。DNS(Domain Name System)
是用于将域名映射到IP
地址的协议,它通常用于解析域名以获取相应的IP
地址。然而,由于DNS
协议的一些特性,恶意用户可以利用其进行数据传输,从而绕过网络安全防御。
DNS
隧道的工作原理通常涉及将需要传输的数据拆分为较小的片段,然后通过DNS
查询或响应中的域名和子域名来隐藏数据。攻击者可以在域名解析请求中隐藏传输的数据,而服务器则将数据存储在DNS
记录中,随后攻击者可以通过查询响应来提取数据。
常见的DNS
隧道就将传输的数据编码然后切分,放在DNS
解析的域名的子域名中,我们就可以通过收集请求解析域名的子域名,然后解码获取数据。
如下图所示,有两个子域名,ZmxhZ3tlNj.i6ov08.dnslog.cn
和YyYWMxNTRj.i6ov08.dnslog.cn
。
拼接在一起得到ZmxhZ3tlNjYyYWMxNTRj
,解码得到flag{e662ac154c
,因此只需要将所有子域名拼接解码,就能够获取flag
。
SSL协议
SSL(Secure Sockets Layer)
是一种用于保护网络通信安全的加密协议。它在通信双方之间建立安全的加密通道,确保数据在传输过程中不被窃取、篡改或劫持。SSL
的升级版本是TLS(Transport Layer Security)
,TLS
在SSL
的基础上进行了改进和扩展。
SSL(Secure Sockets Layer)
使用密钥对进行加密和解密,以确保通信的安全性。公钥/私钥用于数据加密,私钥进行解密,公钥可以发布给任何人,私钥必须保密。
一般SSL
的题需要找到私钥对流量进行解密,有的在流量包中获取,有的会直接以附件的形式给出。
打开wireshark
,在编辑 -> 首选项 -> Protocols
处找到TLS
,在右侧红框处,上方可以导入RSA
密钥,下方可以导入密钥交换的日志文件,都可以解密流量。
设置完毕后,可以发现HTTP
流量已经被解密了。
蓝牙协议
OBEX(Object Exchange Protocol)
是一种用于在蓝牙设备之间交换对象的协议。它旨在支持不同设备之间的数据交换,如手机、计算机、打印机等。OBEX
协议定义了一组操作和命令,用于在蓝牙设备之间传输对象,这些对象可以是文件、联系人、日历事件等。
以下题为例,我们筛选一下obex
协议,发现存在一个what_you_want.7z
的文件
将Body
段的Value
复制出来解一下码转储得到文件。
十六进制解码得到文件。
解压提示密码是蓝牙协议的PIN
码,蓝牙设备之间的通信可以通过PIN
码(Personal Identification Number
)进行安全认证和配对。PIN
码是一种用于验证身份和建立安全连接的密码,通常由用户提供。在蓝牙设备配对时,PIN
码用于确保通信的安全性。
这里提一下wireshark
三个不同分组的区别。
1.分组详情(Packet Details):
•在Wireshark中,选择一个数据包(分组)以查看其详细信息。•在主窗口的底部,您会看到一个分组详情面板,其中显示了数据包的各个字段和属性。•可以展开不同的协议层,以查看每个协议层的详细信息。•分组详情面板提供了数据包的时间戳、源和目标IP地址、协议类型、数据长度等信息。•您还可以查看每个协议层的字段值,以及更深入的协议详细信息。
2.分组列表(Packet List):
•Wireshark的主窗口显示了捕获的数据包列表,称为分组列表。•每个数据包都在列表中显示为一行,包括时间戳、源和目标IP地址、协议类型、数据长度等信息。•您可以在分组列表中点击某个数据包以选中它,并在分组详情面板中查看其详细信息。
3.分组字节流(Packet Bytes):
•在分组详情面板中,您可以找到“Packet Bytes”或“Hex Stream”部分,它显示了数据包的十六进制字节流。•这些字节代表了数据包的实际内容,包括协议头部和载荷。•您可以选择某个特定的字节流部分,并在下方的ASCII视图中查看其对应的ASCII字符表示。
我们将搜索的筛选选到分组列表,搜一下PIN
,找到Sent PIN code Request Reply
,在数据段处就找到了交换的PIN
码为141854
。
WiFi协议
WiFi
协议,也称为无线局域网协议,是一组用于无线网络通信的标准和协议。它允许设备在不使用物理连接的情况下,通过无线信号进行数据传输和通信。WiFi
协议使得移动设备、计算机和其他网络设备能够在局域网范围内相互连接和通信。
像这种无线流量题一般要先知道无线流量包的密码,密码要么告诉你了,要么就是需要爆破。
这里使用Aircrack-ng
来进行爆破,爆破结果如下图所示,红框第一个是WPA
值,第二个是密码。
进行解密,获得的解密后的流量包就可以放到wireshark
进行分析了。
airdecap-ng ctf.pcap -e [爆破出来的WPA值] -p [爆破出来的密码]
airdecap-ng ctf.pcap -e ctf -p password1
ICMP协议
ICMP(Internet Control Message Protocol)
是一种网络协议,用于在IP
网络中传递有关网络状况的控制和错误信息。它通常在网络设备之间进行通信,以便进行网络故障排除、错误报告和网络管理。
在ICMP
协议中,数据段是ICMP
消息的一部分,用于携带特定的数据或信息。不同类型的ICMP
消息具有不同的数据段格式,用于传递与消息类型相关的信息。这也是我们需要重点关注的地方,尤其是当ICMP
大量出现报错的时候。ICMP
的数据包隐写一般在十六进制区域,传输的可以是单个flag
字符,加密的字符串的一部分,明文数据。
以下题为例。如下图中红框标出的部分,就是ICMP
消息的数据段,结合其他ICMP
消息,可以判断下面的那个黄框标注的f
和l
就是隐写的数据,不过在这题中,数据的顺序是打乱的,我们就需要关注其他数据变化的位置,发现了绿框标注的部分是从1依次增加的,这应该就是flag
数据的顺序,只需要将其他ICMP
对应位置的数据全部提取安装顺序拼接即可。
0x03 总结
可以在统计 -> 协议分级
处查看当前流量包的协议分布,从而判断入手点。
全局搜索一些关键词,比如ctf
、flag
、password
、key
等。
查看是否可以导出文件,foremost
是否能分离出文件。
如果http
流量比较多,可以判断是不是在进行WEB
扫描、后台目录爆破、后台账号爆破、WEBSHELL
上传、SQL
注入等攻击行为等。
以上只是总结了一些比较基础的考点,还有很多考点没有涉及,比如工控流量。在遇到实际题目的时候还得认真分析考点,还是需要多做题多总结多积累经验。
0x04免责声明
本文仅限于技术研究学习,切勿将文中技术细节用作非法用途,如有违者后果自负。
关于我们
“TERRA星环”安全团队正式成立于2020年,是贵州泰若数字科技有限公司旗下以互联网攻防技术研究为目标的安全团队。团队核心成员长期从事渗透测试、代码审计、应急响应等安服工作,多次参与国家、省级攻防演练行动,具备丰富的安服及攻防对抗经验。
团队专注于漏洞挖掘、漏洞研究、红蓝对抗、CTF夺旗、溯源取证、威胁情报、代码审计、逆向分析等研究。对外提供安全评估、安全培训、安全咨询、安全集成、应急响应等服务。
原文始发于微信公众号(TERRA星环安全团队):CTF | 流量分析基础题型总结
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论