Created
May 24, 2020 15:26
-
-
Save darkarnium/7101e7043708ddb7b317901b70d87179 to your computer and use it in GitHub Desktop.
magicbus
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ctf) [darkarnium::Callisto MagicBus][0]$ ipython3 --no-banner -i magic_bus.py | |
[x] Opening connection to bus.satellitesabove.me on port 5041 | |
[x] Opening connection to bus.satellitesabove.me on port 5041: Trying 18.222.201.16 | |
[+] Opening connection to bus.satellitesabove.me on port 5041: Done | |
[*] Sent b'^93+00+00+35+.' to bus | |
[*] Sent b'^93+00+00+45+.' to bus | |
[*] Sent b'^93+00+00+55+.' to bus | |
[*] Sent b'^93+00+00+75+.' to bus | |
[*] Sent b'^93+00+00+85+.' to bus | |
[*] Sent b'^93+00+00+a5+.' to bus | |
[*] Got [0x56, 0x01] data chunk | |
[*] Got [0x56, 0x01] data chunk | |
[*] Got [0x56, 0x01] data chunk | |
[*] Got [0x56, 0x01] data chunk | |
[*] Got [0x56, 0x01] data chunk | |
[*] Got [0x56, 0x01] data chunk | |
[!] flag{quebec65854quebec:GA7avHnYEEDa8zhDgc5QPOyaCdDML5gNTrp-IBEPeyZc9FEDrqwwzeN7w6_My-kIFheYjdJakhz1W5H1EmejdSo} | |
In [1]: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import binascii | |
from pwn import * | |
TICKET = "ticket{quebec65854quebec:GHpbhquFdHUCf15aID5DlcdoHsIrBfisgpFey9tVBozA6JwFzPjwJ3SfNIAhkohmmA}" | |
# https://stackoverflow.com/questions/22388866/python-list-set-value-at-index-if-index-does-not-exist | |
class FillList(list): | |
def __setitem__(self, index, value): | |
try: | |
super().__setitem__(index, value) | |
except IndexError: | |
for _ in range(index-len(self)+1): | |
self.append(None) | |
super().__setitem__(index, value) | |
def process_line(line, flag_parts): | |
if line.startswith(b'^56+01'): | |
log.info('Got [0x56, 0x01] data chunk') | |
line = line.replace(b'^', b'').replace(b'+', b'').replace(b'.', b'') | |
line = binascii.a2b_hex(line) | |
offset = line[2] | |
for idx, i in enumerate(line[3:]): | |
flag_parts[int(offset+idx)] = chr(i) | |
flag_parts = FillList() | |
context.log_level = 'info' | |
# Connect and iterate until we have everything. | |
r = remote("bus.satellitesabove.me", 5041) | |
r.recvline() # ticket pls | |
r.sendline(TICKET) | |
# Addresses (?) to read. | |
addresses = [ | |
0x35, | |
0x45, | |
0x55, | |
0x75, | |
0x85, | |
0xa5, | |
] | |
# Capture first chunk before pause. | |
buffer = r.recvuntil(b'.') | |
buffer += r.recvuntil(b'^92+00+00+3d') | |
buffer += r.recvuntil(b'.') | |
try: | |
# Read data from the addresses we care about. | |
for address in addresses: | |
reader = bytes('^93+00+00+{0:02x}+.'.format(address), 'utf-8') | |
r.send(reader) | |
log.info('Sent %s to bus', reader) | |
# Read back the results. | |
buffer += r.recvuntil(b'.') # Echo back. | |
buffer += r.recvuntil(b'.') # Response (?) | |
buffer += r.recvuntil(b'.') # | |
buffer += r.recvuntil(b'.') # | |
buffer += r.recvuntil(b'.') # Data! | |
buffer += r.recvuntil(b'.') # Trailer (?) | |
buffer += r.recvuntil(b'.') # | |
# ...Then read the rest of the data in the exchange. | |
while True: | |
buffer += r.recvuntil(b'.') | |
except: | |
pass | |
# Process the last chunk of data - if required. | |
for command in buffer.split(b'.'): | |
process_line(command, flag_parts) | |
# Find the flag | |
flag_start = None | |
flag_end = None | |
for idx,_ in enumerate(flag_parts): | |
# Find the start of the flag. | |
try: | |
if flag_parts[idx] == 'f' and \ | |
flag_parts[idx+1] == 'l' and \ | |
flag_parts[idx+2] == 'a' and \ | |
flag_parts[idx+3] == 'g': | |
flag_start = idx | |
# Find the end of the flag. | |
if flag_parts[idx] == '}' and \ | |
flag_parts[idx+1] == '\x00': | |
flag_end = idx | |
if flag_start and flag_end: | |
break | |
except IndexError: | |
continue | |
flag = '' | |
flag_index = flag_start | |
while flag_index <= flag_end: | |
if flag_parts[flag_index]: | |
flag += flag_parts[flag_index] | |
else: | |
flag += '*' | |
flag_index += 1 | |
# get_flag | |
log.warning(flag) |
Nice write up. Looked like some sort of I2C protocol
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Basically, by hating ourselves for a few hours when searches were coming up dry for potential protocol formats. Here are my notes, which may be varying levels of readable.
@bsmt identified the start and end sentinels for each "packet" (
^
, and.
respectively). After that the focus was on identifying which parts of the data were present in other packets, and parts of the packet that were the same on ones with differing data. After that it was basically trying to identify whether there was any fields which corresponded with the location of the overlapping data between each packet, and the distance between them.Not exactly very scientific, but hey! When the only tool you have is a hammer... :)
Capture Notes:
Annotated capture: