private SecurityHeader GetBasicUnsignedHeader() { // The header should have a mustUnderstand attribute value of 1 var mustUnderstandAttribute = Util.CreateXmlAttribute("mustUnderstand", SOAP_ENVELOPE_NS, "1"); DateTime createdTime = DateTime.Now; DateTime expiresTime = createdTime + RequestTimestampValidPeriod; string timestampId = CreateElementId(TIMESTAMP_ID_PREFIX); SecurityHeader ssoHeader = new SecurityHeader { Timestamp = new Timestamp { Id = timestampId, Created = new AttributedDateTime { Value = createdTime }, Expires = new AttributedDateTime { Value = expiresTime } }, AnyAttr = new[] { mustUnderstandAttribute } }; return(ssoHeader); }
private static void AssertSignedReferences(Receipt receiptMessage, SecurityHeader securityHeader) { IEnumerable <Reference> receiptRefs = receiptMessage.NonRepudiationInformation.MessagePartNRIReferences; Assert.All( securityHeader.GetReferences(), cryptoRef => Assert.Contains(receiptRefs, r => r.URI.Equals(cryptoRef.Uri))); }
private void AppendUserNameToken(SecurityHeader wsSecurityHeader, string userName, SecureString password) { // Reusing the WCF UserNameSecurityToken as there is a built-in serializer for this type. UserNameSecurityToken userNameToken = null; string tokenId = CreateElementId(SECURITY_TOKEN_ID_PREFIX); userNameToken = new UserNameSecurityToken(userName, Util.ConvertSecureStringToString(password), tokenId); wsSecurityHeader.UsernameToken = SerializeToken(userNameToken); }
private static XmlDocument ToXmlDocument(SecurityHeader value) { using (XmlDocumentWriterHelper documentWriterHelper = new XmlDocumentWriterHelper()) { SecurityHeaderSerializer.Serialize(documentWriterHelper.CreateDocumentWriter(), value); return(documentWriterHelper.ReadDocument()); } }
/// <summary> /// Asynchronously deserializes the given <paramref name="input"/> stream to an <see cref="AS4Message"/> model. /// </summary> /// <param name="input">The source stream from where the message should be read.</param> /// <param name="contentType">The content type required to correctly deserialize the message into different MIME parts.</param> /// <param name="cancellation">The token to control the cancellation of the deserialization.</param> public async Task <AS4Message> DeserializeAsync( Stream input, string contentType, CancellationToken cancellation = default(CancellationToken)) { if (input == null) { throw new ArgumentNullException(nameof(input)); } if (contentType == null) { throw new ArgumentNullException(nameof(contentType)); } var envelopeDocument = new XmlDocument { PreserveWhitespace = true }; envelopeDocument.Load(input); // Sometimes throws 'The 'http://www.w3.org/XML/1998/namespace:lang' attribute is not declared.' // ValidateEnvelopeDocument(envelopeDocument); XmlNamespaceManager nsMgr = GetNamespaceManagerForDocument(envelopeDocument); SecurityHeader securityHeader = DeserializeSecurityHeader(envelopeDocument, nsMgr); Messaging messagingHeader = DeserializeMessagingHeader(envelopeDocument, nsMgr); Body1 body = DeserializeBody(envelopeDocument, nsMgr); if (messagingHeader == null) { throw new InvalidMessageException("The envelopeStream does not contain a Messaging element"); } AS4Message as4Message = await AS4Message.CreateAsync( envelopeDocument, contentType, securityHeader, messagingHeader, body); StreamUtilities.MovePositionToStreamStart(input); return(as4Message); }
/// <summary> /// Appends client certificate information as a BinarySecurityToken XML element /// under the root Security element. /// </summary> /// <returns> /// A SecurityTokenReference element which references to the appended client certificate. /// </returns> private XmlElement AppendBinarySecurityToken(SecurityHeader wsSecurityHeader, X509Certificate2 clientCertificate) { XmlElement result = null; // Reusing the WCF X509SecurityToken as there is a built-in serializer for this type. string tokenId = CreateElementId(SECURITY_TOKEN_ID_PREFIX); using (var certificateToken = new X509SecurityToken(clientCertificate, tokenId)) { var binarySecurityToken = SerializeToken(certificateToken); wsSecurityHeader.BinarySecurityToken = binarySecurityToken; result = GetKeyIdentifierClause(certificateToken); } return(result); }
public async Task Creates_Receipt_With_Same_Signed_References_Tags_From_UserMessage() { // Arrange MessagingContext messagingContext = CreateSignedUserMessageWrappedInContext(); messagingContext.ReceivingPMode.ReplyHandling.ReceiptHandling.UseNRRFormat = true; messagingContext.ReceivingPMode.ReplyHandling.ResponseSigning.IsEnabled = true; // Act AS4Message result = await ExerciseCreateReceiptAsync(messagingContext); // Assert var receiptMessage = result.FirstSignalMessage as Receipt; SecurityHeader securityHeader = messagingContext.AS4Message.SecurityHeader; Assert.NotNull(receiptMessage); Assert.NotNull(securityHeader); AssertSignedReferences(receiptMessage, securityHeader); }
// V3 exploit // Magic // internal async static Task LumiaV3CustomFlash(PhoneNotifierViewModel Notifier, List <FlashPart> FlashParts, bool CheckSectorAlignment = true, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, ExitSuccess ExitSuccess = null, ExitFailure ExitFailure = null) { if (SetWorkingStatus == null) { SetWorkingStatus = (m, s, v, a, st) => { } } ; if (UpdateWorkingStatus == null) { UpdateWorkingStatus = (m, s, v, st) => { } } ; if (ExitSuccess == null) { ExitSuccess = (m, s) => { } } ; if (ExitFailure == null) { ExitFailure = (m, s) => { } } ; uint chunkSize = 131072u; int chunkSizes = 131072; if (FlashParts != null) { foreach (FlashPart Part in FlashParts) { if (Part.Stream == null) { throw new ArgumentException("Stream is null"); } if (!Part.Stream.CanSeek) { throw new ArgumentException("Streams must be seekable"); } if (((Part.StartSector * 0x200) % chunkSize) != 0) { throw new ArgumentException("Invalid StartSector alignment"); } if (CheckSectorAlignment) { if ((Part.Stream.Length % chunkSize) != 0) { throw new ArgumentException("Invalid Data length"); } } } } try { NokiaFlashModel Model = (NokiaFlashModel)Notifier.CurrentModel; PhoneInfo Info = Model.ReadPhoneInfo(); if ((Info.SecureFfuSupportedProtocolMask & ((ushort)FfuProtocol.ProtocolSyncV2)) == 0) // Exploit needs protocol v2 -> This check is not conclusive, because old phones also report support for this protocol, although it is really not supported. { throw new WPinternalsException("Flash failed!", "Protocols not supported. The phone reports that it does not support the Protocol Sync V2."); } if (Info.FlashAppProtocolVersionMajor < 2) // Old phones do not support the hack. These phones have Flash protocol 1.x. { throw new WPinternalsException("Flash failed!", "Protocols not supported. The phone reports that Flash App communication protocol is lower than 2. Reported version by the phone: " + Info.FlashAppProtocolVersionMajor + "."); } if (Info.UefiSecureBootEnabled) { throw new WPinternalsException("Flash failed!", "UEFI Secureboot must be disabled for the Flash V3 exploit to work."); } // The payloads must be ordered by the number of locations // // FlashApp processes payloads like this: // - First payloads which are with one location, those can be sent in bulk // - Then payloads with more than one location, those should not be sent in bulk // // If you do not order payloads like this, you will get an error, most likely hash mismatch // LumiaV2UnlockBootViewModel.FlashingPayload[] payloads = new LumiaV2UnlockBootViewModel.FlashingPayload[0]; if (FlashParts != null) { payloads = LumiaV2UnlockBootViewModel.GetNonOptimizedPayloads(FlashParts, chunkSizes, (uint)(Info.WriteBufferSize / chunkSize), SetWorkingStatus, UpdateWorkingStatus).OrderBy(x => x.TargetLocations.Count()).ToArray(); } MemoryStream Headerstream1 = new MemoryStream(); // ============================== // Header 1 start ImageHeader image = new ImageHeader(); FullFlash ffimage = new FullFlash(); Store simage = new Store(); // Todo make this read the image itself ffimage.OSVersion = "10.0.11111.0"; ffimage.DevicePlatformId0 = Info.PlatformID; ffimage.AntiTheftVersion = "1.1"; simage.SectorSize = 512; simage.MinSectorCount = Info.EmmcSizeInSectors; //Logging.Log("Generating image manifest..."); string manifest = ManifestIni.BuildUpManifest(ffimage, simage);//, partitions); byte[] TextBytes = System.Text.Encoding.ASCII.GetBytes(manifest); image.ManifestLength = (UInt32)TextBytes.Length; byte[] ImageHeaderBuffer = new byte[0x18]; ByteOperations.WriteUInt32(ImageHeaderBuffer, 0, image.Size); ByteOperations.WriteAsciiString(ImageHeaderBuffer, 0x04, image.Signature); ByteOperations.WriteUInt32(ImageHeaderBuffer, 0x10, image.ManifestLength); ByteOperations.WriteUInt32(ImageHeaderBuffer, 0x14, image.ChunkSize); Headerstream1.Write(ImageHeaderBuffer, 0, 0x18); Headerstream1.Write(TextBytes, 0, TextBytes.Length); RoundUpToChunks(Headerstream1, chunkSize); // Header 1 stop + round // ============================== MemoryStream Headerstream2 = new MemoryStream(); // ============================== // Header 2 start StoreHeader store = new StoreHeader(); store.WriteDescriptorCount = (UInt32)payloads.Count(); store.FinalTableIndex = (UInt32)payloads.Count() - store.FinalTableCount; store.PlatformId = Info.PlatformID; foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads) { store.WriteDescriptorLength += payload.GetStoreHeaderSize(); } foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads) { /*if (payload.TargetLocations.First() > PlatEnd) * break;*/ store.FlashOnlyTableIndex += 1; } byte[] StoreHeaderBuffer = new byte[0xF8]; ByteOperations.WriteUInt32(StoreHeaderBuffer, 0, store.UpdateType); ByteOperations.WriteUInt16(StoreHeaderBuffer, 0x04, store.MajorVersion); ByteOperations.WriteUInt16(StoreHeaderBuffer, 0x06, store.MinorVersion); ByteOperations.WriteUInt16(StoreHeaderBuffer, 0x08, store.FullFlashMajorVersion); ByteOperations.WriteUInt16(StoreHeaderBuffer, 0x0A, store.FullFlashMinorVersion); ByteOperations.WriteAsciiString(StoreHeaderBuffer, 0x0C, store.PlatformId); ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xCC, store.BlockSizeInBytes); ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xD0, store.WriteDescriptorCount); ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xD4, store.WriteDescriptorLength); ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xD8, store.ValidateDescriptorCount); ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xDC, store.ValidateDescriptorLength); ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xE0, store.InitialTableIndex); ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xE4, store.InitialTableCount); ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xE8, store.FlashOnlyTableIndex); ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xEC, store.FlashOnlyTableCount); ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xF0, store.FinalTableIndex); ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xF4, store.FinalTableCount); Headerstream2.Write(StoreHeaderBuffer, 0, 0xF8); byte[] descriptorsBuffer = new byte[store.WriteDescriptorLength]; UInt32 NewWriteDescriptorOffset = 0; foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads) { ByteOperations.WriteUInt32(descriptorsBuffer, NewWriteDescriptorOffset + 0x00, (UInt32)payload.TargetLocations.Count()); // Location count ByteOperations.WriteUInt32(descriptorsBuffer, NewWriteDescriptorOffset + 0x04, payload.ChunkCount); // Chunk count NewWriteDescriptorOffset += 0x08; foreach (UInt32 location in payload.TargetLocations) { ByteOperations.WriteUInt32(descriptorsBuffer, NewWriteDescriptorOffset + 0x00, 0x00000000); // Disk access method (0 = Begin, 2 = End) ByteOperations.WriteUInt32(descriptorsBuffer, NewWriteDescriptorOffset + 0x04, location); // Chunk index NewWriteDescriptorOffset += 0x08; } } Headerstream2.Write(descriptorsBuffer, 0, (Int32)store.WriteDescriptorLength); RoundUpToChunks(Headerstream2, chunkSize); // Header 2 stop + round // ============================== SecurityHeader security = new SecurityHeader(); Headerstream1.Seek(0, SeekOrigin.Begin); Headerstream2.Seek(0, SeekOrigin.Begin); security.HashTableSize = 0x20 * (UInt32)((Headerstream1.Length + Headerstream2.Length) / chunkSize); foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads) { security.HashTableSize += payload.GetSecurityHeaderSize(); } byte[] HashTable = new byte[security.HashTableSize]; BinaryWriter bw = new BinaryWriter(new MemoryStream(HashTable)); SHA256 crypto = SHA256.Create(); for (int i = 0; i < Headerstream1.Length / chunkSize; i++) { byte[] buffer = new byte[chunkSize]; Headerstream1.Read(buffer, 0, (Int32)chunkSize); byte[] hash = crypto.ComputeHash(buffer); bw.Write(hash, 0, hash.Length); } for (int i = 0; i < Headerstream2.Length / chunkSize; i++) { byte[] buffer = new byte[chunkSize]; Headerstream2.Read(buffer, 0, (Int32)chunkSize); byte[] hash = crypto.ComputeHash(buffer); bw.Write(hash, 0, hash.Length); } foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads) { bw.Write(payload.ChunkHashes[0], 0, payload.ChunkHashes[0].Length); } bw.Close(); //Logging.Log("Generating image catalog..."); byte[] catalog = GenerateCatalogFile(HashTable); security.CatalogSize = (UInt32)catalog.Length; byte[] SecurityHeaderBuffer = new byte[0x20]; ByteOperations.WriteUInt32(SecurityHeaderBuffer, 0, security.Size); ByteOperations.WriteAsciiString(SecurityHeaderBuffer, 0x04, security.Signature); ByteOperations.WriteUInt32(SecurityHeaderBuffer, 0x10, security.ChunkSizeInKb); ByteOperations.WriteUInt32(SecurityHeaderBuffer, 0x14, security.HashAlgorithm); ByteOperations.WriteUInt32(SecurityHeaderBuffer, 0x18, security.CatalogSize); ByteOperations.WriteUInt32(SecurityHeaderBuffer, 0x1C, security.HashTableSize); MemoryStream retstream = new MemoryStream(); retstream.Write(SecurityHeaderBuffer, 0, 0x20); retstream.Write(catalog, 0, (Int32)security.CatalogSize); retstream.Write(HashTable, 0, (Int32)security.HashTableSize); RoundUpToChunks(retstream, chunkSize); Headerstream1.Seek(0, SeekOrigin.Begin); Headerstream2.Seek(0, SeekOrigin.Begin); byte[] buff = new byte[Headerstream1.Length]; Headerstream1.Read(buff, 0, (Int32)Headerstream1.Length); Headerstream1.Close(); retstream.Write(buff, 0, buff.Length); buff = new byte[Headerstream2.Length]; Headerstream2.Read(buff, 0, (Int32)Headerstream2.Length); Headerstream2.Close(); retstream.Write(buff, 0, buff.Length); // -------- // Go back to the beginning retstream.Seek(0, SeekOrigin.Begin); byte[] FfuHeader = new byte[retstream.Length]; await retstream.ReadAsync(FfuHeader, 0, (int)retstream.Length); retstream.Close(); byte Options = 0; if (!Info.IsBootloaderSecure) { Options = (byte)((FlashOptions)Options | FlashOptions.SkipSignatureCheck); } LogFile.Log("Flash in progress...", LogType.ConsoleOnly); SetWorkingStatus("Flashing...", null, (UInt64?)payloads.Count(), Status: WPinternalsStatus.Flashing); Model.SendFfuHeaderV1(FfuHeader, Options); UInt64 counter = 0; int numberOfPayloadsToSendAtOnce = (int)Math.Round((double)Info.WriteBufferSize / chunkSize); byte[] payloadBuffer; for (int i = 0; i < payloads.Count(); i += numberOfPayloadsToSendAtOnce) { if (i + numberOfPayloadsToSendAtOnce - 1 >= payloads.Count()) { numberOfPayloadsToSendAtOnce = payloads.Count() - i; } payloadBuffer = new byte[numberOfPayloadsToSendAtOnce * chunkSizes]; string ProgressText = "Flashing resources"; for (int j = 0; j < numberOfPayloadsToSendAtOnce; j++) { LumiaV2UnlockBootViewModel.FlashingPayload payload = payloads[i + j]; UInt32 StreamIndex = payload.StreamIndexes.First(); FlashPart flashPart = FlashParts[(int)StreamIndex]; if (flashPart.ProgressText != null) { ProgressText = flashPart.ProgressText; } Stream Stream = flashPart.Stream; Stream.Seek(payload.StreamLocations.First(), SeekOrigin.Begin); Stream.Read(payloadBuffer, j * chunkSizes, chunkSizes); counter++; } Model.SendFfuPayloadV2(payloadBuffer, int.Parse((counter * 100 / (ulong)payloads.Count()).ToString())); UpdateWorkingStatus(ProgressText, null, counter, WPinternalsStatus.Flashing); } Model.ResetPhone(); await Notifier.WaitForRemoval(); ExitSuccess("Flash succeeded!", null); } catch { throw new WPinternalsException("Custom flash failed"); } } } }
private SecurityHeader GetUnsignedHeader() { // The header should have a mustUnderstand attribute value of 1 var mustUnderstandAttribute = Util.CreateXmlAttribute("mustUnderstand", SOAP_ENVELOPE_NS, "1"); DateTime createdTime = DateTime.Now; DateTime expiresTime = createdTime + RequestTimestampValidPeriod; string timestampId = CreateElementId(TIMESTAMP_ID_PREFIX); SecurityHeader ssoHeader = new SecurityHeader { Timestamp = new Timestamp { Id = timestampId, Created = new AttributedDateTime { Value = createdTime }, Expires = new AttributedDateTime { Value = expiresTime } }, AnyAttr = new[] { mustUnderstandAttribute } }; if (_userNameToken != null) { ssoHeader.UsernameToken = ToXmlElement(_userNameToken); } if (_samlToken != null) { ssoHeader.SamlToken = _samlToken; } else { if (_certificateToken != null) { // The X509 token is serialized as a binary security token in the security header. var binarySecurityToken = ToXmlElement(_certificateToken); ssoHeader.BinarySecurityToken = binarySecurityToken; } } return(ssoHeader); }
public object BeforeSendRequest(ref Message request, IClientChannel channel) { // Working with the message in XML form XmlDocument soapRequest = GetXmlMessage(request); // Setting an ID to the body to be able to reference it in the signature (to be able to sign it) string bodyId = CreateElementId(BODY_ID_PREFIX); SetIdToBodyElement(soapRequest.DocumentElement, bodyId); SecurityHeader wsSecurityHeader = GetUnsignedHeader(); // Converting the sso header from object to xml to easily assign xml values to properties. XmlDocument securityHeaderXml = ToXmlDocument(wsSecurityHeader); // Attaching the header without the signature var ssoHeaderElement = MergeMessageWithHeader( soapRequest.DocumentElement, securityHeaderXml.DocumentElement); if (_certificateToken != null) { // Get a key identifier to the key depending on how the key is specified. XmlElement keyIdentifier = _samlToken != null ? GetKeyIdentifierClause(_samlToken) : GetKeyIdentifierClause(_certificateToken); // Compute the signature on the timestamp and body elements. var signature = Util.ComputeSignature( soapRequest, keyIdentifier, _certificateToken.Certificate.PrivateKey, bodyId, wsSecurityHeader.Timestamp.Id); // Inserting the signature into the security header (and the message respectively). ssoHeaderElement.AppendChild(signature); } // Convert the SOAP request back to a message that replaces the original message request = ToMessage(soapRequest, request.Version, request.Headers.Action, request.Properties); // No need to correlate requests with replays for this inspector. return(null); }
public object BeforeSendRequest(ref Message request, IClientChannel channel) { // Retrieve the security context if specified var securityContext = WsSecurityContext.GetProperties(request); if (securityContext == null) { // exit with unmodified message return(null); } ValidateSecurityContext(securityContext); // Working with the message in XML form XmlDocument soapRequest = GetXmlMessage(request); // Setting an ID to the body to be able to reference it in the signature (to be able to sign it) string bodyId = CreateElementId(BODY_ID_PREFIX); SetIdToBodyElement(soapRequest.DocumentElement, bodyId); SecurityHeader wsSecurityHeader = GetBasicUnsignedHeader(); if (!String.IsNullOrEmpty(securityContext.Credentials.User)) { AppendUserNameToken( wsSecurityHeader, securityContext.Credentials.User, securityContext.Credentials.Password); } // A SecurityTokenReference XmlElement which contains the reference to signing client certificate. XmlElement keyIdentifierClause = null; if (securityContext.Credentials.BearerToken != null) { // No signature is used for Bearer token security context wsSecurityHeader.SamlToken = securityContext.Credentials.BearerToken; } else if (securityContext.Credentials.HolderOfKeyToken != null) { // For HoK token context, the signing certificate is contained within the HoK SAML token XmlElement hokToken = securityContext.Credentials.HolderOfKeyToken; wsSecurityHeader.SamlToken = hokToken; keyIdentifierClause = GetKeyIdentifierClause(hokToken); } else if (securityContext.Credentials.ClientCertificate != null) { // Append local certificate info as a BinarySecurityToken child // element of the WS Security header and save a reference to it. keyIdentifierClause = AppendBinarySecurityToken(wsSecurityHeader, securityContext.Credentials.ClientCertificate); } // Converting the sso header from object to xml to easily assign xml values to properties. XmlElement securityHeaderXml = Util.ToXmlElement(wsSecurityHeader); // Attaching the header without the signature var ssoHeaderElement = MergeMessageWithHeader( soapRequest.DocumentElement, securityHeaderXml); if (keyIdentifierClause != null) { // This should already be ensured by ValidateSecurityContext() method Debug.Assert(securityContext.SigningKey != null); // Compute signature for timestamp and body elements and add the signature element to the security header. var signature = Util.ComputeSignature( soapRequest, keyIdentifierClause, securityContext.SigningKey, bodyId, wsSecurityHeader.Timestamp.Id); ssoHeaderElement.AppendChild(signature); } // Convert the SOAP request back to a message that replaces the original message request = ToMessage(soapRequest, request.Version, request.Headers.Action, request.Properties); // No need to correlate requests with replays for this inspector. return(null); }