跳转至

Attitude

attitude

这一关给了一个星表文件 txt,一个链接地址:172.17.0.1:31312

环境搭建

make build  #构建镜像
mkdir test  #用来存放题目给的星表文件
#注意Docker挂载的路径要改一下,生成星表文件
docker run --rm -v /home/iot/Desktop/HAS/attitude/test:/out -e SEED=3472657338860861762  attitude:generator
#运行环境
socat -v tcp-listen:31312,reuseaddr exec:"docker run --rm -i -e SEED=3472657338860861762  -e FLAG=flag{1234}  attitude\:challenge"

环境搭建起来之后 nc 连接上去会给出星跟踪器采集的一组恒星的视轴向量,我们需要输入一组浮点数(用四元数来描述姿态)

1672493512930-de3cfbb1-0f4b-4e31-a6b6-a21bc8231df6.png

给出的 test.txt 中记录的是一颗恒星的相关信息,一行代表一颗恒星的相关信息,每行有 4 个值分别表示天球参考系中指向某颗恒星的单位向量的 XYZ 坐标值和星等值

题目的意思是,给了恒星在天球参考系中的位置信息,给了星跟踪器采集的恒心相对于卫星来说的位置信息,根据这俩值做个转化,确定出卫星在天球参考系中的位置信息

涉及太多额外的知识了叭,暂时先知道是咋回事吧,学不动

EXP

先处理一下 test.txt 生成一个 python 列表

(echo -n catalog = [; sed '/^$/d;s/^/[/;s/$/],/' test.txt ; echo ']') > has_catalog.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-  
import numpy as np
from scipy.spatial.transform import Rotation
import pwn
import rmsd
from has_catalog import *

lines = []

#从服务器获取一组星跟踪器采集的向量,存在一个二位列表中
def nextr():
    rez = p.recvuntil(b'\n\n').split(b'\n')
    lines = []
    for line in rez:
        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 compute_matrix(stars):
    v_ref, v_obs = [], []
    for idx, x, y, z in stars:
        v_ref.append([catalog[idx][0], catalog[idx][1], catalog[idx][2]])  #根据idx找出恒星在天球参考系的x y z
        v_obs.append([x, y, z])    #卫星拍摄的恒星的x y z

    A = np.array(v_ref)   #天球参考系向量组
    B = np.array(v_obs)   #星跟踪器观测向量组
    A -= rmsd.centroid(A) #计算质心
    B -= rmsd.centroid(B) #计算质心
    R = rmsd.kabsch(A, B)  #通过kabsch算法获得最佳旋转矩阵
    sol = Rotation.from_dcm(R).as_quat()  #将旋转矩阵转换为四元数
    return ','.join(str(x) for x in sol)

p = pwn.remote('172.17.0.1',31312) #建立连接

running = True
while running:                       #循环求解,直到数量为0
    stars = nextr()
    sol = compute_matrix(stars)
    p.sendline(sol)
    data = p.recvuntil('\n')
    if data.startswith(b'0 Left'):  #如果剩余的数量是0表示结束了
        while True:
            try:
                print(p.recv())
            except:
                running = False   #running写为False
                break
p.close()

原文: https://www.yuque.com/hxfqg9/iot/ea1wx6nkq9obi63q