首页
社区
课程
招聘
[原创]Hack-A-Sat 2020预选赛 beckley
2022-12-11 12:30 12481

[原创]Hack-A-Sat 2020预选赛 beckley

2022-12-11 12:30
12481

逛论坛发现了这本书:https://bbs.pediy.com/thread-275220.htm 好家伙,这不是日卫星吗,必须学一波

在 Github 搜了搜题目的源码:https://github.com/cromulencellc/hackasat-qualifier-2020,准备复现一遍,这一关叫做模拟卫星视角,给了我们一个卫星拍摄时的TLE,我们通过谷歌地球去设置卫星视角观察得到 flag

环境搭建

进入 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

我会把我用的最终版本放在 https://github.com/yichen115/hackasat-qualifier-2020 用这个就不用改 url 了

使用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'

如图所示

正式做题

按照 https://blog.csdn.net/hackasat/article/details/127814688 的描述,这道题环境搭建起来后你能看的就只有 static 文件夹里面的 remote.kml 和一个 172.17.0.1 19020 的地址

就从这两个提示开始入手,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:52:55 按照特定的视角拍到了华盛顿纪念碑,让我们通过 Google Earth Pro 的 KML 文件模拟卫星拍摄时的位置看一下华盛顿纪念碑从而获得 flag

Google Earth Pro 可以在这里下载到 https://www.google.com/earth/versions/

KML 文件格式

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... 说明咱还没找到正确的观察视角

双线元素集 (TLE)

接下来我们研究研究 LookAt 要怎么设置,就是卫星拍到华盛顿纪念碑时的位置,相关线索就是 nc 上去输出的两行信息,这个叫做双线元素集 (TLE),好家伙,专业知识来了

https://www.space-track.org/documentation#/tle

卫星双线元素集(TLE)是一种编码格式,用于在两行中存储卫星的轨道参数。这些轨道参数是由观测到的卫星运动数据计算得出的。TLE 可以用来预测卫星的运动,并用于各种应用,例如卫星导航和通信

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得到卫星视角

我们需要通过给出的 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



[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

最后于 2022-12-11 12:32 被yichen115编辑 ,原因: 修改内容
收藏
点赞5
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回