class SPMPPacket(PacketType): DEFINITION_IDENTIFIER = "devices.management.SPMPPacket" DEFINITION_VERSION = "1.0" MAX_ID = (2**16) - 1 FIELDS = [ ("requestId", UINT16), ("request", STRING), ("args", LIST(STRING)), ("result", STRING), ("error", STRING({Optional: True})), # The security fields are generic on purpose. Different # security mechanisms have an arbitrary number of fields # For example, a security buffer could be a signature, # encrypted data, password data, etc. ("securityType", STRING({Optional: True})), ("security", LIST(BUFFER, {Optional: True})) ] def generateRequestId(self): self.requestId = random.randint(0, self.MAX_ID) def failed(self): return self.error != FIELD_NOT_SET
def __init__(self): super().__init__ self.ClientNonce = random.randint(10000, 99999) self.ServerNonce = None self.deserializer = BasePacketType.Deserializer() self.ClientCert = LIST(BUFFER) self.ServerCert = LIST(BUFFER) self.PacketsList = [] self.Certobject = []
class PlsHello(BasePacketType): DEFINITION_IDENTIFIER = "netsecfall2017.pls.hello" DEFINITION_VERSION = "1.0" FIELDS = [ ("Nonce", UINT64), ("Certs", LIST(BUFFER)) ]
class MobileCodeServiceDiscoveryResponse(MobileCodePacket): DEFINITION_IDENTIFIER = MOBILE_CODE_PACKAGE+"MobileCodeServiceDiscoveryResponse" DEFINITION_VERSION = "1.0" FIELDS = [ ("Address", STRING), ("Port", UINT16), ("Traits", LIST(STRING)) ]
class PlsHello(PacketType): DEFINITION_IDENTIFIER = "netsecfall2017.pls.hello" DEFINITION_VERSION = "1.0" FIELDS = [("Nonce", UINT64), ("Certs", LIST(BUFFER))] def __init__(self, nonce, certs): super().__init__() self.Nonce = nonce self.Certs = certs
class SITHPacket(PacketType): DEFINITION_IDENTIFIER = "SITH.kandarp.packet.Base" DEFINITION_VERSION = "1.0" TYPE_HELLO = "HELLO" TYPE_FINISH = "FINISH" TYPE_DATA = "DATA" TYPE_CLOSE = "CLOSE" FIELDS = [ ("Random", BUFFER({Optional: True})), #older version ("Type", STRING({Optional: True})), # HELLO, FINISH, DATA, CLOSE ("PublicValue", BUFFER({Optional: True})), #to store public key ("Certificate", LIST(BUFFER)({Optional: True})), #inherit older version 'Certs' ("Signature", BUFFER({Optional: True})), ("Ciphertext", BUFFER({Optional: True})) #inherit older version 'Ciphertext' ] @classmethod def makeHelloPacket(cls, random, certs, public_key): pkt = cls() pkt.Random = random pkt.Certificate = certs pkt.Type = cls.TYPE_HELLO pkt.PublicValue = public_key.public_bytes() #change the format of 'public_key' to bytes, in order to be stored in 'Buffer' field return pkt @classmethod def makeFinishPacket(cls, m1, m2, private_key): pkt = cls() hasher = hashes.Hash(hashes.SHA256(), backend = default_backend()) hasher.update(m1 + m2) #input message needed to hash hash_msg = hasher.finalize() # get the hash result signed_msg = private_key.sign( #generate the signature of messages by signing its hash hash_msg, ec.ECDSA(hashes.SHA256()) ) pkt.Type = cls.TYPE_FINISH pkt.Signature = signed_msg return pkt @classmethod def makeDataPacket(cls, ciphertext): pkt = cls() pkt.Ciphertext = ciphertext pkt.Type = cls.TYPE_DATA return pkt @classmethod def makeClosePacket(cls, error): pkt = cls() pkt.Ciphertext = bytes(error) pkt.Type = cls.TYPE_CLOSE return pkt
class OpenSessionResponse(MobileCodePacket): DEFINITION_IDENTIFIER = MOBILE_CODE_PACKAGE+"OpenSessionResponse" DEFINITION_VERSION = "1.0" FIELDS = [ ("Cookie", UINT64), ("WalletId", STRING), ("AuthId", STRING), ("EngineId", STRING), ("NegotiationAttributes", LIST(STRING)) ]
class PlsHello(PlsBasePacket): DEFINITION_IDENTIFIER = "netsecfall2017.pls.hello" DEFINITION_VERSION = "1.0" FIELDS = [("Nonce", UINT64), ("Certs", LIST(BUFFER))] def __repr__(self): certs = [] for c in self.Certs: certs.append(str(c)) return "PlsHello: \nNonce: " + str( self.Nonce) + "\nCerts: " + str(certs) + "\n"
class SITHPacket(PacketType): DEFINITION_IDENTIFIER = "SITH.kandarp.packet" DEFINITION_VERSION = "1.0" FIELDS = [ ("Type", STRING), ("Random", BUFFER({Optional: True})), ("PublicValue", BUFFER({Optional: True})), ("Certificate", LIST(BUFFER)({Optional: True})), ("Signature", BUFFER({Optional: True})), ("Ciphertext", BUFFER({Optional: True})) ]
class HandshakePacket(CrapPacketType): DEFINITION_IDENTIFIER = "crap.handshakepacket" DEFINITION_VERSION = "1.0" NOT_STARTED = 0 SUCCESS = 1 ERROR = 2 FIELDS = [("status", UINT8), ("nonce", UINT32({Optional: True})), ("nonceSignature", BUFFER({Optional: True})), ("signature", BUFFER({Optional: True})), ("pk", BUFFER({Optional: True})), ("cert", BUFFER({Optional: True})), ("certChain", LIST(BUFFER, {Optional: True}))]
def __init__(self): super().__init__ self.privatekeyaddr = "/Users/runjiezhang/Desktop/public&private_key/host/Dumplinghostprivate.pem" self.hostmediacert = "/Users/runjiezhang/Desktop/public&private_key/host/Dumplinghostcert.cert" self.rootaddr = "/Users/runjiezhang/Desktop/public&private_key/root/root.crt" self.intermidiacertaddr = "/Users/runjiezhang/Desktop/public&private_key/intermedia/DumplingCertificate.cert" self.transport = None self.ClientNonce = random.randint(10000, 99999) self.ServerNonce = None self.deserializer = BasePacketType.Deserializer() self.privateKeystring = getPrivateKeyForAddr(self.privatekeyaddr) self.privateKey = RSA.importKey(self.privateKeystring) self.certificate = getCertificateForAddr(self.hostmediacert) self.intermediaCert = getCertificateForAddr(self.intermidiacertaddr) self.rootcert = getRootCert(self.rootaddr) self.ClientCert = LIST(BUFFER) self.ClientCert.append(self.certificate.encode()) self.ClientCert.append(self.intermediaCert.encode()) self.ClientCert.append(self.rootcert.encode()) self.ServerCert = LIST(BUFFER) self.PacketsList = [] self.Certobject = []
class PlsHello(PacketBaseType): DEFINITION_IDENTIFIER = "netsecfall2017.pls.hello" DEFINITION_VERSION = "1.0" FIELDS = [("Nonce", UINT64), ("Certs", LIST(BUFFER))] @staticmethod def create(Nonce, Certs): newPacket = PlsHello() newPacket.Nonce = Nonce newPacket.Certs = Certs return newPacket
class PlsHello(PlsBasicType): DEFINITION_IDENTIFIER = "netsecfall2017.pls.hello" DEFINITION_VERSION = "1.0" FIELDS = [ ("Nonce", UINT64), ("Certs", LIST(BUFFER)) ] @classmethod def makeHelloPacket(cls, nonce, certs): pkt = cls() pkt.Nonce = nonce pkt.Certs = certs return pkt
class SITHPacket(PacketType): DEFINITION_IDENTIFIER = "SITH.kandarp.packet" DEFINITION_VERSION = "1.0" FIELDS = [ ("Type", STRING), # HELLO, FINISH, DATA, CLOSE ("Random", BUFFER({Optional: True})), ("PublicValue", BUFFER({Optional: True})), ("Certificate", LIST(BUFFER)({ Optional: True })), ("Signature", BUFFER({Optional: True})), ("Ciphertext", BUFFER({Optional: True})) ] def sith_hello(self, random, public_val, certs): hello = SITHPacket() hello.Type = SITHPacketType.HELLO.value hello.Random = random hello.PublicValue = public_val hello.Certificate = certs return hello def sith_finish(self, signature): finish = SITHPacket() finish.Type = SITHPacketType.FINISH.value finish.Signature = signature return finish def sith_data(self, ciphertext): data = SITHPacket() data.Type = SITHPacketType.DATA.value data.Ciphertext = ciphertext return data def sith_close(self, error=None): close = SITHPacket() close.Type = SITHPacketType.CLOSE.value close.Ciphertext = bytes(error, 'utf-8') return close def __repr__(self): return super(SITHPacket, self).__repr__() + \ ". Type: " + str(self.Type) + \ ". Random: " + str(self.Random) + \ ". PublicValue: " + str(self.PublicValue) + \ ". Certificate: " + str(self.Certificate) + \ ". Ciphertext: " + str(self.Ciphertext)
def getCertificateForAddr(addr): if addr == "20174.1.12321.666": hostmediacert = "/Users/wangweizhou/Desktop/public&private_key/host/Dumplinghostcert.cert" intermidiacertaddr = "/Users/wangweizhou/Desktop/public&private_key/intermedia/DumplingCertificate.cert" ClientCert = LIST(BUFFER) with open(hostmediacert) as f: Certificate0 = f.read() ClientCert.append(Certificate0.encode()) with open(intermidiacertaddr) as f: Certificate1 = f.read() ClientCert.append(Certificate1.encode()) return ClientCert
class PLSPacket(PacketType): DEFINITION_IDENTIFIER = 'PLS.Packet' DEFINITION_VERSION = '1.0' FIELDS = [ ('Type', STRING), # type can be Hello, KeyTransport, Finished, Data and Close. ('Premaster_Secret', BUFFER({Optional: True})), ('Random', BUFFER({Optional: True})), ('Certificate', LIST(BUFFER, {Optional: True})), ('Encrypted_Data', BUFFER) ] @classmethod def HelloPacket(cls, random, mychain): pkt = cls() pkt.Type = "Hello" pkt.Random = random pkt.Certificate = mychain pkt.Encrypted_Data = b"" print("<><><><> SENT Hello Packet <><><><>") return pkt @classmethod def KeyPacket(cls, random): pkt = cls() pkt.Type = "KeyTransport" pkt.Premaster_Secret = random # need to sort it out #pkt.Random = random #This too #pkt.Certificate = PLSCertificate #Should send a list pkt.Encrypted_Data = b"" print("<><><><> SENT Key Packet <><><><>") return pkt @classmethod def FinPacket(cls): pkt = cls() pkt.Type = "Finished" #pkt.Premaster_Secret = "" # need to sort it out #pkt.Random = "" #This too #pkt.Certificate = "" #Should send a list pkt.Encrypted_Data = b"" print("<><><><> SENT Finished Packet <><><><>") return pkt @classmethod def ClosePacket(cls): pkt = cls() pkt.Type = "Close" #pkt.Premaster_Secret = "" # need to sort it out #pkt.Random = 0 #This too #pkt.Certificate = "" #Should send a list pkt.Encrypted_Data = b"" print("<><><><> SENT Close Packet <><><><>") return pkt @classmethod def DataPacket(cls, encrypted_data): pkt = cls() pkt.Type = "Data" #pkt.Premaster_Secret = "" # need to sort it out #pkt.Random = 0 #This too #pkt.Certificate = "" #Should send a list pkt.Encrypted_Data = encrypted_data print("<><><><> SENT Data Packet <><><><>") return pkt
class PLSClient(StackingProtocol): def __init__(self): super().__init__ self.privatekeyaddr = "/Users/runjiezhang/Desktop/public&private_key/host/Dumplinghostprivate.pem" self.hostmediacert = "/Users/runjiezhang/Desktop/public&private_key/host/Dumplinghostcert.cert" self.rootaddr = "/Users/runjiezhang/Desktop/public&private_key/root/root.crt" self.intermidiacertaddr = "/Users/runjiezhang/Desktop/public&private_key/intermedia/DumplingCertificate.cert" self.transport = None self.ClientNonce = random.randint(10000, 99999) self.ServerNonce = None self.deserializer = BasePacketType.Deserializer() self.privateKeystring = getPrivateKeyForAddr(self.privatekeyaddr) self.privateKey = RSA.importKey(self.privateKeystring) self.certificate = getCertificateForAddr(self.hostmediacert) self.intermediaCert = getCertificateForAddr(self.intermidiacertaddr) self.rootcert = getRootCert(self.rootaddr) self.ClientCert = LIST(BUFFER) self.ClientCert.append(self.certificate.encode()) self.ClientCert.append(self.intermediaCert.encode()) self.ClientCert.append(self.rootcert.encode()) self.ServerCert = LIST(BUFFER) self.PacketsList = [] self.Certobject = [] def connection_made(self, transport): print("Client: PLS initialized!") self.transport = transport self.higherTransport = PlsTransport(self.transport, self) #self.higherProtocol().connection_made(higherTransport) HelloPacket = PlsHello() HelloPacket.Nonce = self.ClientNonce HelloPacket.Certs = self.ClientCert # required for modification self.transport.write(HelloPacket.__serialize__()) self.PacketsList.append(HelloPacket) self.status = 0 #print(self.certificate) def data_received(self, data): self.deserializer.update(data) for pkt in self.deserializer.nextPackets(): if self.status == 0: if isinstance(pkt, PlsHello): self.ServerCert = pkt.Certs if self.ChainVerifyer(self.ServerCert): print("Client: PlsHello packet receive!") self.PacketsList.append(pkt) self.ServerNonce = pkt.Nonce self.ServerCertificate = self.ServerCert[0].decode() self.tmpPublickey = OpenSSL.crypto.load_certificate( OpenSSL.crypto.FILETYPE_PEM, self.ServerCertificate).get_pubkey() self.publickeystring = OpenSSL.crypto.dump_publickey( OpenSSL.crypto.FILETYPE_PEM, self.tmpPublickey).decode() self.serverPublicKey = RSA.importKey( self.publickeystring) KeyExchangePacket = PlsKeyExchange() self.ClientPrekey = b"helloworld" cipher = self.serverPublicKey.encrypt( self.ClientPrekey, 32)[0] KeyExchangePacket.PreKey = cipher KeyExchangePacket.NoncePlusOne = self.ServerNonce + 1 self.transport.write(KeyExchangePacket.__serialize__()) print("Client: KeyExchange sent!") self.PacketsList.append(KeyExchangePacket) else: print("Client: Authentication Error!") if isinstance(pkt, PlsKeyExchange): print("Client: PlskeyExchange receive!") self.PacketsList.append(pkt) self.ServerPrekey = self.privateKey.decrypt(pkt.PreKey) self.validation = b'' for packet in self.PacketsList: pktdata = packet.__serialize__() self.validation = self.validation + pktdata self.hashvalidation = hashlib.sha1( self.validation).hexdigest() HandshakeDonePacket = PlsHandshakeDone() HandshakeDonePacket.ValidationHash = self.hashvalidation.encode( ) self.transport.write(HandshakeDonePacket.__serialize__()) print("Client: HandshakeDone packet sent!") if isinstance(pkt, PlsHandshakeDone): print("Client: Handshake Done!") self.CalHash() self.higherProtocol().connection_made(self.higherTransport) self.status = 1 if isinstance(pkt, PlsClose): self.connection_lost("Error raised!") if self.status == 1: if isinstance(pkt, PlsData): if pkt.Mac == self.VerificationEngine(pkt.Ciphertext): higherData = self.decryptEngine(pkt.Ciphertext) self.higherProtocol().data_received(higherData) def ChainVerifyer(self, certs): for cert in certs: self.Certobject.append( x509.load_pem_x509_certificate(cert, default_backend())) address = self.transport.get_extra_info("peername")[0] if address != self.Certobject[0].subject.get_attributes_for_oid( NameOID.COMMON_NAME)[0].value: return False verifyaddr = address for i in range(len(self.Certobject)): if verifyaddr.startswith( self.Certobject[i].subject.get_attributes_for_oid( NameOID.COMMON_NAME)[0].value): verifyaddr = self.Certobject[i].subject.get_attributes_for_oid( NameOID.COMMON_NAME)[0].value else: return False for i in range(len(self.Certobject) - 1): this = self.Certobject[i] issuer = RSA_SIGNATURE_MAC(self.Certobject[i + 1].public_key()) if not issuer.verify(this.tbs_certificate_bytes, this.signature): return False print("Certification Authentication Passed!") return True def VerificationEngine(self, ciphertext): hm = HMAC.new(self.MKs, digestmod=SHA) hm.update(ciphertext) return hm.digest() def MacEngine(self, ciphertext): hm = HMAC.new(self.MKc, digestmod=SHA) hm.update(ciphertext) return hm.digest() def encryptEngine(self, plaintext): crt = Counter.new(128, initial_value=int( codecs.encode(self.IVc, 'hex_codec'), 16)) aesEncrypter = AES.new(self.EKc, counter=crt, mode=AES.MODE_CTR) ciphertext = aesEncrypter.encrypt(plaintext) return ciphertext def decryptEngine(self, ciphertext): crt = Counter.new(128, initial_value=int( codecs.encode(self.IVs, 'hex_codec'), 16)) aesDecrypter = AES.new(self.EKs, counter=crt, mode=AES.MODE_CTR) plaintext = aesDecrypter.decrypt(ciphertext) return plaintext def CalHash(self): hashdata = b"PLS1.0" + self.ClientNonce.__str__().encode( ) + self.ServerNonce.__str__().encode( ) + self.ClientPrekey + self.ServerPrekey block0 = hashlib.sha1(hashdata).hexdigest() block1 = hashlib.sha1(block0.encode()).hexdigest() block2 = hashlib.sha1(block1.encode()).hexdigest() block3 = hashlib.sha1(block2.encode()).hexdigest() block4 = hashlib.sha1(block3.encode()).hexdigest() keyset = block0.encode() + block1.encode() + block2.encode( ) + block3.encode() + block4.encode() self.EKc = keyset[0:32] self.EKs = keyset[32:64] self.IVc = keyset[64:96] self.IVs = keyset[96:128] self.MKc = keyset[128:160] self.MKs = keyset[160:192] def connection_lost(self, exc): print('Connection stopped because {}'.format(exc))
class GPSNetworkMessage(playground.network.packet.PacketType): DEFINITION_IDENTIFIER = "simulator.traffic.gps_message" DEFINITION_VERSION = "1.0" FIELDS = [("Timestamp", UINT32), ("Map", LIST(LIST(STRING))), ("Signature", BUFFER)]
class PlsHello(PLSPacket): DEFINITION_IDENTIFIER = 'netsecfall2017.pls.hello' DEFINITION_VERSION = '1.0' FIELDS = [('Nonce', UINT64), ('Certs', LIST(BUFFER))]
class AdminBalanceResponse(PacketType): DEFINITION_IDENTIFIER = "apps.bank.AdminBalanceResponse" DEFINITION_VERSION = "1.0" FIELDS = [("ClientNonce", UINT64), ("ServerNonce", UINT64), ("RequestId", UINT64), ("Accounts", LIST(STRING)), ("Balances", LIST(INT64))]
class ListUsersResponse(PacketType): DEFINITION_IDENTIFIER = "apps.bank.ListUsersResponse" DEFINITION_VERSION = "1.0" FIELDS = [("ClientNonce", UINT64), ("ServerNonce", UINT64), ("RequestId", UINT64), ("Users", LIST(STRING))]
class LedgerResponse(PacketType): DEFINITION_IDENTIFIER = "apps.bank.LedgerResponse" DEFINITION_VERSION = "1.0" FIELDS = [("ClientNonce", UINT64), ("ServerNonce", UINT64), ("RequestId", UINT64), ("Lines", LIST(BUFFER))]