SECCON 2018 Quals - Special device file

reversing

## General problem description

We were given a arm64 ELF-Binary which was accessing a special device named `xorshift64`. The flag and some additional random values were hard-coded into the elf.

## Solution

The ELF does more-or-less the same as this pseudocode:

``````# init device
#with open('/dev/xorshift64', 'r') as d:
d.write(0x139408fcbbf7a44)

# decode flag
with open('/dev/xorshift64', 'r') as d:
for i in range(len(flag)):
flag[i] = randval[i] ^ d.read(8) ^ flag[i]
``````

According to Marsaglia [1] there are a finite number of more-than-less secure configurations of the xorshift PRNG family. As we know the first 7 chars of the plain flag (`SECCON{`) we can calculate the values we would need from the PRNG. After this we only have to find the right configuration, which can be done with the following script:

``````#!/usr/bin/env python3
from ctypes import *

possible_params = [
( 1, 1,54), ( 1, 1,55), ( 1, 3,45), ( 1, 7, 9), ( 1, 7,44), ( 1, 7,46), ( 1, 9,50), ( 1,11,35), ( 1,11,50),
( 1,13,45), ( 1,15, 4), ( 1,15,63), ( 1,19, 6), ( 1,19,16), ( 1,23,14), ( 1,23,29), ( 1,29,34), ( 1,35, 5),
( 1,35,11), ( 1,35,34), ( 1,45,37), ( 1,51,13), ( 1,53, 3), ( 1,59,14), ( 2,13,23), ( 2,31,51), ( 2,31,53),
( 2,43,27), ( 2,47,49), ( 3, 1,11), ( 3, 5,21), ( 3,13,59), ( 3,21,31), ( 3,25,20), ( 3,25,31), ( 3,25,56),
( 3,29,40), ( 3,29,47), ( 3,29,49), ( 3,35,14), ( 3,37,17), ( 3,43, 4), ( 3,43, 6), ( 3,43,11), ( 3,51,16),
( 3,53, 7), ( 3,61,17), ( 3,61,26), ( 4, 7,19), ( 4, 9,13), ( 4,15,51), ( 4,15,53), ( 4,29,45), ( 4,29,49),
( 4,31,33), ( 4,35,15), ( 4,35,21), ( 4,37,11), ( 4,37,21), ( 4,41,19), ( 4,41,45), ( 4,43,21), ( 4,43,31),
( 4,53, 7), ( 5, 9,23), ( 5,11,54), ( 5,15,27), ( 5,17,11), ( 5,23,36), ( 5,33,29), ( 5,41,20), ( 5,45,16),
( 5,47,23), ( 5,53,20), ( 5,59,33), ( 5,59,35), ( 5,59,63), ( 6, 1,17), ( 6, 3,49), ( 6,17,47), ( 6,23,27),
( 6,27, 7), ( 6,43,21), ( 6,49,29), ( 6,55,17), ( 7, 5,41), ( 7, 5,47), ( 7, 5,55), ( 7, 7,20), ( 7, 9,38),
( 7,11,10), ( 7,11,35), ( 7,13,58), ( 7,19,17), ( 7,19,54), ( 7,23, 8), ( 7,25,58), ( 7,27,59), ( 7,33, 8),
( 7,41,40), ( 7,43,28), ( 7,51,24), ( 7,57,12), ( 8, 5,59), ( 8, 9,25), ( 8,13,25), ( 8,13,61), ( 8,15,21),
( 8,25,59), ( 8,29,19), ( 8,31,17), ( 8,37,21), ( 8,51,21), ( 9, 1,27), ( 9, 5,36), ( 9, 5,43), ( 9, 7,18),
( 9,19,18), ( 9,21,11), ( 9,21,20), ( 9,21,40), ( 9,23,57), ( 9,27,10), ( 9,29,12), ( 9,29,37), ( 9,37,31),
( 9,41,45), (10, 7,33), (10,27,59), (10,53,13), (11, 5,32), (11, 5,34), (11, 5,43), (11, 5,45), (11, 9,14),
(11, 9,34), (11,13,40), (11,15,37), (11,23,42), (11,23,56), (11,25,48), (11,27,26), (11,29,14), (11,31,18),
(11,53,23), (12, 1,31), (12, 3,13), (12, 3,49), (12, 7,13), (12,11,47), (12,25,27), (12,39,49), (12,43,19),
(13, 3,40), (13, 3,53), (13, 7,17), (13, 9,15), (13, 9,50), (13,13,19), (13,17,43), (13,19,28), (13,19,47),
(13,21,18), (13,21,49), (13,29,35), (13,35,30), (13,35,38), (13,47,23), (13,51,21), (14,13,17), (14,15,19),
(14,23,33), (14,31,45), (14,47,15), (15, 1,19), (15, 5,37), (15,13,28), (15,13,52), (15,17,27), (15,19,63),
(15,21,46), (15,23,23), (15,45,17), (15,47,16), (15,49,26), (16, 5,17), (16, 7,39), (16,11,19), (16,11,27),
(16,13,55), (16,21,35), (16,25,43), (16,27,53), (16,47,17), (17,15,58), (17,23,29), (17,23,51), (17,23,52),
(17,27,22), (17,45,22), (17,47,28), (17,47,29), (17,47,54), (18, 1,25), (18, 3,43), (18,19,19), (18,25,21),
(18,41,23), (19, 7,36), (19, 7,55), (19,13,37), (19,15,46), (19,21,52), (19,25,20), (19,41,21), (19,43,27),
(20, 1,31), (20, 5,29), (21, 1,27), (21, 9,29), (21,13,52), (21,15,28), (21,15,29), (21,17,24), (21,17,30),
(21,17,48), (21,21,32), (21,21,34), (21,21,37), (21,21,38), (21,21,40), (21,21,41), (21,21,43), (21,41,23),
(22, 3,39), (23, 9,38), (23, 9,48), (23, 9,57), (23,13,38), (23,13,58), (23,13,61), (23,17,25), (23,17,54),
(23,17,56), (23,17,62), (23,41,34), (23,41,51), (24, 9,35), (24,11,29), (24,25,25), (24,31,35), (25, 7,46),
(25, 7,49), (25, 9,39), (25,11,57), (25,13,29), (25,13,39), (25,13,62), (25,15,47), (25,21,44), (25,27,27),
(25,27,53), (25,33,36), (25,39,54), (28, 9,55), (28,11,53), (29,27,37), (31, 1,51), (31,25,37), (31,27,35),
(33,31,43), (33,31,55), (43,21,46), (49,15,61), (55, 9,56)]

