【卫星安全系列一】HAS-beckley赛题复现
【卫星安全系列一】HAS-beckley赛题复现
原创 明月清风我 山石网科安全技术研究院 2023-11-30 10:41
题目介绍
题目名:beckley
Fire up your Google Earth and brush up on your KML tutorials, we're going to make it look at things!
大概意思是利用Google Earth软件和给出的KML文件找到flag。
环境搭建
题目源码链接:https://github.com/cromulencellc/hackasat-qualifier-2020
由于网络问题,需要对源Dockerfile文件进行一些修改,
修改后的Dockerfile文件如下:
FROM ubuntu:16.04
#Install Apache, Python, Curl. Enable CGI. Install PIP, use PIP to install skyfield
RUN sed -i 's#http://archive.ubuntu.com/#http://mirrors.tuna.tsinghua.edu.cn/#' /etc/apt/sources.list;\
apt-get update -y; \
apt-get install -y apache2 python curl;\
a2enmod cgi; \
curl -O https://bootstrap.pypa.io/pip/2.7/get-pip.py; \
python2 get-pip.py; \
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple;\
pip install skyfield;
COPY errors /etc/apache2/sites-enabled/000-default.conf
COPY custom_50x.html /var/www/html/custom_50x.html
WORKDIR /usr/lib/cgi-bin
# Upload all files to cgi-bin directory
COPY *.py ./
COPY entrypoint.sh ./
COPY deltat.* ./
COPY Leap_Second.dat ./
RUN chmod +x challenge.py
# Suppress error output
RUN echo "ServerName beckley.mydomain.com" >> /etc/apache2/apache2.conf
#ENV FLAG=flag{Hungry_For_Apples}
# RUN
ENTRYPOINT ./entrypoint.sh
编译challenge环境
make challenge
运行一个beckley挑战题服务端容器:
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{test_beckley} -p 19021\:80 beckley\:challenge"
运行之后,nc设定的ip和端口,即可开始做题。
解题过程
直接使用nc 172.17.0.1 19020开启
yjp@ubuntu:~$ nc 172.17.0.1 19020
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:13The satellite we used was: REDACT1 13337U 98067A 20087.38052801 -.00000452 00000-0 00000+0 0 99952 13337 51.6460 33.2488 0005270 61.9928 83.3154 15.48919755219337Use a Google Earth Pro KML file to 'Link' to http://172.17.0.1:19021/cgi-bin/HSCKML.pyand 'LookAt' that spot from where the satellite when it took the photo and get us that flag!
我们需要根据给出的satellite的信息和利用KML文件模拟卫星的拍摄角度,要完成这些需要对kml文件和python的Skyfield库进行学习。
KML文件
可以在static文件夹下找到题目给出remote.kml文件,完整代码如下。
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Folder>
<name>HackASatCompetition</name>
<visibility>0</visibility>
<open>0</open>
<description>HackASatComp1</description>
<NetworkLink>
<name>View Centered Placemark</name>
<visibility>0</visibility>
<open>0</open>
<description>This is where the satellite was located when we saw it.</description>
<refreshVisibility>0</refreshVisibility>
<flyToView>0</flyToView>
<LookAt id="ID">
<!-- specific to LookAt -->
<longitude>FILL ME IN</longitude> <!-- kml:angle180 -->
<latitude>FILL ME IN TOO</latitude> <!-- kml:angle90 -->
<altitude>FILL ME IN AS WELL</altitude> <!-- double -->
<heading>FILL IN THIS VALUE</heading> <!-- kml:angle360 -->
<tilt>FILL IN THIS VALUE TOO</tilt> <!-- kml:anglepos90 -->
<range>FILL IN THIS VALUE ALSO</range> <!-- double -->
<altitudeMode>clampToGround</altitudeMode>
</LookAt>
<Link>
<href>http://FILL ME IN:FILL ME IN/cgi-bin/HSCKML.py</href>
<refreshInterval>1</refreshInterval>
<viewRefreshMode>onStop</viewRefreshMode>
<viewRefreshTime>1</viewRefreshTime>
<viewFormat>BBOX=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth];CAMERA=[lookatLon],[lookatLat],[lookatRange],[lookatTilt],[lookatHeading];VIEW=[horizFov],[vertFov],[horizPixels],[vertPixels],[terrainEnabled]</viewFormat>
</Link>
</NetworkLink>
</Folder>
</kml>
我们只需要关注
(1)
用于指定本地或者远程的kml文件,在remote.kml文件里就是标签中的
(2)
<LookAt id="ID">
<longitude></longitude> <!-- kml:angle180 -->
<latitude></latitude> <!-- kml:angle90 -->
<altitude>0</altitude> <!-- double -->
<range></range> <!-- double -->
<tilt>0</tilt> <!-- float -->
<heading>0</heading> <!-- float -->
<altitudeMode>clampToGround</altitudeMode>
<!--kml:altitudeModeEnum:clampToGround, relativeToGround, absolute -->
<!-- or, gx:altitudeMode can be substituted: clampToSeaFloor, relativeToSeaFloor -->
</LookAt>
下图展示了
问题 | <LookAt> 中的规范 |
---|---|
当前在查看什么目标? | <longitude> 、<latitude> 、<altitude> 、<altitudeMode> |
视点距景点有多远? | <range> |
视图方向是否是北面朝上? | 如果是,则使用默认的 <heading> 值0。如果不是,请指定一个0(不含)到360°的 <heading> 旋转值 |
视图方向是否直指地球? | 如果是,则使用默认的 <tilt> 值。如果不是,镜头将向上朝着地平线;请指定一个不大于90°的 <tilt> 旋转值。 90°表示直接沿着地平线看过去(如果您离地球表面很远,而且 <tilt> 值为90°,那么您可能看不到地球表面)。 |
(3)
上面说过可以用于指定kml文件。
深入了解,请参考KML 教程 | “Keyhole 标记语言” | Google for Developers
Skyfield
(一)安装
使用 pip install Skyfield 即可
(二)使用
查询卫星某一刻的x,y,z坐标,代码如下:
from skyfield.api import EarthSatellite
from skyfield.api import load
ts = load.timescale()
line1 = '1 25544U 98067A 14020.93268519 .00009878 00000-0 18200-3 0 5082'
line2 = '2 25544 51.6498 109.4756 0003572 55.9686 274.8005 15.49815350868473'
#从TLE数据中加载卫星轨道元素
satellite = EarthSatellite(line1, line2, 'ISS (ZARYA)', ts)
print(satellite)
t = ts.utc(2014, 1, 23, 11, 18, 7)
geocentric = satellite.at(t)
print(geocentric.position.km)
运行结果
ISS (ZARYA) catalog #25544 epoch 2014-01-20 22:23:04 UTC
[-3918.87650458 -1887.64838745 5209.08801512]
查询卫星相对于观察者的位置,可以通过构建一个Topos对象来表示观察者的纬度和经度,再结合矢量减法来确定,代码如下:
from skyfield.api import Topos
bluffton = Topos('38.8894838 N', '77.0352791 W')
difference = satellite - bluffton
topocentric = difference.at(t)
alt, az, distance = topocentric.altaz()
print("(alt, az, distance)=",(alt, az, distance))
# (alt, az, distance)= (<Angle 49deg 37' 40.9">, <Angle 243deg 31' 48.1">, <Distance 3.60007e-06 au>)
解题
现在我们可以回到解题要求上了,我们需要计算出
计算出
因为
下面的python代码可以计算出剩下的属性的值:
from skyfield.api import EarthSatellite
from skyfield.api import load
from skyfield.api import 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'
satellite = EarthSatellite(line1, line2, 'REDACT', ts)
t = ts.utc(2020, 3, 26, 21, 53, 13)
photo = Topos('38.889100 N', '77.0354 W')
difference = satellite - photo
topocentric = difference.at(t)
alt, az, distance = topocentric.altaz()
print('Altitude(deg): %f' % alt.degrees)
print('Azimuth(def): %f' % az.degrees)
print('Range(m): %d' % int(distance.m))
tilt = 90 - alt.degrees
print('Tilt(deg): %f' % tilt)
heading = (180 + az.degrees) % 360
print('Heading(deg): %f' % heading)
构造payload
curl http://172.17.0.1:19021/cgi-bin/HSCKML.py?CAMERA=-77.03,38.89,538544,40.369421,63.535801 -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'
最后成功显示了flag
总结
卫星安全不同于传统的安全,涉及到很多数学和物理知识;本题是较为简单的一题,适合用来入门卫星安全。