Finalize CFB test script

This commit is contained in:
stulle123 2023-12-26 15:45:33 +01:00
parent 306ff798cd
commit 3c9880d142

View File

@ -1,9 +1,9 @@
import bson
from lib.crypto_utils import aes_decrypt, aes_encrypt
from lib.crypto_utils import aes_decrypt
from lib.loco_parser import LocoParser
"""
# Hexdump of the LOCO packet used here as an example
_HEXDUMP = """
Offset 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000 8A 80 CE 0E 00 00 4D 53 47 00 00 00 00 00 00 00 ......MSG.......
00000010 00 08 DD 00 00 00 DD 00 00 00 10 73 74 61 74 75 ...........statu
@ -23,29 +23,52 @@ from lib.loco_parser import LocoParser
000000F0 00 00 00
"""
_CIPHERTEXT = b"\xeb.\xbc\x0e\x9eHr3\xd4n]\x97\x9c{;\xa77\x7f\x94\x1b\xf7\xba\x126\xa32\xe2\x89\xe8\xa4-S\xf9\x80\r\x17kn\x15\x97\xa6\xe5\x8d\xd1\nE\xb1\xd9\xec\xb1`O\x86\xce\x1e\xbc\xa7\x99\x1c\xc2\x8au\xa0a\x04\x03\xacj<L\xe7D\x91\x82\xbb\xa4\xc5\xcb\x89\x0e\xd17\xb9\x90R\xc8;\x95+\xd5\xfb\xd4\xf2\x03`\xcdF\xc8\xc1\x0b\xe08\xbaY\r\x86S\xd0.\xca\xf6\xce\xdc\xf9\x11\xc1\xbdV\xcf\xd4S\x8db\xff\xfb\xb4x\xc6\xfe4\x05\xe2T6\xc7j\xb7\x1f\t\x18o;\xfb\xad\xc8\x86\x8f'1$\xfe\xdc\xf3O\xd8?e\x84[\xbcR\\\xac\x82f'\x02\xf1\x11\xda\xf5/\x8c\x91\xfc\xe01\x8e\xf3!\xf7\xd4\x12\ts\x82\t\xe7_f\x15\x8ev\xf6c)\r\x0b\xb8\xee\x9cZc8W\xd6/m?\x7f\xe7S:4\xd1ud4\x18{f\x07\xb8\xfa\xbd\x10f\x96\x18\x88\xe2\x17]\xce\xd2\xdbK1\xcf\xd4\x91N\\"
_IV = b"g\xedV]\x84M\x9e\xb0\xe6\x83X\x98x\x80\xd0]"
def xor(param1, param2):
return bytes((x ^ y) for (x, y) in zip(param1, param2))
parser = LocoParser()
ciphertext = b"\xeb.\xbc\x0e\x9eHr3\xd4n]\x97\x9c{;\xa77\x7f\x94\x1b\xf7\xba\x126\xa32\xe2\x89\xe8\xa4-S\xf9\x80\r\x17kn\x15\x97\xa6\xe5\x8d\xd1\nE\xb1\xd9\xec\xb1`O\x86\xce\x1e\xbc\xa7\x99\x1c\xc2\x8au\xa0a\x04\x03\xacj<L\xe7D\x91\x82\xbb\xa4\xc5\xcb\x89\x0e\xd17\xb9\x90R\xc8;\x95+\xd5\xfb\xd4\xf2\x03`\xcdF\xc8\xc1\x0b\xe08\xbaY\r\x86S\xd0.\xca\xf6\xce\xdc\xf9\x11\xc1\xbdV\xcf\xd4S\x8db\xff\xfb\xb4x\xc6\xfe4\x05\xe2T6\xc7j\xb7\x1f\t\x18o;\xfb\xad\xc8\x86\x8f'1$\xfe\xdc\xf3O\xd8?e\x84[\xbcR\\\xac\x82f'\x02\xf1\x11\xda\xf5/\x8c\x91\xfc\xe01\x8e\xf3!\xf7\xd4\x12\ts\x82\t\xe7_f\x15\x8ev\xf6c)\r\x0b\xb8\xee\x9cZc8W\xd6/m?\x7f\xe7S:4\xd1ud4\x18{f\x07\xb8\xfa\xbd\x10f\x96\x18\x88\xe2\x17]\xce\xd2\xdbK1\xcf\xd4\x91N\\"
iv = b"g\xedV]\x84M\x9e\xb0\xe6\x83X\x98x\x80\xd0]"
if __name__ == "__main__":
parser = LocoParser()
# The known plaintext of the 11th block
known_plaintext_block_11 = b"AAAAAAAAAAAAAAAA"
ciphertext_block_11 = _CIPHERTEXT[0xA0 : 0xA0 + 0x10]
p11 = b"AAAAAAAAAAAAAAAA"
c11 = ciphertext[0xA0 : 0xA0 + 0x10]
x = xor(c11, p11)
c11_new = xor(x, b"BBBBBBBB\x00\x05\x00\x11\x00\x00\x00\x00")
# XOR the two blocks
x = xor(ciphertext_block_11, known_plaintext_block_11)
plaintext_unmodified = aes_decrypt(ciphertext, iv)
body_unmodified = parser.parse_loco_packet(plaintext_unmodified).body_payload
print(bson.loads(bytes(body_unmodified)))
# As the 12th block will be garbled after modification, we tell the BSON decoder to treat it as binary data
# \x00 -> null terminator
# \x05 -> 0x05 = type binary data
# \x00 -> null terminator
# \x11\x00\x00\x00\x00 -> field value size (which is 17 including the null terminator)
# See https://en.wikipedia.org/wiki/BSON
target_plaintext_block_11 = b"BBBBBBBB\x00\x05\x00\x11\x00\x00\x00\x00"
ciphertext_modified = bytearray(ciphertext)
ciphertext_modified[0xA0 : 0xA0 + 0x10] = c11_new
plaintext_modified = aes_decrypt(ciphertext_modified, iv)
# XOR again
ciphertext_block_11_new = xor(x, target_plaintext_block_11)
loco_packet = parser.parse_loco_packet(plaintext_modified)
body = bytearray(loco_packet.body_payload)
body[128:129] = b"\x0F"
print(bson.loads(bytes(body)))
# Replace the 11th block with the new block
modified_ciphertext = bytearray(_CIPHERTEXT)
modified_ciphertext[0xA0 : 0xA0 + 0x10] = ciphertext_block_11_new
# Decrypt the modified ciphertext and let the bits flip
modified_packet = aes_decrypt(modified_ciphertext, _IV)
loco_packet = parser.parse_loco_packet(modified_packet)
loco_body = bytearray(loco_packet.body_payload)
# Patch the size of the "message" field value from 39 to 15
# Python's BSON decoder requires this
# KakaoTalk's BSON parser doesn't
loco_body[128:129] = b"\x0F"
# Print the packet before bit flipping
unmodified_packet = aes_decrypt(_CIPHERTEXT, _IV)
unmodified_body = parser.parse_loco_packet(unmodified_packet).body_payload
print(bson.loads(bytes(unmodified_body)))
# Print the packet after it
print(bson.loads(bytes(loco_body)))