def c0(val, conf):
val.value ^= val.value << conf[0]
val.value ^= val.value >> conf[1]
val.value ^= val.value << conf[2]
return val

def c1(val, conf):
val.value ^= val.value << conf[2]
val.value ^= val.value >> conf[1]
val.value ^= val.value << conf[0]
return val

def c2(val, conf):
val.value ^= val.value >> conf[0]
val.value ^= val.value << conf[1]
val.value ^= val.value >> conf[2]
return val

def c3(val, conf):
val.value ^= val.value >> conf[2]
val.value ^= val.value << conf[1]
val.value ^= val.value >> conf[0]
return val

def c4(val, conf):
val.value ^= val.value << conf[0]
val.value ^= val.value << conf[2]
val.value ^= val.value >> conf[1]
return val

def c5(val, conf):
val.value ^= val.value << conf[2]
val.value ^= val.value << conf[0]
val.value ^= val.value >> conf[1]
return val

def c6(val, conf):
val.value ^= val.value >> conf[0]
val.value ^= val.value >> conf[2]
val.value ^= val.value << conf[1]
return val

def c7(val, conf):
val.value ^= val.value >> conf[2]
val.value ^= val.value >> conf[0]
val.value ^= val.value << conf[1]
return val

possible_ops = [
c0, c1, c2, c3, c4, c5, c6, c7
]

for op in possible_ops:
for param in possible_params:
val = c_uint64(0x139408fcbbf7a44)
v_list = []
for i in range(7):
val = op(val, param)
v_list.append('{:02x}'.format(val.value & 0xff))
print(''.join(v_list))
``````

After this we only have to decode with the right values:

``````flag = bytes.fromhex('fe7588a95aaa10529c6a67f482be2156590b9732214693ae400d2e1f834340')
randval = bytes.fromhex('1dab1b0fa7d91ab0617eb648a456cf7e4905fd059cf95445fa24c61d68f246')
xorshift = bytes.fromhex('b09bd0e5b23d71b78e7185d443bb9e4d73670b5bf9dab182d94cae6b87d47b')
xored = bytes([a ^ b for (a,b) in zip(flag,randval)])
``````

The flag was: `SECCON{UseTheSpecialDeviceFile}`

## References

[1] Marsaglia, George. "Xorshift rngs." Journal of Statistical Software 8.14 (2003): 1-6.

SECCON 2018 Quals - Runme

reversing

General problem description Given was a Windows binary, which was apparently waiting to be started with the correct cmd arguments. Solution The binary checked character by character the cmd arguments with a hard-coded value which was: "C:\\Temp\\SECCON2018Online.exe" SECCON{Runn1n6_P47h} The flag was: SECCON{Runn1n6_P47h}...

SECCON 2018 Quals - Special instructions

reversing

General problem description We were given a moxie ELF-Binary which was implementing the xorshift32 PRNG algorithm. The flag and some additional random values were hard-coded into the elf. Solution Similar to the Special device file challenge the binary took the flag xored with a random value hard-coded into to binary and xored again with a value taken from the xorshift32 algorithm. The catch was again, that we didn't know the correct configuration of the algorithm only the seed and...

SECCON 2018 Quals - Needle in a haystack

Media

General problem description We got a 9 hours long video captured with a webcam on the top of a tall building in Tokyo(?). Find the flag. Solution First our guess was, that there will be a single frame which shows the flag, but fast-forwarding the video did not reveal anything like that. The next idea was to export every frame and use fuzzy hashing to find very different frames. While the script was doing the exporting we were fast-forwarding the...

HITCON 2018 - EV3 Basic

MISC

General problem description For this challenge we got a picture of a Lego Mindstorm EV3, which displays the flag partly (see below). And we also got a pcap (OK, it was in the apple PackageLogger format) with captured Bluetooth transmission. Solution The pcap shows Bluetooth traffic, and wireshark finds furthermore identifies RFCOMM protocol. Some of them includes additional data parts. If you dig around long enough on the internet you can find a wireshark dissector written...