记录一道 sql 注入流量分析题
题目:一个流量包 ddos.pcapng
在ddos中寻找黑客的真实意图。提交flag格式:flag{xxxx)。
思路:
分析一下流量包,过了 http 请求,不难发现,黑客在尝试登入,那肯定就是在破解密码了,那我们可以看看登入成功的包
然后,继续往下看流量包,可以发现登入成功的数据包
并且请求包有在做一些 sql 注入的操作
然后我们就想办法吧登入成功的数据包提取出来,观察一下,发现在进行 sql 注入时能发现,登录成功的数据包长度是 620,登录失败的长度是 640,那我们可以通过 frame.len == 620
来过滤出登录成功的返回包,那现在的问题是,我们需要的是请求包里面的东西,我们能发现返回包中是能看到来自那条请求包的,写脚本提取出来就行
import os
import json
import re
from urllib.parse import unquote
os.system('tshark -r ddos.pcapng -Y "frame.len == 620" -e http.request_in -T json > 登录成功.json')
with open('登录成功.json', 'r') as f:
data = json.load(f)
frame_numbers = []
for num in data:
frame_number = num['_source']['layers']['http.request_in'][0]
frame_numbers.append(frame_number)
print(frame_numbers)
接下来就行根据请求包的 id 去取出我们想要的数据就行
# 导出所有 post 请求的 urlencoded-form.value 和 frame.number
os.system('tshark -r ddos.pcapng -Y "http.request.method == POST" -e urlencoded-form.value -e frame.number -T json > post.json')
'''
现在根据我们登入成功的 id 去过滤出对应的数据
'''
with open('post.json', 'r') as f:
data = json.load(f)
msg = []
for num in data:
try:
frame_number = num['_source']['layers']['frame.number'][0]
if frame_number in frame_numbers:
value = num['_source']['layers']['urlencoded-form.value'][0]
msg.append(unquote(value))
except KeyError:
# 如果某个数据项缺少 'frame.number' 或 'urlencoded-form.value',则跳过该项
continue
# 将数据写入 result.txt 进行分析
with open('result.txt', 'w') as f:
for m in msg:
f.write(m + '\n')
然后分析 result.txt 可以发现基本都在做,sql 注入,现在找到我们有用的就行,很明显,黑客是要爆破密码的,所以搜索一下就行可以发现如下:
aaa'/**/OR/**/NOT/**/ORD(MID((SELECT/**/IFNULL(CAST(password/**/AS/**/NCHAR),0x20)/**/FROM/**/web.users/**/ORDER/**/BY/**/password/**/LIMIT/**/0,1),1,1))>96#
然后,就将类似这些数据提取出来,取值就行
# 我们需要的数据提取出来
psassword = []
for i in msg:
if '''aaa'/**/OR/**/NOT/**/ORD(MID((SELECT/**/IFNULL(CAST(password/**/AS/**/NCHAR),0x20)''' in i:
psassword.append(i)
'''
/0,1),6,1))>51#
'''
num = {}
pat = pat = r"\),(\d+),1\)\)>(\d+)#"
for p in psassword:
re_ = re.compile(pat)
match = re_.search(p)[1]
match1 = int(re_.search(p)[2])
# 都是取最后一次的才是正确的
num[match] = match1
print(num)
flag=""
for i in num:
flag+=chr(num[i])
print("flag:", flag)
完整代码
import os
import json
import re
from urllib.parse import unquote
'''
这里有个问题,外面必须是单引号,里面必须是双引号,不能换
'''
# 这是提取数据的命令,运行一次提取出来就可以注释了,不然后面调试可能有点慢
os.system('tshark -r ddos.pcapng -Y "frame.len == 620" -e http.request_in -T json > 登录成功.json')
with open('登录成功.json', 'r') as f:
data = json.load(f)
frame_numbers = []
for num in data:
frame_number = num['_source']['layers']['http.request_in'][0]
frame_numbers.append(frame_number)
# print(frame_numbers)
# 导出所有 post 请求的 urlencoded-form.value 和 frame.number
os.system('tshark -r ddos.pcapng -Y "http.request.method == POST" -e urlencoded-form.value -e frame.number -T json > post.json')
'''
现在根据我们登入成功的 id 去过滤出对应的数据
'''
with open('post.json', 'r') as f:
data = json.load(f)
msg = []
for num in data:
try:
frame_number = num['_source']['layers']['frame.number'][0]
if frame_number in frame_numbers:
value = num['_source']['layers']['urlencoded-form.value'][0]
msg.append(unquote(value))
except KeyError:
# 如果某个数据项缺少 'frame.number' 或 'urlencoded-form.value',则跳过该项
continue
# 将数据写入 result.txt 进行分析
with open('result.txt', 'w') as f:
for m in msg:
f.write(m + '\n')
# 我们需要的数据提取出来
psassword = []
for i in msg:
if '''aaa'/**/OR/**/NOT/**/ORD(MID((SELECT/**/IFNULL(CAST(password/**/AS/**/NCHAR),0x20)''' in i:
psassword.append(i)
'''
/0,1),6,1))>51#
'''
num = {}
pat = pat = r"\),(\d+),1\)\)>(\d+)#"
for p in psassword:
re_ = re.compile(pat)
match = re_.search(p)[1]
match1 = int(re_.search(p)[2])
# 都是取最后一次的才是正确的
num[match] = match1
print(num)
flag=""
for i in num:
flag+=chr(num[i])
print("flag:", flag)
flag:flag{Lsadu21b2ud2b}