35C3CTF – box of blink
provided is a 400MB .csv file and a photo of an oscilloscope with logic inputs connected on to data bus between a raspberry pi and 2 chained led matrix boards.
Recon
after quick examination i realized the csv file was a log of the measurements from the oscilloscope.
the beginning of the file looked like this.
Model,MDO3014
Firmware Version,1.26
#
Waveform Type,DIGITAL,,,,,,,,,,,,,
Point Format,Y,,,,,,,,,,,,,
Horizontal Units,s,,,,,,,,,,,,,
Horizontal Scale,0.004,,,,,,,,,,,,,
,,,,,,,,,,,,,,
Sample Interval,4e-09,,,,,,,,,,,,,
Record Length,1e+07,,,,,,,,,,,,,
Gating,0.0% to 100.0%,,,,,,,,,,,,,
,,,,,,,,,,,,,,
Vertical Units,V,V,V,V,V,V,V,V,V,V,V,V,V,V
Threshold Used,1.65,1.65,1.65,1.65,1.65,1.65,1.65,1.65,1.65,1.65,1.65,1.65,1.65,1.65
,,,,,,,,,,,,,,
,,,,,,,,,,,,,,
,,,,,,,,,,,,,,
,,,,,,,,,,,,,,
,,,,,,,,,,,,,,
Label,OE,LAT,CLK,E,D,C,B,A,B2,B1,G2,G1,R2,R1
TIME,D13,D12,D11,D10,D9,D8,D7,D6,D5,D4,D3,D2,D1,D0
-1.0000000e-03,0,0,0,0,1,0,0,0,0,0,0,1,0,1
and continued with 400MB worth of lines like
-1.0000000e-03,0,0,0,0,1,0,0,0,0,0,0,1,0,1
I’ve worked a lot with digital oscilloscopes in the past so no need to look up any Information on this, since it’s still in my head.
but the only led matrix I’ve ever worked with was a home build one made from some cheap xmas-lights and a IR-strobe light for a industrial sheet metal inspection line.
After some googeling i found a nice tutorial on how to connect a led matrix to a arduino. with some explanation on what each pin is used for. https://learn.adafruit.com/32×16-32×32-rgb-led-matrix/connecting-with-jumper-wires
and since the labels are in the header of the blink.csv file are the same as the pin names. i can conclude that this it the same type of data bus.
so we have the following signal: output enable bit - - to enable output. latch bit - - to indicate end of data clock puls - - to tell the board to read new data from the bus A,B,C,D,E - - to select what line(s) to send the output to. R1,G1,B1 - - color data for the firs row. R2,G2,B2 - - color data for the second row. /------- OUTPUT ENABLE (TURNS ALL LEDS OFF OR ON) / /------LATCH (INDICATED END OF DATASTREAM) / / /-- CLOCK PULSE | | / [ select rows ][ blues][greens][reds ] Label, | OE |LAT|CLK|E |D |C |B |A |B2 |B1 |G2 |G1 |R2 |R1 | -1.0000000e-03 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
The board ‘writes’ the color data from left to right to the selected line, latch resets the write Postion to the beginning of the line.
There are 2 lines writen at the same time its a 5bit adress so that means the first line is some were between 0 and 32 and the second is the same as the first+33
looking at the photo of the matrix broad that seemed to be right.
Now i know what im looking at, i just need to find a way to reproduce what was displayed on the matrix board.
cleaning up file.
There were a lot of dupplicate measurements because the sample rate of the oscilloscope was much higher than the bus speed.
So i decided to write a script cleaning out duplicate measurements to reduce file size. while i was doing this i was brain stroming on how to parse the data and display it.
Solution
I decided it would be fun to output it in a terminal screen. write block Charterers and display and use v100 esacpe codes for color.
This is the code i came up with to pars the oscilloscope log file.
#!/usr/bin/python # -*- coding: utf-8 -*- '''''''''''''''''''''''''''''''' ' ' ' ''''''''''''''''''''''''''''''''''''''''' ▄▄▄▄ ▄▄▄ █ █░ ██▓ ██████ ▓█████ ▄████▄ ▓█████▄ ▒████▄ ▓█░ █ ░█░▓██▒ ▒██ ▒ ▓█ ▀ ▒██▀ ▀█ ▒██▒ ▄██▒██ ▀█▄ ▒█░ █ ░█ ▒██░ ░ ▓██▄ ▒███ ▒▓█ ▄ ▒██░█▀ ░██▄▄▄▄██ ░█░ █ ░█ ▒██░ ▒ ██▒▒▓█ ▄ ▒▓▓▄ ▄██▒ ░▓█ ▀█▓ ▓█ ▓██▒░░██▒██▓ ░██████▒▒██████▒▒░▒████▒▒ ▓███▀ ░ ░▒▓███▀▒ ▒▒ ▓▒█░░ ▓░▒ ▒ ░ ▒░▓ ░▒ ▒▓▒ ▒ ░░░ ▒░ ░░ ░▒ ▒ ░ ▒░▒ ░ ▒ ▒▒ ░ ▒ ░ ░ ░ ░ ▒ ░░ ░▒ ░ ░ ░ ░ ░ ░ ▒ ░ ░ ░ ▒ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░░ ░ ░ ░ -=Bawling since 2017=- ▒░ ▒ ░ ▒░ By: M42D ░ ░ CTF: 35c3ctf challege: box of blink ░ ░ ░ date: 27-12-2018 usage : cat blink.csv | ./blink.py notes : for best cinematic experiance adjust your termial window to display a resolution of 265x64 charcters it's a damm shame the output wasn't more animated and colorfull. '''''''''''''''''''''''''''''''' ' ' ' ''''''''''''''''''''''''''''''''''''''''' B,A,W,L='',' ',' ',open(__file__).readlines() for S in range(3,30): B+=L[S] if S>7 and S<13: A=L[S]+A W+=L[S] print '\033[94m'+B+'\033[0m' PB='\033[94m'+A+W+'\033[0m' print " sit back 'n enjoy" print " "*40+"-xXx- M42D" print PB from time import sleep sleep(5) #------------------------------------------------------------------------------- # END OF HEADER #------------------------------------------------------------------------------- file_out = 'catme.txt' f = open(file_out, "w") last_clk = '1' last_oe = '1' last_lat = '1' i=0 #string in counter o=0 #string out counter x=5 #knowing me x is probebly y while 1: try: input = raw_input() except: f.close() print 'done..' print 'results saved to catme.txt' break #input skip the whole header section of the file i +=1 if i > 24: if input == '' or input[0] == '#': continue tt = input.split(',') ''' 0 = TIMESTAMP 1 = OUTPUT ENABLE --- i guess to select matrix board 1 or 2 2 = LATCH but we can ignore this 3 = CLOCK 4 = E MSB --\ 5 = D \ 6 = C >-- ROW ADDRESS 7 = B / 8 = A LSB --/ 9 = B2 ---\ 10 = B1 \ 11 = G2 \____RGB COLORS 12 = G1 / B1,G1,R1 = top half of matrix 13 = R2 / B2,G2,R2 = bottom half of matrix 14 = R1 ---/ ''' if tt[3] != last_clk : last_clk = tt[3] last_lat = tt[2] last_oe = tt[1] adr_1 = int(''.join(tt[4:9]),2) adr_2 = adr_1+32 ''' ive used ansi-vt100 escape sequences to move cursor and change color. for a nice overview check: http://www.termsys.demon.co.uk/vtansi.htm ''' color1 = (int(tt[10])*4)+(int(tt[12])*2)+(int(tt[14])*1) color2 = (int(tt[9])*4)+(int(tt[11])*2)+(int(tt[13])*1) line1 = "\033["+str(adr_1)+";"+str(x)+"H" #place cursor top half line1 +='\x1b[6;3'+str(color1)+';40m'+'█' #print a colored block line2 = "\033["+str(adr_2)+";"+str(x)+"H" #place cursor bottom half line2 +='\x1b[6;3'+str(color2)+';40m'+'█' #print a colored block print line1+line2 f.write(line1+line2) # i know this slows it al down for now # but we can just cat the output later on # and hopefully see a nice animation in an # resonable frame rate. x +=1 if tt[2] == "1": #end of line x= 5