Skip to content

Instantly share code, notes, and snippets.

@darkarnium
Created May 24, 2020 15:26
Show Gist options
  • Save darkarnium/7101e7043708ddb7b317901b70d87179 to your computer and use it in GitHub Desktop.
Save darkarnium/7101e7043708ddb7b317901b70d87179 to your computer and use it in GitHub Desktop.
magicbus
(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]:
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)
@DeathsPirate
Copy link

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