感谢ChatGPT在我学习过程中给我的帮助
Hack-A-Sat 是美国办的太空信息安全挑战,最近发现本书《Hack-A-Sat太空信息安全挑战赛深度题解》讲2020年预选赛的题解,在 github 上找到了题目的源文件,慢慢复现一遍
进入 generator-base 之后运行把基础的镜像生成出来
docker build -t generator-base .
然后进入 beckley 文件夹把 solver 和 challenge 文件夹中的 Dockerfile 的 get-pip.py 的 url 换一下,换成:
https://bootstrap.pypa.io/pip/2.7/get-pip.py
我把我用的最终版本放在 github 了,用这个就不用改 url 了
https://github.com/yichen115/hackasat-qualifier-2020
使用 make build 生成镜像,也可以用 make challenge 只生成题目镜像,然后使用 apt install socat 安装 socat,使用以下命令运行环境
socat -v tcp-listen:19020,reuseaddr exec:"docker run --rm -i -e SERVICE_HOST=172.17.0.1 -e SERVICE_PORT=19021 -e SEED=1000 -e FLAG=flag{zulu49225delta:GG1EnNVMK3-hPvlNKAdEJxcujvp9WK4rEchuEdlDp3yv_Wh_uvB5ehGq-fyRowvwkWpdAMTKbidqhK4JhFsaz1k} -p 19021:80 beckley:challenge"
咱也不知道这题是啥意思,按照 wp 先验证一下能不能拿到 flag,新开一个终端运行得到一些提示
nc 172.17.0.1 19020
然后运行下面的命令得到 flag
curl http://172.17.0.1:19021/cgi-bin/HSCKML.py?CAMERA=-77.03,38.89,430000,40.3694166667,63.5358055556 -H 'User-Agent: GoogleEarth/7.3.2.5815(X11;Linux (5.2.0.0);en;kml:2.2;client:Pro;type:default)' -H 'Accept: application/vnd.google-earth.kml+xml, application/vnd.google-earth.kmz, image/*, */*' -H 'Accept-Language: en-US, *' -H 'Connection: keep-alive'
如图所示
按照下面这篇文章的描述,这道题环境搭建起来后你能看的就只有 static 文件夹里面的 remote.kml 和一个地址 172.17.0.1 19020
https://blog.csdn.net/hackasat/article/details/127814688
就从这两个提示开始入手,nc 连接之后获得了如下信息:
We've captured data from a satellite that shows a flag located at the base of the Washington Monument.
The image was taken on March 26th, 2020, at 21:53:13
The satellite we used was:
REDACT
1 13337U 98067A 20087.38052801 -.00000452 00000-0 00000+0 0 9995
2 13337 51.6460 33.2488 0005270 61.9928 83.3154 15.48919755219337
Use a Google Earth Pro KML file to 'Link' to http://172.17.0.1:19021/cgi-bin/HSCKML.py
and 'LookAt' that spot from where the satellite when it took the photo and get us that flag!
大意是太空中有颗卫星于 2020 年 3 月 26 日 21:53:13 按照特定的视角拍到了华盛顿纪念碑,让我们通过 Google Earth Pro 的 KML 文件模拟卫星拍摄时的位置看一下华盛顿纪念碑从而获得 flag。Google Earth Pro 可以在下面这个链接下载到
https://www.google.com/earth/versions/
谷歌官方的介绍:
https://developers.google.com/kml/documentation/kmlreference
可以在谷歌地球上新建一个地标,试试 kml 文件是怎么创建的,点击这个黄色的工字钉
然后随便在地图上找个点,把工字钉拖上去,随便写点名称和说明
然后将右键地图上的工字钉,保存的时候选择类型是 kml 格式
可以看到主要的位置信息就是在 LookAt 这个标签里面的,LookAt 就是你从哪个视角来观看这个地标的
对应的,在题目给的 remote.kml 文件中也是要我们修改这个位置的信息
longitude 是经度,不用解释吧
latitude 是纬度,不用解释吧
altitude 是海拔,不用解释吧
heading 是飞行器前进的方向,看下面的图示,就是按照左边这个图来的
tilt 是卫星与地球表面法线之间的角度
range 是卫星距离目标的距离
altitudeMode 是高度模式,这个不用咱们改
还有一个在这里面没有体现出来的 <Link> 标签,这个是用来通过网络链接获取 KML 文件,那我们先把这个 link 换成 nc 连接上后获得的地址
http://172.17.0.1:19021/cgi-bin/HSCKML.py
选择文件 -> 打开 -> remote.kml 把临时位置的层级全部展开,可以看到一个地标是 Keep Looking... 说明咱还没找到正确的观察视角
接下来我们研究研究 LookAt 要怎么设置,就是卫星拍到华盛顿纪念碑时的位置,相关线索就是 nc 上去输出的两行信息,这个叫做双线元素集 (TLE),好家伙,专业知识来了
https://www.space-track.org/documentation#/tle
卫星双线元素集(TLE)是一种编码格式,用于在两行中存储卫星的轨道参数。这些轨道参数是由观测到的卫星运动数据计算得出的。TLE 可以用来预测卫星的运动,并用于各种应用,例如卫星导航和通信(本段由ChatGPT生成)
我们做个表说明一下这些数据的含义(感觉给的这些数据对不太起来,这个表建议阅读原文观看)
REDACT
1 13337U 98067A 20087.38052801 -.00000452 00000-0 00000+0 0 9995
2 13337 51.6460 33.2488 0005270 61.9928 83.3154 15.48919755219337
第 0 行 |
||
列 |
数据 |
描述 |
1-24 |
REDACT |
基于卫星目录的信息的对象的通用名称 |
第 1 行 |
||
列 |
数据 |
描述 |
1 |
1 |
行号 |
3-7 |
13337 |
北美防空司令部 的卫星编号 |
8 |
U |
U 非保密的,C 机密的,S 绝密的 |
10-17 |
98067A |
国际卫星标识符,98表示年,067表示这年第几次发射,A 表示卫星的第一部分 可以参考:https://www.zhihu.com/question/268074570/answer/332683919 |
19-32 |
20087.38052801 |
TLE历时,轨道数据的时间点,20 表示 20 年,087表示第 87 天(我咋算的 86 天),38052801 表示这一天的时刻 |
34-43 |
-.00000452 |
平均运动对时间的一阶导数 |
45-52 |
00000-0 |
平均运动对时间的二阶导数(假设有小数点) |
54-61 |
00000+0 |
BSTAR拖调制系数 |
63 |
0 |
美国空军空间指挥中心内部使用的为 1,美国空军空间指挥中心以外公开使用标识为 0 |
65-68 |
999 |
星历编号,星历编号是TLE数据按新发现卫星的先后顺序的编号 |
69 |
5 |
校验和,指这一行的所有非数字字符,按照“字母、空格、句点、正号= 0;负号=1”的规则换算成0和1后,将这一行中原来的全部数字加起来,以10为模计算后所得的和 |
第 2 行 |
||
列 |
数据 |
描述 |
1 |
2 |
行号 |
3-7 |
13337 |
北美防空司令部 的卫星编号 |
9-16 |
51.6460 |
轨道的交角度数,指天体的轨道面和地球赤道面之间的夹度 |
18-25 |
33.2488 |
升交点赤经度数,指从地球的球心点望过去,升交点的赤经坐标 |
27-33 |
0005270 |
轨道离心率,指卫星椭圆轨道的中心点到地球的球心点的距离(c)除以卫星轨道半长轴(a)得到的一个0(圆型)到1(抛物线)之间的小数值 |
35-42 |
61.9928 |
近地点角距,指在卫星的轨道平面内,从升交点到近地点按照卫星运行方向所走过的角度 |
44-51 |
83.3154 |
平近点角度数,指平近点角与真近点角和偏近点角之间的关系,即卫星在椭圆轨道上的瞬间位置 |
53-63 |
15.48919755 |
平均运动,指在一个太阳日内(24h),卫星在它的轨道上绕了多少圈 |
64-68 |
21933 |
在轨圈数,指卫星从发射到 TLE 数据记录的 TLE 历时之间卫星在轨道上绕行的总圈数 |
69 |
7 |
校验和 |
我们需要通过给出的 TLE 数据填充 LookAt 中的信息,其中 longitude 和 latitude 是经纬度,直接在谷歌地球中找就行了,按照上面添加地标的方式添加保存为 KML 文件,再查看即可,纬度:38.88937190244597,经度:-77.03521514741283
同时因为 altitudeMode 是 clampToGround,表示可以忽略高度,因此 altitude 是 0
这意味着我们只需要解析出来 heading、tilt、range 即可,我们用 Python 来实现,参考这个库:
https://rhodesmill.org/skyfield/earth-satellites.html
首先从字符集加载 TLE 数据,然后根据时间确定卫星在头顶的位置(注意这里的时间要用 nc 上去之后题目给我们的时间而不是 TLE 解析的时间),这里得到的位置是地心天球参考系中卫星的 x、y、z 坐标,也就是说是以地心为观察者视角得到的卫星的位置
from skyfield.api import EarthSatellite, load, Topos
ts = load.timescale()
line1 = '1 13337U 98067A 20087.38052801 -.00000452 00000-0 00000+0 0 9995'
line2 = '2 13337 51.6460 33.2488 0005270 61.9928 83.3154 15.48919755219337'
# 从字符串加载TLE集
satellite = EarthSatellite(line1, line2, 'REDACT', ts)
print("nsatellite:")
print(satellite)
# 通过卫星在头顶上面的时间确定卫星位置,这里按照题目提示时间 2020 年 3 月 26 日 21:52:55
t = ts.utc(2020, 3, 26, 21, 52, 55)
geocentric = satellite.at(t)
print("ngeocentric.position.km:")
print(geocentric.position.km)
我们解题需要知道的是以华盛顿纪念碑为观察者视角的卫星位置,需要先创建一个 Topos 对象来表示观察者的位置,然后用卫星相对地心的位置减去华盛顿纪念碑相对于地心的位置,以此确定卫星相对于观察者的位置信息,其中距离就是我们要修改的 range 值
# 计算华盛顿纪念碑看卫星的角度
bluffton = Topos('38.88937190244597 N', '77.03521514741283 W')
huashengdun = bluffton.at(t)
print(huashengdun.position.km)
difference = satellite - bluffton # 这俩一减得到了华盛顿纪念碑和卫星之间的位置信息
topocentric = difference.at(t)
print(topocentric.position.km)
alt, az, distance = topocentric.altaz() # 通过altaz函数得到高度角、方位角、距离
print('nAltitude: %f' % alt.degrees) # 高度角
print('Azimuth: %f' % az.degrees) # 方位角
print('Distance: %d' % int(distance.m)) # 距离
得到这个之后我们来看一下 heading 和 tilt 与高度角和方位角的关系,其中 tilt 与高度角是互补的,因此直接用 90 减去高度角就是 tilt
heading 是卫星前进的方向,与当前的方位角有个 180 度的差值,所以在 Azimuth 的基础上加上 180 度得到 heading(目前理解是这个意思),再模 360 度是为了保证度数在 360 度之内
heading = (180 + az.degrees) % 360
print('nHeading: %f' % heading)
tilt = 90 - alt.degrees
print('Tilt: %f' % tilt)
根据输出的结果修改 LookAt 中的值,然后用谷歌地球打开就可以看到 flag 了
<LookAt id="ID">
<longitude>-77.03</longitude>
<latitude>38.89</latitude>
<altitude>0</altitude>
<heading>63.532442</heading>
<tilt>40.371925</tilt>
<range>538562</range>
<altitudeMode>clampToGround</altitudeMode>
</LookAt>
https://github.com/solar-wine/writeups/blob/master/2020/Qualifications/Astronomy%2C%20Astrophysics%2C%20Astrometry%2C%20Astrodynamics%2C%20AAAA/I%20Like%20to%20Watch/writeup.md
https://blog.csdn.net/hackasat/article/details/127814688
原文始发于微信公众号(陈冠男的游戏人生):HackaSat2020预选赛beckley
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论