Aug-26-2018, 03:28 PM
hello, i got a job offer which will send me to a fully paid studying program which i will be able to work at the end of, if only i will be able to solve a few of they're riddles, they said there is no need in previous knowledge and i already figured out what i need to do but in order to solve it i need to use python which i never did before
i got a gif file i need to decrypt in order to get a message from but i have no idea how to use code i got 2 other files that came with the gif file, one of them seems to be the encryption but i don't know which command lines to use in python in order to decrypt it
here are the 3 files: https://files.fm/u/6z5xrsx3 and this might be a key ill need to use in order to access the message: Steganos & Graphein (i might be wrong on this one but i saw someone else using something similar to encrypt and decrypt a picture and he used 2 key codes to do so)
Thank you in advance!!
I'm new here so i don't know if I'm doing it right so correct me if I'm wrong:
file codes:
enc.py:
i got a gif file i need to decrypt in order to get a message from but i have no idea how to use code i got 2 other files that came with the gif file, one of them seems to be the encryption but i don't know which command lines to use in python in order to decrypt it
here are the 3 files: https://files.fm/u/6z5xrsx3 and this might be a key ill need to use in order to access the message: Steganos & Graphein (i might be wrong on this one but i saw someone else using something similar to encrypt and decrypt a picture and he used 2 key codes to do so)
Thank you in advance!!
I'm new here so i don't know if I'm doing it right so correct me if I'm wrong:
file codes:
enc.py:
from __future__ import print_function from random import randint, shuffle import sys from struct import unpack, pack as pk from io import BytesIO as BIO import lzwlib up = lambda *args: unpack(*args)[0] def F(f): assert f.read(3) == 'GIF', '' assert f.read(3) == '89a', '' w, h = unpack('HH', f.read(4)) assert 32 <= w <= 500, '' assert 32 <= h <= 500, '' logflags = up('B', f.read(1)) assert logflags & 0x80, '' size_count = logflags & 0x07 gct_count = 2**(size_count+1) assert 4 <= gct_count <= 256, '' bgcoloridx = up('B', f.read(1)) f.seek(1, 1) clrs = [] for i in xrange(gct_count): clr = (up('B', f.read(1)), up('B', f.read(1)), up('B', f.read(1))) clrs.append(clr) assert len(clrs) > bgcoloridx, '' return clrs, bgcoloridx, size_count, h, w class T(object): I = 0 EG = 1 EA = 2 EC = 3 ET = 4 def C(f): rb = f.read(1) b = up('B', rb) while b != 0x3B: buf = '' buf += rb if b == 0x2c: nbuf = f.read(2*4) eb = f.read(1) assert (up('B', eb) & 0x03) == 0, '' nbuf += eb nbuf += f.read(1) nbuf += V(f) t = T.I elif b == 0x21: rb = f.read(1) buf += rb b = up('B', rb) if b == 0xF9: nbuf = f.read(1) blksize = up('B', nbuf) nbuf += f.read(blksize) nbuf += f.read(1) assert nbuf[-1] == '\x00', '' t = T.EG elif b in [0xFF, 0x01]: nbuf = f.read(1) blksize = up('B', nbuf) nbuf += f.read(blksize) nbuf += V(f) t = (b+3) & 0x0F elif b == 0xFE: nbuf = V(f) t = T.EC else: raise Exception("unsupprted thing @{}".format(f.tell())) buf += nbuf yield t, buf rb = f.read(1) b = up('B', rb) yield None, '\x3B' raise StopIteration def WB(buf): blockcount = len(buf)/0xFF blockcount += 1 if len(buf) % 0xFF else 0 blocks = [ pk('B', len(subblock))+subblock for subblock in [ buf[i:0xFF+i] for i in xrange(0, blockcount*0xFF, 0xFF) ] ] return ''.join(blocks) + '\x00' def k(bf): combined_buf = '' while True: cb = ord(bf.read(1)) if not cb: break combined_buf += bf.read(cb) return combined_buf def V(f): sbx = '' while True: rcb = f.read(1) sbx += rcb if rcb == '\x00': break cb = up('B', rcb) blk = f.read(cb) sbx += blk return sbx def Q(delay, w, h, x, y, tidx): assert 0 <= tidx <= 255 assert 0 <= delay < 2**16 indices = [tidx]*(w*h) buf = BIO('') buf.write('\x21\xF9\x04\x05') buf.write(pk('H', delay)) buf.write(pk('B', tidx)) buf.write('\x00') buf.write('\x2c') buf.write(pk('H', x)) buf.write(pk('H', y)) buf.write(pk('H', w)) buf.write(pk('H', h)) buf.write('\x00') LZWMinimumCodeSize = 8 cmprs, _ = lzwlib.Lzwg.compress( indices, LZWMinimumCodeSize) obuf = pk('B', LZWMinimumCodeSize) + WB(cmprs) buf.write(obuf) buf.seek(0) return buf.read() def z(n): import math for i in xrange(1, int(math.sqrt(n) + 1)): if n % i == 0: yield i def m(a, mm, hh): if a < 0x08: if a % 2: _0 = 0 _1 = 1 _4 = a << 2 _3 = randint(4, mm-1) else: _0 = 1 _1 = a << 1 _3 = randint(4, mm/2) _4 = randint(4, hh/3) else: ds = list(z(a)) _0 = 0 _1 = 0 shuffle(ds) _4 = ds[0] assert a % _4 == 0 _3 = a/_4 return _0, _1, _3, _4 def h(b6, b1, mw, mh, mci, d=3): idx = randint(0, (mci-1)/2)*2 + b1 x, xx, xxx, xxxx = m(b6, mw, mh) f = Q(d, xxx, xxxx, x, xx, idx) return f def M(s): l = list(set(s.upper())) shuffle(l) d = ''.join(l) assert len(d) <= 2**6, '' return d, [(d.index(c.upper()), int(c.isupper())) for c in s] def E(f, s, o): global_colors, bgcoloridx, size_count, hh, ww = F(f) mp, ks = M(s) hdr_end = f.tell() f.seek(0) o.write(f.read(hdr_end)) fc = 0 o.write('\x21\xFE') o.write(WB('RDBNB'+mp)) o.flush() for t, buf in C(f): print('.', end='') if t == T.EC: continue if t == T.EG: if ks: delay = up('<H', buf[4:6]) assert delay >= 6 buf = buf[:4] + pk('<H', delay - 3) + buf[6:] obuf = buf elif t == T.I: fc += 1 total_raw_blocks_data = '' bf = BIO(buf) pref = bf.read(10) LZWMinimumCodeSize = ord(bf.read(1)) total_raw_blocks_data = k(bf) indices, dcmprsdcodes = lzwlib.Lzwg.decompress( total_raw_blocks_data, LZWMinimumCodeSize) xxx = unpack('<B H H H H B', pref) cmprs, codes = lzwlib.Lzwg.compress( indices, LZWMinimumCodeSize) obuf = pref + pk('B', LZWMinimumCodeSize) + WB(cmprs) if ks: mpindx, isup = ks.pop(0) obuf += h(mpindx, isup, ww, hh, len(global_colors)-1) else: obuf = buf o.write(obuf) o.flush() assert not ks, '' return 0 if __name__ == '__main__': assert len(sys.argv) > 2, 'bad input' fpath = sys.argv[1] flag = sys.argv[2] if len(sys.argv) > 3: outpath = sys.argv[3] else: outpath = fpath + '.out.gif' f = open(fpath, 'rb') o = open(outpath, 'wb') rv = E(f, flag, o) sys.exit(rv)lzwlib.py:
from io import BytesIO as BIO class Bitstream(object): def __init__(self, buf=None, raw=None, bits=None): self.bytes = buf or BIO(raw) self.bits = bits or [] def __len__(self): curr = self.bytes.tell() last = self.bytes.seek(0, 2) self.bytes.seek(curr) total = len(self.bits) + (last - curr)*8 return total def _write_bits(self, newbits): self.bits += newbits def write(self, v, count): newbits = [1 if v & (1 << i) else 0 for i in range(count)] self._write_bits(newbits) def _read_bits(self, count): bytes_for_bits = count/8 + (1 if (count % 8) else 0) raw_bytes = self.bytes.read(bytes_for_bits) for b in raw_bytes: self.bits += [1 if ord(b) & (1 << i) else 0 for i in range(8)] def _makeint(self, bitcount): assert bitcount < 13, bitcount x = 0 for i in xrange(bitcount): b = self.bits.pop(0) x |= (b << i) return x def readByte(self): return chr(self.read(8)) def read(self, bitcount): current_bit_count = len(self.bits) if current_bit_count < bitcount: self._read_bits(bitcount - current_bit_count) return self._makeint(bitcount) class Lzwg(object): @classmethod def extract_info_from_imagedatadescriptor(cls, buf): buf.seek(1+2*4, 1) desc_flags = ord(buf.read(1)) assert desc_flags == 0, 'flags: {:08b}'.format(desc_flags) lzw_min_codesize = ord(buf.read(1)) size = ord(buf.read(1)) subblocks = [] while size: subblocks.append(buf.read(size)) size = ord(buf.read(1)) return lzw_min_codesize, subblocks @classmethod def _get_initialized_code_table(cls, lzw_min_codesize): max_indx = 2**(lzw_min_codesize) - 1 + 2 # 2 for CC and EOI codes return [[i] for i in xrange(max_indx + 1)] @classmethod def decompress(cls, buf, lzw_min_codesize=2): can_insert_to_table = True index_stream = [] current_bits_per_code = initial_bits_per_code = lzw_min_codesize+1 code_table = cls._get_initialized_code_table(lzw_min_codesize) bits = Bitstream(raw=buf) codes = [] CLEAR_CODE = len(code_table) - 2 EOI_CODE = len(code_table) - 1 assert CLEAR_CODE == bits.read( initial_bits_per_code), 'first code is not CC' pc = c = bits.read(initial_bits_per_code) codes.append(CLEAR_CODE) codes.append(c) index_stream.extend(code_table[c]) k = None while len(bits): c = bits.read(current_bits_per_code) codes.append(c) if c == CLEAR_CODE: code_table = cls._get_initialized_code_table(lzw_min_codesize) current_bits_per_code = initial_bits_per_code pc = c = bits.read(initial_bits_per_code) codes.append(c) index_stream.extend(code_table[c]) can_insert_to_table = True continue if c == EOI_CODE: assert len(bits) == 0 or (len(bits) <= 8 and bits.read(len(bits) ) == 0), '{} left: {}'.format(len(bits), bits.bits) break if len(code_table) > c: index_stream.extend(code_table[c]) k = code_table[c][:1] if can_insert_to_table: code_table.append(code_table[pc] + k) else: k = code_table[pc][:1] index_stream.extend(code_table[pc] + k) if can_insert_to_table: code_table.append(code_table[pc] + k) if len(code_table) - 1 == (2**current_bits_per_code) - 1: if current_bits_per_code < 12: current_bits_per_code += 1 else: can_insert_to_table = False assert current_bits_per_code < 13, 'bad bits per code' pc = c return index_stream, codes @classmethod def _compress_indices_using_table(cls, indices, lzw_min_codesize): code_table = cls._get_initialized_code_table(lzw_min_codesize) CLEAR_CODE = len(code_table) - 2 EOI_CODE = len(code_table) - 1 current_bits_per_code = initial_bits_per_code = lzw_min_codesize+1 yield CLEAR_CODE, current_bits_per_code intermediate_index_buffer = [indices[0]] for indx in indices[1:]: k = indx if intermediate_index_buffer + [k] in code_table: intermediate_index_buffer.append(k) else: code_table.append(intermediate_index_buffer+[k]) new_idx = code_table.index(intermediate_index_buffer) yield new_idx, current_bits_per_code intermediate_index_buffer = [k] k = None if len(code_table) == 2**12 - 1-1: yield CLEAR_CODE, current_bits_per_code current_bits_per_code = initial_bits_per_code code_table = cls._get_initialized_code_table( lzw_min_codesize) # code_table.append(intermediate_index_buffer+[k]) if len(code_table) == 2**current_bits_per_code + 1: current_bits_per_code += 1 yield code_table.index(intermediate_index_buffer), current_bits_per_code yield EOI_CODE, current_bits_per_code @classmethod def compress(cls, indices, lzw_min_codesize=2): bits = Bitstream() comcodes = [] cmprsd = '' for c, bits_per_code in cls._compress_indices_using_table(indices, lzw_min_codesize): comcodes.append(c) bits.write(c, bits_per_code) while len(bits) >= 8: b = bits.readByte() cmprsd += b if len(bits) > 0: assert len(bits) < 8, 'bitstream has more than a byte left!: {}'.format( bits.bits) bits.write(0, 8-len(bits)) b = bits.readByte() cmprsd += b return cmprsd, comcodes