2024 ByteCTF
ByteCTF
极限逃脱
题目描述:本题需要通过动态调试分析出要输入的内容,可能在某些地方会有提示出现。
这是一个IOS逆向,因为没有设备只能静态分析
流程和安卓逆向大概一致 解压拖进ida
提示输入flag格式 根据"-"进行切割
其实就是uuid格式,正确输入后有一个赋值操作
然后往下看注意到
{%@-%@-%@-%@-%@} part5,part2,part3,part4,part5
计算这个字符串的sha256
后面是根据每一部分的长度进行切片操作,然后是一个替换
注意每个部分的起始位置
最后进行比较
最后切片进行替换
a="6c9838a3c6810bdb2633ed5910b8547c09a7a4c08bf69ae3a95c5c37f9e8f57e"
#print 1 to 9
for i in range(1,9):
print(a[i],end='')
print("-",end='')
for i in range(9,13):
print(a[i],end='')
print("-",end='')
for i in range(5,9):
print(a[i],end='')
print("-",end='')
for i in range(5,9):
print(a[i],end='')
print("-",end='')
for i in range(5,17):
print(a[i],end='')
# c9838a3c-6810-8a3c-8a3c-8a3c6810bdb2
ByteBuffer
FlatBuffers 的序列化格式
FlatBuffers 就是把对象数据,保存在一个一维的数组中,将数据都缓存在一个 ByteBuffer 中,每个对象在数组中被分为两部分。
元数据部分:负责存放索引。真实数据部分:存放实际的值
使用 4 字节的 UInt 来存储 10 位数字的整数。
FlatBuffers 对序列化基本使用原则:
- 小端模式。FlatBuffers 对各种基本数据的存储都是按照小端模式来进行的,因为这种模式目前和大部分处理器的存储模式是一致的,可以加快数据读写的数据。
- 写入数据方向和读取数据方向不同
从给的二进制文件看
一部分给的是dot数据
另一部分给的是Edge数据
对应着点和边,我们需要恢复原来的数据
dot数据 每4位为一组
这里采用小端序排序
x1=06 40=1600 y1=4B=75 依次每四位可以拿到所有的点的数据
同理 在边上
Edge #103对应着 0x77 0x75 即点119 117
根据原理可以写出梭哈脚本
cnt = 0
with open("ByteBuffer.bin", "rb") as file:
ans = file.read()
# print(ans)
import struct
edge_index = 0x3AC
dot_index = 0x1230
while edge_index < 0x120C:
tmp = struct.unpack("<Q", ans[edge_index : edge_index + 8])[0]
edge_index += 8
dot1 = struct.unpack("<L", ans[edge_index : edge_index + 4])[0]
edge_index += 4
dot2 = struct.unpack("<L", ans[edge_index : edge_index + 4])[0]
edge_index += 4
edge_index += 4
length = ((struct.unpack("<L", ans[edge_index : edge_index + 4])[0] + 4) // 4) * 4
# print(length)
edge_index += 4
name = ans[edge_index : edge_index + length].decode()
print("line_name:" + name)
print("linked_dot1:" + str(dot1))
print("linked_dot2:" + str(dot2))
edge_index += length
print("line_name:" + "Edge #0")
print("linked_dot1:" + str(2))
print("linked_dot2:" + str(1))
while dot_index < 0x1F88:
tmp = struct.unpack("<L", ans[dot_index : dot_index + 4])[0]
dot_index += 4
x1 = struct.unpack("<L", ans[dot_index : dot_index + 4])[0]
dot_index += 4
y1 = struct.unpack("<L", ans[dot_index : dot_index + 4])[0]
dot_index += 4
dot_index += 4
length = ((struct.unpack("<L", ans[dot_index : dot_index + 4])[0] + 4) // 4) * 4
# print(length)
dot_index += 4
name = ans[dot_index : dot_index + length].decode()
print("dot_name:" + name)
print("x:" + str(x1))
print("y:" + str(y1))
dot_index += length
print("dot_name:" + "Dot #2")
print("x:" + str(0x19))
print("y:" + str(0x4B))
得到
然后根据点和线的关系进行绘图
import matplotlib.pyplot as plt
# 读取数据
dots = {}
edges = []
with open("1(1).txt", "r") as f:
lines = f.readlines()
for i in range(0, len(lines), 3):
line = lines[i].strip()
if line.startswith("dot_name"):
dot_name = line.split(":")[1].split("#")[1]
line2 = lines[i + 1].strip()
line3 = lines[i + 2].strip()
x = int(line2.split(":")[1])
y = int(line3.split(":")[1])
dots[dot_name] = (y, x)
elif line.startswith("line_name"):
line_name = line.split(":")[1]
line2 = lines[i + 1].strip()
line3 = lines[i + 2].strip()
dot1 = line2.split(":")[1]
dot2 = line3.split(":")[1]
edges.append((dot1, dot2))
# 绘制点
for dot_name, (x, y) in dots.items():
plt.plot(x, y)
# 绘制线段
for dot1, dot2 in edges:
x1, y1 = dots[dot1]
x2, y2 = dots[dot2]
plt.plot([x1, x2], [y1, y2], "b-")
# 设置标签
plt.xlabel("X")
plt.ylabel("Y")
plt.legend()
plt.show()
得到flag