# Confidence CTF 2k17: Starbyte - misc - 200 pts


# cat starbyte.py
from PIL import Image, ImageDraw
import scipy.io.wavfile
import sys
import wave

inputfile = sys.argv[1]

wave_read_object = wave.open(inputfile, 'rb')
print 'Number of audio channels = ',  wave_read_object.getnchannels()
print 'Sample width = ', wave_read_object.getsampwidth(), '(bytes)'
print 'Sampling frequency = ', wave_read_object.getframerate(), '(Hz)'
frames = wave_read_object.getnframes()
print 'Number of audio frames = ', frames
wave_read_object.close()
rate, data = scipy.io.wavfile.read(inputfile)

last_frame = -1
c = ''
r = ''
i = 0

for frame in data:
 if frame > 90:
  if last_frame != 1:
   c += '1'
   i += 1
  last_frame = 1
 elif frame > 23:
  if  last_frame != 0:
   c += '0'
   i += 1
  last_frame = 0
 else:
  last_frame = -1
 if i == 10:
  nc = ''
  for j in c:
   nc = j + nc
  r += chr(int(nc, 2))
  c = ''
  i = 0
r = r.split('\n')

image = Image.new('RGB', (1000, 1000), 'black')
draw = ImageDraw.Draw(image)

for line in r:
 line = line.split()
 if 'LINE' in line:
  x1, y1, x2, y2 = map(int, line[1:])
  draw.line([(x1, y1), (x2, y2)], 'green')
 #elif 'REKT' in line:
 # x1, y1, x2, y2 = map(int, line[1:])
 # draw.rectangle([(x1, y1), (x2, y2)], None, 'green')
 elif 'CRCL' in line:
  x1, y1, rad = map(int, line[1:])
  draw.arc([(x1 - rad, y1 - rad), (x1 + rad, y1 + rad)], 0, 360, 'green')

image.save('image.png')
# python starbyte.py starbyte.wav
Number of audio channels =  1
Sample width =  1 (bytes)
Sampling frequency =  44100 (Hz)
Number of audio frames =  3885808
# eog image.png

# GynvaelEN mission 004


# cat mission_04.py
def hex2bin(h):
 binary = ''
 for i in range(0, len(h), 2):
  byte = u[i:i + 2]
  binary += format(int(byte, 16), '08b')
 return binary

def decode(u):
 lu = len(u)
 if lu == 2:
  return u.decode('hex')
 elif lu  == 4:
  binary = hex2bin(u)
  r = binary[3:8] + binary[10:]
  return chr(int(r, 2))
 elif lu  == 6:
  binary = hex2bin(u)
  r = binary[4:8] + binary[10:16] + binary[18:]
  return chr(int(r, 2))
 elif lu  == 8:
  binary = ''
  binary = hex2bin(u)
  r = binary[5:8] + binary[10:16] + binary[18:24] + binary[26:]
  return chr(int(r, 2))

message = 'E0818F766572C1ACE081AFE081AEC1A7E080A0E08195C194E081862DE080B8E080A0F08081B7C1A17320C1B3F08081B563C1A820E081A1F08080A0E081A6F08081B5F08081AE20E081A6E081A5F08081A1C1B475E081B2E081A5F08080AE'

result = ''

i = 0

while i < len(message):
 byte = int(message[i:i+2], 16)
 binary = format(byte, '08b')
 if binary[0] == '0':
  j = 2
 elif binary[0:3] == '110':
  j = 4
 elif binary[0:4] == '1110':
  j = 6
 elif binary[0:5] == '11110':
  j = 8
 u = message[i:i + j]
 i += j
 result += decode(u)

print result
# python mission_04.py
Overlong UTF-8 was such a fun feature.

Source

https://www.youtube.com/watch?v=iwRSFlZoSCM (1:26:42)

Reference

https://es.wikipedia.org/wiki/UTF-8#Codificaci.C3.B3n_de_los_caracteres

# GynvaelEN mission 003


# cat mission_03.py
import itertools

def base4to10(num):
 result = 0
 ln = len(num) - 1
 for i in num:
  result += int(i) * (4 ** ln)
  ln -= 1
 return result

def ascii_string(s):
 for i in s:
  if ord(i) < 32 or ord(i) > 126:
   return False
 return True

with open('huffman.code') as f:
 bd = f.read()[:-1]

values = ['0', '1', '00', '01', '10', '11', '000', '001', '010', '011', '100', '101', '110', '111']

for i in itertools.permutations(values, 4):
 tree = {
  i[0]: '0',
  i[1]: '1',
  i[2]: '2',
  i[3]: '3',
 }
 code = ''
 result = ''
 for d in bd:
  code += d
  if code in tree:
   result += tree[code]
   code = ''
 try:
  decv  = base4to10(result)
  hexv = hex(decv)[2:].replace('L', '')
  ascv  = hexv.decode('hex')
  if ascii_string(ascv) and len(ascv) > 4:
   print 'tree =', tree
   print 'result =', result
   print 'dec =', decv
   print 'bytes =', hexv
   print 'ascii =', ascv[::-1]
   print
 except:
  pass

# python mission_03.py
tree = {'11': '1', '0': '2', '100': '0', '101': '3'}
result = 3231202120213111211131203001031030012101202131112031322131303001323130113211313131312111030030013010300120213011212030012101031
dec = 26860288614901905570716094189682157357950360778336264927367113021610209076301
bytes = 3b6262756576304d30646275637a77307b71797777654c30713062716630644d
ascii = Md0fqb0q0Lewwyq{0wzcubd0M0veubb;

tree = {'11': '1', '0': '3', '100': '0', '101': '2'}
result = 2321303130312111311121302001021020013101303121113021233121202001232120112311212121213111020020012010200130312011313020013101021
dec = 21010374883428224108739011194252932925839770786883498221738205492211234141257
bytes = 2e7373657567204920747365726f66206e616d66667548206120736177207449
ascii = It was a Huffman forest I guess.

Source

https://www.youtube.com/watch?v=iwRSFlZoSCM (1:26:42)

# GynvaelEN mission 002


# cat mission_02.py
tree = {
'01': '0',
'0010': '1',
'0001': '2',
'00110': '3',
'10': '4',
'000000': '5',
'00000100': '6',
'00000101': '7',
'00000110': '8',
'00000111': '9',
'00001': 'a',
'001110': 'b',
'001111': 'c',
'111': 'd',
'1101': 'e',
'1100': 'f'

}

code = ''
hexencoded = ''

with open('huffman.code') as f:
 bd = f.read()[:-1]
 for d in bd:
  code += d
  if code in tree:
   hexencoded += tree[code]
   code = ''
print hexencoded
print hexencoded.decode('hex')

# python mission_02.py
49204c696b652054726565732e20466c6f7765727320746f6f2e
I Like Trees. Flowers too.

Source

https://www.youtube.com/watch?v=HN_tI601jNU (1:38:27)

Reference

https://www.siggraph.org/education/materials/HyperGraph/video/mpeg/mpegfaq/huffman_tutorial.html