题目介绍
环境搭建
deb http://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb http://mirrors.aliyun.com/debian-security bullseye-security main
deb-src http://mirrors.aliyun.com/debian-security bullseye-security main
deb http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib
2)复制sources.list到challenge、solver、generator目录下
3)修改Dockerfile文件
ADD sources.list /etc/apt/sources.list
4)复制文件到ubuntu20.04,进行编译
-
编译generator-base
-
make build
-
make test
输入make test 可以查看解题效果
相关知识
卫星姿态
卫星姿态描述方式
-
旋转矩阵(Rotation Matrix): 旋转矩阵是一个3×3的正交矩阵,用来表示姿态的旋转。对于卫星,通常用一个从卫星系到惯性系的旋转矩阵来描述姿态。 -
四元数(Quaternion): 四元数是一种数学工具,可以用来表示三维空间中的旋转。它是一个包含四个实数的向量,通常表示为 q = [w, x, y, z],其中w是标量部分,(x, y, z)是向量部分。四元数常用于在旋转中避免万向锁问题。 -
欧拉角(Euler Angles): 欧拉角是一组三个角度,通常用来描述三维空间中的旋转。这三个角度通常是绕固定坐标轴(通常是x、y、z轴)旋转的角度,可以是滚转角(Roll)、俯仰角(Pitch)、偏航角(Yaw)等。 -
方向余弦矩阵(Direction Cosine Matrix,DCM): 方向余弦矩阵是一个3×3的正交矩阵,用于描述两个坐标系之间的方向关系。在卫星姿态中,它可以用于描述卫星坐标系相对于惯性坐标系的方向。 -
轴角表示法(Axis-Angle Representation): 轴角表示法使用一个单位向量表示旋转轴,再加上一个旋转角度来描述旋转。这种表示方式简单且直观。
-
旋转矩阵
-
正交性(Orthogonality): 矩阵的行向量和列向量是单位向量,且互相垂直,即,其中是矩阵 的转置, 是单位矩阵。 -
行列式为1(Determinant = 1): 矩阵的行列式等于1,即 。
一个通用的三维旋转矩阵可以表示为:
-
绕X轴的旋转矩阵(Roll): -
绕Y轴的旋转矩阵(Pitch): -
绕Z轴的旋转矩阵(Yaw):
-
方向余弦矩阵
-
四元数
-
是实部(标量部分), -
是虚部,分别对应 轴的系数。
-
加法:
-
乘法:
-
欧拉角
1.滚转(Roll):绕Z轴旋转的角度,通常用符号 表示。
2.俯仰(Pitch):绕Y轴旋转的角度,通常用符号 表示。
3.偏航(Yaw):绕X轴旋转的角度,通常用符号 表示。
1. 是绕X轴旋转 的旋转矩阵。
2. 是绕Y轴旋转 的旋转矩阵。
3. 是绕Z轴旋转 的旋转矩阵。
Kabsch算法
-
中心化数据: 对两组点集进行平移,将它们的质心移动到原点,以消除平移的影响。 -
计算协方差矩阵: 计算两组点集的协方差矩阵。协方差矩阵描述了数据的分散和方向。 -
计算奇异值分解(SVD): 对协方差矩阵进行奇异值分解,得到左奇异向量、右奇异向量和奇异值。SVD是一种矩阵分解方法,将矩阵分解为三个矩阵的乘积。 -
计算旋转矩阵: 利用SVD结果,通过构造旋转矩阵,使其从一个点集到另一个点集的映射最优。这通常涉及选择左奇异向量和右奇异向量构造旋转矩阵。
解题过程
with open("test.txt","r") as f:
data = f.readlines()
dataA_list = []
data = data[:-1]
for t in data:
tmp = [float(num) for num in t.split(",")]
dataA_list.append(tmp)
import numpy as np
from scipy.spatial.transform import Rotation
import rmsd
from pwn import *
context.log_level = "debug"
def cal_matrix(stars):
dataAlist = get_dataAlist()
v_ref, v_obs = [], []
for idx,x,y,z in stars:
v_ref.append([dataAlist[idx][0],dataAlist[idx][1],dataAlist[idx][2]])
v_obs.append([x, y, z])
A = np.array(v_ref)
B = np.array(v_obs)
# 通过Kabsch算法获得旋转矩阵
R = rmsd.kabsch(A, B)
sol = Rotation.from_matrix(R).as_quat()
return ','.join(str(x) for x in sol)
def recvdata():
res = p.recvuntil(b"nn").split(b"n")
lines = []
for line in res:
if b'0.' in line:
id = int(line.split(b" : ")[0].strip())
r = line.split(b" : ")[1].split(b',t')
x = float(r[0])
y = float(r[1])
z = float(r[2])
lines.append([id, x, y, z])
return lines
def get_dataAlist():
with open("test.txt", "r") as f:
data = f.readlines()
dataA_list = []
data = data[:-1]
for t in data:
tmp = [float(num) for num in t.split(",")]
dataA_list.append(tmp)
return dataA_list
p = remote("172.17.0.1",31312)
for i in range(20):
stars = recvdata()
sol = cal_matrix(stars)
p.sendline(sol)
data = p.recvuntil('n')
# p.interactive()
socat -v tcp-listen:31312,reuseaddr exec:"docker run --rm -i -e SEED=3472657338860861762 -e FLAG=flag{1234} attitude:challenge" > run.log 2>&1
原文始发于微信公众号(山石网科安全技术研究院):【卫星安全系列五】attitude 赛题复现