def get_send_bytes(jsono, convid, key=PK_KEY, typemsg="dk"): try: if convid is None: convid = generatestring(32) if 'serial' in jsono and jsono['serial'] is None: jsono['serial'] = SendBufferTimer.get_serial() if 'key' in jsono and jsono['key'] is None: jsono['key'] = generatestring(16) msg = s2b(json.dumps(jsono)) _LOGGER.info("Encrypting with %s MSG %s" % (b2s(key), b2s(msg))) lnmsg = len(msg) remain = lnmsg % 16 if remain > 0: remain = (lnmsg // 16) * 16 + 16 - lnmsg msg += b"\x20" * remain ln = lnmsg + remain + 4 + 2 + 2 + 2 + 32 cry = AES.new(s2b(key), AES.MODE_ECB) newbytes = cry.encrypt(msg) crc32 = binascii.crc32(newbytes) bytesa = MAGIC + struct.pack('>H', ln) + typemsg + \ struct.pack('>i', crc32) + s2b(convid) return bytesa + newbytes except: # noqa: E722 _LOGGER.warning(f"{traceback.format_exc()}") return b''
def mqtt_on_message(self, client, userdata, msg): Device.mqtt_on_message(self, client, userdata, msg) sub = self.mqtt_sub(msg.topic) try: if sub == "backup": if len(msg.payload): try: out = json.loads(msg.payload) except: # noqa: E722 out = msg.payload if isinstance(out, dict): topic = out["topic"] convert = 'convert' not in out or out['convert'] else: topic = out convert = False event.EventManager.fire(eventname='ExtInsertAction', hp=(self.host, self.port), cmdline="", action=ActionBackup( self, topic, convert)) elif sub == "learn" or sub == "emit": _LOGGER.info("topic " + msg.topic + " [" + b2s(msg.payload) + "]") learnk = json.loads(msg.payload) keyall = [] for d in learnk: ksing = ('' if d['key'][0] == '@' or d['key'][0] == '$' else (d["remote"] + ':')) + d["key"] # _LOGGER.info("KSING "+ksing+" "+str(type(ksing))) if 'a' in d and 'remote' in d and len(d['remote']): event.EventManager.fire( eventname='ExtInsertAction', hp=(self.host, self.port), cmdline="", action=ActionInsertKey( self, d['remote'], d['key'], d['a'], { k: v for k, v in d.items() if k not in ['a', 'remote', 'key'] })) else: keyall.append(ksing) if len(keyall): tall = tuple(keyall) if sub == "learn": if keyall[0][0] == '@': tall = tuple(keyall[1:]) action = ActionCreatesh(self, keyall[0][1:], *tall) else: action = ActionLearnir(self, *tall) else: action = ActionEmitir(self, *tall) event.EventManager.fire(eventname='ExtInsertAction', hp=(self.host, self.port), cmdline="", action=action) except: # noqa: E722 _LOGGER.warning(f"{traceback.format_exc()}")
def handle_incoming_data(data, key=PK_KEY): try: valasci = binascii.crc32(data[42:]) _LOGGER.info( f"K={b2s(key)} Computed CRC %08X vs {tohexs(data[6:10])}" % valasci) if valasci == struct.unpack('>i', data[6:10])[0]: cry = AES.new(s2b(key), AES.MODE_ECB) msg = cry.decrypt(data[42:]) _LOGGER.info("Decrypted MSG %s" % b2s(msg)) jsono = json.loads(msg[0:msg.rfind(b'}') + 1]) return {'msg': jsono, 'convid': b2s(data[10:42])} except: # noqa: E722 _LOGGER.warning(f"{traceback.format_exc()}") pass return None
def server_protocol(self, server: Server, moreargtext: str) -> RequestProtocolGenerator: log = logger.getChild('AuthPlainRequest._server_protocol') try: if not (authtext := moreargtext): yield ResponseEvent(334, '') yield from (event := NeedDataEvent()).go() authtext = b2s(event.data or b'').rstrip() _, uid, pwd = b64_decode_str(authtext).split('\0')
def server_protocol(self, server: Server, moreargtext: str) -> RequestProtocolGenerator: log = logger.getChild('AuthLoginRequest._server_protocol') if moreargtext and server.pedantic: raise ResponseEvent(501, 'Syntax error (no extra parameters allowed)') event = NeedDataEvent() try: yield ResponseEvent(334, b64_encode_str('Username:'******'')).rstrip() yield ResponseEvent(334, b64_encode_str('Password:'******'')).rstrip() except Exception as e: log.debug(f'{e=}') yield ResponseEvent(501, 'malformed auth input RFC4616#2') else: yield from self._on_authenticate(server, uid, pwd)
def _parse_request_line ( self, line: BYTES ) -> Tuple[str,Opt[Type[BaseRequest]],str]: log = logger.getChild ( 'Server._parse_request_line' ) m = _r_pop3_request.match ( b2s ( line ).rstrip() ) if not m: return '', None, '' verb, suffix = m.groups() verb = verb.upper() # TODO FIXME: are POP3 verbs case-sensitive? requestcls = _request_verbs.get ( verb ) if requestcls is None: log.debug ( f'{requestcls=} {verb=} {_request_verbs=}' ) return '', requestcls, suffix or ''
def parse_table4(self, data): if len(self.name) == 0 or self.name == self.default_name(): strname = b2s(data[70:86].replace(b'\xff', '').replace(b'\x00', '').strip()) if len(strname): self.name = strname timerSetString = struct.unpack('<B', data[164:165])[0] timerValString = struct.unpack('<H', data[166:168])[0] self.timer_off_after_on = 0 if not timerSetString else timerValString tzS = struct.unpack('<B', data[162:163])[0] tz = struct.unpack('<B', data[163:164])[0] self.timezone = DeviceUDP.TIMEZONE_NOT_SET if tzS else tz
def mqtt_on_message(self, client, userdata, msg): Device.mqtt_on_message(self, client, userdata, msg) sub = self.mqtt_sub(msg.topic) try: if sub == "state": event.EventManager.fire(eventname='ExtInsertAction', hp=(self.host, self.port), cmdline="", action=ActionStatechange( self, b2s(msg.payload))) except: # noqa: E722 _LOGGER.warning(f"{traceback.format_exc()}")
def parse ( line: BYTES ) -> Union[SuccessResponse,ErrorResponse]: #log = logger.getChild ( 'Response.parse' ) assert isinstance ( line, bytes_types ) and len ( line ) > 0, f'invalid {line=}' try: ok, *extra = b2s ( line ).split ( ' ', 1 ) assert ok in ( '+OK', '-ERR' ), f'invalid {ok=}' except Exception as e: raise Closed ( f'malformed response from server {line=}: {e=}' ) from e text = extra[0].rstrip() if extra else '' if ok == '+OK': return SuccessResponse ( text ) else: return ErrorResponse ( text )
def on_CompleteEvent(self, event: smtp_proto.CompleteEvent) -> None: test.assertEqual(event.mail_from, '*****@*****.**') test.assertEqual(event.rcpt_to, ['*****@*****.**']) test.assertEqual( b2s(b''.join(event.data)), 'From: [email protected]\r\n' 'To: [email protected]\r\n' 'Subject: Test email\r\n' 'Date: 2000-01-01T00:00:00Z\r\n' # yes I know this isn't formatted correctly... '\r\n' # a sane person would use the email module to create their email content... 'This is a test. This message does not end in a period, period.\r\n' '.<<< Evil line beginning with a dot\r\n' 'Last line of message\r\n') event.accept() # or .reject()
def parse_multi ( cls: Type[MultiResponseType], *lines: BYTES, ) -> MultiResponseType: assert ( len ( lines ) >= 3 and isinstance ( lines[0], bytes_types ) and lines[0][0:1] in b'+-' and lines[-1][:] == b'.\r\n' ), f'invalid {[bytes(line) for line in lines]=}' self: MultiResponseType = cls.__new__ ( cls ) ok, *message = b2s ( lines[0] ).rstrip().split ( ' ', 1 ) self.ok = ( ok == '+OK' ) self.message = message[0] if message else '' self.lines = tuple ( map ( str.strip, map ( b2s, lines[1:-1] ) ) ) return self
def _parse_request_line( self, line: BYTES) -> Tuple[str, Opt[Type[BaseRequest]], str]: log = logger.getChild('Server._parse_request_line') m = _r_smtp_request.match(b2s(line).rstrip()) if not m: #log.critical ( f'{m=} {bytes(line)=}' ) return '', None, '' verb, suffix = m.groups() verb = verb.upper() # RFC5321#2.4 command verbs are not case-sensitive requestcls = _request_verbs.get(verb) if requestcls is None: log.debug(f'{requestcls=} {verb=} {_request_verbs=}') else: assert issubclass(requestcls, Request) requestcls, suffix = requestcls.subparse(self, suffix) return '', requestcls, suffix or ''
def _parse_dat(self, buf): """Parses the binary data from a channel list chunk and initilizes the member variables.""" # Each entry consists of (all integers are 16-bit little-endian unsigned): # [2 bytes int] Type of the channel. I've only seen 3 and 4, meaning # CDTV (Cable Digital TV, I guess) or CATV (Cable Analog # TV) respectively as argument for <ChType> # [2 bytes int] Major channel (<MajorCh>) # [2 bytes int] Minor channel (<MinorCh>) # [2 bytes int] PTC (Physical Transmission Channel?), <PTC> # [2 bytes int] Program Number (in the mux'ed MPEG or so?), <ProgNum> # [2 bytes int] They've always been 0xffff for me, so I'm just assuming # they have to be :) # [4 bytes string, \0-padded] The (usually 3-digit, for me) channel number # that's displayed (and which you can enter), in ASCII # [2 bytes int] Length of the channel title # [106 bytes string, \0-padded] The channel title, in UTF-8 (wow) t = _getint(buf, 0) if t == 4: self.ch_type = 'CDTV' elif t == 3: self.ch_type = 'CATV' elif t == 2: self.ch_type = 'DTV' else: raise ParseException('Unknown channel type %d' % t) self.major_ch = _getint(buf, 2) self.minor_ch = _getint(buf, 4) self.ptc = _getint(buf, 6) self.prog_num = _getint(buf, 8) if _getint(buf, 10) != 0xffff: raise ParseException('reserved field mismatch (%04x)' % _getint(buf, 10)) self.dispno = b2s(buf[12:16].rstrip(b'\x00')) title_len = _getint(buf, 22) self.title = buf[24:24 + title_len].decode('utf-8')
def parse( line: BYTES ) -> Union[SuccessResponse, ErrorResponse, IntermediateResponse]: #log = logger.getChild ( 'Response.parse' ) assert isinstance(line, bytes_types) try: code = int(line[:3]) assert 200 <= code <= 599, f'invalid {code=}' intermediate = line[3:4] text = b2s(line[4:]).rstrip() assert intermediate in (b' ', b'-') except Exception as e: raise Closed( f'malformed response from server {line=}: {e=}') from e if intermediate == b'-': return IntermediateResponse(code, text) if code < 400: return SuccessResponse(code, text) else: return ErrorResponse(code, text)
import base64 import util a_a = "1c0111001f010100061a024b53535009181c" b_a = "686974207468652062756c6c277320657965" a_i = util.a2i(a_a) b_i = util.a2i(b_a) c_i = int(a_i ^ b_i) c_a = util.i2a(c_i) print(c_a) print(util.b2s(util.a2b(c_a)))
import util # Mostly copied code from s6.py ciphertexts = [base64.b64decode(l.strip()) for l in open('20.txt')] min_len = min(len(ct) for ct in ciphertexts) keysize = min_len chunks = [ct[:min_len] for ct in ciphertexts] key_chars = [] key_score = 0 for block in zip(*chunks): candidates = [] for key_i in range(256): try: candidates.append( (key_i, util.b2s(util.single_byte_xor(util.safe_bytes(block), key_i)))) except UnicodeDecodeError: pass key, pt = max(candidates, key=lambda x: util.score_plaintext(x[1])) key_chars.append(key) key_score += util.score_plaintext(pt) for chunk in chunks: msg_b = util.repeating_key_xor(chunk, key_chars) print(msg_b.decode())
import util if __name__ == '__main__': a_a = '1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736' a_b = util.a2b(a_a) candidates = [] for key_i in range(256): try: candidates.append((key_i, util.b2s(util.single_byte_xor(a_b, key_i)))) except UnicodeDecodeError: pass print(max(candidates, key=lambda x: util.score_plaintext(x[1]))[1])
def process_asynch_state_change(self, state): self.state = b2s(state)
import base64 import util # Mostly copied code from s6.py ciphertexts = [base64.b64decode(l.strip()) for l in open('20.txt')] min_len = min(len(ct) for ct in ciphertexts) keysize = min_len chunks = [ct[:min_len] for ct in ciphertexts] key_chars = [] key_score = 0 for block in zip(*chunks): candidates = [] for key_i in range(256): try: candidates.append((key_i, util.b2s(util.single_byte_xor(util.safe_bytes(block), key_i)))) except UnicodeDecodeError: pass key, pt = max(candidates, key=lambda x: util.score_plaintext(x[1])) key_chars.append(key) key_score += util.score_plaintext(pt) for chunk in chunks: msg_b = util.repeating_key_xor(chunk, key_chars) print(msg_b.decode())
import base64 import util f = open('10.txt') enc_b = base64.b64decode(''.join(f)) f.close() key_b = b'YELLOW SUBMARINE' msg_b = util.cbc_dec(enc_b, key_b) print(util.b2s(msg_b))
import util if __name__ == '__main__': a_a = '1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736' a_b = util.a2b(a_a) candidates = [] for key_i in range(256): try: candidates.append( (key_i, util.b2s(util.single_byte_xor(a_b, key_i)))) except UnicodeDecodeError: pass print(max(candidates, key=lambda x: util.score_plaintext(x[1]))[1])
import base64 from Crypto.Cipher import AES import util key_b = b'YELLOW SUBMARINE' cipher = AES.new(key_b, AES.MODE_ECB) f = open('7.txt') s = ''.join(l.strip() for l in f) f.close() enc_b = base64.standard_b64decode(s) print(util.b2s(util.aes_ecb_dec(enc_b, key_b)))
# step 2: detect that the function is using ECB test_str = util.random_bytes(blocksize) test_enc = oracle(test_str + test_str) p1, p2 = util.make_chunks(test_enc, blocksize)[:2] if p1 == p2: print('Oracle is using ECB') enc_block_at = {} dec_so_far = bytes() for byte_num in range(start_len): if byte_num < blocksize: prepend = b'a' * (blocksize - byte_num - 1) else: prepend = dec_so_far[-blocksize + 1:] enc_chunks = util.make_chunks(oracle(prepend), blocksize) if byte_num < blocksize: for n, chunk in enumerate(enc_chunks[1:]): enc_block_at[byte_num + (n * blocksize)] = chunk want = enc_chunks[0] else: want = enc_block_at[byte_num - blocksize] if byte_num < blocksize: prepend += dec_so_far for b in range(256): if oracle(prepend + bytes([b]))[:blocksize] == want: dec_so_far += bytes([b]) break print() print(util.b2s(dec_so_far))
def mqtt_on_message_discovery(client, devices, msg): topic = b2s(msg.topic) devname = topic[len("tele/tasmota_switch/"):-4] _LOGGER.info(f"Found {devname}") devices["tasmota_switch_" + devname] = DeviceTasmotaswitch( mac="tasmota_switch_" + devname, name=devname)
import util candidates = [] f = open('4.txt') for l in f: l_a = l.strip() l_b = util.a2b(l_a) for key_i in range(256): try: candidates.append( (l_a, key_i, util.b2s(util.single_byte_xor(l_b, key_i)))) except UnicodeDecodeError: pass f.close() print(max(candidates, key=lambda x: util.score_plaintext(x[2]))[2])
def parse(self, clinfo, data): if isinstance(clinfo, dict): returnv = clinfo else: returnv = {'addr': clinfo} hp = returnv['addr'] if len(data) > 6 and data[0:1] == b'@': returnv['type'] = b'mfz' idx = data.find(b'\n') if idx < 0: if len(data) >= 200: returnv['idxout'] = RoughParser.DISCARD_BUFFER else: returnv['idxout'] = RoughParser.STILL_WAIT else: _LOGGER.info("R [" + hp[0] + ":" + str(hp[1]) + "] <-" + b2s(data)) event.EventManager.fire(eventname='ExtInsertAction', hp=hp, cmdline=b2s(data[1:]), action=None) returnv['idxout'] = idx + 1 elif len(data) > 7 and data[0:2] == MAGIC: msgid = data[4:6] ln = struct.unpack('>H', data[2:4])[0] _LOGGER.info("Detected Magic with ln %d and id %s" % (ln, b2s(msgid))) if len(data) >= ln: returnv[ 'type'] = b'cry' if msgid == PK_MSG_ID or msgid == DK_MSG_ID else b'orv' returnv['idxout'] = ln contentmsg = data[0:ln] if msgid == PK_MSG_ID: outv = SendBufferTimer.handle_incoming_data(contentmsg) if outv is not None: obj = outv['msg'] if obj['cmd'] == 0: name = obj['hardwareVersion'] # obj['serial'] dictout = { 'serial': 0, 'cmd': 0, 'key': None, 'status': 0 } returnv['name'] = name.replace(' ', '_') returnv['reply'] = SendBufferTimer.get_send_bytes( dictout, None, typemsg=b"pk") returnv['key'] = dictout['key'] elif msgid == DK_MSG_ID: if 'sender' in clinfo: outv = clinfo['sender'].handle_incoming_data2( contentmsg) else: outv = SendBufferTimer.handle_incoming_data( contentmsg, returnv['key']) if outv is not None: obj = outv['msg'] if obj['cmd'] == 6: returnv['hp'] = hp returnv['localIp'] = obj['localIp'] returnv['localPort'] = obj['localPort'] returnv['password'] = obj['password'] returnv['mac'] = tohexs(obj['uid']) returnv['convid'] = outv['convid'] dictout = { 'serial': obj['serial'], 'cmd': 6, 'status': 0 } returnv['reply'] = SendBufferTimer.get_send_bytes( dictout, outv['convid'], key=returnv['key'], typemsg=b"dk") dev = DeviceCT10( hp=hp, mac=returnv['mac'], name=returnv['name'] + '_' + obj['uid'], key=returnv['key'], password=obj['password'], deviceid=generatestring(32), clientsessionid=generatestring(32), hp2=(obj['localIp'], obj['localPort'])) returnv['device'] = dev act = ActionDiscovery() act.hosts[obj['uid']] = dev event.EventManager.fire( eventname='ActionDiscovery', device=dev, action=act, retval=1) elif obj['cmd'] == 116 or obj['cmd'] == 32: dictout = { 'serial': obj['serial'], 'cmd': obj['cmd'], 'status': 0, 'uid': obj['uid'] } returnv['reply'] = SendBufferTimer.get_send_bytes( dictout, outv['convid'], key=returnv['key'], typemsg=b"dk") returnv['disconnecttimer'] = time.time() + 3 * 60 else: if msgid == STATECHANGE_EXT_ID or msgid == DISCOVERY_ID: event.EventManager.fire( eventname='ExtChangeState', hp=hp, mac=DeviceUDP.mac_from_data(data), newstate="1" if data[-1:] == b'\x01' else "0") rx = re.compile(MAGIC + b'(.{2}).{2}.*' + MAC_START) control = {} off = 0 while True: m = re.search(rx, data) if m: st = m.start() ln = struct.unpack('>H', m.group(1))[0] # _LOGGER.info("st = {} ln = {}".format(st,ln)) off = st + ln if off <= len(data): sect = data[st:off] data = data[off:] keyv = DeviceUDP.keyfind(hp, sect) if keyv not in control: control[keyv] = 1 event.EventManager.fire( eventname='RawDataReceived', key=keyv, hp=hp, data=sect) _LOGGER.info("R [" + keyv + "] <-" + tohexs(sect)) else: break else: break returnv[ 'idxout'] = RoughParser.UNRECOGNIZED if not off else off else: returnv['idxout'] = RoughParser.STILL_WAIT else: returnv['idxout'] = RoughParser.UNRECOGNIZED return returnv
d = enc_b[keysize*4:keysize*5] score = sum(util.hamming_dist(x, y) for x, y in combinations([a, b, c, d], 2)) candidates.append((keysize, score / keysize)) possible_sizes = [x[0] for x in sorted(candidates, key=lambda x: x[1])[:3]] possible_keys = [] for keysize in possible_sizes: chunks = util.make_chunks(enc_b, keysize) key_chars = [] key_score = 0 # zip_longest transposes the list of lists for block in zip_longest(*chunks): candidates = [] for key_i in range(256): try: candidates.append((key_i, util.b2s(util.single_byte_xor(util.safe_bytes(block), key_i)))) except UnicodeDecodeError: pass key, pt = max(candidates, key=lambda x: util.score_plaintext(x[1])) key_chars.append(key) key_score += util.score_plaintext(pt) possible_keys.append((bytes(key_chars), key_score)) key_b = max(possible_keys, key=lambda x: x[1])[0] dec_b = util.repeating_key_xor(enc_b, key_b) print('Key: {}\n------'.format(util.b2s(key_b))) print(util.b2s(dec_b))