数据安全1
处理数据解题脚本:
import re
# 分类规则函数
def classify(value):
if value.isdigit() and 1 <= int(value) <= 10000:
return 1 # 区间值1-10000
elif len(value) == 32 and re.match(r'^[a-f0-9]{32}$', value):
return 2 # 32位md5
elif re.match(r'^[\u4e00-\u9fa5]+$', value) and value not in ["男", "女"]:
return 3 # 中文但不是"男"和"女"
elif value in ["男", "女"]:
return 4 # "男"或"女"
elif len(value) == 8 and value.isdigit():
return 5 # 长度为8且全为数字
elif len(value) == 18 and (value.isdigit() or re.match(r'^\d{17}[a-zA-Z]$', value)):
return 6 # 长度为18且全为数字或仅包含1个字母
elif len(value) == 11 and value.isdigit():
return 7 # 长度为11且全为数字
else:
return 8 # 其余的放第八位
# 排序函数
def sort_line(line):
elements = line.split(',')
sorted_elements = sorted(elements, key=classify)
return '\t'.join(sorted_elements)
# 文件处理函数
def process_file(input_file, output_file):
with open(input_file, 'r', encoding='utf-8') as infile, open(output_file, 'w', encoding='utf-8') as outfile:
for line in infile:
sorted_line = sort_line(line.strip())
outfile.write(sorted_line + '\n')
# 输入文件名和输出文件名
input_file = 'res.txt'
output_file = 'sorted_res.txt'
# 处理文件
process_file(input_file, output_file)
print(f"数据已成功处理并保存到 {output_file}")
数据安全2
这道题是队友做的,摘抄网上记录之:
处理数据解题脚本:
(先用自带的tshark和python的pyshark模块进行wireshark文件的内容的读取)
import pyshark
import json
cap = pyshark.FileCapture(input_file='data.pcapng', tshark_path='D:\\Wireshark\\tshark.exe',use_json=True,include_raw=True)
file_path = 'data.pcapng'
json_data_list = []
for packet in cap:
print(packet)
try:
raw_packet = packet.get_raw_packet()
json_start = raw_packet.index(b'{"') # 查找 JSON 数据的起始位置
json_data = raw_packet[json_start:] # 提取 JSON 数据
print(json_data) # 调试输出 JSON 数据
json_data_list.append(json_data.decode('utf-8')) # 存储 JSON 数据到列表中
except Exception as e:
print(f"异常: {e}")
# 将提取的 JSON 数据保存到 JSON 文件中
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(json_data_list, f, ensure_ascii=False, indent=4)
得到了data.json文件,然后通过python进行数据清洗:
import csv
import json
xishu=[7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
jiaoyan=["1","0","X","9","8","7","6","5","4","3","2"]
alpha="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
digit="0123456789"
dot=[' ', '!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~']
phone=[734, 735, 736, 737, 738, 739, 747, 748, 750, 751, 752, 757, 758, 759, 772,778, 782, 783, 784, 787, 788, 795, 798, 730, 731, 732, 740, 745, 746, 755,756, 766, 767, 771, 775, 776, 785, 786, 796, 733, 749, 753, 773, 774, 777,780, 781, 789, 790, 791, 793, 799]
def check(data):
for i in dot:
if i in data[0] or i in data[1] or i in data[2] or i in data[3] or i in data[4] or i in data[5]:
return 0
for i in data[1]:
if i in digit or i in alpha:
return 0
if data[2]!="男" and data[2]!="女":
return 0
if data[3] not in data[4]:
return 0
if (data[2]=="男" and int(data[4][-2])%2==0) or (data[2]=="女" and int(data[4][-2])%2==1):
return 0
sum=0
for i in range(len(data[4])-1):
sum += (int(data[4][i])*xishu[i])
if jiaoyan[sum%11]!=data[4][-1]:
return 0
if int(data[5][:3]) not in phone:
return 0
return 1
# 读取 JSON 文件
with open('data.json', 'r', encoding='utf-8') as f:
data_list = json.load(f)
# 处理数据
new_data = []
for item in data_list:
# 将字典转换为列表
item=json.loads(item)
data = [item.get('username', ''), item.get('name', ''), item.get('sex', ''), item.get('birth', ''), item.get('idcard', ''), item.get('phone', '')]
print(data) # 打印数据以检查转换结果
if len(data) == 6:
if not check(data):
new_data.append(data)
# 将结果写入 CSV 文件
with open('person_data2.csv', mode='w', newline='', encoding='utf-8') as file:
csv_writer = csv.writer(file)
# 写入 CSV 文件的表头
csv_writer.writerow(['username', 'name', 'sex', 'birth', 'idcard', 'phone'])
# 写入数据
csv_writer.writerows(new_data)
print("检查结果已保存到 'person_data2.csv' 文件中。")
数据安全3
这道题是队友做的,摘抄网上记录之:
处理数据解题脚本:
(在输入了所有内容信息之后,还会有一个判断,说是用户名不存在或者是输入密码:。如果有密码我们就要把密码拿下来,然后再切片、截取到题目所需要的位置,如果没有就正常删除)
import csv
import urllib.parse
import hashlib
xishu=[7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
jiaoyan=["1","0","X","9","8","7","6","5","4","3","2"]
alpha="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
digit="0123456789"
dot=[' ', '!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~']
phone=[734, 735, 736, 737, 738, 739, 747, 748, 750, 751, 752, 757, 758, 759, 772,778, 782, 783, 784, 787, 788, 795, 798, 730, 731, 732, 740, 745, 746, 755,756, 766, 767, 771, 775, 776, 785, 786, 796, 733, 749, 753, 773, 774, 777,780, 781, 789, 790, 791, 793, 799]
def md5_encrypt(input_string):
# 创建一个md5 hash对象
md5_hash = hashlib.md5()
# 更新hash对象以字符串值(需要先编码为字节串)
md5_hash.update(input_string.encode('utf-8'))
# 获取十六进制数格式的hash值,并转换为小写
return md5_hash.hexdigest()
def check(data):
for i in dot:
if i in data[0] or i in data[1] or i in data[2] or i in data[3] or i in data[4]:
return 0
for i in data[2]:
if i in digit or i in alpha:
return 0
sum=0
for i in range(len(data[3])-1):
sum += (int(data[3][i])*xishu[i])
if jiaoyan[sum%11]!=data[3][-1]:
return 0
if int(data[4][:3]) not in phone:
return 0
return 1
def read_log_until_next_bracket(filepath):
new=[['username','password','name','idcard','phone']]
"""
读取指定的日志文件,在遇到包含'username'的行时,继续读取直到遇到下一个'['符号或文件结束。
"""
try:
with open(filepath, 'r', encoding='utf-8') as file:
current_block = "" # 用于存储从'username'开始到'['之前的所有内容
reading = False # 标记是否开始读取块
for line in file:
if "username" in line:
# 如果当前行包含'username',则开始读取块
reading = True
current_block += line # 添加当前行到块中
elif "\\xe6\\x82\\xa8\\xe8\\xbe\\x93\\xe5\\x85\\xa5\\xe7\\x9a\\x84\\xe7\\x94" in line:
current_block = ""
reading = False
elif reading:
# 如果已经开始读取块,则继续添加行到块中
if "\\xe5\\xaf\\x86\\xe7\\xa0\\x81\\xe4\\xb8\\xba" in line:
# 如果当前行包含'[',则停止读取块并打印
# 注意:这里只打印到'['之前的部分(如果需要)
# 或者你可以选择保留整个块直到'['
idx = line.find("\\xe5\\xaf\\x86\\xe7\\xa0\\x81\\xe4\\xb8\\xba")
if idx != -1: # 确保'['确实存在
current_block += line
tmp=(current_block.strip()[143:]) # 打印并去除首尾空白
edx = line
tmp=(tmp.split('&'))
tmp[3]=(tmp[3].split('\n'))
tmp.append(tmp[3])
tmp[3]=tmp[4][0]
tmp[4]=tmp[4][-1][-30:][:-2]
tmp[4]=tmp[4].split(": ")[1]
tmp.append(tmp[4])
tmp[4]=tmp[3]
tmp[3]=tmp[2]
tmp[2]=tmp[1]
tmp[1]=tmp[5]
tmp.pop()
tmp[0]=urllib.parse.unquote(tmp[0][9:])
tmp[2] = urllib.parse.unquote(tmp[2][5:])
tmp[3] = urllib.parse.unquote(tmp[3][7:])
tmp[4] = urllib.parse.unquote(tmp[4][6:])
if not check(tmp):
current_block = ""
tmp=[]
reading = False
continue
if len(tmp[0])==1:
pass
elif len(tmp[0])==2:
tmp[0]=tmp[0][0]+"*"
else:
tmp[0]=tmp[0][0]+(len(tmp[0])-2)*"*"+tmp[0][-1]
tmp[1]=md5_encrypt(tmp[1])
if len(tmp[2])==2:
tmp[2]=tmp[2][0]+"*"
else:
tmp[2]=tmp[2][0] + (len(tmp[2])-2)*"*"+tmp[2][-1]
tmp[3]="******"+tmp[3][6:10]+"********"
tmp[4]=tmp[4][:3]+"****"+tmp[4][-4:]
new.append(tmp)
current_block = "" # 重置块
reading = False # 停止读取
else:
current_block += line # 否则,继续添加整行到块中
print(new)
with open("person_data2.csv", mode='w', newline='', encoding='utf-8') as file:
csv_writer = csv.writer(file)
csv_writer.writerows(new)
except FileNotFoundError:
print(f"文件 {filepath} 未找到。")
# 调用函数,传入日志文件路径
read_log_until_next_bracket('error.log')
题目:miaoro
附件是一个流量包:直接扔进wireshark 可正常打开。跟踪tcp流,在第4个流看到攻击流量,通过返回的信息<h3>Roles you DON’T have</h3>,查询后出现apache Shiro 关键字,因此考虑是Shinro 相关漏洞利用。
继续跟踪tcp流量,在第6个流最后一个请求后返回为0 不再提示需要登录,因此漏洞利用成功,继续跟踪之后的流量,看一下都做了哪些操作:
在第7个流看到新的头部参数 GWHT 明显带有YCB2024的提示后面为base64,因此解码得到,执行了 whoami 命令,并得到正确的返回:
第8个流执行 echo 1234 返回0 执行成功
第9个流执行 net user 查询系统用户
第10个流执行 echo Th15_11111111s_pP@sssssw000rd!!!>pass.txt 返回0执行成功。这里“Th15_11111111s_pP@sssssw000rd!!!”是一个重要的信息。
第11个流 获取了test.txt 文件正常返回,没啥信息
第12个流 执行ipconfig
第13个流 获取secret.txt文件,需要将该文件导出。
通过对返回的内容拼接后进行base64解码 发现关键信息:
存在倒序的zip数据包特征,处理后得到一个加密的压缩包,输入前面字节10获得的密码,解压得到一张png图片
图片图像看上去比较混乱,由于是png图片,观察图片格式,对图片的高宽进行互换
调整宽带为1404 并调整高度为380(随便,宽度要对):
通过在线试图得到猫字符的线索:
跟随这张图片得到链接
https://shejijingsai.com/2019/07/277603.html
在页面中翻查到,A-Z的猫字符原设计图,根据这个设计图,识别图片中为:EBOFDELQDIAA}得到后一半flag
还差一半的flag ,Shiro是通过cookiela加载攻击载荷,之前分析第6个流最后一次请求返回为0显示攻击成功,之后的cookie都使用了这个攻击载荷,因此我们想看这个攻击载荷中是否存在信息,但cookie是加密的需要进行解密,通过 https://vulsee.com/tools/shiroDe/shiroDecrypt.html 可实现内置的64个key进行爆破,最终在攻击载荷中我们得到了前半部分flag:DASCTF{B916CFEB-C40F-45D6-A7BC-
最终本题的Flag为:DASCTF{B916CFEB-C40F-45D6-A7BC-EBOFDELQDIAA}
题目:so much
解压附件得到一个c2hpZnQh.ad1的文件,文件名像是base编码过的,解码后得到shift!,这是一个很重要的提示,后续解题过程中要用到。通过010EDITOR打开,观注文件头和文件尾的信息
这里提示 the key is 1234567 really?,结合文件名的shift!,可以想到有一个密码是!@#¥%……&.
根据已知信息继续跟进:文件头部提示ADCRYPT。通过查询得知需要使用FTK Imager打开
通过FTK Imager 4.7.14(低版本打开会报错) 取证工具打开镜像,输入前面得知的密码:!@#$%^&,成功打开磁盘镜像。这个磁盘镜像总计有344个后缀名为crypto的加密文件,需要解密。导出文件后,发现,文件名为顺序增长,代表了一个顺序,而文件被修改时间只有分别为16:19 和16:20这明显代表了二进制数据。同时我们通过导出对所有文件的hash值列表,发现只有2个hash值,这也印证了我们的猜测。
根据已有的信息,按照文件名顺序进行排序,并替换文件0的hash 为0 另外一个hash值为1,得到下图:
组合后的二进制串为:
01110100011010000110010101011111011010110110010101111001010111110110100101110011010111110011011100110000001100000011001000110010001110010110001100110000001101010011001101100010001101000110010101100010011000100110001101100110001100010110000100110011011000110110001100110011001101110110001100110011001110000011100101100011001101000110011001100001
得到一个key:the_key_is_700229c053b4ebbcf1a3cc37c389c4fa,因此判断需要这个key对crypto后缀的文件进行解密。
查询crypto后缀文件解密工具
由此可知下载encrypto工具,安装后对文件0.crypto 和1.crypto进行解密:
由此得到完整的flag: DASCTF{85235bd803c2a0662b771396bce9968f}
题目:hiden
解压附件得到两个文件,一个为txt 一个为wav文件;
其中txt文件名比较奇怪,应该是解题的提示,txt文件内容无法解读:
看文件内容和排列,貌似为一段代码进行了字符替换。判断首行为6字符+空格+4字符,加之本地另外一个附件为.wav 根据这个特征假定首行为python 代码 import wave,通过假设,发现 G与i直间的ASCII值相差为34.由于文件名为60=?+?,因此初步判断经过2次rot变换,因此通过该值可得到60-34=?*2,得出其中一个为13,另一个为47.通过执行rot47后再次执行rot13,得到还原后的代码:
import wave
with open('flag.txt', 'rb') as f:
txt_data = f.read()
file_len = len(txt_data)
txt_data = file_len.to_bytes(3, byteorder = 'little') + txt_data
with wave.open("test.wav", "rb") as f:
attrib = f.getparams()
wav_data = bytearray( f.readframes(-1) )
for index in range(len(txt_data)):
wav_data[index * 4] = txt_data[index]
with wave.open("hiden.wav", "wb") as f:
f.setparams(attrib)
f.writeframes(wav_data)
解读代码:
打开一个flag.txt,读取文本内容,并统计文本长度。
txt_data = file_len.to_bytes(3, byteorder = ‘little’) + txt_data意思是封装新txt_data字符串,将字符串长度附加在原来文本之前,长度为3字节,little参数表示存储格式为小端存储,即最高有效位存储在3字节的末端,最低有效位存储在3字节的开头具体如下:比如文本DASCTF{qa-2236-v7-9ffg-wdfhk}长度为29,经过该运算后,变成:
‘\x1d\x00\x00DASCTF{qa-2236-v7-9ffg-wdfhk}’ 其中\x1d 为长度存储在高位上。
将字符串格式化后,脚本打开了名为test.wav的文件,并读取音频帧并将其转换为可变的字节数组(bytearray),通过遍历文本数据,将其字节逐个写入音频数据的每隔4个字节的位置。
根据解读结果我们可以按照以下两种方式进行:
0X01:
由于是直接写入,因此并未对flag内容进行改变,因此直接使用010editer打开hiden.wav,翻查
每隔3个字节取一个字符得到flag:DASCTF{12jkl-456m78-90n1234}}
0x02:
编写脚本从hiden.wav中还原flag.txt:
import wave
with wave.open('hiden.wav','rb') as f:
attrib=f.getparams()
data=bytearray(f.readframes(-1))
txt_len=int.from_bytes(data[0:3],'little') +30//这里有坑,长度被修改了,因此+30
contents=bytearray()
for index in range(3,txt_len):
contents.append(data[index*4])
print(contents)
得到flag:DASCTF{12jkl-456m78-90n1234}