From 501450aa4516af9e3e8afc66681f9e07535271fd Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Wed, 10 Apr 2024 12:05:03 +0200 Subject: [PATCH 01/38] feat: draft implementation of authenticode parser --- Cargo.lock | 87 ++++++ Cargo.toml | 3 + lib/Cargo.toml | 6 + lib/src/modules/dotnet/parser.rs | 1 + lib/src/modules/pe/authenticode.rs | 424 +++++++++++++++++++++++++++++ lib/src/modules/pe/mod.rs | 1 + lib/src/modules/pe/parser.rs | 149 +++++++--- 7 files changed, 628 insertions(+), 43 deletions(-) create mode 100644 lib/src/modules/pe/authenticode.rs diff --git a/Cargo.lock b/Cargo.lock index 82dd172ca..fceb24663 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -578,6 +578,18 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +[[package]] +name = "cms" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b77c319abfd5219629c45c34c89ba945ed3c5e49fcde9d16b6c3885f118a730" +dependencies = [ + "const-oid", + "der", + "spki", + "x509-cert", +] + [[package]] name = "colorchoice" version = "1.0.0" @@ -620,6 +632,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "const-random" version = "0.1.18" @@ -970,6 +988,30 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5729f5117e208430e437df2f4843f5e5952997175992d1414f94c57d61e270b4" +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "der_derive", + "flagset", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "der_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fe87ce4529967e0ba1dcf8450bab64d97dfd5010a6256187ffe2e43e6f0e049" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + [[package]] name = "deranged" version = "0.3.11" @@ -1189,6 +1231,12 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "flagset" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb3aa5e95cf9aabc17f060cfa0ced7b83f042390760ca53bf09df9968acaa1" + [[package]] name = "flate2" version = "1.0.28" @@ -2222,6 +2270,15 @@ dependencies = [ "sha2 0.10.8", ] +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "pest" version = "2.7.8" @@ -2951,6 +3008,16 @@ dependencies = [ "serde", ] +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "sptr" version = "0.3.2" @@ -4205,6 +4272,17 @@ dependencies = [ "tap", ] +[[package]] +name = "x509-cert" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94" +dependencies = [ + "const-oid", + "der", + "spki", +] + [[package]] name = "yaml-rust" version = "0.4.5" @@ -4240,7 +4318,10 @@ dependencies = [ "bitmask", "bitvec", "bstr 1.9.1", + "cms", + "const-oid", "crc32fast", + "der", "fmmap", "globwalk", "goldenfile", @@ -4423,6 +4504,12 @@ dependencies = [ "syn 2.0.55", ] +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" + [[package]] name = "zip" version = "0.6.6" diff --git a/Cargo.toml b/Cargo.toml index b7d85deff..e63aaec37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,7 +45,10 @@ cbindgen = "0.26.0" chrono = "0.4.35" clap = "4.5.3" clap_complete = "4.5.1" +cms = "0.2.3" +const-oid = "0.9.6" crc32fast = "1.4.0" +der = "0.7.9" enable-ansi-support = "0.2.1" env_logger = "0.11.3" fmmap = "0.3.3" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 1c8e4c67f..6dff49fc9 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -116,7 +116,10 @@ math-module = [] # The `pe` module parses PE files. pe-module = [ "dep:authenticode-parser", + "dep:cms", + "dep:const-oid", "dep:nom", + "dep:sha1", ] # The `string` modules offer some functions for parsing strings as integers, @@ -168,7 +171,10 @@ bincode = { workspace = true } bitmask = { workspace = true } bitvec = { workspace = true } bstr = { workspace = true, features = ["serde"] } +cms = { workspace = true, optional = true } +const-oid = { workspace = true, optional = true } crc32fast = { workspace = true, optional = true } +der = { workspace = true, features = ["derive"] } fmmap = { workspace = true } indexmap = { workspace = true, features = ["serde"] } intaglio = { workspace = true } diff --git a/lib/src/modules/dotnet/parser.rs b/lib/src/modules/dotnet/parser.rs index 24b53d932..fa9e8e023 100644 --- a/lib/src/modules/dotnet/parser.rs +++ b/lib/src/modules/dotnet/parser.rs @@ -135,6 +135,7 @@ impl<'a> Dotnet<'a> { .get_dir_entry_data( PE::IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR, false, + true, ) .ok_or(Error::InvalidDotNet)?; diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs new file mode 100644 index 000000000..f581b15f4 --- /dev/null +++ b/lib/src/modules/pe/authenticode.rs @@ -0,0 +1,424 @@ +use array_bytes::bytes2hex; +use cms::cert::x509::{spki, Certificate}; +use cms::content_info::CmsVersion; +use cms::content_info::ContentInfo; +use cms::signed_data::{SignedData, SignerInfo}; +use const_oid::db::{rfc5912, rfc6268}; +use const_oid::ObjectIdentifier; +use der::asn1::OctetString; +use der::{Decode, Encode, EncodeValue}; +use der::{Sequence, SliceReader}; +use protobuf::MessageField; +use sha1::digest::Output; +use sha1::{Digest, Sha1}; + +use crate::modules::protos; + +/// OID for [`SpcIndirectDataContent`]. +pub const SPC_INDIRECT_DATA_OBJID: ObjectIdentifier = + ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.2.1.4"); + +pub const SPC_NESTED_SIGNATURE: ObjectIdentifier = + ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.2.4.1"); + +/// Authenticode ASN.1 image and digest data. +#[derive(Clone, Debug, Eq, PartialEq, Sequence)] +pub struct SpcIndirectDataContent { + /// Image data. + pub data: SpcAttributeTypeAndOptionalValue, + + /// Authenticode digest. + pub message_digest: DigestInfo, +} + +/// Authenticode ASN.1 image data. +#[derive(Clone, Debug, Eq, PartialEq, Sequence)] +pub struct SpcAttributeTypeAndOptionalValue { + /// Type of data stored in the `value` field. + pub value_type: ObjectIdentifier, + + /// Image data. + //TODO(nicholasbishop): implement SpcPeImageData. + pub value: der::Any, +} + +/// Authenticode ASN.1 digest data. +#[derive(Clone, Debug, Eq, PartialEq, Sequence)] +pub struct DigestInfo { + /// Authenticode digest algorithm. + pub digest_algorithm: spki::AlgorithmIdentifierOwned, + + /// Authenticode digest. + pub digest: OctetString, +} + +/// Error returned by [`AuthenticodeParser::parse`]. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum AuthenticodeParseError { + /// The signature data is empty. + Empty, + + /// The signature data is not valid [`ContentInfo`]. + InvalidContentInfo(der::Error), + + /// The content type does not match [`rfc6268::ID_SIGNED_DATA`]. + InvalidContentType(ObjectIdentifier), + + /// The content info is not valid [`SignedData`]. + InvalidSignedData(der::Error), + + /// The version of [`SignedData`] is not 1. + InvalidSignedDataVersion(CmsVersion), + + /// The number of digest algorithms is not 1. + InvalidNumDigestAlgorithms(usize), + + /// The encapsulated content type does not match [`SPC_INDIRECT_DATA_OBJID`]. + InvalidEncapsulatedContentType(ObjectIdentifier), + + /// The encapsulated content is empty. + EmptyEncapsulatedContent, + + /// The encapsulated content is not valid [`SpcIndirectDataContent`]. + InvalidSpcIndirectDataContent(der::Error), + + /// The number of signer infos is not 1. + InvalidNumSignerInfo(usize), + + /// The version of [`SignerInfo`] is not 1. + InvalidSignerInfoVersion(CmsVersion), + + /// The digest algorithm is not internally consistent. + AlgorithmMismatch, + + /// No authenticated attributes are present. + EmptyAuthenticatedAttributes, + + /// The `contentType` authenticated attribute is missing. + MissingContentTypeAuthenticatedAttribute, + + /// The `messageDigest` authenticated attribute is missing. + MissingMessageDigestAuthenticatedAttribute, +} + +/// Parses Authenticode signatures in a PE file. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AuthenticodeParser {} + +impl AuthenticodeParser { + pub fn new() -> Self { + Self {} + } + + /// Parses Authenticode signatures from DER-encoded bytes. + pub fn parse( + bytes: &[u8], + ) -> Result, AuthenticodeParseError> { + // Use a reader rather than using `Decode::from_der`, because there may + // be unused trailing data in `input`, which causes a `TrailingData` + // error. + let mut reader = SliceReader::new(bytes) + .map_err(|_| AuthenticodeParseError::Empty)?; + + let content_info = ContentInfo::decode(&mut reader) + .map_err(AuthenticodeParseError::InvalidContentInfo)?; + + if content_info.content_type != rfc6268::ID_SIGNED_DATA { + return Err(AuthenticodeParseError::InvalidContentType( + content_info.content_type, + )); + } + + let signed_data = content_info + .content + .decode_as::() + .map_err(AuthenticodeParseError::InvalidSignedData)?; + + if signed_data.version != CmsVersion::V1 { + return Err(AuthenticodeParseError::InvalidSignedDataVersion( + signed_data.version, + )); + } + + // According to the specification, SignedData must contain exactly one + // digest algorithm, and it must match the one specified in SignerInfo. + if signed_data.digest_algorithms.len() != 1 { + return Err(AuthenticodeParseError::InvalidNumDigestAlgorithms( + signed_data.digest_algorithms.len(), + )); + } + + // Exactly one SignerInfo, as required by the specification. + if signed_data.signer_infos.0.len() != 1 { + return Err(AuthenticodeParseError::InvalidNumSignerInfo( + signed_data.signer_infos.0.len(), + )); + } + + if signed_data.encap_content_info.econtent_type + != SPC_INDIRECT_DATA_OBJID + { + return Err( + AuthenticodeParseError::InvalidEncapsulatedContentType( + signed_data.encap_content_info.econtent_type, + ), + ); + } + + let indirect_data = signed_data + .encap_content_info + .econtent + .as_ref() + .ok_or(AuthenticodeParseError::EmptyEncapsulatedContent)? + .decode_as::() + .map_err(AuthenticodeParseError::InvalidSpcIndirectDataContent)?; + + let signer_info = &signed_data.signer_infos.0.as_slice()[0]; + + if signer_info.version != CmsVersion::V1 { + return Err(AuthenticodeParseError::InvalidSignerInfoVersion( + signer_info.version, + )); + } + + if signer_info.digest_alg + != signed_data.digest_algorithms.as_slice()[0] + { + return Err(AuthenticodeParseError::AlgorithmMismatch); + } + + let signed_attrs = if let Some(signed_attrs) = + &signer_info.signed_attrs + { + signed_attrs + } else { + return Err(AuthenticodeParseError::EmptyAuthenticatedAttributes); + }; + + // The contentType attribute must be present. + if !signed_attrs + .iter() + .any(|attr| attr.oid == rfc6268::ID_CONTENT_TYPE) + { + return Err(AuthenticodeParseError::MissingContentTypeAuthenticatedAttribute); + } + + // The messageDigest attribute must be present. + let signer_info_digest = if let Some(digest_attr) = signed_attrs + .iter() + .find(|attr| attr.oid == rfc6268::ID_MESSAGE_DIGEST) + { + digest_attr.values.as_slice()[0].value() + } else { + return Err(AuthenticodeParseError::MissingMessageDigestAuthenticatedAttribute); + }; + + // An Authenticode signature can contain nested signatures in + // an unsigned attribute with OID 1.3.6.1.4.1.311.2.4.1. + let mut nested_signatures = Vec::new(); + + if let Some(attrs) = &signer_info.unsigned_attrs { + for attr in attrs.iter() { + if attr.oid == SPC_NESTED_SIGNATURE { + // TODO: can we do this without having to use encode_to_vec? + let mut raw = Vec::new(); + if attr.values.as_slice()[0] + .encode_to_vec(&mut raw) + .is_ok() + { + if let Ok(signatures) = + AuthenticodeParser::parse(raw.as_slice()) + { + nested_signatures.extend(signatures); + } + } + } + } + } + + let mut signatures = Vec::with_capacity(nested_signatures.len() + 1); + + signatures.push(AuthenticodeSignature { + signer_info_digest: bytes2hex("", signer_info_digest), + signed_data, + indirect_data, + }); + + signatures.append(&mut nested_signatures); + + Ok(signatures) + } +} + +pub struct AuthenticodeSignature { + signer_info_digest: String, + signed_data: SignedData, + indirect_data: SpcIndirectDataContent, +} + +impl AuthenticodeSignature { + /// Get the authenticode digest stored in the signature. + pub fn digest(&self) -> String { + bytes2hex("", self.indirect_data.message_digest.digest.as_bytes()) + } + + /// Get the name of the digest algorithm. + pub fn digest_alg(&self) -> String { + oid_to_algorithm_name( + &self.indirect_data.message_digest.digest_algorithm.oid, + ) + .to_string() + } + + /// Get [`SignerInfo`]. + pub fn signer_info(&self) -> &SignerInfo { + // The constructor validates that exactly one signer info is + // present, so this won't panic. + &self.signed_data.signer_infos.0.as_slice()[0] + } + + pub fn signer_info_digest_alg(&self) -> String { + oid_to_algorithm_name(&self.signer_info().digest_alg.oid).to_string() + } + + pub fn signer_info_digest(&self) -> String { + self.signer_info_digest.clone() + } + + /// Get the certificate chain. + pub fn certificates(&self) -> impl Iterator { + self.signed_data.certificates.as_ref().unwrap().0.iter().map(|cert| { + if let cms::cert::CertificateChoices::Certificate(cert) = cert { + cert + } else { + panic!() + } + }) + } +} + +impl From<&AuthenticodeSignature> for protos::pe::Signature { + fn from(value: &AuthenticodeSignature) -> Self { + let mut sig = protos::pe::Signature::new(); + + sig.set_digest(value.digest()); + sig.set_digest_alg(value.digest_alg()); + + sig.certificates + .extend(value.certificates().map(protos::pe::Certificate::from)); + + let mut signer_info = protos::pe::SignerInfo::new(); + + signer_info.set_digest_alg(value.signer_info_digest_alg()); + signer_info.set_digest(value.signer_info_digest()); + + sig.signer_info = MessageField::from(Some(signer_info)); + + // Some fields from the first certificate in the chain are replicated + // in the `pe::Signature` structure for backward compatibility. The + // `chain` field in `SignerInfo` didn't exist in previous versions of + // YARA. + if let Some(signer_info) = sig.signer_info.as_ref() { + if let Some(cert) = signer_info.chain.first() { + sig.version = cert.version; + sig.thumbprint = cert.thumbprint.clone(); + sig.issuer = cert.issuer.clone(); + sig.subject = cert.subject.clone(); + sig.serial = cert.serial.clone(); + sig.not_after = cert.not_after; + sig.not_before = cert.not_before; + sig.algorithm = cert.algorithm.clone(); + sig.algorithm_oid = cert.algorithm_oid.clone(); + } + } + + sig + } +} + +impl From<&Certificate> for protos::pe::Certificate { + fn from(value: &Certificate) -> Self { + let mut cert = protos::pe::Certificate::new(); + // Versions are 0-based, add 1 for getting the actual version. + cert.set_version(value.tbs_certificate.version as i64 + 1); + + // TODO: + // /C=ZA/ST=Western Cape/L=Durbanville/O=Thawte/OU=Thawte Certification/CN=Thawte Timestamping CA + // CN=Thawte Timestamping CA,OU=Thawte Certification,O=Thawte,L=Durbanville,ST=Western Cape,C=ZA + cert.set_issuer(format!("{}", value.tbs_certificate.issuer)); + cert.set_subject(format!("{}", value.tbs_certificate.subject)); + + // TODO: to lower + cert.set_serial(format!("{}", value.tbs_certificate.serial_number)); + + cert.set_algorithm_oid(format!("{}", value.signature_algorithm.oid)); + cert.set_algorithm( + oid_to_algorithm_name(&value.signature_algorithm.oid).to_string(), + ); + + // The certificate thumbprint is the SHA1 of the DER-encoded certificate. + let mut hasher = Sha1Hasher::new(); + value.encode(&mut hasher).unwrap(); + cert.set_thumbprint(format!("{:x}", hasher.finalize())); + + if let Ok(time) = value + .tbs_certificate + .validity + .not_before + .to_unix_duration() + .as_secs() + .try_into() + { + cert.set_not_before(time); + } + + if let Ok(time) = value + .tbs_certificate + .validity + .not_after + .to_unix_duration() + .as_secs() + .try_into() + { + cert.set_not_after(time); + } + + cert + } +} + +fn oid_to_algorithm_name(oid: &ObjectIdentifier) -> &'static str { + if oid == &rfc5912::ID_SHA_1 { + "sha1" + } else if oid == &rfc5912::ID_SHA_256 { + "sha256" + } else if oid == &rfc5912::ID_MD_5 { + "md5" + } else if oid == &rfc5912::SHA_1_WITH_RSA_ENCRYPTION { + "sha1WithRSAEncryption" + } else if oid == &rfc5912::SHA_256_WITH_RSA_ENCRYPTION { + "sha256WithRSAEncryption" + } else { + unreachable!() + } +} + +struct Sha1Hasher { + hasher: Sha1, +} + +impl Sha1Hasher { + pub fn new() -> Self { + Self { hasher: Sha1::new() } + } + pub fn finalize(self) -> Output { + self.hasher.finalize() + } +} + +impl der::Writer for Sha1Hasher { + fn write(&mut self, slice: &[u8]) -> der::Result<()> { + self.hasher.update(slice); + Ok(()) + } +} diff --git a/lib/src/modules/pe/mod.rs b/lib/src/modules/pe/mod.rs index 183b5a5c0..f151c5d60 100644 --- a/lib/src/modules/pe/mod.rs +++ b/lib/src/modules/pe/mod.rs @@ -22,6 +22,7 @@ use crate::types::Struct; #[cfg(test)] mod tests; +mod authenticode; pub mod parser; mod rva2off; diff --git a/lib/src/modules/pe/parser.rs b/lib/src/modules/pe/parser.rs index 2ad591e4e..891fa651a 100644 --- a/lib/src/modules/pe/parser.rs +++ b/lib/src/modules/pe/parser.rs @@ -6,11 +6,6 @@ use std::iter::zip; use std::str::{from_utf8, FromStr}; use std::sync::OnceLock; -use array_bytes::bytes2hex; -use authenticode_parser::{ - Authenticode, AuthenticodeArray, AuthenticodeVerify, - CounterSignatureVerify, -}; use bstr::{BStr, ByteSlice}; use itertools::Itertools; use memchr::memmem; @@ -18,12 +13,17 @@ use nom::branch::{alt, permutation}; use nom::bytes::complete::{take, take_till}; use nom::combinator::{cond, consumed, iterator, map, opt, success, verify}; use nom::error::ErrorKind; -use nom::multi::{count, fold_many1, length_data, many0, many1, many_m_n}; +use nom::multi::{ + count, fold_many0, fold_many1, length_data, many0, many1, many_m_n, +}; use nom::number::complete::{le_u16, le_u32, le_u64, u8}; use nom::sequence::tuple; use nom::{Err, IResult, Parser, ToUsize}; use protobuf::{EnumOrUnknown, MessageField}; +use crate::modules::pe::authenticode::{ + AuthenticodeParser, AuthenticodeSignature, +}; use crate::modules::pe::rva2off; use crate::modules::protos; @@ -33,12 +33,6 @@ type Error<'a> = nom::error::Error<&'a [u8]>; /// that DLL. type DllImports<'a> = Vec<(&'a str, Vec)>; -/// The initialization token needed by the authenticode_parser library must be -/// created only once per process, and it must be done in a thread-safe way. -static AUTHENTICODE_INIT_TOKEN: OnceLock< - authenticode_parser::InitializationToken, -> = OnceLock::new(); - /// Represents a Windows Portable Executable (PE) file. /// /// New instances of this type are created by parsing the content of a PE @@ -75,7 +69,7 @@ pub struct PE<'a> { resources: OnceCell>)>>, /// PE authenticode signatures. - signatures: OnceCell>, + signatures: OnceCell>>, /// PE directory entries. Directory entries are parsed lazily when /// [`PE::get_dir_entries`] is called for the first time. @@ -320,6 +314,7 @@ impl<'a> PE<'a> { &self, index: usize, strict_size: bool, + addr_to_rva: bool, ) -> Option<(u32, u32, &'a [u8])> { // Nobody should call this function with an index greater // than MAX_DIR_ENTRIES. @@ -342,17 +337,21 @@ impl<'a> PE<'a> { .and_then(|entry| Self::parse_dir_entry(entry).ok()) .map(|(_reminder, entry)| entry)?; - let start = self.rva_to_offset(dir_entry.addr)? as usize; + let start = if addr_to_rva { + self.rva_to_offset(dir_entry.addr)? + } else { + dir_entry.addr + }; let end = if strict_size { - min(self.data.len(), start.saturating_add(dir_entry.size as usize)) + min(self.data.len(), start.saturating_add(dir_entry.size) as usize) } else { self.data.len() }; - let data = self.data.get(start..end)?; + let data = self.data.get(start as usize..end)?; - Some((dir_entry.addr, dir_entry.size, data)) + Some((start, dir_entry.size, data)) } /// Returns information about the functions imported by this PE file. @@ -397,14 +396,12 @@ impl<'a> PE<'a> { } /// Returns the authenticode signatures in this PE. - pub fn get_signatures(&self) -> &[Authenticode<'_>] { - if let Some(array) = - self.signatures.get_or_init(|| self.parse_signatures()) - { - array.signatures() - } else { - &[] - } + pub fn get_signatures(&self) -> &[AuthenticodeSignature] { + self.signatures + .get_or_init(|| self.parse_signatures()) + .as_ref() + .map(|s| s.as_slice()) + .unwrap_or(&[]) } } @@ -415,6 +412,7 @@ impl<'a> PE<'a> { pub const IMAGE_DIRECTORY_ENTRY_EXPORT: usize = 0; pub const IMAGE_DIRECTORY_ENTRY_IMPORT: usize = 1; pub const IMAGE_DIRECTORY_ENTRY_RESOURCE: usize = 2; + pub const IMAGE_DIRECTORY_ENTRY_SECURITY: usize = 4; pub const IMAGE_DIRECTORY_ENTRY_DEBUG: usize = 6; pub const IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT: usize = 13; pub const IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR: usize = 14; @@ -1150,7 +1148,7 @@ impl<'a> PE<'a> { // Read the structure's length and round it up to a 32-bits // boundary. let (_, length) = le_u16(input)?; - let length = Self::round_up(length); + let length = Self::round_up::<4, _>(length); // Read the structure's bytes. let (remainder, structure) = take(length)(input)?; @@ -1168,7 +1166,7 @@ impl<'a> PE<'a> { // aligning the rest of the structure to a 32-bits boundary. // Here we get the length of the data consumed so far and round // it up to a 32-bits boundary. - let alignment = Self::round_up(consumed.len()); + let alignment = Self::round_up::<4, _>(consumed.len()); // Then take `alignment` bytes from the start of the structure. The // remaining bytes contain the value and children. @@ -1222,9 +1220,9 @@ impl<'a> PE<'a> { } } - /// Round up an offset to the next 32-bit boundary. - fn round_up(offset: O) -> usize { - offset.to_usize().div_ceil(4) * 4 + /// Round up a `value` to the `ROUND_TO` byte boundary. + fn round_up(value: O) -> usize { + value.to_usize().div_ceil(ROUND_TO) * ROUND_TO } /// Parses the PE resources. @@ -1255,8 +1253,11 @@ impl<'a> PE<'a> { /// individual resources of that type, and the children of each individual /// resource represent the resource in a specific language. fn parse_resources(&self) -> Option<(ResourceDir, Vec>)> { - let (_, _, rsrc_section) = self - .get_dir_entry_data(Self::IMAGE_DIRECTORY_ENTRY_RESOURCE, false)?; + let (_, _, rsrc_section) = self.get_dir_entry_data( + Self::IMAGE_DIRECTORY_ENTRY_RESOURCE, + false, + true, + )?; let mut queue = VecDeque::new(); let mut resources = vec![]; @@ -1356,11 +1357,60 @@ impl<'a> PE<'a> { Some((resources_info, resources)) } - fn parse_signatures(&self) -> Option { - let token = AUTHENTICODE_INIT_TOKEN.get_or_init(|| unsafe { - authenticode_parser::InitializationToken::new() - }); - authenticode_parser::parse_pe(token, self.data) + /// Parses the PE Authenticode signatures. + fn parse_signatures(&self) -> Option> { + let (_, _, cert_table) = self.get_dir_entry_data( + Self::IMAGE_DIRECTORY_ENTRY_SECURITY, + true, + false, + )?; + + // The certificate table is an array of WIN_CERTIFICATE structures. + let signatures = fold_many0( + Self::parse_win_cert, + Vec::new, + |mut acc: Vec<_>, signatures| { + acc.extend(signatures); + acc + }, + )(cert_table) + .map(|(_, cert)| cert) + .ok()?; + + Some(signatures) + } + + fn parse_win_cert( + input: &[u8], + ) -> IResult<&[u8], Vec> { + // Parse the WIN_CERTIFICATE structure. + let (remainder, (length, revision, cert_type)) = tuple(( + le_u32::<&[u8], Error>, // length + le_u16, // revision, should be WIN_CERT_REVISION_1_0 (0x0100) + le_u16, // certificate type + ))(input)?; + + // The length includes the header, compute the length of the signature. + let signature_length: u32 = length + .checked_sub(8) + .ok_or_else(|| Err::Error(Error::new(input, ErrorKind::Fail)))?; + + let (_, signature_data) = take(signature_length)(remainder)?; + let (_, signatures) = Self::parse_signature(signature_data)?; + + // The next WIN_CERTIFICATE is aligned to the next 8-bytes boundary. + let (remainder, _) = take(Self::round_up::<8, _>(length))(input)?; + + Ok((remainder, signatures)) + } + + /// Parses the PKCS#7 blob that containing an Authenticode signature. + fn parse_signature( + input: &[u8], + ) -> IResult<&[u8], Vec> { + let signatures = AuthenticodeParser::parse(input) + .map_err(|_| Err::Error(Error::new(input, ErrorKind::Fail)))?; + Ok((&[], signatures)) } fn parse_dir_entries(&self) -> Option> { @@ -1378,8 +1428,11 @@ impl<'a> PE<'a> { /// Parses the PE debug information and extracts the PDB path. fn parse_dbg(&self) -> Option<&'a [u8]> { - let (_, _, dbg_section) = - self.get_dir_entry_data(Self::IMAGE_DIRECTORY_ENTRY_DEBUG, true)?; + let (_, _, dbg_section) = self.get_dir_entry_data( + Self::IMAGE_DIRECTORY_ENTRY_DEBUG, + true, + true, + )?; let entries = many0(Self::parse_dbg_dir_entry)(dbg_section) .map(|(_, entries)| entries) @@ -1516,8 +1569,11 @@ impl<'a> PE<'a> { /// Parses PE imports. fn parse_imports(&self) -> Option)>> { - let (rva, _, import_data) = self - .get_dir_entry_data(Self::IMAGE_DIRECTORY_ENTRY_IMPORT, false)?; + let (rva, _, import_data) = self.get_dir_entry_data( + Self::IMAGE_DIRECTORY_ENTRY_IMPORT, + false, + true, + )?; if rva == 0 { return None; @@ -1533,6 +1589,7 @@ impl<'a> PE<'a> { let (rva, _, import_data) = self.get_dir_entry_data( Self::IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT, true, + true, )?; if rva == 0 { @@ -1790,8 +1847,12 @@ impl<'a> PE<'a> { } fn parse_exports(&self) -> Option> { - let (exports_rva, exports_size, exports_data) = - self.get_dir_entry_data(Self::IMAGE_DIRECTORY_ENTRY_EXPORT, true)?; + let (exports_rva, exports_size, exports_data) = self + .get_dir_entry_data( + Self::IMAGE_DIRECTORY_ENTRY_EXPORT, + true, + true, + )?; if exports_rva == 0 { return None; @@ -2318,6 +2379,7 @@ impl From<&Section<'_>> for protos::pe::Section { } } +/* impl From<&authenticode_parser::Authenticode<'_>> for protos::pe::Signature { fn from(value: &authenticode_parser::Authenticode) -> Self { let mut sig = protos::pe::Signature::new(); @@ -2461,6 +2523,7 @@ impl From<&authenticode_parser::Certificate<'_>> for protos::pe::Certificate { cert } } +*/ impl rva2off::Section for Section<'_> { fn virtual_address(&self) -> u32 { From 2b31e59ec15bb5c9df0386934841414c86a2137f Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Wed, 10 Apr 2024 13:46:42 +0200 Subject: [PATCH 02/38] feat: get certificate chain for Authenticode signatures. --- lib/src/modules/pe/authenticode.rs | 58 ++++++++++++++++++++++++++---- lib/src/modules/pe/parser.rs | 2 +- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index f581b15f4..683ced563 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -2,11 +2,11 @@ use array_bytes::bytes2hex; use cms::cert::x509::{spki, Certificate}; use cms::content_info::CmsVersion; use cms::content_info::ContentInfo; -use cms::signed_data::{SignedData, SignerInfo}; +use cms::signed_data::{SignedData, SignerIdentifier, SignerInfo}; use const_oid::db::{rfc5912, rfc6268}; use const_oid::ObjectIdentifier; use der::asn1::OctetString; -use der::{Decode, Encode, EncodeValue}; +use der::{Decode, Encode}; use der::{Sequence, SliceReader}; use protobuf::MessageField; use sha1::digest::Output; @@ -106,10 +106,6 @@ pub enum AuthenticodeParseError { pub struct AuthenticodeParser {} impl AuthenticodeParser { - pub fn new() -> Self { - Self {} - } - /// Parses Authenticode signatures from DER-encoded bytes. pub fn parse( bytes: &[u8], @@ -295,6 +291,52 @@ impl AuthenticodeSignature { } }) } + + /// Returns the certificate chain for this signature. + pub fn chain(&self) -> Vec<&Certificate> { + if let SignerIdentifier::IssuerAndSerialNumber(signer) = + &self.signer_info().sid + { + self.build_chain(signer) + } else { + unreachable!() + } + } +} + +impl AuthenticodeSignature { + /// Returns a certificate chain containing the certificate with the given + /// issuer and serial number, and all the certificates participating in the + /// chain of trust for that certificate, up to the highest level certificate + /// found in the Authenticode signature. + /// + /// The first item in the vector is the requested certificate, and the + /// highest level certificate in the chain is the last one. + fn build_chain( + &self, + issuer_and_serial_number: &cms::cert::IssuerAndSerialNumber, + ) -> Vec<&Certificate> { + let mut chain = vec![]; + + let mut current = match self.certificates().find(|cert| { + cert.tbs_certificate.serial_number + == issuer_and_serial_number.serial_number + }) { + Some(current) => current, + None => return vec![], + }; + + chain.push(current); + + while let Some(cert) = self.certificates().find(|cert| { + cert.tbs_certificate.subject == current.tbs_certificate.issuer + }) { + chain.push(cert); + current = cert; + } + + chain + } } impl From<&AuthenticodeSignature> for protos::pe::Signature { @@ -312,6 +354,10 @@ impl From<&AuthenticodeSignature> for protos::pe::Signature { signer_info.set_digest_alg(value.signer_info_digest_alg()); signer_info.set_digest(value.signer_info_digest()); + signer_info.chain.extend( + value.chain().into_iter().map(protos::pe::Certificate::from), + ); + sig.signer_info = MessageField::from(Some(signer_info)); // Some fields from the first certificate in the chain are replicated diff --git a/lib/src/modules/pe/parser.rs b/lib/src/modules/pe/parser.rs index 891fa651a..9abc70946 100644 --- a/lib/src/modules/pe/parser.rs +++ b/lib/src/modules/pe/parser.rs @@ -1384,7 +1384,7 @@ impl<'a> PE<'a> { input: &[u8], ) -> IResult<&[u8], Vec> { // Parse the WIN_CERTIFICATE structure. - let (remainder, (length, revision, cert_type)) = tuple(( + let (remainder, (length, _revision, _cert_type)) = tuple(( le_u32::<&[u8], Error>, // length le_u16, // revision, should be WIN_CERT_REVISION_1_0 (0x0100) le_u16, // certificate type From 6c736ac295566bcedc1f8dfe4b5d7db92dfbe108 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Thu, 11 Apr 2024 13:52:29 +0200 Subject: [PATCH 03/38] feat: advance in the implementation of Authenticode parser --- Cargo.lock | 73 ++++++++ Cargo.toml | 2 + lib/Cargo.toml | 4 + lib/src/modules/dotnet/parser.rs | 1 - lib/src/modules/pe/authenticode.rs | 273 +++++++++++++++++++++++------ lib/src/modules/pe/parser.rs | 58 +++--- 6 files changed, 321 insertions(+), 90 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fceb24663..082b66c02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -578,6 +578,18 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +[[package]] +name = "cmpv2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "961b955a666e25ee5a1091d219128d6e6401e3dab84efb1a2bf6b4035d797b39" +dependencies = [ + "crmf", + "der", + "spki", + "x509-cert", +] + [[package]] name = "cms" version = "0.2.3" @@ -815,6 +827,18 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crmf" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36fe21b96d5b87f5de4b5b7202ec41c00110ac817ce6728fe75fb2fe5962ed92" +dependencies = [ + "cms", + "der", + "spki", + "x509-cert", +] + [[package]] name = "crossbeam" version = "0.8.4" @@ -3314,6 +3338,27 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tls_codec" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e78c9c330f8c85b2bae7c8368f2739157db9991235123aa1b15ef9502bfb6a" +dependencies = [ + "tls_codec_derive", + "zeroize", +] + +[[package]] +name = "tls_codec_derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9ef545650e79f30233c0003bcc2504d7efac6dad25fca40744de773fe2049c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + [[package]] name = "tlsh-fixed" version = "0.1.1" @@ -4281,6 +4326,18 @@ dependencies = [ "const-oid", "der", "spki", + "tls_codec", +] + +[[package]] +name = "x509-tsp" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5ceece934a21607055b7ac5c25adb56a2ff559804b10705dc674d1d838c15e1" +dependencies = [ + "cmpv2", + "cms", + "der", ] [[package]] @@ -4359,6 +4416,8 @@ dependencies = [ "uuid", "walrus", "wasmtime", + "x509-cert", + "x509-tsp", "yansi 1.0.1", "yara-x-macros", "yara-x-parser", @@ -4509,6 +4568,20 @@ name = "zeroize" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] [[package]] name = "zip" diff --git a/Cargo.toml b/Cargo.toml index e63aaec37..7338835eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -95,6 +95,8 @@ thiserror = "1.0.58" uuid = "1.4.1" walrus = "0.20.2" wasmtime = "19.0.1" +x509-cert = "0.2.5" +x509-tsp = "0.1.0" yaml-rust = "0.4.5" yansi = "1.0.1" yara-x = { path = "lib" } diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 6dff49fc9..e8599b638 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -120,6 +120,8 @@ pe-module = [ "dep:const-oid", "dep:nom", "dep:sha1", + "dep:x509-cert", + "dep:x509-tsp", ] # The `string` modules offer some functions for parsing strings as integers, @@ -204,6 +206,8 @@ tlsh-fixed = { workspace = true, optional = true } uuid = { workspace = true, optional = true, features = ["v4"] } walrus = { workspace = true } wasmtime = { workspace = true, features = ["cranelift", "parallel-compilation"] } +x509-cert = { workspace = true, optional = true } +x509-tsp = { workspace = true, optional = true } yansi = { workspace = true } yara-x-macros = { workspace = true } yara-x-parser = { workspace = true } diff --git a/lib/src/modules/dotnet/parser.rs b/lib/src/modules/dotnet/parser.rs index fa9e8e023..24b53d932 100644 --- a/lib/src/modules/dotnet/parser.rs +++ b/lib/src/modules/dotnet/parser.rs @@ -135,7 +135,6 @@ impl<'a> Dotnet<'a> { .get_dir_entry_data( PE::IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR, false, - true, ) .ok_or(Error::InvalidDotNet)?; diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 683ced563..3ebd434ae 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -1,16 +1,20 @@ +use std::fmt::Write; + use array_bytes::bytes2hex; +use cms::attr::{Countersignature, SigningTime}; use cms::cert::x509::{spki, Certificate}; use cms::content_info::CmsVersion; use cms::content_info::ContentInfo; use cms::signed_data::{SignedData, SignerIdentifier, SignerInfo}; -use const_oid::db::{rfc5912, rfc6268}; +use const_oid::db::{rfc5911, rfc5912, rfc6268}; use const_oid::ObjectIdentifier; -use der::asn1::OctetString; +use der::asn1::{OctetString, UtcTime}; use der::{Decode, Encode}; use der::{Sequence, SliceReader}; use protobuf::MessageField; use sha1::digest::Output; use sha1::{Digest, Sha1}; +use x509_tsp::TstInfo; use crate::modules::protos; @@ -18,9 +22,12 @@ use crate::modules::protos; pub const SPC_INDIRECT_DATA_OBJID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.2.1.4"); -pub const SPC_NESTED_SIGNATURE: ObjectIdentifier = +pub const SPC_MS_NESTED_SIGNATURE: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.2.4.1"); +pub const SPC_MS_COUNTERSIGN: ObjectIdentifier = + ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.3.3.1"); + /// Authenticode ASN.1 image and digest data. #[derive(Clone, Debug, Eq, PartialEq, Sequence)] pub struct SpcIndirectDataContent { @@ -54,7 +61,7 @@ pub struct DigestInfo { /// Error returned by [`AuthenticodeParser::parse`]. #[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum AuthenticodeParseError { +pub enum ParseError { /// The signature data is empty. Empty, @@ -102,6 +109,11 @@ pub enum AuthenticodeParseError { } /// Parses Authenticode signatures in a PE file. +/// +/// Some resources for understanding Authenticode signatures: +/// https://blog.trailofbits.com/2020/05/27/verifying-windows-binaries-without-windows/ +/// https://docs.clamav.net/appendix/Authenticode.html +/// https://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/authenticode_pe.docx #[derive(Clone, Debug, Eq, PartialEq)] pub struct AuthenticodeParser {} @@ -109,18 +121,18 @@ impl AuthenticodeParser { /// Parses Authenticode signatures from DER-encoded bytes. pub fn parse( bytes: &[u8], - ) -> Result, AuthenticodeParseError> { + ) -> Result, ParseError> { // Use a reader rather than using `Decode::from_der`, because there may // be unused trailing data in `input`, which causes a `TrailingData` // error. - let mut reader = SliceReader::new(bytes) - .map_err(|_| AuthenticodeParseError::Empty)?; + let mut reader = + SliceReader::new(bytes).map_err(|_| ParseError::Empty)?; let content_info = ContentInfo::decode(&mut reader) - .map_err(AuthenticodeParseError::InvalidContentInfo)?; + .map_err(ParseError::InvalidContentInfo)?; if content_info.content_type != rfc6268::ID_SIGNED_DATA { - return Err(AuthenticodeParseError::InvalidContentType( + return Err(ParseError::InvalidContentType( content_info.content_type, )); } @@ -128,10 +140,10 @@ impl AuthenticodeParser { let signed_data = content_info .content .decode_as::() - .map_err(AuthenticodeParseError::InvalidSignedData)?; + .map_err(ParseError::InvalidSignedData)?; if signed_data.version != CmsVersion::V1 { - return Err(AuthenticodeParseError::InvalidSignedDataVersion( + return Err(ParseError::InvalidSignedDataVersion( signed_data.version, )); } @@ -139,14 +151,14 @@ impl AuthenticodeParser { // According to the specification, SignedData must contain exactly one // digest algorithm, and it must match the one specified in SignerInfo. if signed_data.digest_algorithms.len() != 1 { - return Err(AuthenticodeParseError::InvalidNumDigestAlgorithms( + return Err(ParseError::InvalidNumDigestAlgorithms( signed_data.digest_algorithms.len(), )); } // Exactly one SignerInfo, as required by the specification. if signed_data.signer_infos.0.len() != 1 { - return Err(AuthenticodeParseError::InvalidNumSignerInfo( + return Err(ParseError::InvalidNumSignerInfo( signed_data.signer_infos.0.len(), )); } @@ -154,25 +166,23 @@ impl AuthenticodeParser { if signed_data.encap_content_info.econtent_type != SPC_INDIRECT_DATA_OBJID { - return Err( - AuthenticodeParseError::InvalidEncapsulatedContentType( - signed_data.encap_content_info.econtent_type, - ), - ); + return Err(ParseError::InvalidEncapsulatedContentType( + signed_data.encap_content_info.econtent_type, + )); } let indirect_data = signed_data .encap_content_info .econtent .as_ref() - .ok_or(AuthenticodeParseError::EmptyEncapsulatedContent)? + .ok_or(ParseError::EmptyEncapsulatedContent)? .decode_as::() - .map_err(AuthenticodeParseError::InvalidSpcIndirectDataContent)?; + .map_err(ParseError::InvalidSpcIndirectDataContent)?; let signer_info = &signed_data.signer_infos.0.as_slice()[0]; if signer_info.version != CmsVersion::V1 { - return Err(AuthenticodeParseError::InvalidSignerInfoVersion( + return Err(ParseError::InvalidSignerInfoVersion( signer_info.version, )); } @@ -180,23 +190,22 @@ impl AuthenticodeParser { if signer_info.digest_alg != signed_data.digest_algorithms.as_slice()[0] { - return Err(AuthenticodeParseError::AlgorithmMismatch); + return Err(ParseError::AlgorithmMismatch); } - let signed_attrs = if let Some(signed_attrs) = - &signer_info.signed_attrs - { - signed_attrs - } else { - return Err(AuthenticodeParseError::EmptyAuthenticatedAttributes); - }; + let signed_attrs = + if let Some(signed_attrs) = &signer_info.signed_attrs { + signed_attrs + } else { + return Err(ParseError::EmptyAuthenticatedAttributes); + }; // The contentType attribute must be present. if !signed_attrs .iter() .any(|attr| attr.oid == rfc6268::ID_CONTENT_TYPE) { - return Err(AuthenticodeParseError::MissingContentTypeAuthenticatedAttribute); + return Err(ParseError::MissingContentTypeAuthenticatedAttribute); } // The messageDigest attribute must be present. @@ -206,28 +215,66 @@ impl AuthenticodeParser { { digest_attr.values.as_slice()[0].value() } else { - return Err(AuthenticodeParseError::MissingMessageDigestAuthenticatedAttribute); + return Err( + ParseError::MissingMessageDigestAuthenticatedAttribute, + ); }; - // An Authenticode signature can contain nested signatures in - // an unsigned attribute with OID 1.3.6.1.4.1.311.2.4.1. let mut nested_signatures = Vec::new(); + let mut countersignatures = Vec::new(); if let Some(attrs) = &signer_info.unsigned_attrs { for attr in attrs.iter() { - if attr.oid == SPC_NESTED_SIGNATURE { - // TODO: can we do this without having to use encode_to_vec? - let mut raw = Vec::new(); - if attr.values.as_slice()[0] - .encode_to_vec(&mut raw) - .is_ok() - { - if let Ok(signatures) = - AuthenticodeParser::parse(raw.as_slice()) + match attr.oid { + // An Authenticode signature can contain nested signatures in + // an unsigned attribute with OID 1.3.6.1.4.1.311.2.4.1. + SPC_MS_NESTED_SIGNATURE => { + // TODO: can we do this without having to use encode_to_vec? + let mut raw = Vec::new(); + if attr.values.as_slice()[0] + .encode_to_vec(&mut raw) + .is_ok() { - nested_signatures.extend(signatures); + if let Ok(signatures) = + AuthenticodeParser::parse(raw.as_slice()) + { + nested_signatures.extend(signatures); + } + }; + } + SPC_MS_COUNTERSIGN => { + for value in attr.values.iter() { + if let Ok(signed_data) = value + .decode_as::() + .and_then(|content_info| { + content_info + .content + .decode_as::() + }) + { + countersignatures.push( + Self::pkcs9_countersignature( + signed_data + .signer_infos + .as_ref() + .get(0) + .unwrap(), + ), + ); + } } } + rfc5911::ID_COUNTERSIGNATURE => { + for value in attr.values.iter() { + if let Ok(cs) = + value.decode_as::().as_ref() + { + countersignatures + .push(Self::pkcs9_countersignature(cs)); + } + } + } + _ => {} } } } @@ -238,18 +285,57 @@ impl AuthenticodeParser { signer_info_digest: bytes2hex("", signer_info_digest), signed_data, indirect_data, + countersignatures, }); signatures.append(&mut nested_signatures); Ok(signatures) } + + fn pkcs9_countersignature( + cs: &Countersignature, + ) -> AuthenticodeCountersign { + let mut digest = None; + let mut signing_time = None; + + if let Some(signed_attrs) = &cs.signed_attrs { + for attr in signed_attrs.iter() { + match attr.oid { + rfc6268::ID_MESSAGE_DIGEST => { + if let Some(value) = attr.values.get(0) { + digest = Some(bytes2hex("", value.value())); + } + } + rfc6268::ID_SIGNING_TIME => { + if let Some(value) = attr.values.get(0) { + signing_time = value.decode_as::().ok(); + } + } + _ => {} + } + } + } + + AuthenticodeCountersign { + digest_alg: oid_to_algorithm_name(&cs.digest_alg.oid), + digest, + signing_time, + } + } +} + +pub struct AuthenticodeCountersign { + digest_alg: &'static str, + digest: Option, + signing_time: Option, } pub struct AuthenticodeSignature { signer_info_digest: String, signed_data: SignedData, indirect_data: SpcIndirectDataContent, + countersignatures: Vec, } impl AuthenticodeSignature { @@ -281,7 +367,6 @@ impl AuthenticodeSignature { self.signer_info_digest.clone() } - /// Get the certificate chain. pub fn certificates(&self) -> impl Iterator { self.signed_data.certificates.as_ref().unwrap().0.iter().map(|cert| { if let cms::cert::CertificateChoices::Certificate(cert) = cert { @@ -292,7 +377,12 @@ impl AuthenticodeSignature { }) } - /// Returns the certificate chain for this signature. + pub fn countersignatures( + &self, + ) -> impl Iterator { + self.countersignatures.iter() + } + pub fn chain(&self) -> Vec<&Certificate> { if let SignerIdentifier::IssuerAndSerialNumber(signer) = &self.signer_info().sid @@ -349,6 +439,10 @@ impl From<&AuthenticodeSignature> for protos::pe::Signature { sig.certificates .extend(value.certificates().map(protos::pe::Certificate::from)); + sig.countersignatures.extend( + value.countersignatures().map(protos::pe::CounterSignature::from), + ); + let mut signer_info = protos::pe::SignerInfo::new(); signer_info.set_digest_alg(value.signer_info_digest_alg()); @@ -382,20 +476,45 @@ impl From<&AuthenticodeSignature> for protos::pe::Signature { } } +impl From<&AuthenticodeCountersign> for protos::pe::CounterSignature { + fn from(value: &AuthenticodeCountersign) -> Self { + let mut cs = protos::pe::CounterSignature::new(); + + cs.digest = value.digest.clone(); + cs.set_digest_alg(value.digest_alg.to_string()); + + /*cs.set_verified( + value + .verify_flags() + .is_some_and(|flags| flags == CounterSignatureVerify::Valid), + );*/ + + cs.sign_time = + value.signing_time.map(|t| t.to_unix_duration().as_secs() as i64); + + /*cs.chain.extend( + value + .certificate_chain() + .iter() + .map(protos::pe::Certificate::from), + );*/ + + cs + } +} + impl From<&Certificate> for protos::pe::Certificate { fn from(value: &Certificate) -> Self { let mut cert = protos::pe::Certificate::new(); // Versions are 0-based, add 1 for getting the actual version. cert.set_version(value.tbs_certificate.version as i64 + 1); - // TODO: - // /C=ZA/ST=Western Cape/L=Durbanville/O=Thawte/OU=Thawte Certification/CN=Thawte Timestamping CA - // CN=Thawte Timestamping CA,OU=Thawte Certification,O=Thawte,L=Durbanville,ST=Western Cape,C=ZA - cert.set_issuer(format!("{}", value.tbs_certificate.issuer)); - cert.set_subject(format!("{}", value.tbs_certificate.subject)); + cert.set_issuer(format_name(&value.tbs_certificate.issuer)); + cert.set_subject(format_name(&value.tbs_certificate.subject)); - // TODO: to lower - cert.set_serial(format!("{}", value.tbs_certificate.serial_number)); + cert.set_serial(format_serial_number( + &value.tbs_certificate.serial_number, + )); cert.set_algorithm_oid(format!("{}", value.signature_algorithm.oid)); cert.set_algorithm( @@ -433,6 +552,56 @@ impl From<&Certificate> for protos::pe::Certificate { } } +/// Produces a printable string for a x509 name. +/// +/// The [`x509_cert::name::Name`] type implements the [`std::fmt::Display`] +/// trait, but the resulting string follows the [RFC 4514], resulting in +/// something like: +/// +/// ```text +/// CN=Thawte Timestamping CA,OU=Thawte Certification,O=Thawte,L=Durbanville,ST=Western Cape,C=ZA +/// ``` +/// +/// However, the format traditionally used by YARA is inherited from OpenSSL and looks like: +/// +/// ```text +/// /C=ZA/ST=Western Cape/L=Durbanville/O=Thawte/OU=Thawte Certification/CN=Thawte Timestamping CA +/// ``` +/// +/// [RFC 4514]: https://datatracker.ietf.org/doc/html/rfc4514 +fn format_name(name: &x509_cert::name::Name) -> String { + let mut result = String::new(); + for s in &name.0 { + write!(result, "/{}", s).unwrap(); + } + result +} + +/// Produces a printable string of a serial number. +/// +/// The [`x509_cert::serial_number::SerialNumber`] type implements the +/// [`std::fmt::Display`] trait, but the resulting string is in uppercase. +fn format_serial_number( + sn: &x509_cert::serial_number::SerialNumber, +) -> String { + let mut iter = sn.as_bytes().iter().peekable(); + let mut result = String::new(); + while let Some(byte) = iter.next() { + match iter.peek() { + Some(_) => write!(result, "{:02x}:", byte).unwrap(), + None => write!(result, "{:02x}", byte).unwrap(), + } + } + result +} + +/// Given an OID that represents an algorithm name, returns a string +/// that identifies the algorithm. +/// +/// # Panics +/// +/// If the OID doesn't correspond to some of the supported algorithm +/// names. fn oid_to_algorithm_name(oid: &ObjectIdentifier) -> &'static str { if oid == &rfc5912::ID_SHA_1 { "sha1" diff --git a/lib/src/modules/pe/parser.rs b/lib/src/modules/pe/parser.rs index 9abc70946..70153664e 100644 --- a/lib/src/modules/pe/parser.rs +++ b/lib/src/modules/pe/parser.rs @@ -305,7 +305,7 @@ impl<'a> PE<'a> { /// Returns the RVA, size and data associated to a given directory entry. /// - /// The returned tuple is `(rva, size, data)`, where `rva` and `size` are + /// The returned tuple is `(addr, size, data)`, where `addr` and `size` are /// the ones indicated in the directory entry, and `data` is a slice that /// contains the file's content from that RVA to the end of the file if /// `strict_size` is false. Otherwise, the slice will be limited to the @@ -314,7 +314,6 @@ impl<'a> PE<'a> { &self, index: usize, strict_size: bool, - addr_to_rva: bool, ) -> Option<(u32, u32, &'a [u8])> { // Nobody should call this function with an index greater // than MAX_DIR_ENTRIES. @@ -330,17 +329,19 @@ impl<'a> PE<'a> { // overly strict here and only parse entries which are less than // `number_of_rva_and_sizes` we run the risk of missing otherwise // perfectly valid files. - let dir_entry = self .directory .get(index * Self::SIZE_OF_DIR_ENTRY..) .and_then(|entry| Self::parse_dir_entry(entry).ok()) .map(|(_reminder, entry)| entry)?; - let start = if addr_to_rva { - self.rva_to_offset(dir_entry.addr)? - } else { + // The IMAGE_DIRECTORY_ENTRY_SECURITY is the only one where the `addr` + // field is not an RVA, but a file offset, so we don't need to convert + // it to offset. + let start = if index == Self::IMAGE_DIRECTORY_ENTRY_SECURITY { dir_entry.addr + } else { + self.rva_to_offset(dir_entry.addr)? }; let end = if strict_size { @@ -351,7 +352,7 @@ impl<'a> PE<'a> { let data = self.data.get(start as usize..end)?; - Some((start, dir_entry.size, data)) + Some((dir_entry.addr, dir_entry.size, data)) } /// Returns information about the functions imported by this PE file. @@ -1253,11 +1254,8 @@ impl<'a> PE<'a> { /// individual resources of that type, and the children of each individual /// resource represent the resource in a specific language. fn parse_resources(&self) -> Option<(ResourceDir, Vec>)> { - let (_, _, rsrc_section) = self.get_dir_entry_data( - Self::IMAGE_DIRECTORY_ENTRY_RESOURCE, - false, - true, - )?; + let (_, _, rsrc_section) = self + .get_dir_entry_data(Self::IMAGE_DIRECTORY_ENTRY_RESOURCE, false)?; let mut queue = VecDeque::new(); let mut resources = vec![]; @@ -1359,11 +1357,8 @@ impl<'a> PE<'a> { /// Parses the PE Authenticode signatures. fn parse_signatures(&self) -> Option> { - let (_, _, cert_table) = self.get_dir_entry_data( - Self::IMAGE_DIRECTORY_ENTRY_SECURITY, - true, - false, - )?; + let (_, _, cert_table) = self + .get_dir_entry_data(Self::IMAGE_DIRECTORY_ENTRY_SECURITY, true)?; // The certificate table is an array of WIN_CERTIFICATE structures. let signatures = fold_many0( @@ -1428,11 +1423,8 @@ impl<'a> PE<'a> { /// Parses the PE debug information and extracts the PDB path. fn parse_dbg(&self) -> Option<&'a [u8]> { - let (_, _, dbg_section) = self.get_dir_entry_data( - Self::IMAGE_DIRECTORY_ENTRY_DEBUG, - true, - true, - )?; + let (_, _, dbg_section) = + self.get_dir_entry_data(Self::IMAGE_DIRECTORY_ENTRY_DEBUG, true)?; let entries = many0(Self::parse_dbg_dir_entry)(dbg_section) .map(|(_, entries)| entries) @@ -1569,13 +1561,10 @@ impl<'a> PE<'a> { /// Parses PE imports. fn parse_imports(&self) -> Option)>> { - let (rva, _, import_data) = self.get_dir_entry_data( - Self::IMAGE_DIRECTORY_ENTRY_IMPORT, - false, - true, - )?; + let (addr, _, import_data) = self + .get_dir_entry_data(Self::IMAGE_DIRECTORY_ENTRY_IMPORT, false)?; - if rva == 0 { + if addr == 0 { return None; } @@ -1586,13 +1575,12 @@ impl<'a> PE<'a> { fn parse_delayed_imports( &self, ) -> Option)>> { - let (rva, _, import_data) = self.get_dir_entry_data( + let (addr, _, import_data) = self.get_dir_entry_data( Self::IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT, true, - true, )?; - if rva == 0 { + if addr == 0 { return None; } @@ -1847,12 +1835,8 @@ impl<'a> PE<'a> { } fn parse_exports(&self) -> Option> { - let (exports_rva, exports_size, exports_data) = self - .get_dir_entry_data( - Self::IMAGE_DIRECTORY_ENTRY_EXPORT, - true, - true, - )?; + let (exports_rva, exports_size, exports_data) = + self.get_dir_entry_data(Self::IMAGE_DIRECTORY_ENTRY_EXPORT, true)?; if exports_rva == 0 { return None; From b918435068595e1ef299acafa6407ab5c76e6fc7 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Fri, 12 Apr 2024 20:36:34 +0200 Subject: [PATCH 04/38] feat: advance with the implementation of authenticode parser --- lib/src/modules/pe/authenticode.rs | 205 +++++++++++++++++++++++++---- 1 file changed, 178 insertions(+), 27 deletions(-) diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 3ebd434ae..3bdad034e 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -1,20 +1,22 @@ -use std::fmt::Write; +use std::fmt::{Display, Write}; use array_bytes::bytes2hex; -use cms::attr::{Countersignature, SigningTime}; +use cms::attr::Countersignature; use cms::cert::x509::{spki, Certificate}; use cms::content_info::CmsVersion; use cms::content_info::ContentInfo; use cms::signed_data::{SignedData, SignerIdentifier, SignerInfo}; -use const_oid::db::{rfc5911, rfc5912, rfc6268}; +use const_oid::db::{rfc5911, rfc5912, rfc6268, DB}; use const_oid::ObjectIdentifier; -use der::asn1::{OctetString, UtcTime}; -use der::{Decode, Encode}; -use der::{Sequence, SliceReader}; +use der::asn1::{ + BmpString, Ia5String, Ia5StringRef, OctetString, PrintableStringRef, + TeletexStringRef, UtcTime, Utf8StringRef, +}; +use der::{Choice, Sequence, SliceReader}; +use der::{Decode, Encode, Tag, Tagged}; use protobuf::MessageField; use sha1::digest::Output; use sha1::{Digest, Sha1}; -use x509_tsp::TstInfo; use crate::modules::protos; @@ -22,13 +24,22 @@ use crate::modules::protos; pub const SPC_INDIRECT_DATA_OBJID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.2.1.4"); +/// OID for [`SpcSpOpusInfo`]. +pub const SPC_SP_OPUS_INFO_OBJID: ObjectIdentifier = + ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.2.1.12"); + pub const SPC_MS_NESTED_SIGNATURE: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.2.4.1"); pub const SPC_MS_COUNTERSIGN: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.3.3.1"); -/// Authenticode ASN.1 image and digest data. +/// ASN.1 SpcIndirectDataContent +/// +/// SpcIndirectDataContent ::= SEQUENCE { +/// data SpcAttributeTypeAndOptionalValue, +/// messageDigest DigestInfo +/// } #[derive(Clone, Debug, Eq, PartialEq, Sequence)] pub struct SpcIndirectDataContent { /// Image data. @@ -38,18 +49,25 @@ pub struct SpcIndirectDataContent { pub message_digest: DigestInfo, } -/// Authenticode ASN.1 image data. +/// ASN.1 SpcAttributeTypeAndOptionalValue +/// +/// SpcAttributeTypeAndOptionalValue ::= SEQUENCE { +/// type ObjectID, +/// value [0] EXPLICIT ANY OPTIONAL +/// } #[derive(Clone, Debug, Eq, PartialEq, Sequence)] pub struct SpcAttributeTypeAndOptionalValue { /// Type of data stored in the `value` field. pub value_type: ObjectIdentifier, - - /// Image data. - //TODO(nicholasbishop): implement SpcPeImageData. pub value: der::Any, } -/// Authenticode ASN.1 digest data. +/// ASN.1 DigestInfo +/// +/// DigestInfo ::= SEQUENCE { +/// digestAlgorithm AlgorithmIdentifier, +/// digest OCTETSTRING +/// } #[derive(Clone, Debug, Eq, PartialEq, Sequence)] pub struct DigestInfo { /// Authenticode digest algorithm. @@ -59,6 +77,58 @@ pub struct DigestInfo { pub digest: OctetString, } +/// ASN.1 SpcSpOpusInfo +/// +/// SpcSpOpusInfo ::= SEQUENCE { +/// programName [0] EXPLICIT SpcString OPTIONAL, +/// moreInfo [1] EXPLICIT SpcLink OPTIONAL, +/// } +#[derive(Clone, Debug, Eq, PartialEq, Sequence)] +pub struct SpcSpOpusInfo { + #[asn1(context_specific = "0", optional = "true")] + pub program_name: Option, + #[asn1(context_specific = "1", optional = "true")] + pub more_info: Option, +} + +/// ASN.1 SpcString +/// +/// SpcString ::= CHOICE { +/// unicode [0] IMPLICIT BMPSTRING, +/// ascii [1] IMPLICIT IA5STRING +/// } +#[derive(Clone, Debug, Eq, PartialEq, Choice)] +pub enum SpcString { + #[asn1(context_specific = "0", tag_mode = "IMPLICIT")] + Unicode(BmpString), + #[asn1(context_specific = "1", tag_mode = "IMPLICIT", type = "IA5String")] + Ascii(Ia5String), +} + +impl Display for SpcString { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let str = match self { + SpcString::Unicode(unicode) => unicode.to_string(), + SpcString::Ascii(ascii) => ascii.to_string(), + }; + write!(f, "{}", str) + } +} + +/// ASN.1 SpcLink +/// +/// SpcLink ::= CHOICE { +/// url [0] IMPLICIT IA5STRING, +/// moniker [1] IMPLICIT SpcSerializedObject, +/// file [2] EXPLICIT SpcString +/// } +/// +#[derive(Clone, Debug, Eq, PartialEq, Choice)] +pub enum SpcLink { + #[asn1(context_specific = "0", tag_mode = "IMPLICIT", type = "IA5String")] + Url(Ia5String), +} + /// Error returned by [`AuthenticodeParser::parse`]. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum ParseError { @@ -220,6 +290,14 @@ impl AuthenticodeParser { ); }; + let opus_info = signed_attrs + .iter() + .find(|attr| attr.oid == SPC_SP_OPUS_INFO_OBJID) + .and_then(|attr| attr.values.get(0)) + .and_then(|attr_val| attr_val.decode_as::().ok()); + + let program_name = opus_info.and_then(|oi| oi.program_name); + let mut nested_signatures = Vec::new(); let mut countersignatures = Vec::new(); @@ -286,6 +364,7 @@ impl AuthenticodeParser { signed_data, indirect_data, countersignatures, + program_name, }); signatures.append(&mut nested_signatures); @@ -336,6 +415,7 @@ pub struct AuthenticodeSignature { signed_data: SignedData, indirect_data: SpcIndirectDataContent, countersignatures: Vec, + program_name: Option, } impl AuthenticodeSignature { @@ -408,24 +488,30 @@ impl AuthenticodeSignature { ) -> Vec<&Certificate> { let mut chain = vec![]; - let mut current = match self.certificates().find(|cert| { + let mut cert = match self.certificates().find(|cert| { cert.tbs_certificate.serial_number == issuer_and_serial_number.serial_number }) { - Some(current) => current, + Some(cert) => cert, None => return vec![], }; - chain.push(current); - - while let Some(cert) = self.certificates().find(|cert| { - cert.tbs_certificate.subject == current.tbs_certificate.issuer - }) { + loop { chain.push(cert); - current = cert; - } - chain + // When the certificate is self-signed issuer == subject, in that + // case we can't keep going up the chain. + if cert.tbs_certificate.subject == cert.tbs_certificate.issuer { + return chain; + } + + match self.certificates().find(|c| { + c.tbs_certificate.subject == cert.tbs_certificate.issuer + }) { + Some(c) => cert = c, + None => return chain, + } + } } } @@ -443,11 +529,23 @@ impl From<&AuthenticodeSignature> for protos::pe::Signature { value.countersignatures().map(protos::pe::CounterSignature::from), ); + sig.set_number_of_certificates( + sig.certificates.len().try_into().unwrap(), + ); + + sig.set_number_of_countersignatures( + sig.countersignatures.len().try_into().unwrap(), + ); + let mut signer_info = protos::pe::SignerInfo::new(); signer_info.set_digest_alg(value.signer_info_digest_alg()); signer_info.set_digest(value.signer_info_digest()); + if let Some(program_name) = &value.program_name { + signer_info.set_program_name(program_name.to_string()) + } + signer_info.chain.extend( value.chain().into_iter().map(protos::pe::Certificate::from), ); @@ -570,11 +668,64 @@ impl From<&Certificate> for protos::pe::Certificate { /// /// [RFC 4514]: https://datatracker.ietf.org/doc/html/rfc4514 fn format_name(name: &x509_cert::name::Name) -> String { - let mut result = String::new(); - for s in &name.0 { - write!(result, "/{}", s).unwrap(); + let mut n = String::new(); + for rdn in &name.0 { + write!(n, "/").unwrap(); + for atv in rdn.0.iter() { + let val = match atv.value.tag() { + Tag::PrintableString => { + PrintableStringRef::try_from(&atv.value) + .ok() + .map(|s| s.as_str()) + } + Tag::Utf8String => Utf8StringRef::try_from(&atv.value) + .ok() + .map(|s| s.as_str()), + Tag::Ia5String => { + Ia5StringRef::try_from(&atv.value).ok().map(|s| s.as_str()) + } + Tag::TeletexString => TeletexStringRef::try_from(&atv.value) + .ok() + .map(|s| s.as_str()), + _ => None, + }; + + if let (Some(key), Some(val)) = + (shortest_name_by_oid(&atv.oid), val) + { + write!(n, "{}=", key.to_ascii_uppercase()).unwrap(); + for char in val.chars() { + n.write_char(char).unwrap(); + } + } else { + let value = atv.value.to_der().unwrap(); + write!(n, "{}=#", atv.oid).unwrap(); + for c in value { + write!(n, "{:02x}", c).unwrap(); + } + } + } } - result + + n +} + +/// Returns a short name from an OID. +/// +/// This returns the strings like "C", "CN", "O", "OU", "ST", etc. This strings +/// represents field names in issuer and subject strings. +fn shortest_name_by_oid(oid: &ObjectIdentifier) -> Option<&str> { + let mut best_match: Option<&str> = None; + for m in DB.find_names_for_oid(*oid) { + if let Some(previous) = best_match { + if m.len() < previous.len() { + best_match = Some(m); + } + } else { + best_match = Some(m); + } + } + best_match } /// Produces a printable string of a serial number. From 74b23ac94e50fd285761a5cd3c5aa480f82ddc72 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Mon, 15 Apr 2024 15:47:27 +0200 Subject: [PATCH 05/38] feat: advance in the implementation of Authenticode parser. --- Cargo.lock | 1 + Cargo.toml | 1 + lib/Cargo.toml | 2 + lib/src/modules/pe/authenticode.rs | 278 +++++++---- lib/src/modules/pe/parser.rs | 142 ++++-- ...f43b9900fdd3a65c985d65a63b8f1535ef5.in.zip | Bin 0 -> 84951 bytes ...b32f43b9900fdd3a65c985d65a63b8f1535ef5.out | 460 ++++++++++++++++++ ...15cdc8dd28a968c6b4d3b88acdd58ce2d3b885.out | 6 +- ...8c44d7f095eb395779de0ad1ac946914dfa34c.out | 10 +- ...6ad42ccfb04ccedd3ada1e8c26939c726a4c8e.out | 3 +- 10 files changed, 772 insertions(+), 131 deletions(-) create mode 100644 lib/src/modules/pe/tests/testdata/00a1067fc96eb2c1d440bb5b44b32f43b9900fdd3a65c985d65a63b8f1535ef5.in.zip create mode 100644 lib/src/modules/pe/tests/testdata/00a1067fc96eb2c1d440bb5b44b32f43b9900fdd3a65c985d65a63b8f1535ef5.out diff --git a/Cargo.lock b/Cargo.lock index 082b66c02..b2640af7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4379,6 +4379,7 @@ dependencies = [ "const-oid", "crc32fast", "der", + "digest 0.10.7", "fmmap", "globwalk", "goldenfile", diff --git a/Cargo.toml b/Cargo.toml index 7338835eb..724f36a5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,7 @@ cms = "0.2.3" const-oid = "0.9.6" crc32fast = "1.4.0" der = "0.7.9" +digest = "0.10.7" enable-ansi-support = "0.2.1" env_logger = "0.11.3" fmmap = "0.3.3" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index e8599b638..8b0478795 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -118,6 +118,7 @@ pe-module = [ "dep:authenticode-parser", "dep:cms", "dep:const-oid", + "dep:digest", "dep:nom", "dep:sha1", "dep:x509-cert", @@ -177,6 +178,7 @@ cms = { workspace = true, optional = true } const-oid = { workspace = true, optional = true } crc32fast = { workspace = true, optional = true } der = { workspace = true, features = ["derive"] } +digest = { workspace = true, optional = true } fmmap = { workspace = true } indexmap = { workspace = true, features = ["serde"] } intaglio = { workspace = true } diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 3bdad034e..5104a1eb0 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -1,22 +1,27 @@ use std::fmt::{Display, Write}; +use crate::modules::pe::parser::PE; use array_bytes::bytes2hex; use cms::attr::Countersignature; use cms::cert::x509::{spki, Certificate}; +use cms::cert::IssuerAndSerialNumber; use cms::content_info::CmsVersion; use cms::content_info::ContentInfo; -use cms::signed_data::{SignedData, SignerIdentifier, SignerInfo}; +use cms::signed_data::{ + CertificateSet, SignedData, SignerIdentifier, SignerInfo, SignerInfos, +}; use const_oid::db::{rfc5911, rfc5912, rfc6268, DB}; use const_oid::ObjectIdentifier; -use der::asn1::{ - BmpString, Ia5String, Ia5StringRef, OctetString, PrintableStringRef, - TeletexStringRef, UtcTime, Utf8StringRef, -}; +use der::asn1; +use der::asn1::OctetString; use der::{Choice, Sequence, SliceReader}; use der::{Decode, Encode, Tag, Tagged}; +use digest::Digest; use protobuf::MessageField; use sha1::digest::Output; -use sha1::{Digest, Sha1}; +use sha1::Sha1; +use sha2::Sha256; +use x509_tsp::TstInfo; use crate::modules::protos; @@ -100,9 +105,9 @@ pub struct SpcSpOpusInfo { #[derive(Clone, Debug, Eq, PartialEq, Choice)] pub enum SpcString { #[asn1(context_specific = "0", tag_mode = "IMPLICIT")] - Unicode(BmpString), + Unicode(asn1::BmpString), #[asn1(context_specific = "1", tag_mode = "IMPLICIT", type = "IA5String")] - Ascii(Ia5String), + Ascii(asn1::Ia5String), } impl Display for SpcString { @@ -126,7 +131,7 @@ impl Display for SpcString { #[derive(Clone, Debug, Eq, PartialEq, Choice)] pub enum SpcLink { #[asn1(context_specific = "0", tag_mode = "IMPLICIT", type = "IA5String")] - Url(Ia5String), + Url(asn1::Ia5String), } /// Error returned by [`AuthenticodeParser::parse`]. @@ -184,29 +189,34 @@ pub enum ParseError { /// https://blog.trailofbits.com/2020/05/27/verifying-windows-binaries-without-windows/ /// https://docs.clamav.net/appendix/Authenticode.html /// https://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/authenticode_pe.docx -#[derive(Clone, Debug, Eq, PartialEq)] pub struct AuthenticodeParser {} impl AuthenticodeParser { /// Parses Authenticode signatures from DER-encoded bytes. pub fn parse( - bytes: &[u8], + input: &[u8], + pe: &PE, ) -> Result, ParseError> { - // Use a reader rather than using `Decode::from_der`, because there may - // be unused trailing data in `input`, which causes a `TrailingData` - // error. + // Use a reader rather than using `Decode::from_der`, because + // there may be unused trailing data in `input`, which causes a + // `TrailingData` error. let mut reader = - SliceReader::new(bytes).map_err(|_| ParseError::Empty)?; + SliceReader::new(input).map_err(|_| ParseError::Empty)?; let content_info = ContentInfo::decode(&mut reader) .map_err(ParseError::InvalidContentInfo)?; - if content_info.content_type != rfc6268::ID_SIGNED_DATA { - return Err(ParseError::InvalidContentType( - content_info.content_type, - )); + if content_info.content_type == rfc6268::ID_SIGNED_DATA { + Self::parse_content_info(content_info, pe) + } else { + Err(ParseError::InvalidContentType(content_info.content_type)) } + } + fn parse_content_info( + content_info: ContentInfo, + pe: &PE, + ) -> Result, ParseError> { let signed_data = content_info .content .decode_as::() @@ -278,25 +288,23 @@ impl AuthenticodeParser { return Err(ParseError::MissingContentTypeAuthenticatedAttribute); } - // The messageDigest attribute must be present. - let signer_info_digest = if let Some(digest_attr) = signed_attrs + let signer_info_digest = signed_attrs .iter() .find(|attr| attr.oid == rfc6268::ID_MESSAGE_DIGEST) - { - digest_attr.values.as_slice()[0].value() - } else { - return Err( - ParseError::MissingMessageDigestAuthenticatedAttribute, - ); - }; + .and_then(|attr| attr.values.get(0)) + .and_then(|value| value.decode_as::().ok()) + .ok_or(ParseError::MissingMessageDigestAuthenticatedAttribute)?; let opus_info = signed_attrs .iter() .find(|attr| attr.oid == SPC_SP_OPUS_INFO_OBJID) .and_then(|attr| attr.values.get(0)) - .and_then(|attr_val| attr_val.decode_as::().ok()); + .and_then(|value| value.decode_as::().ok()); - let program_name = opus_info.and_then(|oi| oi.program_name); + let mut certificates = signed_data + .certificates + .map(Self::certificate_set_to_vec) + .unwrap(); let mut nested_signatures = Vec::new(); let mut countersignatures = Vec::new(); @@ -307,18 +315,18 @@ impl AuthenticodeParser { // An Authenticode signature can contain nested signatures in // an unsigned attribute with OID 1.3.6.1.4.1.311.2.4.1. SPC_MS_NESTED_SIGNATURE => { - // TODO: can we do this without having to use encode_to_vec? - let mut raw = Vec::new(); - if attr.values.as_slice()[0] - .encode_to_vec(&mut raw) - .is_ok() + if let Some(signatures) = attr + .values + .get(0) + .and_then(|value| { + value.decode_as::().ok() + }) + .and_then(|content_info| { + Self::parse_content_info(content_info, pe).ok() + }) { - if let Ok(signatures) = - AuthenticodeParser::parse(raw.as_slice()) - { - nested_signatures.extend(signatures); - } - }; + nested_signatures.extend(signatures); + } } SPC_MS_COUNTERSIGN => { for value in attr.values.iter() { @@ -330,15 +338,55 @@ impl AuthenticodeParser { .decode_as::() }) { - countersignatures.push( - Self::pkcs9_countersignature( - signed_data - .signer_infos - .as_ref() - .get(0) - .unwrap(), - ), + certificates.extend( + signed_data + .certificates + .map(Self::certificate_set_to_vec) + .unwrap(), + ); + + let mut cs = Self::pkcs9_countersignature( + signed_data + .signer_infos + .as_ref() + .get(0) + .unwrap(), + ); + + let tst_info = signed_data + .encap_content_info + .econtent + .and_then(|content| { + content.decode_as::().ok() + }) + .and_then(|octet_string| { + TstInfo::from_der( + octet_string.as_bytes(), + ) + .ok() + }); + + let tst_info = match tst_info { + Some(tst_info) => tst_info, + None => continue, + }; + + cs.digest_alg = oid_to_algorithm_name( + &tst_info + .message_imprint + .hash_algorithm + .oid, ); + + cs.digest = Some(bytes2hex( + "", + tst_info + .message_imprint + .hashed_message + .as_bytes(), + )); + + countersignatures.push(cs); } } } @@ -359,12 +407,28 @@ impl AuthenticodeParser { let mut signatures = Vec::with_capacity(nested_signatures.len() + 1); + let file_digest = match signer_info.digest_alg.oid { + rfc5912::ID_SHA_1 => { + let mut sha1 = Sha1::default(); + pe.authenticode_hash(&mut sha1); + format!("{:x}", sha1.finalize()) + } + rfc5912::ID_SHA_256 => { + let mut sha256 = Sha256::default(); + pe.authenticode_hash(&mut sha256); + format!("{:x}", sha256.finalize()) + } + _ => unreachable!(), + }; + signatures.push(AuthenticodeSignature { - signer_info_digest: bytes2hex("", signer_info_digest), - signed_data, + signer_infos: signed_data.signer_infos, + signer_info_digest: bytes2hex("", signer_info_digest.as_bytes()), + program_name: opus_info.and_then(|oi| oi.program_name), + file_digest, indirect_data, countersignatures, - program_name, + certificates, }); signatures.append(&mut nested_signatures); @@ -388,7 +452,8 @@ impl AuthenticodeParser { } rfc6268::ID_SIGNING_TIME => { if let Some(value) = attr.values.get(0) { - signing_time = value.decode_as::().ok(); + signing_time = + value.decode_as::().ok(); } } _ => {} @@ -396,34 +461,64 @@ impl AuthenticodeParser { } } + let signer = match &cs.sid { + SignerIdentifier::IssuerAndSerialNumber(signer) => signer, + _ => unreachable!(), + }; + AuthenticodeCountersign { + signer: signer.clone(), digest_alg: oid_to_algorithm_name(&cs.digest_alg.oid), digest, signing_time, } } + + fn certificate_set_to_vec(cs: CertificateSet) -> Vec { + cs.0.into_vec() + .into_iter() + .map(|cert| { + if let cms::cert::CertificateChoices::Certificate(cert) = cert + { + cert + } else { + panic!() + } + }) + .collect() + } } pub struct AuthenticodeCountersign { + signer: IssuerAndSerialNumber, digest_alg: &'static str, digest: Option, - signing_time: Option, + signing_time: Option, } pub struct AuthenticodeSignature { signer_info_digest: String, - signed_data: SignedData, indirect_data: SpcIndirectDataContent, + signer_infos: SignerInfos, + certificates: Vec, countersignatures: Vec, program_name: Option, + file_digest: String, } impl AuthenticodeSignature { /// Get the authenticode digest stored in the signature. + #[inline] pub fn digest(&self) -> String { bytes2hex("", self.indirect_data.message_digest.digest.as_bytes()) } + /// Get the authenticode digest, as computed by the + #[inline] + pub fn file_digest(&self) -> String { + self.file_digest.clone() + } + /// Get the name of the digest algorithm. pub fn digest_alg(&self) -> String { oid_to_algorithm_name( @@ -433,30 +528,29 @@ impl AuthenticodeSignature { } /// Get [`SignerInfo`]. + #[inline] pub fn signer_info(&self) -> &SignerInfo { - // The constructor validates that exactly one signer info is - // present, so this won't panic. - &self.signed_data.signer_infos.0.as_slice()[0] + // The parser validates that exactly one signer info is present, so + // this won't panic. + &self.signer_infos.0.as_ref()[0] } + #[inline] pub fn signer_info_digest_alg(&self) -> String { oid_to_algorithm_name(&self.signer_info().digest_alg.oid).to_string() } + #[inline] pub fn signer_info_digest(&self) -> String { self.signer_info_digest.clone() } + #[inline] pub fn certificates(&self) -> impl Iterator { - self.signed_data.certificates.as_ref().unwrap().0.iter().map(|cert| { - if let cms::cert::CertificateChoices::Certificate(cert) = cert { - cert - } else { - panic!() - } - }) + self.certificates.iter() } + #[inline] pub fn countersignatures( &self, ) -> impl Iterator { @@ -484,7 +578,7 @@ impl AuthenticodeSignature { /// highest level certificate in the chain is the last one. fn build_chain( &self, - issuer_and_serial_number: &cms::cert::IssuerAndSerialNumber, + issuer_and_serial_number: &IssuerAndSerialNumber, ) -> Vec<&Certificate> { let mut chain = vec![]; @@ -521,13 +615,20 @@ impl From<&AuthenticodeSignature> for protos::pe::Signature { sig.set_digest(value.digest()); sig.set_digest_alg(value.digest_alg()); + sig.set_file_digest(value.file_digest()); sig.certificates .extend(value.certificates().map(protos::pe::Certificate::from)); - sig.countersignatures.extend( - value.countersignatures().map(protos::pe::CounterSignature::from), - ); + for cs in value.countersignatures() { + let mut pbcs = protos::pe::CounterSignature::from(cs); + pbcs.chain = value + .build_chain(&cs.signer) + .into_iter() + .map(protos::pe::Certificate::from) + .collect(); + sig.countersignatures.push(pbcs); + } sig.set_number_of_certificates( sig.certificates.len().try_into().unwrap(), @@ -590,13 +691,6 @@ impl From<&AuthenticodeCountersign> for protos::pe::CounterSignature { cs.sign_time = value.signing_time.map(|t| t.to_unix_duration().as_secs() as i64); - /*cs.chain.extend( - value - .certificate_chain() - .iter() - .map(protos::pe::Certificate::from), - );*/ - cs } } @@ -620,7 +714,7 @@ impl From<&Certificate> for protos::pe::Certificate { ); // The certificate thumbprint is the SHA1 of the DER-encoded certificate. - let mut hasher = Sha1Hasher::new(); + let mut hasher = DerHasher::::new(); value.encode(&mut hasher).unwrap(); cert.set_thumbprint(format!("{:x}", hasher.finalize())); @@ -674,19 +768,21 @@ fn format_name(name: &x509_cert::name::Name) -> String { for atv in rdn.0.iter() { let val = match atv.value.tag() { Tag::PrintableString => { - PrintableStringRef::try_from(&atv.value) + asn1::PrintableStringRef::try_from(&atv.value) .ok() .map(|s| s.as_str()) } - Tag::Utf8String => Utf8StringRef::try_from(&atv.value) + Tag::Utf8String => asn1::Utf8StringRef::try_from(&atv.value) .ok() .map(|s| s.as_str()), - Tag::Ia5String => { - Ia5StringRef::try_from(&atv.value).ok().map(|s| s.as_str()) - } - Tag::TeletexString => TeletexStringRef::try_from(&atv.value) + Tag::Ia5String => asn1::Ia5StringRef::try_from(&atv.value) .ok() .map(|s| s.as_str()), + Tag::TeletexString => { + asn1::TeletexStringRef::try_from(&atv.value) + .ok() + .map(|s| s.as_str()) + } _ => None, }; @@ -731,7 +827,7 @@ fn shortest_name_by_oid(oid: &ObjectIdentifier) -> Option<&str> { /// Produces a printable string of a serial number. /// /// The [`x509_cert::serial_number::SerialNumber`] type implements the -/// [`std::fmt::Display`] trait, but the resulting string is in uppercase. +/// [`Display`] trait, but the resulting string is in uppercase. fn format_serial_number( sn: &x509_cert::serial_number::SerialNumber, ) -> String { @@ -769,20 +865,22 @@ fn oid_to_algorithm_name(oid: &ObjectIdentifier) -> &'static str { } } -struct Sha1Hasher { - hasher: Sha1, +/// A wrapper that implements the [`der::Writer`] trait for a +/// [`Digest`]. +struct DerHasher { + hasher: T, } -impl Sha1Hasher { +impl DerHasher { pub fn new() -> Self { - Self { hasher: Sha1::new() } + Self { hasher: T::default() } } - pub fn finalize(self) -> Output { + pub fn finalize(self) -> Output { self.hasher.finalize() } } -impl der::Writer for Sha1Hasher { +impl der::Writer for DerHasher { fn write(&mut self, slice: &[u8]) -> der::Result<()> { self.hasher.update(slice); Ok(()) diff --git a/lib/src/modules/pe/parser.rs b/lib/src/modules/pe/parser.rs index 70153664e..5ab7cb6b3 100644 --- a/lib/src/modules/pe/parser.rs +++ b/lib/src/modules/pe/parser.rs @@ -3,6 +3,7 @@ use std::cmp::min; use std::collections::{HashMap, VecDeque}; use std::default::Default; use std::iter::zip; +use std::mem; use std::str::{from_utf8, FromStr}; use std::sync::OnceLock; @@ -404,6 +405,69 @@ impl<'a> PE<'a> { .map(|s| s.as_slice()) .unwrap_or(&[]) } + + /// Compute an Authenticode hash for this PE file. + /// + /// The Authenticode covers all the data in the PE file except: + /// + /// * The checksum in the PE header + /// * The security entry in the data directory (which points to the certificate table) + /// * The certificate table. + /// + /// The algorithm is described in the [PE format specification][1]. + /// + /// [1]: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#process-for-generating-the-authenticode-pe-image-hash + pub fn authenticode_hash( + &self, + digest: &mut dyn digest::Update, + ) -> Option<()> { + // Offset within the PE file where the checksum field is located. The + // checksum is skipped while computing the digest. + let checksum_offset = self.dos_stub.len() + + Self::SIZE_OF_PE_SIGNATURE + + Self::SIZE_OF_FILE_HEADER + + 64_usize; + + // Offset of the security entry in the data directory. This entry is skipped + // while computing the digest. + let security_data_offset = self.dos_stub.len() + + Self::SIZE_OF_PE_SIGNATURE + + Self::SIZE_OF_FILE_HEADER + + if self.optional_hdr.magic == Self::IMAGE_NT_OPTIONAL_HDR32_MAGIC + { + Self::SIZE_OF_OPT_HEADER_32 + } else { + Self::SIZE_OF_OPT_HEADER_64 + } + + Self::SIZE_OF_DIR_ENTRY * Self::IMAGE_DIRECTORY_ENTRY_SECURITY; + + // Hash from start of the file to the checksum. + digest.update(self.data.get(0..checksum_offset)?); + + // Hash from the end of the checksum to the start of the security entry + // in the data directory. + digest.update(self.data.get( + checksum_offset + mem::size_of::()..security_data_offset, + )?); + + let (cert_table_offset, cert_table_size, _) = self + .get_dir_entry_data(Self::IMAGE_DIRECTORY_ENTRY_SECURITY, true)?; + + // Hash from the end of the security entry in the data directory, to the + // certificate table. + digest.update(self.data.get( + security_data_offset + Self::SIZE_OF_DIR_ENTRY + ..cert_table_offset as usize, + )?); + + // Hash from the end of the certificate table to the end of the file. + digest.update(self.data.get( + cert_table_offset as usize + cert_table_size as usize + ..self.data.len(), + )?); + + Some(()) + } } impl<'a> PE<'a> { @@ -423,8 +487,20 @@ impl<'a> PE<'a> { const RICH_TAG: &'static [u8] = &[0x52_u8, 0x69, 0x63, 0x68]; const DANS_TAG: u32 = 0x536e6144; - const SIZE_OF_PE_SIGNATURE: usize = 4; // size of PE signature (PE\0\0). - const SIZE_OF_FILE_HEADER: usize = 20; // size of IMAGE_FILE_HEADER + // size of PE signature (PE\0\0). + const SIZE_OF_PE_SIGNATURE: usize = 4; + + // size of IMAGE_FILE_HEADER + const SIZE_OF_FILE_HEADER: usize = 20; + + // size of IMAGE_OPTIONAL_HEADER for 32-bit files. + // Without data directory entries. + const SIZE_OF_OPT_HEADER_32: usize = 96; + + // size of IMAGE_OPTIONAL_HEADER for 64-bit files. + // Without data directory entries. + const SIZE_OF_OPT_HEADER_64: usize = 112; + const SIZE_OF_DIR_ENTRY: usize = 8; const SIZE_OF_SYMBOL: u32 = 18; @@ -1362,7 +1438,7 @@ impl<'a> PE<'a> { // The certificate table is an array of WIN_CERTIFICATE structures. let signatures = fold_many0( - Self::parse_win_cert, + self.win_cert_parser(), Vec::new, |mut acc: Vec<_>, signatures| { acc.extend(signatures); @@ -1375,37 +1451,47 @@ impl<'a> PE<'a> { Some(signatures) } - fn parse_win_cert( - input: &[u8], - ) -> IResult<&[u8], Vec> { - // Parse the WIN_CERTIFICATE structure. - let (remainder, (length, _revision, _cert_type)) = tuple(( - le_u32::<&[u8], Error>, // length - le_u16, // revision, should be WIN_CERT_REVISION_1_0 (0x0100) - le_u16, // certificate type - ))(input)?; + /// Returns a parser that parses a WIN_CERTIFICATE structure. + fn win_cert_parser( + &self, + ) -> impl FnMut(&'a [u8]) -> IResult<&'a [u8], Vec> + '_ + { + move |input: &'a [u8]| { + // Parse the WIN_CERTIFICATE structure. + let (remainder, (length, _revision, _cert_type)) = + tuple(( + le_u32::<&[u8], Error>, // length + le_u16, // revision, should be WIN_CERT_REVISION_1_0 (0x0100) + le_u16, // certificate type + ))(input)?; - // The length includes the header, compute the length of the signature. - let signature_length: u32 = length - .checked_sub(8) - .ok_or_else(|| Err::Error(Error::new(input, ErrorKind::Fail)))?; + // The length includes the header, compute the length of the signature. + let signature_length: u32 = + length.checked_sub(8).ok_or_else(|| { + Err::Error(Error::new(input, ErrorKind::Fail)) + })?; - let (_, signature_data) = take(signature_length)(remainder)?; - let (_, signatures) = Self::parse_signature(signature_data)?; + let (_, signature_data) = take(signature_length)(remainder)?; + let (_, signatures) = self.signature_parser()(signature_data)?; - // The next WIN_CERTIFICATE is aligned to the next 8-bytes boundary. - let (remainder, _) = take(Self::round_up::<8, _>(length))(input)?; + // The next WIN_CERTIFICATE is aligned to the next 8-bytes boundary. + let (remainder, _) = take(Self::round_up::<8, _>(length))(input)?; - Ok((remainder, signatures)) + Ok((remainder, signatures)) + } } - /// Parses the PKCS#7 blob that containing an Authenticode signature. - fn parse_signature( - input: &[u8], - ) -> IResult<&[u8], Vec> { - let signatures = AuthenticodeParser::parse(input) - .map_err(|_| Err::Error(Error::new(input, ErrorKind::Fail)))?; - Ok((&[], signatures)) + /// Returns a parser that parses the PKCS#7 blob that containing an + /// Authenticode signature. + fn signature_parser( + &self, + ) -> impl FnMut(&'a [u8]) -> IResult<&'a [u8], Vec> + '_ + { + move |input: &'a [u8]| { + let signatures = AuthenticodeParser::parse(input, self) + .map_err(|_| Err::Error(Error::new(input, ErrorKind::Fail)))?; + Ok((&[], signatures)) + } } fn parse_dir_entries(&self) -> Option> { diff --git a/lib/src/modules/pe/tests/testdata/00a1067fc96eb2c1d440bb5b44b32f43b9900fdd3a65c985d65a63b8f1535ef5.in.zip b/lib/src/modules/pe/tests/testdata/00a1067fc96eb2c1d440bb5b44b32f43b9900fdd3a65c985d65a63b8f1535ef5.in.zip new file mode 100644 index 0000000000000000000000000000000000000000..cec838aa10fd2b8bedf71de0b8b2c170cbbe573f GIT binary patch literal 84951 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%0AfoH~2W2i4LmbXyd2_gzl4sJkD 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⁡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 Date: Tue, 16 Apr 2024 12:57:01 +0200 Subject: [PATCH 06/38] feat: advance in the implementation of Authenticode parser. --- Cargo.lock | 335 ++++++++++++++++++ Cargo.toml | 2 + lib/Cargo.toml | 4 + lib/src/modules/pe/authenticode.rs | 128 +++++-- ...15cdc8dd28a968c6b4d3b88acdd58ce2d3b885.out | 3 +- ...8c44d7f095eb395779de0ad1ac946914dfa34c.out | 4 +- ...6ad42ccfb04ccedd3ada1e8c26939c726a4c8e.out | 3 +- 7 files changed, 452 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b2640af7d..4dcb1c2b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -231,6 +231,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.13.1" @@ -942,6 +948,18 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -962,6 +980,33 @@ dependencies = [ "phf 0.11.2", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + [[package]] name = "darling" version = "0.14.4" @@ -1067,6 +1112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] @@ -1112,12 +1158,64 @@ dependencies = [ "winapi", ] +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +dependencies = [ + "curve25519-dalek", + "ed25519", + "sha2 0.10.8", + "subtle", +] + [[package]] name = "either" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "enable-ansi-support" version = "0.2.1" @@ -1220,6 +1318,22 @@ version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c007b1ae3abe1cb6f85a16305acd418b7ca6343b953633fee2b76d8f108b830f" + [[package]] name = "filedescriptor" version = "0.8.2" @@ -1347,6 +1461,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -1424,6 +1539,17 @@ dependencies = [ "yansi 1.0.1", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1729,6 +1855,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "sha2 0.10.8", +] + [[package]] name = "lab" version = "0.11.0" @@ -1740,6 +1878,9 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin", +] [[package]] name = "leb128" @@ -1753,6 +1894,12 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + [[package]] name = "libredox" version = "0.0.1" @@ -2080,6 +2227,23 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + [[package]] name = "num-complex" version = "0.4.5" @@ -2166,6 +2330,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -2216,6 +2381,30 @@ version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2 0.10.8", +] + +[[package]] +name = "p384" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2 0.10.8", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -2418,12 +2607,39 @@ dependencies = [ "siphasher", ] +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "platforms" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" + [[package]] name = "powerfmt" version = "0.2.0" @@ -2451,6 +2667,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "pretty_assertions" version = "1.4.0" @@ -2461,6 +2683,15 @@ dependencies = [ "yansi 0.5.1", ] +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "proc-macro2" version = "1.0.79" @@ -2652,6 +2883,17 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", "rand_core", ] @@ -2660,6 +2902,9 @@ name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] [[package]] name = "rayon" @@ -2755,6 +3000,16 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "rgb" version = "0.8.37" @@ -2770,6 +3025,26 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f" +[[package]] +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid", + "digest 0.10.7", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "signature", + "spki", + "subtle", + "zeroize", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -2782,6 +3057,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.22", +] + [[package]] name = "rustix" version = "0.38.32" @@ -2822,6 +3106,19 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "subtle", + "zeroize", +] + [[package]] name = "semver" version = "0.11.0" @@ -2976,6 +3273,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core", +] + [[package]] name = "similar" version = "2.4.0" @@ -3032,6 +3339,12 @@ dependencies = [ "serde", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "spki" version = "0.7.3" @@ -4340,6 +4653,26 @@ dependencies = [ "der", ] +[[package]] +name = "x509-verify" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e407b6fb3a8638bc7af2216647e045f3ce6cd71235e84ada35dd03c77a6cd6d" +dependencies = [ + "const-oid", + "der", + "ecdsa", + "ed25519-dalek", + "k256", + "p256", + "p384", + "rsa", + "sha1", + "sha2 0.10.8", + "signature", + "spki", +] + [[package]] name = "yaml-rust" version = "0.4.5" @@ -4406,6 +4739,7 @@ dependencies = [ "regex-automata 0.4.6", "regex-syntax 0.8.3", "roxmltree", + "rsa", "rustc-hash", "serde", "serde_json", @@ -4419,6 +4753,7 @@ dependencies = [ "wasmtime", "x509-cert", "x509-tsp", + "x509-verify", "yansi 1.0.1", "yara-x-macros", "yara-x-parser", diff --git a/Cargo.toml b/Cargo.toml index 724f36a5d..2d2aa4a99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,6 +88,7 @@ rayon = "1.5.3" regex-syntax = "0.8.3" regex-automata = "0.4.6" roxmltree = "0.19.0" +rsa = "0.9.6" rustc-hash = "1.1.0" smallvec = "1.13.2" serde = "1.0" @@ -98,6 +99,7 @@ walrus = "0.20.2" wasmtime = "19.0.1" x509-cert = "0.2.5" x509-tsp = "0.1.0" +x509-verify = "0.4.5" yaml-rust = "0.4.5" yansi = "1.0.1" yara-x = { path = "lib" } diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 8b0478795..2712b0118 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -120,9 +120,11 @@ pe-module = [ "dep:const-oid", "dep:digest", "dep:nom", + "dep:rsa", "dep:sha1", "dep:x509-cert", "dep:x509-tsp", + "dep:x509-verify", ] # The `string` modules offer some functions for parsing strings as integers, @@ -200,6 +202,7 @@ rustc-hash = { workspace = true } regex-syntax = { workspace = true } regex-automata = { workspace = true } roxmltree = { workspace = true, optional = true } +rsa = { workspace = true, optional = true } smallvec = { workspace = true, features = ["serde"] } serde = { workspace = true, features = ["rc"] } serde_json = { workspace = true } @@ -210,6 +213,7 @@ walrus = { workspace = true } wasmtime = { workspace = true, features = ["cranelift", "parallel-compilation"] } x509-cert = { workspace = true, optional = true } x509-tsp = { workspace = true, optional = true } +x509-verify = { workspace = true, optional = true, features = ["rsa", "sha1"] } yansi = { workspace = true } yara-x-macros = { workspace = true } yara-x-parser = { workspace = true } diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 5104a1eb0..f19889d94 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -8,7 +8,7 @@ use cms::cert::IssuerAndSerialNumber; use cms::content_info::CmsVersion; use cms::content_info::ContentInfo; use cms::signed_data::{ - CertificateSet, SignedData, SignerIdentifier, SignerInfo, SignerInfos, + CertificateSet, SignedData, SignerIdentifier, SignerInfo, }; use const_oid::db::{rfc5911, rfc5912, rfc6268, DB}; use const_oid::ObjectIdentifier; @@ -303,6 +303,7 @@ impl AuthenticodeParser { let mut certificates = signed_data .certificates + .as_ref() .map(Self::certificate_set_to_vec) .unwrap(); @@ -341,6 +342,7 @@ impl AuthenticodeParser { certificates.extend( signed_data .certificates + .as_ref() .map(Self::certificate_set_to_vec) .unwrap(), ); @@ -411,20 +413,20 @@ impl AuthenticodeParser { rfc5912::ID_SHA_1 => { let mut sha1 = Sha1::default(); pe.authenticode_hash(&mut sha1); - format!("{:x}", sha1.finalize()) + sha1.finalize().to_vec() } rfc5912::ID_SHA_256 => { let mut sha256 = Sha256::default(); pe.authenticode_hash(&mut sha256); - format!("{:x}", sha256.finalize()) + sha256.finalize().to_vec() } _ => unreachable!(), }; signatures.push(AuthenticodeSignature { - signer_infos: signed_data.signer_infos, - signer_info_digest: bytes2hex("", signer_info_digest.as_bytes()), program_name: opus_info.and_then(|oi| oi.program_name), + signer_info_digest, + signed_data, file_digest, indirect_data, countersignatures, @@ -474,13 +476,12 @@ impl AuthenticodeParser { } } - fn certificate_set_to_vec(cs: CertificateSet) -> Vec { - cs.0.into_vec() - .into_iter() + fn certificate_set_to_vec(cs: &CertificateSet) -> Vec { + cs.0.iter() .map(|cert| { if let cms::cert::CertificateChoices::Certificate(cert) = cert { - cert + cert.clone() } else { panic!() } @@ -497,26 +498,26 @@ pub struct AuthenticodeCountersign { } pub struct AuthenticodeSignature { - signer_info_digest: String, + signer_info_digest: OctetString, indirect_data: SpcIndirectDataContent, - signer_infos: SignerInfos, + signed_data: SignedData, certificates: Vec, countersignatures: Vec, program_name: Option, - file_digest: String, + file_digest: Vec, } impl AuthenticodeSignature { /// Get the authenticode digest stored in the signature. #[inline] - pub fn digest(&self) -> String { - bytes2hex("", self.indirect_data.message_digest.digest.as_bytes()) + pub fn digest(&self) -> &[u8] { + self.indirect_data.message_digest.digest.as_bytes() } /// Get the authenticode digest, as computed by the #[inline] - pub fn file_digest(&self) -> String { - self.file_digest.clone() + pub fn file_digest(&self) -> &[u8] { + self.file_digest.as_slice() } /// Get the name of the digest algorithm. @@ -532,7 +533,7 @@ impl AuthenticodeSignature { pub fn signer_info(&self) -> &SignerInfo { // The parser validates that exactly one signer info is present, so // this won't panic. - &self.signer_infos.0.as_ref()[0] + &self.signed_data.signer_infos.0.as_ref()[0] } #[inline] @@ -542,7 +543,7 @@ impl AuthenticodeSignature { #[inline] pub fn signer_info_digest(&self) -> String { - self.signer_info_digest.clone() + bytes2hex("", self.signer_info_digest.as_bytes()) } #[inline] @@ -558,14 +559,92 @@ impl AuthenticodeSignature { } pub fn chain(&self) -> Vec<&Certificate> { + self.build_chain(self.signer()) + } + + pub fn signer(&self) -> &IssuerAndSerialNumber { if let SignerIdentifier::IssuerAndSerialNumber(signer) = &self.signer_info().sid { - self.build_chain(signer) + signer } else { unreachable!() } } + + pub fn verify(&self) -> bool { + return self.file_digest == self.digest(); + + /* let signing_cert_sn = &self.signer().serial_number; + + + + // Find the certificate that is signing this Authenticode signature. + let signing_cert = match self.certificates().find(|cert| { + cert.tbs_certificate.serial_number.eq(signing_cert_sn) + }) { + Some(cert) => cert, + None => return false, + }; + + let public_key: VerifyingKey = signing_cert + .tbs_certificate + .subject_public_key_info + .owned_to_ref() + .try_into() + .unwrap(); + + let publib_key = rsa::RsaPublicKey::try_from( + signing_cert + .tbs_certificate + .subject_public_key_info + .owned_to_ref(), + ) + .unwrap(); + + let verifying_key: VerifyingKey = publib_key.try_into().unwrap(); + + let d = self.indirect_data.message_diges.to_ber(); + + let signature = self.signer_info().signature.as_bytes(); + + let d = sha1::Sha1::digest(d.as_bytes()); + + publib_key + .verify( + Pkcs1v15Sign::new::(), + d.as_slice(), + self.signer_info().signature.as_bytes(), + ) + .unwrap(); + + let parent_cert = match self.certificates().find(|cert| { + cert.tbs_certificate + .subject + .eq(&signing_cert.tbs_certificate.issuer) + }) { + Some(cert) => cert, + None => return false, + }; + + let key: VerifyingKey = parent_cert + .tbs_certificate + .subject_public_key_info + .owned_to_ref() + .try_into() + .unwrap(); + + key.verify(VerifyInfo::new( + signing_cert.tbs_certificate.to_der().unwrap().into(), + Signature::new( + &parent_cert.tbs_certificate.signature, + signing_cert.signature.as_bytes().unwrap(), + ), + )) + .unwrap(); + + */ + } } impl AuthenticodeSignature { @@ -613,9 +692,10 @@ impl From<&AuthenticodeSignature> for protos::pe::Signature { fn from(value: &AuthenticodeSignature) -> Self { let mut sig = protos::pe::Signature::new(); - sig.set_digest(value.digest()); + sig.set_digest(bytes2hex("", value.digest())); sig.set_digest_alg(value.digest_alg()); - sig.set_file_digest(value.file_digest()); + sig.set_file_digest(bytes2hex("", value.file_digest())); + sig.set_verified(value.verify()); sig.certificates .extend(value.certificates().map(protos::pe::Certificate::from)); @@ -867,11 +947,11 @@ fn oid_to_algorithm_name(oid: &ObjectIdentifier) -> &'static str { /// A wrapper that implements the [`der::Writer`] trait for a /// [`Digest`]. -struct DerHasher { +struct DerHasher { hasher: T, } -impl DerHasher { +impl DerHasher { pub fn new() -> Self { Self { hasher: T::default() } } @@ -880,7 +960,7 @@ impl DerHasher { } } -impl der::Writer for DerHasher { +impl der::Writer for DerHasher { fn write(&mut self, slice: &[u8]) -> der::Result<()> { self.hasher.update(slice); Ok(()) diff --git a/lib/src/modules/pe/tests/testdata/079a472d22290a94ebb212aa8015cdc8dd28a968c6b4d3b88acdd58ce2d3b885.out b/lib/src/modules/pe/tests/testdata/079a472d22290a94ebb212aa8015cdc8dd28a968c6b4d3b88acdd58ce2d3b885.out index 9a0a47e6e..feae3fcc6 100644 --- a/lib/src/modules/pe/tests/testdata/079a472d22290a94ebb212aa8015cdc8dd28a968c6b4d3b88acdd58ce2d3b885.out +++ b/lib/src/modules/pe/tests/testdata/079a472d22290a94ebb212aa8015cdc8dd28a968c6b4d3b88acdd58ce2d3b885.out @@ -356,7 +356,7 @@ export_details: ordinal: 204 rva: 4624 offset: 1552 -is_signed: false +is_signed: true signatures: - subject: "/C=US/ST=California/L=Menlo Park/O=Quicken, Inc./OU=Operations/CN=Quicken, Inc." issuer: "/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 SHA256 Code Signing CA" @@ -367,6 +367,7 @@ signatures: serial: "21:bd:b2:cb:ec:e5:43:1e:24:f7:56:74:d6:0e:9c:1d" not_before: 1491955200 # 2017-04-12 00:00:00 UTC not_after: 1559692799 # 2019-06-04 23:59:59 UTC + verified: true digest_alg: "sha1" digest: "f4ca190ec9052243b8882d492b1c12d04da7817f" file_digest: "f4ca190ec9052243b8882d492b1c12d04da7817f" diff --git a/lib/src/modules/pe/tests/testdata/2e9c671b8a0411f2b397544b368c44d7f095eb395779de0ad1ac946914dfa34c.out b/lib/src/modules/pe/tests/testdata/2e9c671b8a0411f2b397544b368c44d7f095eb395779de0ad1ac946914dfa34c.out index 4ad761441..4055826cf 100644 --- a/lib/src/modules/pe/tests/testdata/2e9c671b8a0411f2b397544b368c44d7f095eb395779de0ad1ac946914dfa34c.out +++ b/lib/src/modules/pe/tests/testdata/2e9c671b8a0411f2b397544b368c44d7f095eb395779de0ad1ac946914dfa34c.out @@ -472,7 +472,7 @@ import_details: rva: 100456 - name: "TranslateMessage" rva: 100464 -is_signed: false +is_signed: true signatures: - subject: "/C=CH/ST=Bern/L=Bolligen/O=Ghisler Software GmbH/OU=Development/CN=Ghisler Software GmbH" issuer: "/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Code Signing 2010 CA" @@ -483,6 +483,7 @@ signatures: serial: "03:6c:61:75:7a:92:3f:50:c8:2e:b6:aa:18:d2:1f:c6" not_before: 1473379200 # 2016-09-09 00:00:00 UTC not_after: 1495756799 # 2017-05-25 23:59:59 UTC + verified: true digest_alg: "sha1" digest: "7383d4bc5c4eb4c78f0358a815886ff643d71728" file_digest: "7383d4bc5c4eb4c78f0358a815886ff643d71728" @@ -579,6 +580,7 @@ signatures: serial: "1a:f2:6d:2b:4d:e7:eb:bb:26:05:fd:83:cc:b1:f4:ad" not_before: 1464134400 # 2016-05-25 00:00:00 UTC not_after: 1495756799 # 2017-05-25 23:59:59 UTC + verified: true digest_alg: "sha256" digest: "b43e10921c479054beeb47518aa62be7f90d45f5e65791681ec687ecb294d502" file_digest: "b43e10921c479054beeb47518aa62be7f90d45f5e65791681ec687ecb294d502" diff --git a/lib/src/modules/pe/tests/testdata/af3f20a9272489cbef4281c8c86ad42ccfb04ccedd3ada1e8c26939c726a4c8e.out b/lib/src/modules/pe/tests/testdata/af3f20a9272489cbef4281c8c86ad42ccfb04ccedd3ada1e8c26939c726a4c8e.out index d800a0d49..660722ace 100644 --- a/lib/src/modules/pe/tests/testdata/af3f20a9272489cbef4281c8c86ad42ccfb04ccedd3ada1e8c26939c726a4c8e.out +++ b/lib/src/modules/pe/tests/testdata/af3f20a9272489cbef4281c8c86ad42ccfb04ccedd3ada1e8c26939c726a4c8e.out @@ -106,7 +106,7 @@ data_directories: size: 2832 - virtual_address: 0 size: 0 -is_signed: false +is_signed: true signatures: - subject: "/C=AT/O=Security Coding Factory GmbH/OU=Security Coding Factory Certificate Authority/CN=Security Coding Factory Software CA" issuer: "/C=AT/O=Security Coding Factory GmbH/OU=Security Coding Factory Certificate Authority/CN=Security Coding Factory Software CA" @@ -117,6 +117,7 @@ signatures: serial: "01" not_before: 1615365865 # 2021-03-10 08:44:25 UTC not_after: 2246431465 # 2041-03-09 08:44:25 UTC + verified: true digest_alg: "sha256" digest: "2a344e5a930211be79c3d2a867d8923d154af27c9be0f8e5b6fd7a5411934375" file_digest: "2a344e5a930211be79c3d2a867d8923d154af27c9be0f8e5b6fd7a5411934375" From 1c6cbf5a14d8ba69956018d9263594f870d7e198 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Wed, 17 Apr 2024 10:45:47 +0200 Subject: [PATCH 07/38] feat: implement verification of Authenticode signatures. --- lib/src/modules/pe/authenticode.rs | 233 ++++++++++++++++++----------- lib/src/modules/pe/parser.rs | 149 +----------------- 2 files changed, 152 insertions(+), 230 deletions(-) diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index f19889d94..8430903c4 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -11,17 +11,21 @@ use cms::signed_data::{ CertificateSet, SignedData, SignerIdentifier, SignerInfo, }; use const_oid::db::{rfc5911, rfc5912, rfc6268, DB}; -use const_oid::ObjectIdentifier; +use const_oid::{AssociatedOid, ObjectIdentifier}; use der::asn1; use der::asn1::OctetString; +use der::referenced::OwnedToRef; use der::{Choice, Sequence, SliceReader}; use der::{Decode, Encode, Tag, Tagged}; use digest::Digest; +use itertools::Itertools; use protobuf::MessageField; +use rsa::Pkcs1v15Sign; use sha1::digest::Output; use sha1::Sha1; use sha2::Sha256; use x509_tsp::TstInfo; +use x509_verify::{Signature, VerifyInfo, VerifyingKey}; use crate::modules::protos; @@ -559,7 +563,9 @@ impl AuthenticodeSignature { } pub fn chain(&self) -> Vec<&Certificate> { - self.build_chain(self.signer()) + self.certificate_chain(|cert| { + cert.tbs_certificate.serial_number == self.signer().serial_number + }) } pub fn signer(&self) -> &IssuerAndSerialNumber { @@ -572,99 +578,50 @@ impl AuthenticodeSignature { } } + /// Returns `true` if the [`AuthenticodeSignature`] is valid. + /// + /// A valid Authenticode signature must comply with the following requisites: + /// + /// * The Authenticode hash included in the file (in the `message_digest` + /// field of [`SpcIndirectDataContent`]) must match the hash computed by + /// ourselves using [`PE::authenticode_hash`]. + /// + /// * The message digest stored the signed attribute [`rfc6268::ID_MESSAGE_DIGEST`] + /// of [`SignerInfo`], must match the one computed by ourselves by hashing + /// the `econtent` field in [`EncapsulatedContentInfo`]. + /// + /// * The signature in [`SignerInfo`] must be valid. This signature is the + /// result of signing the hash of the DER encoding of the signed + /// attributes in [`SignerInfo`] with the private key of the signing + /// certificate. We compute this hash by ourselves, and then use the + /// public key included in the signing certificate to verify that the + /// signature is valid. + /// + /// * The signing certificate must be valid. pub fn verify(&self) -> bool { - return self.file_digest == self.digest(); - - /* let signing_cert_sn = &self.signer().serial_number; - - - - // Find the certificate that is signing this Authenticode signature. - let signing_cert = match self.certificates().find(|cert| { - cert.tbs_certificate.serial_number.eq(signing_cert_sn) - }) { - Some(cert) => cert, - None => return false, - }; - - let public_key: VerifyingKey = signing_cert - .tbs_certificate - .subject_public_key_info - .owned_to_ref() - .try_into() - .unwrap(); - - let publib_key = rsa::RsaPublicKey::try_from( - signing_cert - .tbs_certificate - .subject_public_key_info - .owned_to_ref(), - ) - .unwrap(); - - let verifying_key: VerifyingKey = publib_key.try_into().unwrap(); - - let d = self.indirect_data.message_diges.to_ber(); - - let signature = self.signer_info().signature.as_bytes(); - - let d = sha1::Sha1::digest(d.as_bytes()); - - publib_key - .verify( - Pkcs1v15Sign::new::(), - d.as_slice(), - self.signer_info().signature.as_bytes(), - ) - .unwrap(); - - let parent_cert = match self.certificates().find(|cert| { - cert.tbs_certificate - .subject - .eq(&signing_cert.tbs_certificate.issuer) - }) { - Some(cert) => cert, - None => return false, - }; - - let key: VerifyingKey = parent_cert - .tbs_certificate - .subject_public_key_info - .owned_to_ref() - .try_into() - .unwrap(); - - key.verify(VerifyInfo::new( - signing_cert.tbs_certificate.to_der().unwrap().into(), - Signature::new( - &parent_cert.tbs_certificate.signature, - signing_cert.signature.as_bytes().unwrap(), - ), - )) - .unwrap(); - - */ + match self.signer_info().digest_alg.oid { + rfc5912::ID_SHA_1 => self.verify_impl::(), + rfc5912::ID_SHA_256 => self.verify_impl::(), + _ => unreachable!(), + } } } impl AuthenticodeSignature { - /// Returns a certificate chain containing the certificate with the given - /// issuer and serial number, and all the certificates participating in the + /// Returns a certificate chain containing the first certificate that + /// matches the predicate, and all the certificates participating in the /// chain of trust for that certificate, up to the highest level certificate /// found in the Authenticode signature. /// /// The first item in the vector is the requested certificate, and the /// highest level certificate in the chain is the last one. - fn build_chain( - &self, - issuer_and_serial_number: &IssuerAndSerialNumber, - ) -> Vec<&Certificate> { + fn certificate_chain

(&self, predicate: P) -> Vec<&Certificate> + where + P: Fn(&Certificate) -> bool, + { let mut chain = vec![]; - let mut cert = match self.certificates().find(|cert| { - cert.tbs_certificate.serial_number - == issuer_and_serial_number.serial_number - }) { + let mut cert = match self.certificates().find(|cert| predicate(cert)) { Some(cert) => cert, None => return vec![], }; @@ -686,6 +643,111 @@ impl AuthenticodeSignature { } } } + + /// Returns `true` if the given certificate is valid. + /// + /// A certificate is considered valid if it is correctly signed by a parent + /// certificate that is included in the PE file, and the parent certificate + /// is also valid. The validation process goes up the chain of trust until + /// finding a self-signed certificate or a certificate that is signed by + /// some other certificate that is not included in the PE. + /// + /// When the last certificate in the chain is one that is signed by an + /// external certificate (not included in the PE) no attempt is made to + /// continue the validation by retrieving the external certificate from the + /// operating system certificate store. + fn is_valid_certificate(&self, cert: &Certificate) -> bool { + // Get the certificate chain that starts with the given `cert` and + // contains the issuer of ` + let chain = self.certificate_chain(|c| { + c.tbs_certificate.serial_number + == cert.tbs_certificate.serial_number + }); + + // Iterate over the chain taking a certificate and its signer on each + // iteration. + for (signed, signer) in chain.iter().tuple_windows() { + // The `signed` certificate is the one that will be verified. + let verify_info = VerifyInfo::new( + signed.tbs_certificate.to_der().unwrap().into(), + Signature::new( + &signed.signature_algorithm, + signed.signature.as_bytes().unwrap(), + ), + ); + + // The public key in the `signer` certificate is used for + // verifying the signature in the `signed` certificate. + let key: VerifyingKey = match signer + .tbs_certificate + .subject_public_key_info + .owned_to_ref() + .try_into() + { + Ok(key) => key, + Err(_) => return false, + }; + + if key.verify(verify_info).is_err() { + return false; + } + } + + true + } + + /// Generic implementation for [`AuthenticodeSignature::verify`]. + fn verify_impl(&self) -> bool { + if self.file_digest != self.digest() { + return false; + } + + let content = self + .signed_data + .encap_content_info + .econtent + .as_ref() + .unwrap() + .value(); + + if D::digest(content).as_slice() != self.signer_info_digest.as_ref() { + return false; + } + + // Find the certificate that signed the Authenticode hash. + let signing_cert_sn = &self.signer().serial_number; + + let signing_cert = match self.certificates().find(|cert| { + cert.tbs_certificate.serial_number.eq(signing_cert_sn) + }) { + Some(cert) => cert, + None => return false, + }; + + if !self.is_valid_certificate(signing_cert) { + return false; + } + + let key = match rsa::RsaPublicKey::try_from( + signing_cert + .tbs_certificate + .subject_public_key_info + .owned_to_ref(), + ) { + Ok(key) => key, + Err(_) => return false, + }; + + let attrs_digest = + D::digest(self.signer_info().signed_attrs.to_der().unwrap()); + + key.verify( + Pkcs1v15Sign::new::(), + attrs_digest.as_slice(), + self.signer_info().signature.as_bytes(), + ) + .is_ok() + } } impl From<&AuthenticodeSignature> for protos::pe::Signature { @@ -703,7 +765,10 @@ impl From<&AuthenticodeSignature> for protos::pe::Signature { for cs in value.countersignatures() { let mut pbcs = protos::pe::CounterSignature::from(cs); pbcs.chain = value - .build_chain(&cs.signer) + .certificate_chain(|cert| { + cert.tbs_certificate.serial_number + == cs.signer.serial_number + }) .into_iter() .map(protos::pe::Certificate::from) .collect(); diff --git a/lib/src/modules/pe/parser.rs b/lib/src/modules/pe/parser.rs index 5ab7cb6b3..2dc570fec 100644 --- a/lib/src/modules/pe/parser.rs +++ b/lib/src/modules/pe/parser.rs @@ -421,6 +421,9 @@ impl<'a> PE<'a> { &self, digest: &mut dyn digest::Update, ) -> Option<()> { + // TODO: according to the specification the sections must be sorted before + // computing the hash. + // Offset within the PE file where the checksum field is located. The // checksum is skipped while computing the digest. let checksum_offset = self.dos_stub.len() @@ -2449,152 +2452,6 @@ impl From<&Section<'_>> for protos::pe::Section { } } -/* -impl From<&authenticode_parser::Authenticode<'_>> for protos::pe::Signature { - fn from(value: &authenticode_parser::Authenticode) -> Self { - let mut sig = protos::pe::Signature::new(); - - sig.digest = value.digest().map(|v| bytes2hex("", v)); - sig.digest_alg = value - .digest_alg() - .and_then(|v| String::from_utf8(v.to_vec()).ok()); - - sig.file_digest = value.file_digest().map(|v| bytes2hex("", v)); - - sig.certificates - .extend(value.certs().iter().map(protos::pe::Certificate::from)); - - sig.countersignatures.extend( - value.countersigs().iter().map(protos::pe::CounterSignature::from), - ); - - sig.signer_info = MessageField::from_option( - value.signer().map(protos::pe::SignerInfo::from), - ); - - sig.set_number_of_certificates( - sig.certificates.len().try_into().unwrap(), - ); - - sig.set_number_of_countersignatures( - sig.countersignatures.len().try_into().unwrap(), - ); - - sig.set_verified( - value - .verify_flags() - .is_some_and(|flags| flags == AuthenticodeVerify::Valid), - ); - - // Some fields from the first certificate in the chain are replicated - // in the `pe::Signature` structure for backward compatibility. The - // `chain` field in `SignerInfo` didn't exist in previous versions of - // YARA. - if let Some(signer_info) = sig.signer_info.as_ref() { - if let Some(cert) = signer_info.chain.first() { - sig.version = cert.version; - sig.thumbprint = cert.thumbprint.clone(); - sig.issuer = cert.issuer.clone(); - sig.subject = cert.subject.clone(); - sig.serial = cert.serial.clone(); - sig.not_after = cert.not_after; - sig.not_before = cert.not_before; - sig.algorithm = cert.algorithm.clone(); - sig.algorithm_oid = cert.algorithm_oid.clone(); - } - } - - sig - } -} - -impl From> for protos::pe::SignerInfo { - fn from(value: authenticode_parser::Signer) -> Self { - let mut signer_info = protos::pe::SignerInfo::new(); - - signer_info.digest = value.digest().map(|v| bytes2hex("", v)); - signer_info.digest_alg = value - .digest_alg() - .and_then(|v| String::from_utf8(v.to_vec()).ok()); - - signer_info.program_name = value - .program_name() - .and_then(|v| String::from_utf8(v.to_vec()).ok()); - - signer_info.chain.extend( - value - .certificate_chain() - .iter() - .map(protos::pe::Certificate::from), - ); - - signer_info - } -} - -impl From<&authenticode_parser::Countersignature<'_>> - for protos::pe::CounterSignature -{ - fn from(value: &authenticode_parser::Countersignature) -> Self { - let mut cs = protos::pe::CounterSignature::new(); - - cs.digest = value.digest().map(|v| bytes2hex("", v)); - cs.digest_alg = value - .digest_alg() - .and_then(|v| String::from_utf8(v.to_vec()).ok()); - - cs.set_verified( - value - .verify_flags() - .is_some_and(|flags| flags == CounterSignatureVerify::Valid), - ); - - cs.set_sign_time(value.sign_time()); - - cs.chain.extend( - value - .certificate_chain() - .iter() - .map(protos::pe::Certificate::from), - ); - - cs - } -} - -impl From<&authenticode_parser::Certificate<'_>> for protos::pe::Certificate { - fn from(value: &authenticode_parser::Certificate) -> Self { - let mut cert = protos::pe::Certificate::new(); - - // Versions are 0-based, add 1 for getting the actual version. - cert.set_version(value.version() + 1); - - cert.issuer = - value.issuer().and_then(|v| String::from_utf8(v.to_vec()).ok()); - - cert.subject = - value.subject().and_then(|v| String::from_utf8(v.to_vec()).ok()); - - cert.serial = - value.serial().and_then(|v| String::from_utf8(v.to_vec()).ok()); - - cert.algorithm = - value.sig_alg().and_then(|v| String::from_utf8(v.to_vec()).ok()); - - cert.algorithm_oid = value - .sig_alg_oid() - .and_then(|v| String::from_utf8(v.to_vec()).ok()); - - cert.thumbprint = value.sha1().map(|v| bytes2hex("", v)); - - cert.set_not_before(value.not_before()); - cert.set_not_after(value.not_after()); - - cert - } -} -*/ - impl rva2off::Section for Section<'_> { fn virtual_address(&self) -> u32 { self.virtual_address From 428140dd3fa38b75d93dc1b547f7d38919013e5a Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Wed, 17 Apr 2024 10:48:00 +0200 Subject: [PATCH 08/38] chore: remove unused dependency --- .github/workflows/release.yaml | 5 +---- Cargo.lock | 19 ------------------- Cargo.toml | 1 - 3 files changed, 1 insertion(+), 24 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index c25e2f008..c54c1981b 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -20,21 +20,18 @@ jobs: rust: stable target: x86_64-unknown-linux-gnu vcpkg_openssl_triplet: x64-linux-release - args: "--features=openssl-static" - build: macos os: macos-latest rust: stable target: x86_64-apple-darwin vcpkg_openssl_triplet: x64-osx-release - args: "--features=openssl-static" - build: windows os: windows-latest rust: stable target: x86_64-pc-windows-msvc vcpkg_openssl_triplet: x64-windows-static - args: "" steps: - name: Checkout sources @@ -63,7 +60,7 @@ jobs: token: ${{ github.token }} - name: Build - run: cargo build --bin yr --profile release-lto --target ${{ matrix.target }} ${{ matrix.args }} + run: cargo build --bin yr --profile release-lto --target ${{ matrix.target }} env: RUSTFLAGS: "-C target-feature=+crt-static" OPENSSL_DIR: "${{ github.workspace }}/vcpkg/installed/${{ matrix.vcpkg_openssl_triplet }}" diff --git a/Cargo.lock b/Cargo.lock index 4dcb1c2b2..c898e102e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -192,24 +192,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "authenticode-parser" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b04c8a6168fa3d7733652b4604dbad1c0587b16382ad24b082d2de7ee7296087" -dependencies = [ - "authenticode-parser-sys", -] - -[[package]] -name = "authenticode-parser-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6fec48978e90f3740da7ba30f501beb08d1729dabdcc685e163226b564f3737" -dependencies = [ - "cc", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -4702,7 +4684,6 @@ dependencies = [ "anyhow", "array-bytes", "ascii_tree", - "authenticode-parser", "base64 0.22.0", "bincode", "bitmask", diff --git a/Cargo.toml b/Cargo.toml index 2d2aa4a99..6c2b8f24f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,6 @@ annotate-snippets = "0.11.1" anyhow = "1.0.81" array-bytes = "6.2.2" ascii_tree = "0.1.1" -authenticode-parser = "0.5.0" base64 = "0.22.0" bincode = "1.3.3" bitmask = "0.5.0" From 226d269636e200fa5d1ed6e1428db41300696996 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Wed, 17 Apr 2024 10:48:11 +0200 Subject: [PATCH 09/38] chore: remove unused feature --- lib/Cargo.toml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 2712b0118..04e4ef9d8 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -20,19 +20,6 @@ exclude = [ ] [features] -# When this feature is enabled the OpenSSL library is linked statically. -# However, you need to specify the path where the library and its header files -# are located by setting the environment variable OPENSSL_DIR. For example: -# -# OPENSSL_DIR=/usr/local/Cellar/openssl@3/3.2.0_1/ cargo build --features=openssl-static -# -# The directory specified in OPENSSL_DIR must contain subdirectories /include -# and /lib. The latter must contain `libcrypto.a`. -# -# You can also set OPENSSL_INCLUDE_DIR and OPENSSL_LIB_DIR, for setting the -# two directories independently. -openssl-static = ['authenticode-parser/openssl-static'] - # Enables constant folding. When constant folding is enabled, expressions # like `2+2+2` and `true or false`, whose value can be determined at compile # time, will be reduced to its final value, instead of producing code that @@ -115,7 +102,6 @@ math-module = [] # The `pe` module parses PE files. pe-module = [ - "dep:authenticode-parser", "dep:cms", "dep:const-oid", "dep:digest", @@ -170,7 +156,6 @@ aho-corasick = { workspace = true, features = ["logging"] } anyhow = { workspace = true } array-bytes = { workspace = true } ascii_tree = { workspace = true } -authenticode-parser = { workspace = true, optional = true } base64 = { workspace = true } bincode = { workspace = true } bitmask = { workspace = true } From 1b2c2b8412072d17da3b2686eb5c561907f7c561 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Wed, 17 Apr 2024 17:40:20 +0200 Subject: [PATCH 10/38] refactor: prepare for implementing countersignatures verification --- lib/src/modules/pe/authenticode.rs | 408 ++++++++++++++++------------- 1 file changed, 232 insertions(+), 176 deletions(-) diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 8430903c4..8200f1775 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -11,7 +11,7 @@ use cms::signed_data::{ CertificateSet, SignedData, SignerIdentifier, SignerInfo, }; use const_oid::db::{rfc5911, rfc5912, rfc6268, DB}; -use const_oid::{AssociatedOid, ObjectIdentifier}; +use const_oid::ObjectIdentifier; use der::asn1; use der::asn1::OctetString; use der::referenced::OwnedToRef; @@ -305,11 +305,13 @@ impl AuthenticodeParser { .and_then(|attr| attr.values.get(0)) .and_then(|value| value.decode_as::().ok()); - let mut certificates = signed_data + let mut certificates: Vec = signed_data .certificates .as_ref() - .map(Self::certificate_set_to_vec) - .unwrap(); + .map(Self::certificate_set_to_iter) + .unwrap() + .cloned() + .collect(); let mut nested_signatures = Vec::new(); let mut countersignatures = Vec::new(); @@ -347,8 +349,10 @@ impl AuthenticodeParser { signed_data .certificates .as_ref() - .map(Self::certificate_set_to_vec) - .unwrap(), + .map(Self::certificate_set_to_iter) + .unwrap() + .map(|c| c.clone()) + .collect::>(), ); let mut cs = Self::pkcs9_countersignature( @@ -401,6 +405,15 @@ impl AuthenticodeParser { if let Ok(cs) = value.decode_as::().as_ref() { + let valid = verify_signer_info( + cs, + certificates.as_slice(), + signer_info.signature.as_bytes(), + ); + + // THIS SHOULD BE TRUE + println!("{}", valid); + countersignatures .push(Self::pkcs9_countersignature(cs)); } @@ -480,17 +493,16 @@ impl AuthenticodeParser { } } - fn certificate_set_to_vec(cs: &CertificateSet) -> Vec { - cs.0.iter() - .map(|cert| { - if let cms::cert::CertificateChoices::Certificate(cert) = cert - { - cert.clone() - } else { - panic!() - } - }) - .collect() + fn certificate_set_to_iter( + cs: &CertificateSet, + ) -> impl Iterator { + cs.0.iter().map(|cert| { + if let cms::cert::CertificateChoices::Certificate(cert) = cert { + cert + } else { + panic!() + } + }) } } @@ -551,8 +563,15 @@ impl AuthenticodeSignature { } #[inline] - pub fn certificates(&self) -> impl Iterator { - self.certificates.iter() + pub fn certificates(&self) -> &[Certificate] { + self.certificates.as_slice() + } + + #[inline] + pub fn chain(&self) -> impl Iterator { + CertificateChain::new(self.certificates.as_slice(), |cert| { + cert.tbs_certificate.serial_number == self.signer().serial_number + }) } #[inline] @@ -562,12 +581,6 @@ impl AuthenticodeSignature { self.countersignatures.iter() } - pub fn chain(&self) -> Vec<&Certificate> { - self.certificate_chain(|cert| { - cert.tbs_certificate.serial_number == self.signer().serial_number - }) - } - pub fn signer(&self) -> &IssuerAndSerialNumber { if let SignerIdentifier::IssuerAndSerialNumber(signer) = &self.signer_info().sid @@ -599,154 +612,20 @@ impl AuthenticodeSignature { /// /// * The signing certificate must be valid. pub fn verify(&self) -> bool { - match self.signer_info().digest_alg.oid { - rfc5912::ID_SHA_1 => self.verify_impl::(), - rfc5912::ID_SHA_256 => self.verify_impl::(), - _ => unreachable!(), - } - } -} - -impl AuthenticodeSignature { - /// Returns a certificate chain containing the first certificate that - /// matches the predicate, and all the certificates participating in the - /// chain of trust for that certificate, up to the highest level certificate - /// found in the Authenticode signature. - /// - /// The first item in the vector is the requested certificate, and the - /// highest level certificate in the chain is the last one. - fn certificate_chain

(&self, predicate: P) -> Vec<&Certificate> - where - P: Fn(&Certificate) -> bool, - { - let mut chain = vec![]; - - let mut cert = match self.certificates().find(|cert| predicate(cert)) { - Some(cert) => cert, - None => return vec![], - }; - - loop { - chain.push(cert); - - // When the certificate is self-signed issuer == subject, in that - // case we can't keep going up the chain. - if cert.tbs_certificate.subject == cert.tbs_certificate.issuer { - return chain; - } - - match self.certificates().find(|c| { - c.tbs_certificate.subject == cert.tbs_certificate.issuer - }) { - Some(c) => cert = c, - None => return chain, - } - } - } - - /// Returns `true` if the given certificate is valid. - /// - /// A certificate is considered valid if it is correctly signed by a parent - /// certificate that is included in the PE file, and the parent certificate - /// is also valid. The validation process goes up the chain of trust until - /// finding a self-signed certificate or a certificate that is signed by - /// some other certificate that is not included in the PE. - /// - /// When the last certificate in the chain is one that is signed by an - /// external certificate (not included in the PE) no attempt is made to - /// continue the validation by retrieving the external certificate from the - /// operating system certificate store. - fn is_valid_certificate(&self, cert: &Certificate) -> bool { - // Get the certificate chain that starts with the given `cert` and - // contains the issuer of ` - let chain = self.certificate_chain(|c| { - c.tbs_certificate.serial_number - == cert.tbs_certificate.serial_number - }); - - // Iterate over the chain taking a certificate and its signer on each - // iteration. - for (signed, signer) in chain.iter().tuple_windows() { - // The `signed` certificate is the one that will be verified. - let verify_info = VerifyInfo::new( - signed.tbs_certificate.to_der().unwrap().into(), - Signature::new( - &signed.signature_algorithm, - signed.signature.as_bytes().unwrap(), - ), - ); - - // The public key in the `signer` certificate is used for - // verifying the signature in the `signed` certificate. - let key: VerifyingKey = match signer - .tbs_certificate - .subject_public_key_info - .owned_to_ref() - .try_into() - { - Ok(key) => key, - Err(_) => return false, - }; - - if key.verify(verify_info).is_err() { - return false; - } - } - - true - } - - /// Generic implementation for [`AuthenticodeSignature::verify`]. - fn verify_impl(&self) -> bool { if self.file_digest != self.digest() { return false; } - let content = self - .signed_data - .encap_content_info - .econtent - .as_ref() - .unwrap() - .value(); - - if D::digest(content).as_slice() != self.signer_info_digest.as_ref() { - return false; - } - - // Find the certificate that signed the Authenticode hash. - let signing_cert_sn = &self.signer().serial_number; - - let signing_cert = match self.certificates().find(|cert| { - cert.tbs_certificate.serial_number.eq(signing_cert_sn) - }) { - Some(cert) => cert, - None => return false, - }; - - if !self.is_valid_certificate(signing_cert) { - return false; - } - - let key = match rsa::RsaPublicKey::try_from( - signing_cert - .tbs_certificate - .subject_public_key_info - .owned_to_ref(), - ) { - Ok(key) => key, - Err(_) => return false, - }; - - let attrs_digest = - D::digest(self.signer_info().signed_attrs.to_der().unwrap()); - - key.verify( - Pkcs1v15Sign::new::(), - attrs_digest.as_slice(), - self.signer_info().signature.as_bytes(), + verify_signer_info( + self.signer_info(), + self.certificates(), + self.signed_data + .encap_content_info + .econtent + .as_ref() + .unwrap() + .value(), ) - .is_ok() } } @@ -759,17 +638,17 @@ impl From<&AuthenticodeSignature> for protos::pe::Signature { sig.set_file_digest(bytes2hex("", value.file_digest())); sig.set_verified(value.verify()); - sig.certificates - .extend(value.certificates().map(protos::pe::Certificate::from)); + sig.certificates.extend( + value.certificates().iter().map(protos::pe::Certificate::from), + ); for cs in value.countersignatures() { let mut pbcs = protos::pe::CounterSignature::from(cs); - pbcs.chain = value - .certificate_chain(|cert| { + pbcs.chain = + CertificateChain::new(value.certificates.as_slice(), |cert| { cert.tbs_certificate.serial_number == cs.signer.serial_number }) - .into_iter() .map(protos::pe::Certificate::from) .collect(); sig.countersignatures.push(pbcs); @@ -792,9 +671,9 @@ impl From<&AuthenticodeSignature> for protos::pe::Signature { signer_info.set_program_name(program_name.to_string()) } - signer_info.chain.extend( - value.chain().into_iter().map(protos::pe::Certificate::from), - ); + signer_info + .chain + .extend(value.chain().map(protos::pe::Certificate::from)); sig.signer_info = MessageField::from(Some(signer_info)); @@ -951,6 +830,103 @@ fn format_name(name: &x509_cert::name::Name) -> String { n } +fn verify_signer_info( + si: &SignerInfo, + certs: &[Certificate], + content: &[u8], +) -> bool { + // Find the certificate that signed the data in `content`. + let signing_cert_sn = + if let SignerIdentifier::IssuerAndSerialNumber(signer) = &si.sid { + &signer.serial_number + } else { + unreachable!() + }; + + // Get a certificate chain that starts with the certificate that signed + // data and contains all the certificates in the chain of truth. + let cert_chain = CertificateChain::new(certs, |cert| { + cert.tbs_certificate.serial_number.eq(signing_cert_sn) + }); + + // Make sure that whole certificate chain is valid. + if !cert_chain.verify() { + return false; + } + + let signing_cert = match certs + .iter() + .find(|cert| cert.tbs_certificate.serial_number.eq(signing_cert_sn)) + { + Some(cert) => cert, + None => return false, + }; + + match si.signature_algorithm.oid { + rfc5912::RSA_ENCRYPTION => {} + _ => unreachable!(), + } + + // Find the attribute that contains the message digest and extract + // the digest from it. + let message_digest = match si + .signed_attrs + .as_ref() + .unwrap() + .iter() + .find(|attr| attr.oid == rfc6268::ID_MESSAGE_DIGEST) + .and_then(|attr| attr.values.get(0)) + .and_then(|value| value.decode_as::().ok()) + { + Some(digest) => digest, + None => return false, + }; + + // Get the public key contained in the certificate that signed the data. + let key = match rsa::RsaPublicKey::try_from( + signing_cert.tbs_certificate.subject_public_key_info.owned_to_ref(), + ) { + Ok(key) => key, + Err(_) => return false, + }; + + match si.digest_alg.oid { + rfc5912::ID_SHA_1 => { + // Make sure that the actual digest of the signed data matches the + // digest found in SignerInfo. + if Sha1::digest(content).as_slice() != message_digest.as_ref() { + return false; + } + + let attrs_digest = Sha1::digest(si.signed_attrs.to_der().unwrap()); + + // Make sure that the + key.verify( + Pkcs1v15Sign::new::(), + attrs_digest.as_slice(), + si.signature.as_bytes(), + ) + .is_ok() + } + rfc5912::ID_SHA_256 => { + if Sha256::digest(content).as_slice() != message_digest.as_ref() { + return false; + } + + let attrs_digest = + Sha256::digest(si.signed_attrs.to_der().unwrap()); + + key.verify( + Pkcs1v15Sign::new::(), + attrs_digest.as_slice(), + si.signature.as_bytes(), + ) + .is_ok() + } + _ => unreachable!(), + } +} + /// Returns a short name from an OID. /// /// This returns the strings like "C", "CN", "O", "OU", "ST", etc. This strings @@ -1031,3 +1007,83 @@ impl der::Writer for DerHasher { Ok(()) } } + +struct CertificateChain<'a> { + certs: &'a [Certificate], + next: Option<&'a Certificate>, +} + +impl<'a> CertificateChain<'a> { + pub fn new

(certs: &'a [Certificate], predicate: P) -> Self + where + P: Fn(&Certificate) -> bool, + { + let next = certs.iter().find(|cert| predicate(cert)); + Self { certs, next } + } + + /// Returns `true` if the certificate chain is valid. + /// + /// A certificate is considered valid if it is correctly signed by a parent + /// certificate that is included in the PE file, and the parent certificate + /// is also valid. The validation process goes up the chain of trust until + /// finding a self-signed certificate or a certificate that is signed by + /// some other certificate that is not included in the PE. + /// + /// When the last certificate in the chain is one that is signed by an + /// external certificate (not included in the PE) no attempt is made to + /// continue the validation by retrieving the external certificate from the + /// operating system certificate store. + pub fn verify(self) -> bool { + // Iterate over the chain taking a certificate and its signer on each + // iteration. + for (signed, signer) in self.tuple_windows() { + // The `signed` certificate is the one that will be verified. + let verify_info = VerifyInfo::new( + signed.tbs_certificate.to_der().unwrap().into(), + Signature::new( + &signed.signature_algorithm, + signed.signature.as_bytes().unwrap(), + ), + ); + + // The public key in the `signer` certificate is used for + // verifying the signature in the `signed` certificate. + let key: VerifyingKey = match signer + .tbs_certificate + .subject_public_key_info + .owned_to_ref() + .try_into() + { + Ok(key) => key, + Err(_) => return false, + }; + + if key.verify(verify_info).is_err() { + return false; + } + } + + true + } +} + +impl<'a> Iterator for CertificateChain<'a> { + type Item = &'a Certificate; + + fn next(&mut self) -> Option { + let next = self.next; + if let Some(next) = self.next { + // When the certificate is self-signed issuer == subject, in that + // case we can't keep going up the chain. + if next.tbs_certificate.subject == next.tbs_certificate.issuer { + self.next = None + } else { + self.next = self.certs.iter().find(|c| { + c.tbs_certificate.subject == next.tbs_certificate.issuer + }); + } + } + next + } +} From 1829de29c9c84ace6d0d48389fcc8d33d6869810 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Thu, 18 Apr 2024 11:04:50 +0200 Subject: [PATCH 11/38] feat: advance in the implementation of Authenticode verification --- Cargo.lock | 54 +++- Cargo.toml | 4 +- lib/Cargo.toml | 13 +- lib/src/modules/elf/mod.rs | 6 +- lib/src/modules/hash/mod.rs | 16 +- lib/src/modules/pe/authenticode.rs | 297 ++++++++++++------ lib/src/modules/pe/mod.rs | 16 +- ...b32f43b9900fdd3a65c985d65a63b8f1535ef5.out | 7 +- ...15cdc8dd28a968c6b4d3b88acdd58ce2d3b885.out | 3 +- ...8c44d7f095eb395779de0ad1ac946914dfa34c.out | 6 +- ...606d0de3cfa34938eb76a1412c49a9082962ee.out | 8 +- 11 files changed, 302 insertions(+), 128 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c898e102e..5f9588873 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1151,6 +1151,7 @@ dependencies = [ "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] @@ -1192,6 +1193,9 @@ dependencies = [ "ff", "generic-array", "group", + "hkdf", + "pem-rfc7468", + "pkcs8", "rand_core", "sec1", "subtle", @@ -1598,6 +1602,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + [[package]] name = "hmac" version = "0.12.1" @@ -2043,10 +2056,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" [[package]] -name = "md5" -version = "0.7.0" +name = "md-5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest 0.10.7", +] [[package]] name = "memchr" @@ -2363,6 +2380,30 @@ version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" +[[package]] +name = "p192" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b0533bc6c238f2669aab8db75ae52879dc74e88d6bd3685bd4022a00fa85cd2" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sec1", +] + +[[package]] +name = "p224" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30c06436d66652bc2f01ade021592c80a2aad401570a18aa18b82e440d2b9aa1" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2 0.10.8", +] + [[package]] name = "p256" version = "0.13.2" @@ -3097,6 +3138,7 @@ dependencies = [ "base16ct", "der", "generic-array", + "pkcs8", "subtle", "zeroize", ] @@ -4646,6 +4688,8 @@ dependencies = [ "ecdsa", "ed25519-dalek", "k256", + "p192", + "p224", "p256", "p384", "rsa", @@ -4694,6 +4738,7 @@ dependencies = [ "crc32fast", "der", "digest 0.10.7", + "ecdsa", "fmmap", "globwalk", "goldenfile", @@ -4706,12 +4751,13 @@ dependencies = [ "linkme", "log", "magic", - "md5", + "md-5", "memchr", "memx", "nom 7.1.3", "num-derive 0.4.2", "num-traits", + "p384", "pretty_assertions", "protobuf", "protobuf-codegen", diff --git a/Cargo.toml b/Cargo.toml index 6c2b8f24f..bd66027a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,7 @@ const-oid = "0.9.6" crc32fast = "1.4.0" der = "0.7.9" digest = "0.10.7" +ecdsa = "0.16.9" enable-ansi-support = "0.2.1" env_logger = "0.11.3" fmmap = "0.3.3" @@ -63,7 +64,7 @@ lazy_static = "1.4.0" line-span = "0.1.5" linkme = "0.3.25" log = "0.4.21" -md5 = "0.7.0" +md-5 = "0.10.6" sha1 = "0.10.6" sha2 = "0.10.8" # Using tlsh-fixed instead of tlsh because tlsh-fixed includes a fix for this @@ -75,6 +76,7 @@ memx = "0.1.28" nom = "7.1.3" num-traits = "0.2.18" num-derive = "0.4.2" +p384 = "0.13.0" pest = "2.7.8" pest_derive = "2.7.8" pretty_assertions = "1.4.0" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 04e4ef9d8..8f20ba407 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -68,12 +68,13 @@ dotnet-module = [ elf-module = [ "dep:tlsh-fixed", "dep:nom", + "dep:md-5", ] # The `hash` module provides functions for computing md5, sha1, sha-256, # crc32 and checksum. hash-module = [ - "dep:md5", + "dep:md-5", "dep:sha1", "dep:sha2", "dep:crc32fast", @@ -105,9 +106,13 @@ pe-module = [ "dep:cms", "dep:const-oid", "dep:digest", + "dep:ecdsa", "dep:nom", "dep:rsa", + "dep:md-5", + "dep:p384", "dep:sha1", + "dep:sha2", "dep:x509-cert", "dep:x509-tsp", "dep:x509-verify", @@ -166,6 +171,7 @@ const-oid = { workspace = true, optional = true } crc32fast = { workspace = true, optional = true } der = { workspace = true, features = ["derive"] } digest = { workspace = true, optional = true } +ecdsa = { workspace = true, optional = true } fmmap = { workspace = true } indexmap = { workspace = true, features = ["serde"] } intaglio = { workspace = true } @@ -173,7 +179,7 @@ itertools = { workspace = true } lazy_static = { workspace = true } linkme = { workspace = true } log = { workspace = true, optional = true } -md5 = { workspace = true, optional = true } +md-5 = { workspace = true, optional = true, features = ["oid"] } sha1 = { workspace = true, optional = true } sha2 = { workspace = true, optional = true } magic = { workspace = true, optional = true } @@ -182,6 +188,7 @@ memx = { workspace = true } nom = { workspace = true, optional = true } num-derive = { workspace = true } num-traits = { workspace = true } +p384 = { workspace = true, optional = true, features = ["ecdsa"] } protobuf = { workspace = true } rustc-hash = { workspace = true } regex-syntax = { workspace = true } @@ -198,7 +205,7 @@ walrus = { workspace = true } wasmtime = { workspace = true, features = ["cranelift", "parallel-compilation"] } x509-cert = { workspace = true, optional = true } x509-tsp = { workspace = true, optional = true } -x509-verify = { workspace = true, optional = true, features = ["rsa", "sha1"] } +x509-verify = { workspace = true, optional = true, features = ["rsa", "sha1", "ecdsa"] } yansi = { workspace = true } yara-x-macros = { workspace = true } yara-x-parser = { workspace = true } diff --git a/lib/src/modules/elf/mod.rs b/lib/src/modules/elf/mod.rs index 265296207..d3e1f318b 100644 --- a/lib/src/modules/elf/mod.rs +++ b/lib/src/modules/elf/mod.rs @@ -6,6 +6,7 @@ and sections information, exported symbols, target platform, etc. use itertools::Itertools; use lazy_static::lazy_static; +use md5::{Digest, Md5}; use rustc_hash::FxHashSet; use tlsh_fixed as tlsh; @@ -45,7 +46,10 @@ fn import_md5(ctx: &mut ScanContext) -> Option { .sorted() .join(","); - let digest = format!("{:x}", md5::compute(comma_separated_names)); + let mut hasher = Md5::new(); + hasher.update(comma_separated_names.as_bytes()); + + let digest = format!("{:x}", hasher.finalize()); Some(RuntimeString::new(digest)) } diff --git a/lib/src/modules/hash/mod.rs b/lib/src/modules/hash/mod.rs index 429c23143..88aaecfed 100644 --- a/lib/src/modules/hash/mod.rs +++ b/lib/src/modules/hash/mod.rs @@ -1,6 +1,6 @@ use std::cell::RefCell; -use md5 as md5_hash; +use md5::Md5; use rustc_hash::FxHashMap; use sha1::Sha1; use sha2::{Digest, Sha256}; @@ -59,7 +59,11 @@ fn md5_data( let range = offset.try_into().ok()?..(offset + size).try_into().ok()?; let data = ctx.scanned_data().get(range)?; - let digest = format!("{:x}", md5_hash::compute(data)); + let mut hasher = Sha1::new(); + + hasher.update(data); + + let digest = format!("{:x}", hasher.finalize()); MD5_CACHE.with(|cache| { cache.borrow_mut().insert((offset, size), digest.clone()); @@ -70,10 +74,10 @@ fn md5_data( #[module_export(name = "md5")] fn md5_str(ctx: &mut ScanContext, s: RuntimeString) -> Option { - Some(RuntimeString::new(format!( - "{:x}", - md5_hash::compute(s.as_bstr(ctx)) - ))) + let mut hasher = Md5::new(); + hasher.update(s.as_bstr(ctx)); + + Some(RuntimeString::new(format!("{:x}", hasher.finalize()))) } #[module_export(name = "sha1")] diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 8200f1775..2cf2674b7 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -11,19 +11,23 @@ use cms::signed_data::{ CertificateSet, SignedData, SignerIdentifier, SignerInfo, }; use const_oid::db::{rfc5911, rfc5912, rfc6268, DB}; -use const_oid::ObjectIdentifier; +use const_oid::{AssociatedOid, ObjectIdentifier}; use der::asn1; use der::asn1::OctetString; use der::referenced::OwnedToRef; use der::{Choice, Sequence, SliceReader}; use der::{Decode, Encode, Tag, Tagged}; use digest::Digest; + +use ecdsa::signature::hazmat::PrehashVerifier; use itertools::Itertools; +use md5::Md5; use protobuf::MessageField; +use rsa::traits::SignatureScheme; use rsa::Pkcs1v15Sign; use sha1::digest::Output; use sha1::Sha1; -use sha2::Sha256; +use sha2::{Sha256, Sha384}; use x509_tsp::TstInfo; use x509_verify::{Signature, VerifyInfo, VerifyingKey}; @@ -351,17 +355,18 @@ impl AuthenticodeParser { .as_ref() .map(Self::certificate_set_to_iter) .unwrap() - .map(|c| c.clone()) + .cloned() .collect::>(), ); - let mut cs = Self::pkcs9_countersignature( - signed_data - .signer_infos - .as_ref() - .get(0) - .unwrap(), - ); + let cs = signed_data + .signer_infos + .as_ref() + .get(0) + .unwrap(); + + let mut countersignature = + Self::pkcs9_countersignature(cs); let tst_info = signed_data .encap_content_info @@ -381,14 +386,15 @@ impl AuthenticodeParser { None => continue, }; - cs.digest_alg = oid_to_algorithm_name( - &tst_info - .message_imprint - .hash_algorithm - .oid, - ); + countersignature.digest_alg = + oid_to_algorithm_name( + &tst_info + .message_imprint + .hash_algorithm + .oid, + ); - cs.digest = Some(bytes2hex( + countersignature.digest = Some(bytes2hex( "", tst_info .message_imprint @@ -396,7 +402,7 @@ impl AuthenticodeParser { .as_bytes(), )); - countersignatures.push(cs); + countersignatures.push(countersignature); } } } @@ -405,17 +411,17 @@ impl AuthenticodeParser { if let Ok(cs) = value.decode_as::().as_ref() { - let valid = verify_signer_info( + let mut countersignature = + Self::pkcs9_countersignature(cs); + + countersignature.verified = verify_signed_data( cs, - certificates.as_slice(), signer_info.signature.as_bytes(), + certificates.as_slice(), + true, ); - // THIS SHOULD BE TRUE - println!("{}", valid); - - countersignatures - .push(Self::pkcs9_countersignature(cs)); + countersignatures.push(countersignature); } } } @@ -437,7 +443,17 @@ impl AuthenticodeParser { pe.authenticode_hash(&mut sha256); sha256.finalize().to_vec() } - _ => unreachable!(), + rfc5912::ID_SHA_384 => { + let mut sha384 = Sha384::default(); + pe.authenticode_hash(&mut sha384); + sha384.finalize().to_vec() + } + rfc5912::ID_MD_5 => { + let mut md5 = Md5::default(); + pe.authenticode_hash(&mut md5); + md5.finalize().to_vec() + } + oid => unimplemented!("{:?}", oid), }; signatures.push(AuthenticodeSignature { @@ -490,6 +506,7 @@ impl AuthenticodeParser { digest_alg: oid_to_algorithm_name(&cs.digest_alg.oid), digest, signing_time, + verified: false, } } @@ -511,6 +528,7 @@ pub struct AuthenticodeCountersign { digest_alg: &'static str, digest: Option, signing_time: Option, + verified: bool, } pub struct AuthenticodeSignature { @@ -616,15 +634,16 @@ impl AuthenticodeSignature { return false; } - verify_signer_info( + verify_signed_data( self.signer_info(), - self.certificates(), self.signed_data .encap_content_info .econtent .as_ref() .unwrap() .value(), + self.certificates(), + false, ) } } @@ -705,12 +724,7 @@ impl From<&AuthenticodeCountersign> for protos::pe::CounterSignature { cs.digest = value.digest.clone(); cs.set_digest_alg(value.digest_alg.to_string()); - - /*cs.set_verified( - value - .verify_flags() - .is_some_and(|flags| flags == CounterSignatureVerify::Valid), - );*/ + cs.set_verified(value.verified); cs.sign_time = value.signing_time.map(|t| t.to_unix_duration().as_secs() as i64); @@ -738,7 +752,7 @@ impl From<&Certificate> for protos::pe::Certificate { ); // The certificate thumbprint is the SHA1 of the DER-encoded certificate. - let mut hasher = DerHasher::::new(); + let mut hasher = DerDigest::::default(); value.encode(&mut hasher).unwrap(); cert.set_thumbprint(format!("{:x}", hasher.finalize())); @@ -830,10 +844,34 @@ fn format_name(name: &x509_cert::name::Name) -> String { n } -fn verify_signer_info( +fn verify_signed_data( si: &SignerInfo, + data: &[u8], certs: &[Certificate], - content: &[u8], + unprefixed: bool, +) -> bool { + match si.digest_alg.oid { + rfc5912::ID_SHA_1 => { + verify_signed_data_impl::(si, data, certs, unprefixed) + } + rfc5912::ID_SHA_256 => { + verify_signed_data_impl::(si, data, certs, unprefixed) + } + rfc5912::ID_SHA_384 => { + verify_signed_data_impl::(si, data, certs, unprefixed) + } + rfc5912::ID_MD_5 => { + verify_signed_data_impl::(si, data, certs, unprefixed) + } + oid => unimplemented!("{:?}", oid), + } +} + +fn verify_signed_data_impl( + si: &SignerInfo, + data: &[u8], + certs: &[Certificate], + unprefixed: bool, ) -> bool { // Find the certificate that signed the data in `content`. let signing_cert_sn = @@ -862,11 +900,6 @@ fn verify_signer_info( None => return false, }; - match si.signature_algorithm.oid { - rfc5912::RSA_ENCRYPTION => {} - _ => unreachable!(), - } - // Find the attribute that contains the message digest and extract // the digest from it. let message_digest = match si @@ -882,48 +915,60 @@ fn verify_signer_info( None => return false, }; - // Get the public key contained in the certificate that signed the data. - let key = match rsa::RsaPublicKey::try_from( - signing_cert.tbs_certificate.subject_public_key_info.owned_to_ref(), - ) { - Ok(key) => key, - Err(_) => return false, - }; + // Make sure that the actual digest of the signed data matches the + // digest found in SignerInfo. + if D::digest(data).as_slice() != message_digest.as_ref() { + return false; + } - match si.digest_alg.oid { - rfc5912::ID_SHA_1 => { - // Make sure that the actual digest of the signed data matches the - // digest found in SignerInfo. - if Sha1::digest(content).as_slice() != message_digest.as_ref() { - return false; - } + let mut attrs_digest = DerDigest::::default(); + si.signed_attrs.encode(&mut attrs_digest).unwrap(); + let attrs_digest = attrs_digest.finalize(); - let attrs_digest = Sha1::digest(si.signed_attrs.to_der().unwrap()); + match si.signature_algorithm.oid { + rfc5912::RSA_ENCRYPTION => { + // Get the public key contained in the certificate that signed the data. + let key = match rsa::RsaPublicKey::try_from( + signing_cert + .tbs_certificate + .subject_public_key_info + .owned_to_ref(), + ) { + Ok(key) => key, + Err(_) => return false, + }; + + let signature = if unprefixed { + Pkcs1v15Sign::new_unprefixed() + } else { + Pkcs1v15Sign::new::() + }; - // Make sure that the - key.verify( - Pkcs1v15Sign::new::(), - attrs_digest.as_slice(), - si.signature.as_bytes(), - ) - .is_ok() + signature + .verify(&key, attrs_digest.as_slice(), si.signature.as_bytes()) + .is_ok() } - rfc5912::ID_SHA_256 => { - if Sha256::digest(content).as_slice() != message_digest.as_ref() { - return false; - } + rfc5912::ID_EC_PUBLIC_KEY => { + // TODO: the hashing algorithm is not always SHA-384 + let key = match p384::ecdsa::VerifyingKey::try_from( + signing_cert + .tbs_certificate + .subject_public_key_info + .owned_to_ref(), + ) { + Ok(key) => key, + Err(_) => return false, + }; - let attrs_digest = - Sha256::digest(si.signed_attrs.to_der().unwrap()); + let signature = + match ecdsa::Signature::from_der(si.signature.as_bytes()) { + Ok(signature) => signature, + Err(_) => return false, + }; - key.verify( - Pkcs1v15Sign::new::(), - attrs_digest.as_slice(), - si.signature.as_bytes(), - ) - .is_ok() + key.verify_prehash(attrs_digest.as_slice(), &signature).is_ok() } - _ => unreachable!(), + oid => unimplemented!("{:?}", oid), } } @@ -971,39 +1016,95 @@ fn format_serial_number( /// If the OID doesn't correspond to some of the supported algorithm /// names. fn oid_to_algorithm_name(oid: &ObjectIdentifier) -> &'static str { - if oid == &rfc5912::ID_SHA_1 { - "sha1" - } else if oid == &rfc5912::ID_SHA_256 { - "sha256" - } else if oid == &rfc5912::ID_MD_5 { - "md5" - } else if oid == &rfc5912::SHA_1_WITH_RSA_ENCRYPTION { - "sha1WithRSAEncryption" - } else if oid == &rfc5912::SHA_256_WITH_RSA_ENCRYPTION { - "sha256WithRSAEncryption" - } else { - unreachable!() + match oid { + &rfc5912::ID_SHA_1 => "sha1", + &rfc5912::ID_SHA_256 => "sha256", + &rfc5912::ID_SHA_384 => "sha384", + &rfc5912::ID_MD_5 => "md5", + // In the default case try to use the string representation provided by + // the `const-oid` crate. Panics if this fails. + oid => { + DB.by_oid(oid).unwrap_or_else(|| panic!("unknown OID: {:?}", oid)) + } } } /// A wrapper that implements the [`der::Writer`] trait for a /// [`Digest`]. -struct DerHasher { - hasher: T, +#[derive(Default)] +struct DerDigest(T); + +impl DerDigest { + pub fn finalize(self) -> Output { + self.0.finalize() + } +} + +/* +impl OutputSizeUser for DerDigest { + type OutputSize = T::OutputSize; } -impl DerHasher { - pub fn new() -> Self { - Self { hasher: T::default() } +impl Digest for DerDigest { + fn new() -> Self { + Self(T::new()) } - pub fn finalize(self) -> Output { - self.hasher.finalize() + + fn new_with_prefix(data: impl AsRef<[u8]>) -> Self { + Self(T::new_with_prefix(data)) + } + + fn update(&mut self, data: impl AsRef<[u8]>) { + Digest::update(&mut self.0, data) + } + + fn chain_update(self, data: impl AsRef<[u8]>) -> Self { + Self(self.0.chain_update(data)) + } + + fn finalize(self) -> Output { + self.0.finalize() + } + + fn finalize_into(self, out: &mut Output) { + Digest::finalize_into(self.0, out) + } + + fn finalize_reset(&mut self) -> Output + where + Self: FixedOutputReset, + { + Digest::finalize_reset(&mut self.0); + GenericArray + } + + fn finalize_into_reset(&mut self, out: &mut Output) + where + Self: FixedOutputReset, + { + Digest::finalize_into_reset(&mut self.0, out) + } + + fn reset(&mut self) + where + Self: Reset, + { + Digest::reset(&mut self.0) + } + + fn output_size() -> usize { + ::output_size() + } + + fn digest(data: impl AsRef<[u8]>) -> Output { + T::digest(data) } } +*/ -impl der::Writer for DerHasher { +impl der::Writer for DerDigest { fn write(&mut self, slice: &[u8]) -> der::Result<()> { - self.hasher.update(slice); + self.0.update(slice); Ok(()) } } diff --git a/lib/src/modules/pe/mod.rs b/lib/src/modules/pe/mod.rs index f151c5d60..4ca98b997 100644 --- a/lib/src/modules/pe/mod.rs +++ b/lib/src/modules/pe/mod.rs @@ -8,6 +8,7 @@ use std::rc::Rc; use std::slice::Iter; use bstr::BStr; +use digest::Digest; use itertools::Itertools; use nom::branch::alt; use nom::character::complete::u8; @@ -212,7 +213,7 @@ fn imphash(ctx: &mut ScanContext) -> Option { return None; } - let mut md5_hash = md5::Context::new(); + let mut md5_hash = md5::Md5::default(); let mut first = true; for import in &pe.import_details { @@ -225,16 +226,19 @@ fn imphash(ctx: &mut ScanContext) -> Option { } for func in &import.functions { if !first { - md5_hash.consume(","); + Digest::update(&mut md5_hash, ",".as_bytes()) } - md5_hash.consume(dll_name); - md5_hash.consume("."); - md5_hash.consume(func.name.as_deref().unwrap().to_lowercase()); + Digest::update(&mut md5_hash, dll_name); + Digest::update(&mut md5_hash, ".".as_bytes()); + Digest::update( + &mut md5_hash, + func.name.as_deref().unwrap().to_lowercase().as_bytes(), + ); first = false; } } - let digest = format!("{:x}", md5_hash.compute()); + let digest = format!("{:x}", md5_hash.finalize()); Some(RuntimeString::new(digest)) } diff --git a/lib/src/modules/pe/tests/testdata/00a1067fc96eb2c1d440bb5b44b32f43b9900fdd3a65c985d65a63b8f1535ef5.out b/lib/src/modules/pe/tests/testdata/00a1067fc96eb2c1d440bb5b44b32f43b9900fdd3a65c985d65a63b8f1535ef5.out index 08a0ef07b..d4a60bcbd 100644 --- a/lib/src/modules/pe/tests/testdata/00a1067fc96eb2c1d440bb5b44b32f43b9900fdd3a65c985d65a63b8f1535ef5.out +++ b/lib/src/modules/pe/tests/testdata/00a1067fc96eb2c1d440bb5b44b32f43b9900fdd3a65c985d65a63b8f1535ef5.out @@ -357,7 +357,7 @@ import_details: rva: 45616 - name: "RaiseException" rva: 45624 -is_signed: false +is_signed: true signatures: - subject: "/C=KR/ST=Jeju-do/L=Jeju-si/O=Kakao corp./CN=Kakao corp." issuer: "/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 SHA256 Code Signing CA" @@ -368,8 +368,10 @@ signatures: serial: "71:d8:85:b4:fe:8c:c7:14:7b:ef:a5:33:62:8e:e3:31" not_before: 1509580800 # 2017-11-02 00:00:00 UTC not_after: 1549065599 # 2019-02-01 23:59:59 UTC + verified: true digest_alg: "md5" digest: "3f3e2ded38ad379857f6dcc42ed85854" + file_digest: "3f3e2ded38ad379857f6dcc42ed85854" number_of_certificates: 4 number_of_countersignatures: 1 signer_info: @@ -433,7 +435,8 @@ signatures: not_before: 1386633600 # 2013-12-10 00:00:00 UTC not_after: 1702166399 # 2023-12-09 23:59:59 UTC countersignatures: - - sign_time: 1527751928 # 2018-05-31 07:32:08 UTC + - verified: true + sign_time: 1527751928 # 2018-05-31 07:32:08 UTC digest: "c7aaa562bef28b00380e0b416297e3e7777d3d2e" digest_alg: "sha1" chain: diff --git a/lib/src/modules/pe/tests/testdata/079a472d22290a94ebb212aa8015cdc8dd28a968c6b4d3b88acdd58ce2d3b885.out b/lib/src/modules/pe/tests/testdata/079a472d22290a94ebb212aa8015cdc8dd28a968c6b4d3b88acdd58ce2d3b885.out index feae3fcc6..aad570187 100644 --- a/lib/src/modules/pe/tests/testdata/079a472d22290a94ebb212aa8015cdc8dd28a968c6b4d3b88acdd58ce2d3b885.out +++ b/lib/src/modules/pe/tests/testdata/079a472d22290a94ebb212aa8015cdc8dd28a968c6b4d3b88acdd58ce2d3b885.out @@ -433,7 +433,8 @@ signatures: not_before: 1386633600 # 2013-12-10 00:00:00 UTC not_after: 1702166399 # 2023-12-09 23:59:59 UTC countersignatures: - - sign_time: 1528216551 # 2018-06-05 16:35:51 UTC + - verified: true + sign_time: 1528216551 # 2018-06-05 16:35:51 UTC digest: "9fa1188e4c656d86e2d7fa133ee8138ac1ec4ec1" digest_alg: "sha1" chain: diff --git a/lib/src/modules/pe/tests/testdata/2e9c671b8a0411f2b397544b368c44d7f095eb395779de0ad1ac946914dfa34c.out b/lib/src/modules/pe/tests/testdata/2e9c671b8a0411f2b397544b368c44d7f095eb395779de0ad1ac946914dfa34c.out index 4055826cf..c7871f989 100644 --- a/lib/src/modules/pe/tests/testdata/2e9c671b8a0411f2b397544b368c44d7f095eb395779de0ad1ac946914dfa34c.out +++ b/lib/src/modules/pe/tests/testdata/2e9c671b8a0411f2b397544b368c44d7f095eb395779de0ad1ac946914dfa34c.out @@ -549,7 +549,8 @@ signatures: not_before: 1265587200 # 2010-02-08 00:00:00 UTC not_after: 1581119999 # 2020-02-07 23:59:59 UTC countersignatures: - - sign_time: 1474471603 # 2016-09-21 15:26:43 UTC + - verified: true + sign_time: 1474471603 # 2016-09-21 15:26:43 UTC digest: "3ac2b9de4c7d90dc44aae8277d512e789de4c818" digest_alg: "sha1" chain: @@ -646,7 +647,8 @@ signatures: not_before: 1452556800 # 2016-01-12 00:00:00 UTC not_after: 1807487999 # 2027-04-11 23:59:59 UTC countersignatures: - - sign_time: 1474471604 # 2016-09-21 15:26:44 UTC + - verified: false + sign_time: 1474471604 # 2016-09-21 15:26:44 UTC digest: "e879962bab47112346d0be7e25ed1d8251a89594ee22ab16ddeed0faeb6c0de0" digest_alg: "sha256" chain: diff --git a/lib/src/modules/pe/tests/testdata/616095160dd4b1556848907729606d0de3cfa34938eb76a1412c49a9082962ee.out b/lib/src/modules/pe/tests/testdata/616095160dd4b1556848907729606d0de3cfa34938eb76a1412c49a9082962ee.out index 6e009581b..ee8dcfdd7 100644 --- a/lib/src/modules/pe/tests/testdata/616095160dd4b1556848907729606d0de3cfa34938eb76a1412c49a9082962ee.out +++ b/lib/src/modules/pe/tests/testdata/616095160dd4b1556848907729606d0de3cfa34938eb76a1412c49a9082962ee.out @@ -414,7 +414,7 @@ import_details: rva: 70312 is_signed: true signatures: - - subject: "/C=DE/ST=Bayern/L=Geretsried/O=Quality First Software GmbH/serialNumber=HRB 140833/CN=Quality First Software GmbH/businessCategory=Private Organization/jurisdictionL=M\\xC3\\xBCnchen/jurisdictionST=Bayern/jurisdictionC=DE" + - subject: "/C=DE/ST=Bayern/L=Geretsried/O=Quality First Software GmbH/SERIALNUMBER=HRB 140833/CN=Quality First Software GmbH/BUSINESSCATEGORY=Private Organization/1.3.6.1.4.1.311.60.2.1.1=#0c084dc3bc6e6368656e/1.3.6.1.4.1.311.60.2.1.2=#0c0642617965726e/1.3.6.1.4.1.311.60.2.1.3=#13024445" issuer: "/C=US/ST=Texas/L=Houston/O=SSL Corp/CN=SSL.com EV Code Signing Intermediate CA ECC R2" thumbprint: "6a63f4e957aa5867f33916e8f57019c2b9987478" version: 3 @@ -434,7 +434,7 @@ signatures: digest_alg: "sha384" chain: - issuer: "/C=US/ST=Texas/L=Houston/O=SSL Corp/CN=SSL.com EV Code Signing Intermediate CA ECC R2" - subject: "/C=DE/ST=Bayern/L=Geretsried/O=Quality First Software GmbH/serialNumber=HRB 140833/CN=Quality First Software GmbH/businessCategory=Private Organization/jurisdictionL=M\\xC3\\xBCnchen/jurisdictionST=Bayern/jurisdictionC=DE" + subject: "/C=DE/ST=Bayern/L=Geretsried/O=Quality First Software GmbH/SERIALNUMBER=HRB 140833/CN=Quality First Software GmbH/BUSINESSCATEGORY=Private Organization/1.3.6.1.4.1.311.60.2.1.1=#0c084dc3bc6e6368656e/1.3.6.1.4.1.311.60.2.1.2=#0c0642617965726e/1.3.6.1.4.1.311.60.2.1.3=#13024445" thumbprint: "6a63f4e957aa5867f33916e8f57019c2b9987478" version: 3 algorithm: "ecdsa-with-SHA384" @@ -462,7 +462,7 @@ signatures: not_before: 1551987465 # 2019-03-07 19:37:45 UTC not_after: 2025027465 # 2034-03-03 19:37:45 UTC - issuer: "/C=US/ST=Texas/L=Houston/O=SSL Corp/CN=SSL.com EV Code Signing Intermediate CA ECC R2" - subject: "/C=DE/ST=Bayern/L=Geretsried/O=Quality First Software GmbH/serialNumber=HRB 140833/CN=Quality First Software GmbH/businessCategory=Private Organization/jurisdictionL=M\\xC3\\xBCnchen/jurisdictionST=Bayern/jurisdictionC=DE" + subject: "/C=DE/ST=Bayern/L=Geretsried/O=Quality First Software GmbH/SERIALNUMBER=HRB 140833/CN=Quality First Software GmbH/BUSINESSCATEGORY=Private Organization/1.3.6.1.4.1.311.60.2.1.1=#0c084dc3bc6e6368656e/1.3.6.1.4.1.311.60.2.1.2=#0c0642617965726e/1.3.6.1.4.1.311.60.2.1.3=#13024445" thumbprint: "6a63f4e957aa5867f33916e8f57019c2b9987478" version: 3 algorithm: "ecdsa-with-SHA384" @@ -489,7 +489,7 @@ signatures: not_before: 1573671005 # 2019-11-13 18:50:05 UTC not_after: 2046970205 # 2034-11-12 18:50:05 UTC countersignatures: - - verified: true + - verified: false sign_time: 1708954610 # 2024-02-26 13:36:50 UTC digest: "ebbcb9430ee128c3126285d91988aa775cc579091e3fbbd07290d93cd42f6623" digest_alg: "sha256" From f12fa6ec92d97bc68f30548bc1d2a4cbf9925b85 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Thu, 18 Apr 2024 18:46:35 +0200 Subject: [PATCH 12/38] feat: more advances in the Authenticode implementation. --- Cargo.lock | 18 + Cargo.toml | 1 + lib/Cargo.toml | 4 +- lib/src/modules/pe/authenticode.rs | 368 ++++++++++++------ ...8c44d7f095eb395779de0ad1ac946914dfa34c.out | 2 +- ...0663afed2728226ad5ec6707d4dd7d2e64e.in.zip | Bin 0 -> 15473 bytes ...cdf0663afed2728226ad5ec6707d4dd7d2e64e.out | 299 ++++++++++++++ 7 files changed, 561 insertions(+), 131 deletions(-) create mode 100644 lib/src/modules/pe/tests/testdata/6d3bbd6f3b6e11d83526c08e3ccdf0663afed2728226ad5ec6707d4dd7d2e64e.in.zip create mode 100644 lib/src/modules/pe/tests/testdata/6d3bbd6f3b6e11d83526c08e3ccdf0663afed2728226ad5ec6707d4dd7d2e64e.out diff --git a/Cargo.lock b/Cargo.lock index 5f9588873..5d654934c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1140,6 +1140,22 @@ dependencies = [ "winapi", ] +[[package]] +name = "dsa" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48bc224a9084ad760195584ce5abb3c2c34a225fa312a128ad245a6b412b7689" +dependencies = [ + "digest 0.10.7", + "num-bigint-dig", + "num-traits", + "pkcs8", + "rfc6979", + "sha2 0.10.8", + "signature", + "zeroize", +] + [[package]] name = "ecdsa" version = "0.16.9" @@ -4685,6 +4701,7 @@ checksum = "8e407b6fb3a8638bc7af2216647e045f3ce6cd71235e84ada35dd03c77a6cd6d" dependencies = [ "const-oid", "der", + "dsa", "ecdsa", "ed25519-dalek", "k256", @@ -4757,6 +4774,7 @@ dependencies = [ "nom 7.1.3", "num-derive 0.4.2", "num-traits", + "p256", "p384", "pretty_assertions", "protobuf", diff --git a/Cargo.toml b/Cargo.toml index bd66027a0..aa9d7789f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,6 +76,7 @@ memx = "0.1.28" nom = "7.1.3" num-traits = "0.2.18" num-derive = "0.4.2" +p256 = "0.13.2" p384 = "0.13.0" pest = "2.7.8" pest_derive = "2.7.8" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 8f20ba407..7cff819a2 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -110,6 +110,7 @@ pe-module = [ "dep:nom", "dep:rsa", "dep:md-5", + "dep:p256", "dep:p384", "dep:sha1", "dep:sha2", @@ -189,6 +190,7 @@ nom = { workspace = true, optional = true } num-derive = { workspace = true } num-traits = { workspace = true } p384 = { workspace = true, optional = true, features = ["ecdsa"] } +p256 = { workspace = true, optional = true, features = ["ecdsa"] } protobuf = { workspace = true } rustc-hash = { workspace = true } regex-syntax = { workspace = true } @@ -205,7 +207,7 @@ walrus = { workspace = true } wasmtime = { workspace = true, features = ["cranelift", "parallel-compilation"] } x509-cert = { workspace = true, optional = true } x509-tsp = { workspace = true, optional = true } -x509-verify = { workspace = true, optional = true, features = ["rsa", "sha1", "ecdsa"] } +x509-verify = { workspace = true, optional = true, features = ["sha1", "dsa", "ecdsa", "rsa"] } yansi = { workspace = true } yara-x-macros = { workspace = true } yara-x-parser = { workspace = true } diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 2cf2674b7..a81b04a07 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -18,7 +18,6 @@ use der::referenced::OwnedToRef; use der::{Choice, Sequence, SliceReader}; use der::{Decode, Encode, Tag, Tagged}; use digest::Digest; - use ecdsa::signature::hazmat::PrehashVerifier; use itertools::Itertools; use md5::Md5; @@ -28,6 +27,7 @@ use rsa::Pkcs1v15Sign; use sha1::digest::Output; use sha1::Sha1; use sha2::{Sha256, Sha384}; +use x509_cert::spki::AlgorithmIdentifierOwned; use x509_tsp::TstInfo; use x509_verify::{Signature, VerifyInfo, VerifyingKey}; @@ -288,7 +288,7 @@ impl AuthenticodeParser { return Err(ParseError::EmptyAuthenticatedAttributes); }; - // The contentType attribute must be present. + // The content type attribute must be present. if !signed_attrs .iter() .any(|attr| attr.oid == rfc6268::ID_CONTENT_TYPE) @@ -296,19 +296,21 @@ impl AuthenticodeParser { return Err(ParseError::MissingContentTypeAuthenticatedAttribute); } - let signer_info_digest = signed_attrs - .iter() - .find(|attr| attr.oid == rfc6268::ID_MESSAGE_DIGEST) - .and_then(|attr| attr.values.get(0)) - .and_then(|value| value.decode_as::().ok()) + // Get the message digest attribute stored in `SignerInfo`, this is + // the digest of `SignedData.EncapsulatedContentInfo.econtent`. + let signer_info_digest = get_message_digest(signer_info) .ok_or(ParseError::MissingMessageDigestAuthenticatedAttribute)?; + // Get the opus info attribute and decode it. let opus_info = signed_attrs .iter() .find(|attr| attr.oid == SPC_SP_OPUS_INFO_OBJID) .and_then(|attr| attr.values.get(0)) .and_then(|value| value.decode_as::().ok()); + // Get all the certificates contained in `SignedData`, more + // certificates from nested signatures and countersignatures will + // be added later to this vector. let mut certificates: Vec = signed_data .certificates .as_ref() @@ -402,6 +404,22 @@ impl AuthenticodeParser { .as_bytes(), )); + countersignature.verified = + verify_message_digest( + &tst_info + .message_imprint + .hash_algorithm, + signer_info.signature.as_bytes(), + tst_info + .message_imprint + .hashed_message + .as_bytes(), + ) && verify_signer_info( + cs, + certificates.as_slice(), + false, + ); + countersignatures.push(countersignature); } } @@ -414,12 +432,22 @@ impl AuthenticodeParser { let mut countersignature = Self::pkcs9_countersignature(cs); - countersignature.verified = verify_signed_data( - cs, - signer_info.signature.as_bytes(), - certificates.as_slice(), - true, - ); + let message_digest = + match get_message_digest(cs) { + Some(digest) => digest, + None => continue, + }; + + countersignature.verified = + verify_message_digest( + &cs.digest_alg, + signer_info.signature.as_bytes(), + message_digest.as_bytes(), + ) && verify_signer_info( + cs, + certificates.as_slice(), + true, + ); countersignatures.push(countersignature); } @@ -432,6 +460,8 @@ impl AuthenticodeParser { let mut signatures = Vec::with_capacity(nested_signatures.len() + 1); + // Compute the Authenticode hash by ourselves. This hash will be + // compared later with the one included in the PE file. let file_digest = match signer_info.digest_alg.oid { rfc5912::ID_SHA_1 => { let mut sha1 = Sha1::default(); @@ -460,7 +490,7 @@ impl AuthenticodeParser { program_name: opus_info.and_then(|oi| oi.program_name), signer_info_digest, signed_data, - file_digest, + computed_authenticode_hash: file_digest, indirect_data, countersignatures, certificates, @@ -538,31 +568,30 @@ pub struct AuthenticodeSignature { certificates: Vec, countersignatures: Vec, program_name: Option, - file_digest: Vec, + computed_authenticode_hash: Vec, } impl AuthenticodeSignature { - /// Get the authenticode digest stored in the signature. + /// Get the Authenticode hash stored in the PE file. #[inline] - pub fn digest(&self) -> &[u8] { + pub fn stored_authenticode_hash(&self) -> &[u8] { self.indirect_data.message_digest.digest.as_bytes() } - /// Get the authenticode digest, as computed by the + /// Get the Authenticode hash computed by ourselves. #[inline] - pub fn file_digest(&self) -> &[u8] { - self.file_digest.as_slice() + pub fn computed_authenticode_hash(&self) -> &[u8] { + self.computed_authenticode_hash.as_slice() } - /// Get the name of the digest algorithm. - pub fn digest_alg(&self) -> String { + /// Get the name of the Authenticode hash algorithm. + pub fn authenticode_hash_algorithm(&self) -> &'static str { oid_to_algorithm_name( &self.indirect_data.message_digest.digest_algorithm.oid, ) - .to_string() } - /// Get [`SignerInfo`]. + /// Get the [`SignerInfo`] struct. #[inline] pub fn signer_info(&self) -> &SignerInfo { // The parser validates that exactly one signer info is present, so @@ -615,36 +644,52 @@ impl AuthenticodeSignature { /// /// * The Authenticode hash included in the file (in the `message_digest` /// field of [`SpcIndirectDataContent`]) must match the hash computed by - /// ourselves using [`PE::authenticode_hash`]. + /// ourselves using [`PE::authenticode_hash`]. This ensures that the file + /// has not been modified. /// /// * The message digest stored the signed attribute [`rfc6268::ID_MESSAGE_DIGEST`] /// of [`SignerInfo`], must match the one computed by ourselves by hashing - /// the `econtent` field in [`EncapsulatedContentInfo`]. + /// the `econtent` field in [`EncapsulatedContentInfo`]. This ensures that + /// the Authenticode hash included in the file has not been tampered. /// /// * The signature in [`SignerInfo`] must be valid. This signature is the /// result of signing the hash of the DER encoding of the signed /// attributes in [`SignerInfo`] with the private key of the signing /// certificate. We compute this hash by ourselves, and then use the /// public key included in the signing certificate to verify that the - /// signature is valid. + /// signature is valid. This ensures that the signed attributes in + /// [`SignerInfo`], including the message digest has not been tampered. /// - /// * The signing certificate must be valid. + /// * The certificate that signed the [`SignerInfo`] struct must be valid, + /// which implies that the chain of trust for that certificate must be + /// validated, until we found a self-signed certificate or a certificate + /// that is not included in the PE file. This last certificate is always + /// considered valid. pub fn verify(&self) -> bool { - if self.file_digest != self.digest() { + if self.computed_authenticode_hash() != self.stored_authenticode_hash() + { return false; } - verify_signed_data( - self.signer_info(), + let message_digest = match get_message_digest(self.signer_info()) { + Some(digest) => digest, + None => return false, + }; + + if !verify_message_digest( + &self.signer_info().digest_alg, self.signed_data .encap_content_info .econtent .as_ref() .unwrap() .value(), - self.certificates(), - false, - ) + message_digest.as_ref(), + ) { + return false; + } + + verify_signer_info(self.signer_info(), self.certificates(), false) } } @@ -652,9 +697,9 @@ impl From<&AuthenticodeSignature> for protos::pe::Signature { fn from(value: &AuthenticodeSignature) -> Self { let mut sig = protos::pe::Signature::new(); - sig.set_digest(bytes2hex("", value.digest())); - sig.set_digest_alg(value.digest_alg()); - sig.set_file_digest(bytes2hex("", value.file_digest())); + sig.set_digest(bytes2hex("", value.stored_authenticode_hash())); + sig.set_digest_alg(value.authenticode_hash_algorithm().to_string()); + sig.set_file_digest(bytes2hex("", value.computed_authenticode_hash())); sig.set_verified(value.verify()); sig.certificates.extend( @@ -844,24 +889,50 @@ fn format_name(name: &x509_cert::name::Name) -> String { n } -fn verify_signed_data( +/// Given a [`SignerInfo`] returns the value of the message digest attribute. +fn get_message_digest(si: &SignerInfo) -> Option { + si.signed_attrs + .as_ref() + .unwrap() + .iter() + .find(|attr| attr.oid == rfc6268::ID_MESSAGE_DIGEST) + .and_then(|attr| attr.values.get(0)) + .and_then(|value| value.decode_as::().ok()) +} + +/// Given a hashing algorithm and a message, compute the message's hash +/// and compare it with `digest`. The function returns `true` if they match. +fn verify_message_digest( + algorithm: &AlgorithmIdentifierOwned, + message: &[u8], + digest: &[u8], +) -> bool { + match algorithm.oid { + rfc5912::ID_SHA_1 => Sha1::digest(message).as_slice() == digest, + rfc5912::ID_SHA_256 => Sha256::digest(message).as_slice() == digest, + rfc5912::ID_SHA_384 => Sha384::digest(message).as_slice() == digest, + rfc5912::ID_MD_5 => Md5::digest(message).as_slice() == digest, + _ => unimplemented!(), + } +} + +fn verify_signer_info( si: &SignerInfo, - data: &[u8], certs: &[Certificate], unprefixed: bool, ) -> bool { match si.digest_alg.oid { rfc5912::ID_SHA_1 => { - verify_signed_data_impl::(si, data, certs, unprefixed) + verify_signed_data_impl::(si, certs, unprefixed) } rfc5912::ID_SHA_256 => { - verify_signed_data_impl::(si, data, certs, unprefixed) + verify_signed_data_impl::(si, certs, unprefixed) } rfc5912::ID_SHA_384 => { - verify_signed_data_impl::(si, data, certs, unprefixed) + verify_signed_data_impl::(si, certs, unprefixed) } rfc5912::ID_MD_5 => { - verify_signed_data_impl::(si, data, certs, unprefixed) + verify_signed_data_impl::(si, certs, unprefixed) } oid => unimplemented!("{:?}", oid), } @@ -869,7 +940,6 @@ fn verify_signed_data( fn verify_signed_data_impl( si: &SignerInfo, - data: &[u8], certs: &[Certificate], unprefixed: bool, ) -> bool { @@ -900,31 +970,76 @@ fn verify_signed_data_impl( None => return false, }; - // Find the attribute that contains the message digest and extract - // the digest from it. - let message_digest = match si - .signed_attrs - .as_ref() - .unwrap() - .iter() - .find(|attr| attr.oid == rfc6268::ID_MESSAGE_DIGEST) - .and_then(|attr| attr.values.get(0)) - .and_then(|value| value.decode_as::().ok()) - { - Some(digest) => digest, - None => return false, - }; - - // Make sure that the actual digest of the signed data matches the - // digest found in SignerInfo. - if D::digest(data).as_slice() != message_digest.as_ref() { - return false; - } - let mut attrs_digest = DerDigest::::default(); si.signed_attrs.encode(&mut attrs_digest).unwrap(); let attrs_digest = attrs_digest.finalize(); + match signing_cert.tbs_certificate.signature.oid { + rfc5912::MD_5_WITH_RSA_ENCRYPTION + | rfc5912::SHA_1_WITH_RSA_ENCRYPTION + | rfc5912::SHA_256_WITH_RSA_ENCRYPTION + | rfc5912::SHA_384_WITH_RSA_ENCRYPTION => { + let key = match rsa::RsaPublicKey::try_from( + signing_cert + .tbs_certificate + .subject_public_key_info + .owned_to_ref(), + ) { + Ok(key) => key, + Err(_) => return false, + }; + + let signature = if unprefixed { + Pkcs1v15Sign::new_unprefixed() + } else { + Pkcs1v15Sign::new::() + }; + + signature + .verify(&key, attrs_digest.as_slice(), si.signature.as_bytes()) + .is_ok() + } + rfc5912::ECDSA_WITH_SHA_256 => { + let key = match p256::ecdsa::VerifyingKey::try_from( + signing_cert + .tbs_certificate + .subject_public_key_info + .owned_to_ref(), + ) { + Ok(key) => key, + Err(_) => return false, + }; + + let signature = + match ecdsa::Signature::from_der(si.signature.as_bytes()) { + Ok(signature) => signature, + Err(_) => return false, + }; + + key.verify_prehash(attrs_digest.as_slice(), &signature).is_ok() + } + rfc5912::ECDSA_WITH_SHA_384 => { + let key = match p384::ecdsa::VerifyingKey::try_from( + signing_cert + .tbs_certificate + .subject_public_key_info + .owned_to_ref(), + ) { + Ok(key) => key, + Err(_) => return false, + }; + + let signature = + match ecdsa::Signature::from_der(si.signature.as_bytes()) { + Ok(signature) => signature, + Err(_) => return false, + }; + + key.verify_prehash(attrs_digest.as_slice(), &signature).is_ok() + } + _ => unimplemented!(), + } + /* match si.signature_algorithm.oid { rfc5912::RSA_ENCRYPTION => { // Get the public key contained in the certificate that signed the data. @@ -949,8 +1064,64 @@ fn verify_signed_data_impl( .is_ok() } rfc5912::ID_EC_PUBLIC_KEY => { - // TODO: the hashing algorithm is not always SHA-384 - let key = match p384::ecdsa::VerifyingKey::try_from( + println!("digest algo: {:?}", si.digest_alg.oid); + println!( + "cert subject public algo: {:?}", + signing_cert + .tbs_certificate + .subject_public_key_info + .algorithm + .oid + ); + + match signing_cert.tbs_certificate.signature.oid { + rfc5912::ECDSA_WITH_SHA_256 => { + let key = match p256::ecdsa::VerifyingKey::try_from( + signing_cert + .tbs_certificate + .subject_public_key_info + .owned_to_ref(), + ) { + Ok(key) => key, + Err(_) => return false, + }; + + let signature = match ecdsa::Signature::from_der( + si.signature.as_bytes(), + ) { + Ok(signature) => signature, + Err(_) => return false, + }; + + key.verify_prehash(attrs_digest.as_slice(), &signature) + .is_ok() + } + rfc5912::ECDSA_WITH_SHA_384 => { + let key = match p384::ecdsa::VerifyingKey::try_from( + signing_cert + .tbs_certificate + .subject_public_key_info + .owned_to_ref(), + ) { + Ok(key) => key, + Err(_) => return false, + }; + + let signature = match ecdsa::Signature::from_der( + si.signature.as_bytes(), + ) { + Ok(signature) => signature, + Err(_) => return false, + }; + + key.verify_prehash(attrs_digest.as_slice(), &signature) + .is_ok() + } + _ => unimplemented!(), + } + } + rfc5912::ECDSA_WITH_SHA_256 => { + let key = match p256::ecdsa::VerifyingKey::try_from( signing_cert .tbs_certificate .subject_public_key_info @@ -970,6 +1141,7 @@ fn verify_signed_data_impl( } oid => unimplemented!("{:?}", oid), } + */ } /// Returns a short name from an OID. @@ -1040,68 +1212,6 @@ impl DerDigest { } } -/* -impl OutputSizeUser for DerDigest { - type OutputSize = T::OutputSize; -} - -impl Digest for DerDigest { - fn new() -> Self { - Self(T::new()) - } - - fn new_with_prefix(data: impl AsRef<[u8]>) -> Self { - Self(T::new_with_prefix(data)) - } - - fn update(&mut self, data: impl AsRef<[u8]>) { - Digest::update(&mut self.0, data) - } - - fn chain_update(self, data: impl AsRef<[u8]>) -> Self { - Self(self.0.chain_update(data)) - } - - fn finalize(self) -> Output { - self.0.finalize() - } - - fn finalize_into(self, out: &mut Output) { - Digest::finalize_into(self.0, out) - } - - fn finalize_reset(&mut self) -> Output - where - Self: FixedOutputReset, - { - Digest::finalize_reset(&mut self.0); - GenericArray - } - - fn finalize_into_reset(&mut self, out: &mut Output) - where - Self: FixedOutputReset, - { - Digest::finalize_into_reset(&mut self.0, out) - } - - fn reset(&mut self) - where - Self: Reset, - { - Digest::reset(&mut self.0) - } - - fn output_size() -> usize { - ::output_size() - } - - fn digest(data: impl AsRef<[u8]>) -> Output { - T::digest(data) - } -} -*/ - impl der::Writer for DerDigest { fn write(&mut self, slice: &[u8]) -> der::Result<()> { self.0.update(slice); diff --git a/lib/src/modules/pe/tests/testdata/2e9c671b8a0411f2b397544b368c44d7f095eb395779de0ad1ac946914dfa34c.out b/lib/src/modules/pe/tests/testdata/2e9c671b8a0411f2b397544b368c44d7f095eb395779de0ad1ac946914dfa34c.out index c7871f989..193e911b0 100644 --- a/lib/src/modules/pe/tests/testdata/2e9c671b8a0411f2b397544b368c44d7f095eb395779de0ad1ac946914dfa34c.out +++ b/lib/src/modules/pe/tests/testdata/2e9c671b8a0411f2b397544b368c44d7f095eb395779de0ad1ac946914dfa34c.out @@ -647,7 +647,7 @@ signatures: not_before: 1452556800 # 2016-01-12 00:00:00 UTC not_after: 1807487999 # 2027-04-11 23:59:59 UTC countersignatures: - - verified: false + - verified: true sign_time: 1474471604 # 2016-09-21 15:26:44 UTC digest: "e879962bab47112346d0be7e25ed1d8251a89594ee22ab16ddeed0faeb6c0de0" digest_alg: "sha256" diff --git a/lib/src/modules/pe/tests/testdata/6d3bbd6f3b6e11d83526c08e3ccdf0663afed2728226ad5ec6707d4dd7d2e64e.in.zip b/lib/src/modules/pe/tests/testdata/6d3bbd6f3b6e11d83526c08e3ccdf0663afed2728226ad5ec6707d4dd7d2e64e.in.zip new file mode 100644 index 0000000000000000000000000000000000000000..e228e5ba36ea8a375ae3b764e3de2f0d3e8ceae3 GIT binary patch literal 15473 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 WiUJDif3HG-pFiN&ad<@mfd2)X`A>iV literal 0 HcmV?d00001 diff --git a/lib/src/modules/pe/tests/testdata/6d3bbd6f3b6e11d83526c08e3ccdf0663afed2728226ad5ec6707d4dd7d2e64e.out b/lib/src/modules/pe/tests/testdata/6d3bbd6f3b6e11d83526c08e3ccdf0663afed2728226ad5ec6707d4dd7d2e64e.out new file mode 100644 index 000000000..a00a07125 --- /dev/null +++ b/lib/src/modules/pe/tests/testdata/6d3bbd6f3b6e11d83526c08e3ccdf0663afed2728226ad5ec6707d4dd7d2e64e.out @@ -0,0 +1,299 @@ +is_pe: true +machine: MACHINE_AMD64 +subsystem: SUBSYSTEM_WINDOWS_GUI +os_version: + major: 4 + minor: 0 +subsystem_version: + major: 6 + minor: 0 +image_version: + major: 0 + minor: 0 +linker_version: + major: 48 + minor: 0 +opthdr_magic: IMAGE_NT_OPTIONAL_HDR64_MAGIC +characteristics: 34 +dll_characteristics: 34144 +timestamp: 1712829193 # 2024-04-11 09:53:13 UTC +image_base: 5368709120 +checksum: 36819 +base_of_code: 8192 +entry_point: 0 +entry_point_raw: 0 +section_alignment: 8192 +file_alignment: 512 +loader_flags: 0 +size_of_optional_header: 240 +size_of_code: 2560 +size_of_initialized_data: 2048 +size_of_uninitialized_data: 0 +size_of_image: 24576 +size_of_headers: 512 +size_of_stack_reserve: 4194304 +size_of_stack_commit: 16384 +size_of_heap_reserve: 1048576 +size_of_heap_commit: 8192 +pointer_to_symbol_table: 0 +win32_version_value: 0 +number_of_symbols: 0 +number_of_rva_and_sizes: 16 +number_of_sections: 2 +number_of_imported_functions: 0 +number_of_delayed_imported_functions: 0 +number_of_resources: 2 +number_of_version_infos: 11 +number_of_imports: 0 +number_of_delayed_imports: 0 +number_of_exports: 0 +number_of_signatures: 1 +version_info: + "Assembly Version": "5.6.0.1" + "Comments": "Continuous Testing Tool for .NET" + "CompanyName": "Remco Software Ltd" + "FileDescription": " " + "FileVersion": "5.6.0.1" + "InternalName": "nCrunch.TaskRunner46.x64.exe" + "LegalCopyright": "© 2010-2024 Remco Software Ltd" + "LegalTrademarks": "" + "OriginalFilename": "nCrunch.TaskRunner46.x64.exe" + "ProductName": "NCrunch" + "ProductVersion": "5.6.0.1" +version_info_list: + - key: "Comments" + value: "Continuous Testing Tool for .NET" + - key: "CompanyName" + value: "Remco Software Ltd" + - key: "FileDescription" + value: " " + - key: "FileVersion" + value: "5.6.0.1" + - key: "InternalName" + value: "nCrunch.TaskRunner46.x64.exe" + - key: "LegalCopyright" + value: "© 2010-2024 Remco Software Ltd" + - key: "LegalTrademarks" + value: "" + - key: "OriginalFilename" + value: "nCrunch.TaskRunner46.x64.exe" + - key: "ProductName" + value: "NCrunch" + - key: "ProductVersion" + value: "5.6.0.1" + - key: "Assembly Version" + value: "5.6.0.1" +pdb_path: "D:\\BuildAgent\\work\\31f27687fbb308be\\nCrunch.TaskRunner\\46.x64\\obj\\x64\\Release\\nCrunch.TaskRunner46.x64.pdb" +sections: + - name: ".text" + full_name: ".text" + characteristics: 1610612768 + raw_data_size: 2560 + raw_data_offset: 512 + virtual_address: 8192 + virtual_size: 2260 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: ".rsrc" + full_name: ".rsrc" + characteristics: 1073741888 + raw_data_size: 2048 + raw_data_offset: 3072 + virtual_address: 16384 + virtual_size: 1624 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 +data_directories: + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 16384 + size: 1624 + - virtual_address: 0 + size: 0 + - virtual_address: 5120 + size: 9064 + - virtual_address: 0 + size: 0 + - virtual_address: 10140 + size: 28 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 8192 + size: 72 + - virtual_address: 0 + size: 0 +resource_timestamp: 0 # 1970-01-01 00:00:00 UTC +resource_version: + major: 0 + minor: 0 +resources: + - length: 968 + rva: 16528 + offset: 3216 + type: RESOURCE_TYPE_VERSION + id: 1 + language: 0 + - length: 490 + rva: 17512 + offset: 4200 + type: RESOURCE_TYPE_MANIFEST + id: 1 + language: 0 +is_signed: true +signatures: + - subject: "/C=NZ/ST=Auckland/O=Remco Software Ltd/CN=Remco Software Ltd" + issuer: "/C=GB/O=Sectigo Limited/CN=Sectigo Public Code Signing CA E36" + thumbprint: "e8fe81981a0fc85d3ce02b09b88d6e6c08dfca5e" + version: 3 + algorithm: "ecdsa-with-SHA256" + algorithm_oid: "1.2.840.10045.4.3.2" + serial: "66:44:c2:5e:50:8b:bf:5f:a1:b1:e4:30:be:02:6a:3d" + not_before: 1683158400 # 2023-05-04 00:00:00 UTC + not_after: 1785801599 # 2026-08-03 23:59:59 UTC + verified: true + digest_alg: "sha1" + digest: "060371e73bbdc18a21434b222a5e4de53bdb7127" + file_digest: "060371e73bbdc18a21434b222a5e4de53bdb7127" + number_of_certificates: 6 + number_of_countersignatures: 1 + signer_info: + program_name: "NCrunch for Visual Studio" + digest: "8bae3e1a555b4f3c0c1e8eb44a9f19d024e95357" + digest_alg: "sha1" + chain: + - issuer: "/C=GB/O=Sectigo Limited/CN=Sectigo Public Code Signing CA E36" + subject: "/C=NZ/ST=Auckland/O=Remco Software Ltd/CN=Remco Software Ltd" + thumbprint: "e8fe81981a0fc85d3ce02b09b88d6e6c08dfca5e" + version: 3 + algorithm: "ecdsa-with-SHA256" + algorithm_oid: "1.2.840.10045.4.3.2" + serial: "66:44:c2:5e:50:8b:bf:5f:a1:b1:e4:30:be:02:6a:3d" + not_before: 1683158400 # 2023-05-04 00:00:00 UTC + not_after: 1785801599 # 2026-08-03 23:59:59 UTC + - issuer: "/C=GB/O=Sectigo Limited/CN=Sectigo Public Code Signing Root E46" + subject: "/C=GB/O=Sectigo Limited/CN=Sectigo Public Code Signing CA E36" + thumbprint: "418293b3ee931f1452bca30e4a587e7124853e86" + version: 3 + algorithm: "ecdsa-with-SHA384" + algorithm_oid: "1.2.840.10045.4.3.3" + serial: "36:02:61:76:36:e7:03:4b:9c:c1:fc:5f:fe:ac:2d:54" + not_before: 1616371200 # 2021-03-22 00:00:00 UTC + not_after: 2089756799 # 2036-03-21 23:59:59 UTC + - issuer: "/C=GB/ST=Greater Manchester/L=Salford/O=Comodo CA Limited/CN=AAA Certificate Services" + subject: "/C=GB/O=Sectigo Limited/CN=Sectigo Public Code Signing Root E46" + thumbprint: "b50cb42cacc0ebe698fe39cbd48b481a5a16851f" + version: 3 + algorithm: "sha384WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.12" + serial: "00:d5:b3:60:02:89:59:a2:7f:84:65:c9:e6:b1:8d:ba:cb" + not_before: 1677542400 # 2023-02-28 00:00:00 UTC + not_after: 1861919999 # 2028-12-31 23:59:59 UTC + certificates: + - issuer: "/C=GB/O=Sectigo Limited/CN=Sectigo Public Code Signing Root E46" + subject: "/C=GB/O=Sectigo Limited/CN=Sectigo Public Code Signing CA E36" + thumbprint: "418293b3ee931f1452bca30e4a587e7124853e86" + version: 3 + algorithm: "ecdsa-with-SHA384" + algorithm_oid: "1.2.840.10045.4.3.3" + serial: "36:02:61:76:36:e7:03:4b:9c:c1:fc:5f:fe:ac:2d:54" + not_before: 1616371200 # 2021-03-22 00:00:00 UTC + not_after: 2089756799 # 2036-03-21 23:59:59 UTC + - issuer: "/C=GB/O=Sectigo Limited/CN=Sectigo Public Code Signing CA E36" + subject: "/C=NZ/ST=Auckland/O=Remco Software Ltd/CN=Remco Software Ltd" + thumbprint: "e8fe81981a0fc85d3ce02b09b88d6e6c08dfca5e" + version: 3 + algorithm: "ecdsa-with-SHA256" + algorithm_oid: "1.2.840.10045.4.3.2" + serial: "66:44:c2:5e:50:8b:bf:5f:a1:b1:e4:30:be:02:6a:3d" + not_before: 1683158400 # 2023-05-04 00:00:00 UTC + not_after: 1785801599 # 2026-08-03 23:59:59 UTC + - issuer: "/C=GB/ST=Greater Manchester/L=Salford/O=Comodo CA Limited/CN=AAA Certificate Services" + subject: "/C=GB/O=Sectigo Limited/CN=Sectigo Public Code Signing Root E46" + thumbprint: "b50cb42cacc0ebe698fe39cbd48b481a5a16851f" + version: 3 + algorithm: "sha384WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.12" + serial: "00:d5:b3:60:02:89:59:a2:7f:84:65:c9:e6:b1:8d:ba:cb" + not_before: 1677542400 # 2023-02-28 00:00:00 UTC + not_after: 1861919999 # 2028-12-31 23:59:59 UTC + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA" + subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Trusted Root G4" + thumbprint: "a99d5b79e9f1cda59cdab6373169d5353f5874c6" + version: 3 + algorithm: "sha384WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.12" + serial: "0e:9b:18:8e:f9:d0:2d:e7:ef:db:50:e2:08:40:18:5a" + not_before: 1659312000 # 2022-08-01 00:00:00 UTC + not_after: 1952035199 # 2031-11-09 23:59:59 UTC + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Trusted Root G4" + subject: "/C=US/O=DigiCert, Inc./CN=DigiCert Trusted G4 RSA4096 SHA256 TimeStamping CA" + thumbprint: "b6c8af834d4e53b673c76872aa8c950c7c54df5f" + version: 3 + algorithm: "sha256WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.11" + serial: "07:36:37:b7:24:54:7c:d8:47:ac:fd:28:66:2a:5e:5b" + not_before: 1647993600 # 2022-03-23 00:00:00 UTC + not_after: 2121379199 # 2037-03-22 23:59:59 UTC + - issuer: "/C=US/O=DigiCert, Inc./CN=DigiCert Trusted G4 RSA4096 SHA256 TimeStamping CA" + subject: "/C=US/O=DigiCert, Inc./CN=DigiCert Timestamp 2023" + thumbprint: "66f02b32c2c2c90f825dceaa8ac9c64f199ccf40" + version: 3 + algorithm: "sha256WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.11" + serial: "05:44:af:f3:94:9d:08:39:a6:bf:db:3f:5f:e5:61:16" + not_before: 1689292800 # 2023-07-14 00:00:00 UTC + not_after: 2044396799 # 2034-10-13 23:59:59 UTC + countersignatures: + - verified: true + sign_time: 1712829194 # 2024-04-11 09:53:14 UTC + digest: "5dd8b869f1aacca4797503e081f18b033049faf1" + digest_alg: "sha1" + chain: + - issuer: "/C=US/O=DigiCert, Inc./CN=DigiCert Trusted G4 RSA4096 SHA256 TimeStamping CA" + subject: "/C=US/O=DigiCert, Inc./CN=DigiCert Timestamp 2023" + thumbprint: "66f02b32c2c2c90f825dceaa8ac9c64f199ccf40" + version: 3 + algorithm: "sha256WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.11" + serial: "05:44:af:f3:94:9d:08:39:a6:bf:db:3f:5f:e5:61:16" + not_before: 1689292800 # 2023-07-14 00:00:00 UTC + not_after: 2044396799 # 2034-10-13 23:59:59 UTC + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Trusted Root G4" + subject: "/C=US/O=DigiCert, Inc./CN=DigiCert Trusted G4 RSA4096 SHA256 TimeStamping CA" + thumbprint: "b6c8af834d4e53b673c76872aa8c950c7c54df5f" + version: 3 + algorithm: "sha256WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.11" + serial: "07:36:37:b7:24:54:7c:d8:47:ac:fd:28:66:2a:5e:5b" + not_before: 1647993600 # 2022-03-23 00:00:00 UTC + not_after: 2121379199 # 2037-03-22 23:59:59 UTC + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA" + subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Trusted Root G4" + thumbprint: "a99d5b79e9f1cda59cdab6373169d5353f5874c6" + version: 3 + algorithm: "sha384WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.12" + serial: "0e:9b:18:8e:f9:d0:2d:e7:ef:db:50:e2:08:40:18:5a" + not_before: 1659312000 # 2022-08-01 00:00:00 UTC + not_after: 1952035199 # 2031-11-09 23:59:59 UTC +overlay: + offset: 5120 + size: 9064 \ No newline at end of file From 2170056a7e4bb3e1b4bb8129f817d6bb61287753 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Thu, 18 Apr 2024 20:52:44 +0200 Subject: [PATCH 13/38] fix: issue in `hash` module. --- lib/src/modules/hash/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/modules/hash/mod.rs b/lib/src/modules/hash/mod.rs index 88aaecfed..6c21b0a6b 100644 --- a/lib/src/modules/hash/mod.rs +++ b/lib/src/modules/hash/mod.rs @@ -59,7 +59,7 @@ fn md5_data( let range = offset.try_into().ok()?..(offset + size).try_into().ok()?; let data = ctx.scanned_data().get(range)?; - let mut hasher = Sha1::new(); + let mut hasher = Md5::new(); hasher.update(data); From ad46cfa756025594c02514f602eb39f8d587067a Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Fri, 19 Apr 2024 10:29:44 +0200 Subject: [PATCH 14/38] fix: some verification issues. --- lib/src/modules/pe/authenticode.rs | 330 +++++++----------- ...606d0de3cfa34938eb76a1412c49a9082962ee.out | 2 +- 2 files changed, 118 insertions(+), 214 deletions(-) diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index a81b04a07..75746d410 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -27,7 +27,7 @@ use rsa::Pkcs1v15Sign; use sha1::digest::Output; use sha1::Sha1; use sha2::{Sha256, Sha384}; -use x509_cert::spki::AlgorithmIdentifierOwned; +use x509_cert::spki::{AlgorithmIdentifierOwned, SubjectPublicKeyInfoRef}; use x509_tsp::TstInfo; use x509_verify::{Signature, VerifyInfo, VerifyingKey}; @@ -388,13 +388,12 @@ impl AuthenticodeParser { None => continue, }; - countersignature.digest_alg = - oid_to_algorithm_name( - &tst_info - .message_imprint - .hash_algorithm - .oid, - ); + countersignature.digest_alg = oid_to_str( + &tst_info + .message_imprint + .hash_algorithm + .oid, + ); countersignature.digest = Some(bytes2hex( "", @@ -417,7 +416,6 @@ impl AuthenticodeParser { ) && verify_signer_info( cs, certificates.as_slice(), - false, ); countersignatures.push(countersignature); @@ -446,7 +444,6 @@ impl AuthenticodeParser { ) && verify_signer_info( cs, certificates.as_slice(), - true, ); countersignatures.push(countersignature); @@ -533,7 +530,7 @@ impl AuthenticodeParser { AuthenticodeCountersign { signer: signer.clone(), - digest_alg: oid_to_algorithm_name(&cs.digest_alg.oid), + digest_alg: oid_to_str(&cs.digest_alg.oid), digest, signing_time, verified: false, @@ -586,9 +583,7 @@ impl AuthenticodeSignature { /// Get the name of the Authenticode hash algorithm. pub fn authenticode_hash_algorithm(&self) -> &'static str { - oid_to_algorithm_name( - &self.indirect_data.message_digest.digest_algorithm.oid, - ) + oid_to_str(&self.indirect_data.message_digest.digest_algorithm.oid) } /// Get the [`SignerInfo`] struct. @@ -601,7 +596,7 @@ impl AuthenticodeSignature { #[inline] pub fn signer_info_digest_alg(&self) -> String { - oid_to_algorithm_name(&self.signer_info().digest_alg.oid).to_string() + oid_to_str(&self.signer_info().digest_alg.oid).to_string() } #[inline] @@ -689,7 +684,7 @@ impl AuthenticodeSignature { return false; } - verify_signer_info(self.signer_info(), self.certificates(), false) + verify_signer_info(self.signer_info(), self.certificates()) } } @@ -793,7 +788,7 @@ impl From<&Certificate> for protos::pe::Certificate { cert.set_algorithm_oid(format!("{}", value.signature_algorithm.oid)); cert.set_algorithm( - oid_to_algorithm_name(&value.signature_algorithm.oid).to_string(), + oid_to_str(&value.signature_algorithm.oid).to_string(), ); // The certificate thumbprint is the SHA1 of the DER-encoded certificate. @@ -916,24 +911,12 @@ fn verify_message_digest( } } -fn verify_signer_info( - si: &SignerInfo, - certs: &[Certificate], - unprefixed: bool, -) -> bool { +fn verify_signer_info(si: &SignerInfo, certs: &[Certificate]) -> bool { match si.digest_alg.oid { - rfc5912::ID_SHA_1 => { - verify_signed_data_impl::(si, certs, unprefixed) - } - rfc5912::ID_SHA_256 => { - verify_signed_data_impl::(si, certs, unprefixed) - } - rfc5912::ID_SHA_384 => { - verify_signed_data_impl::(si, certs, unprefixed) - } - rfc5912::ID_MD_5 => { - verify_signed_data_impl::(si, certs, unprefixed) - } + rfc5912::ID_SHA_1 => verify_signed_data_impl::(si, certs), + rfc5912::ID_SHA_256 => verify_signed_data_impl::(si, certs), + rfc5912::ID_SHA_384 => verify_signed_data_impl::(si, certs), + rfc5912::ID_MD_5 => verify_signed_data_impl::(si, certs), oid => unimplemented!("{:?}", oid), } } @@ -941,7 +924,6 @@ fn verify_signer_info( fn verify_signed_data_impl( si: &SignerInfo, certs: &[Certificate], - unprefixed: bool, ) -> bool { // Find the certificate that signed the data in `content`. let signing_cert_sn = @@ -962,6 +944,13 @@ fn verify_signed_data_impl( return false; } + // Compute the digest for the DER encoding of the signed attributes, this + // digest is signed, and its signature is in SignerInfo.signature. + let mut attrs_digest = DerDigest::::default(); + si.signed_attrs.encode(&mut attrs_digest).unwrap(); + let attrs_digest = attrs_digest.finalize(); + + // Search for the certificate that signed the digest. let signing_cert = match certs .iter() .find(|cert| cert.tbs_certificate.serial_number.eq(signing_cert_sn)) @@ -970,178 +959,16 @@ fn verify_signed_data_impl( None => return false, }; - let mut attrs_digest = DerDigest::::default(); - si.signed_attrs.encode(&mut attrs_digest).unwrap(); - let attrs_digest = attrs_digest.finalize(); - - match signing_cert.tbs_certificate.signature.oid { - rfc5912::MD_5_WITH_RSA_ENCRYPTION - | rfc5912::SHA_1_WITH_RSA_ENCRYPTION - | rfc5912::SHA_256_WITH_RSA_ENCRYPTION - | rfc5912::SHA_384_WITH_RSA_ENCRYPTION => { - let key = match rsa::RsaPublicKey::try_from( - signing_cert - .tbs_certificate - .subject_public_key_info - .owned_to_ref(), - ) { - Ok(key) => key, - Err(_) => return false, - }; - - let signature = if unprefixed { - Pkcs1v15Sign::new_unprefixed() - } else { - Pkcs1v15Sign::new::() - }; - - signature - .verify(&key, attrs_digest.as_slice(), si.signature.as_bytes()) - .is_ok() - } - rfc5912::ECDSA_WITH_SHA_256 => { - let key = match p256::ecdsa::VerifyingKey::try_from( - signing_cert - .tbs_certificate - .subject_public_key_info - .owned_to_ref(), - ) { - Ok(key) => key, - Err(_) => return false, - }; - - let signature = - match ecdsa::Signature::from_der(si.signature.as_bytes()) { - Ok(signature) => signature, - Err(_) => return false, - }; - - key.verify_prehash(attrs_digest.as_slice(), &signature).is_ok() - } - rfc5912::ECDSA_WITH_SHA_384 => { - let key = match p384::ecdsa::VerifyingKey::try_from( - signing_cert - .tbs_certificate - .subject_public_key_info - .owned_to_ref(), - ) { - Ok(key) => key, - Err(_) => return false, - }; - - let signature = - match ecdsa::Signature::from_der(si.signature.as_bytes()) { - Ok(signature) => signature, - Err(_) => return false, - }; - - key.verify_prehash(attrs_digest.as_slice(), &signature).is_ok() - } - _ => unimplemented!(), - } - /* - match si.signature_algorithm.oid { - rfc5912::RSA_ENCRYPTION => { - // Get the public key contained in the certificate that signed the data. - let key = match rsa::RsaPublicKey::try_from( - signing_cert - .tbs_certificate - .subject_public_key_info - .owned_to_ref(), - ) { - Ok(key) => key, - Err(_) => return false, - }; - - let signature = if unprefixed { - Pkcs1v15Sign::new_unprefixed() - } else { - Pkcs1v15Sign::new::() - }; - - signature - .verify(&key, attrs_digest.as_slice(), si.signature.as_bytes()) - .is_ok() - } - rfc5912::ID_EC_PUBLIC_KEY => { - println!("digest algo: {:?}", si.digest_alg.oid); - println!( - "cert subject public algo: {:?}", - signing_cert - .tbs_certificate - .subject_public_key_info - .algorithm - .oid - ); - - match signing_cert.tbs_certificate.signature.oid { - rfc5912::ECDSA_WITH_SHA_256 => { - let key = match p256::ecdsa::VerifyingKey::try_from( - signing_cert - .tbs_certificate - .subject_public_key_info - .owned_to_ref(), - ) { - Ok(key) => key, - Err(_) => return false, - }; - - let signature = match ecdsa::Signature::from_der( - si.signature.as_bytes(), - ) { - Ok(signature) => signature, - Err(_) => return false, - }; - - key.verify_prehash(attrs_digest.as_slice(), &signature) - .is_ok() - } - rfc5912::ECDSA_WITH_SHA_384 => { - let key = match p384::ecdsa::VerifyingKey::try_from( - signing_cert - .tbs_certificate - .subject_public_key_info - .owned_to_ref(), - ) { - Ok(key) => key, - Err(_) => return false, - }; - - let signature = match ecdsa::Signature::from_der( - si.signature.as_bytes(), - ) { - Ok(signature) => signature, - Err(_) => return false, - }; - - key.verify_prehash(attrs_digest.as_slice(), &signature) - .is_ok() - } - _ => unimplemented!(), - } - } - rfc5912::ECDSA_WITH_SHA_256 => { - let key = match p256::ecdsa::VerifyingKey::try_from( - signing_cert - .tbs_certificate - .subject_public_key_info - .owned_to_ref(), - ) { - Ok(key) => key, - Err(_) => return false, - }; - - let signature = - match ecdsa::Signature::from_der(si.signature.as_bytes()) { - Ok(signature) => signature, - Err(_) => return false, - }; + // Obtain the public key included in the certificate. + let key = match PublicKey::try_from( + signing_cert.tbs_certificate.subject_public_key_info.owned_to_ref(), + ) { + Ok(key) => key, + Err(_) => return false, + }; - key.verify_prehash(attrs_digest.as_slice(), &signature).is_ok() - } - oid => unimplemented!("{:?}", oid), - } - */ + // Verify that the signature in SignerInfo.signature is correct. + key.verify::(attrs_digest.as_slice(), si.signature.as_bytes()) } /// Returns a short name from an OID. @@ -1180,14 +1007,12 @@ fn format_serial_number( result } -/// Given an OID that represents an algorithm name, returns a string -/// that identifies the algorithm. +/// Given an OID returns a string that describes it. /// /// # Panics /// -/// If the OID doesn't correspond to some of the supported algorithm -/// names. -fn oid_to_algorithm_name(oid: &ObjectIdentifier) -> &'static str { +/// If the OID is unknown. +fn oid_to_str(oid: &ObjectIdentifier) -> &'static str { match oid { &rfc5912::ID_SHA_1 => "sha1", &rfc5912::ID_SHA_256 => "sha256", @@ -1201,8 +1026,7 @@ fn oid_to_algorithm_name(oid: &ObjectIdentifier) -> &'static str { } } -/// A wrapper that implements the [`der::Writer`] trait for a -/// [`Digest`]. +/// A wrapper that implements the [`der::Writer`] trait for a [`Digest`]. #[derive(Default)] struct DerDigest(T); @@ -1219,12 +1043,25 @@ impl der::Writer for DerDigest { } } +/// Represents a certificate chain. +/// +/// A certificate chain starts with an initial certificate, and contains the +/// certificate that signed the initial certificate, the certificate that +/// signed the signer, and so on, until finding a self-signed certificate, or +/// a certificate that is signed by some external certificate that is not +/// contained in the PE file. struct CertificateChain<'a> { certs: &'a [Certificate], next: Option<&'a Certificate>, } impl<'a> CertificateChain<'a> { + /// Creates a new certificate chain. + /// + /// This function receives a pool of certificates in the `certs` arguments, + /// and a `predicate` that identifies the initial certificate in the chain. + /// The initial certificate will be the first certificate in the pool that + /// matches the predicate. pub fn new

(certs: &'a [Certificate], predicate: P) -> Self where P: Fn(&Certificate) -> bool, @@ -1298,3 +1135,70 @@ impl<'a> Iterator for CertificateChain<'a> { next } } + +/// Represents public key found in certificate. +enum PublicKey { + Rsa(rsa::RsaPublicKey), + EcdsaP256(p256::ecdsa::VerifyingKey), + EcdsaP384(p384::ecdsa::VerifyingKey), +} + +impl TryFrom> for PublicKey { + type Error = spki::Error; + + fn try_from(value: SubjectPublicKeyInfoRef) -> Result { + match value.algorithm.oid { + rfc5912::RSA_ENCRYPTION => { + Ok(Self::Rsa(rsa::RsaPublicKey::try_from(value)?)) + } + rfc5912::ID_EC_PUBLIC_KEY => { + match value + .algorithm + .parameters + .ok_or(Self::Error::AlgorithmParametersMissing)? + .decode_as::() + .map_err(Self::Error::Asn1)? + { + rfc5912::SECP_256_R_1 => Ok(Self::EcdsaP256( + p256::ecdsa::VerifyingKey::try_from(value)?, + )), + rfc5912::SECP_384_R_1 => Ok(Self::EcdsaP384( + p384::ecdsa::VerifyingKey::try_from(value)?, + )), + oid => unimplemented!("{:?}", oid), + } + } + oid => unimplemented!("{:?}", oid), + } + } +} + +impl PublicKey { + fn verify( + &self, + hashed: &[u8], + signature: &[u8], + ) -> bool { + match self { + PublicKey::Rsa(key) => { + if Pkcs1v15Sign::new::() + .verify(key, hashed, signature) + .is_ok() + { + return true; + } + Pkcs1v15Sign::new_unprefixed() + .verify(key, hashed, signature) + .is_ok() + } + PublicKey::EcdsaP256(key) => ecdsa::Signature::from_der(signature) + .is_ok_and(|signature| { + key.verify_prehash(hashed, &signature).is_ok() + }), + PublicKey::EcdsaP384(key) => ecdsa::Signature::from_der(signature) + .is_ok_and(|signature| { + key.verify_prehash(hashed, &signature).is_ok() + }), + } + } +} diff --git a/lib/src/modules/pe/tests/testdata/616095160dd4b1556848907729606d0de3cfa34938eb76a1412c49a9082962ee.out b/lib/src/modules/pe/tests/testdata/616095160dd4b1556848907729606d0de3cfa34938eb76a1412c49a9082962ee.out index ee8dcfdd7..eb099acfd 100644 --- a/lib/src/modules/pe/tests/testdata/616095160dd4b1556848907729606d0de3cfa34938eb76a1412c49a9082962ee.out +++ b/lib/src/modules/pe/tests/testdata/616095160dd4b1556848907729606d0de3cfa34938eb76a1412c49a9082962ee.out @@ -489,7 +489,7 @@ signatures: not_before: 1573671005 # 2019-11-13 18:50:05 UTC not_after: 2046970205 # 2034-11-12 18:50:05 UTC countersignatures: - - verified: false + - verified: true sign_time: 1708954610 # 2024-02-26 13:36:50 UTC digest: "ebbcb9430ee128c3126285d91988aa775cc579091e3fbbd07290d93cd42f6623" digest_alg: "sha256" From be6fad17ffac4db7c1803bbcaf9b0ce9a8c56635 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Fri, 19 Apr 2024 11:00:15 +0200 Subject: [PATCH 15/38] fix: issues while generating subject and issuer names --- lib/src/modules/pe/authenticode.rs | 44 +++++++++---------- ...606d0de3cfa34938eb76a1412c49a9082962ee.out | 6 +-- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 75746d410..bbdf51e9e 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -10,7 +10,7 @@ use cms::content_info::ContentInfo; use cms::signed_data::{ CertificateSet, SignedData, SignerIdentifier, SignerInfo, }; -use const_oid::db::{rfc5911, rfc5912, rfc6268, DB}; +use const_oid::db::{rfc4519, rfc5911, rfc5912, rfc6268, DB}; use const_oid::{AssociatedOid, ObjectIdentifier}; use der::asn1; use der::asn1::OctetString; @@ -47,6 +47,15 @@ pub const SPC_MS_NESTED_SIGNATURE: ObjectIdentifier = pub const SPC_MS_COUNTERSIGN: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.3.3.1"); +pub const JURISDICTION_L: ObjectIdentifier = + ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.60.2.1.1"); + +pub const JURISDICTION_ST: ObjectIdentifier = + ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.60.2.1.2"); + +pub const JURISDICTION_C: ObjectIdentifier = + ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.60.2.1.3"); + /// ASN.1 SpcIndirectDataContent /// /// SpcIndirectDataContent ::= SEQUENCE { @@ -864,10 +873,8 @@ fn format_name(name: &x509_cert::name::Name) -> String { _ => None, }; - if let (Some(key), Some(val)) = - (shortest_name_by_oid(&atv.oid), val) - { - write!(n, "{}=", key.to_ascii_uppercase()).unwrap(); + if let (key, Some(val)) = (oid_to_str(&atv.oid), val) { + write!(n, "{}=", key).unwrap(); for char in val.chars() { n.write_char(char).unwrap(); } @@ -971,24 +978,6 @@ fn verify_signed_data_impl( key.verify::(attrs_digest.as_slice(), si.signature.as_bytes()) } -/// Returns a short name from an OID. -/// -/// This returns the strings like "C", "CN", "O", "OU", "ST", etc. This strings -/// represents field names in issuer and subject strings. -fn shortest_name_by_oid(oid: &ObjectIdentifier) -> Option<&str> { - let mut best_match: Option<&str> = None; - for m in DB.find_names_for_oid(*oid) { - if let Some(previous) = best_match { - if m.len() < previous.len() { - best_match = Some(m); - } - } else { - best_match = Some(m); - } - } - best_match -} - /// Produces a printable string of a serial number. /// /// The [`x509_cert::serial_number::SerialNumber`] type implements the @@ -1018,6 +1007,15 @@ fn oid_to_str(oid: &ObjectIdentifier) -> &'static str { &rfc5912::ID_SHA_256 => "sha256", &rfc5912::ID_SHA_384 => "sha384", &rfc5912::ID_MD_5 => "md5", + // OIDs related to issuer and subject names. + &JURISDICTION_C => "jurisdictionC", + &JURISDICTION_L => "jurisdictionL", + &JURISDICTION_ST => "jurisdictionST", + &rfc4519::C => "C", + &rfc4519::COMMON_NAME => "CN", + &rfc4519::O => "O", + &rfc4519::OU => "OU", + &rfc4519::ST => "ST", // In the default case try to use the string representation provided by // the `const-oid` crate. Panics if this fails. oid => { diff --git a/lib/src/modules/pe/tests/testdata/616095160dd4b1556848907729606d0de3cfa34938eb76a1412c49a9082962ee.out b/lib/src/modules/pe/tests/testdata/616095160dd4b1556848907729606d0de3cfa34938eb76a1412c49a9082962ee.out index eb099acfd..224768071 100644 --- a/lib/src/modules/pe/tests/testdata/616095160dd4b1556848907729606d0de3cfa34938eb76a1412c49a9082962ee.out +++ b/lib/src/modules/pe/tests/testdata/616095160dd4b1556848907729606d0de3cfa34938eb76a1412c49a9082962ee.out @@ -414,7 +414,7 @@ import_details: rva: 70312 is_signed: true signatures: - - subject: "/C=DE/ST=Bayern/L=Geretsried/O=Quality First Software GmbH/SERIALNUMBER=HRB 140833/CN=Quality First Software GmbH/BUSINESSCATEGORY=Private Organization/1.3.6.1.4.1.311.60.2.1.1=#0c084dc3bc6e6368656e/1.3.6.1.4.1.311.60.2.1.2=#0c0642617965726e/1.3.6.1.4.1.311.60.2.1.3=#13024445" + - subject: "/C=DE/ST=Bayern/L=Geretsried/O=Quality First Software GmbH/serialNumber=HRB 140833/CN=Quality First Software GmbH/businessCategory=Private Organization/jurisdictionL=München/jurisdictionST=Bayern/jurisdictionC=DE" issuer: "/C=US/ST=Texas/L=Houston/O=SSL Corp/CN=SSL.com EV Code Signing Intermediate CA ECC R2" thumbprint: "6a63f4e957aa5867f33916e8f57019c2b9987478" version: 3 @@ -434,7 +434,7 @@ signatures: digest_alg: "sha384" chain: - issuer: "/C=US/ST=Texas/L=Houston/O=SSL Corp/CN=SSL.com EV Code Signing Intermediate CA ECC R2" - subject: "/C=DE/ST=Bayern/L=Geretsried/O=Quality First Software GmbH/SERIALNUMBER=HRB 140833/CN=Quality First Software GmbH/BUSINESSCATEGORY=Private Organization/1.3.6.1.4.1.311.60.2.1.1=#0c084dc3bc6e6368656e/1.3.6.1.4.1.311.60.2.1.2=#0c0642617965726e/1.3.6.1.4.1.311.60.2.1.3=#13024445" + subject: "/C=DE/ST=Bayern/L=Geretsried/O=Quality First Software GmbH/serialNumber=HRB 140833/CN=Quality First Software GmbH/businessCategory=Private Organization/jurisdictionL=München/jurisdictionST=Bayern/jurisdictionC=DE" thumbprint: "6a63f4e957aa5867f33916e8f57019c2b9987478" version: 3 algorithm: "ecdsa-with-SHA384" @@ -462,7 +462,7 @@ signatures: not_before: 1551987465 # 2019-03-07 19:37:45 UTC not_after: 2025027465 # 2034-03-03 19:37:45 UTC - issuer: "/C=US/ST=Texas/L=Houston/O=SSL Corp/CN=SSL.com EV Code Signing Intermediate CA ECC R2" - subject: "/C=DE/ST=Bayern/L=Geretsried/O=Quality First Software GmbH/SERIALNUMBER=HRB 140833/CN=Quality First Software GmbH/BUSINESSCATEGORY=Private Organization/1.3.6.1.4.1.311.60.2.1.1=#0c084dc3bc6e6368656e/1.3.6.1.4.1.311.60.2.1.2=#0c0642617965726e/1.3.6.1.4.1.311.60.2.1.3=#13024445" + subject: "/C=DE/ST=Bayern/L=Geretsried/O=Quality First Software GmbH/serialNumber=HRB 140833/CN=Quality First Software GmbH/businessCategory=Private Organization/jurisdictionL=München/jurisdictionST=Bayern/jurisdictionC=DE" thumbprint: "6a63f4e957aa5867f33916e8f57019c2b9987478" version: 3 algorithm: "ecdsa-with-SHA384" From 390f61a002ef310e1d21268555fc1ee887598f93 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Fri, 19 Apr 2024 11:39:10 +0200 Subject: [PATCH 16/38] feat: add support for DSA signatures --- Cargo.lock | 1 + Cargo.toml | 1 + lib/Cargo.toml | 2 ++ lib/src/modules/pe/authenticode.rs | 28 +++++++++++++++------------- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5d654934c..b0d8346a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4755,6 +4755,7 @@ dependencies = [ "crc32fast", "der", "digest 0.10.7", + "dsa", "ecdsa", "fmmap", "globwalk", diff --git a/Cargo.toml b/Cargo.toml index aa9d7789f..afb7efb74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,7 @@ const-oid = "0.9.6" crc32fast = "1.4.0" der = "0.7.9" digest = "0.10.7" +dsa = "0.6.3" ecdsa = "0.16.9" enable-ansi-support = "0.2.1" env_logger = "0.11.3" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 7cff819a2..02850b0ed 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -106,6 +106,7 @@ pe-module = [ "dep:cms", "dep:const-oid", "dep:digest", + "dep:dsa", "dep:ecdsa", "dep:nom", "dep:rsa", @@ -172,6 +173,7 @@ const-oid = { workspace = true, optional = true } crc32fast = { workspace = true, optional = true } der = { workspace = true, features = ["derive"] } digest = { workspace = true, optional = true } +dsa = { workspace = true, optional = true } ecdsa = { workspace = true, optional = true } fmmap = { workspace = true } indexmap = { workspace = true, features = ["serde"] } diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index bbdf51e9e..b8923c6a1 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -29,7 +29,7 @@ use sha1::Sha1; use sha2::{Sha256, Sha384}; use x509_cert::spki::{AlgorithmIdentifierOwned, SubjectPublicKeyInfoRef}; use x509_tsp::TstInfo; -use x509_verify::{Signature, VerifyInfo, VerifyingKey}; +use x509_verify::{VerifyInfo, VerifyingKey}; use crate::modules::protos; @@ -1087,7 +1087,7 @@ impl<'a> CertificateChain<'a> { // The `signed` certificate is the one that will be verified. let verify_info = VerifyInfo::new( signed.tbs_certificate.to_der().unwrap().into(), - Signature::new( + x509_verify::Signature::new( &signed.signature_algorithm, signed.signature.as_bytes().unwrap(), ), @@ -1137,6 +1137,7 @@ impl<'a> Iterator for CertificateChain<'a> { /// Represents public key found in certificate. enum PublicKey { Rsa(rsa::RsaPublicKey), + Dsa(dsa::VerifyingKey), EcdsaP256(p256::ecdsa::VerifyingKey), EcdsaP384(p384::ecdsa::VerifyingKey), } @@ -1149,6 +1150,9 @@ impl TryFrom> for PublicKey { rfc5912::RSA_ENCRYPTION => { Ok(Self::Rsa(rsa::RsaPublicKey::try_from(value)?)) } + rfc5912::ID_DSA => { + Ok(Self::Dsa(dsa::VerifyingKey::try_from(value)?)) + } rfc5912::ID_EC_PUBLIC_KEY => { match value .algorithm @@ -1163,10 +1167,10 @@ impl TryFrom> for PublicKey { rfc5912::SECP_384_R_1 => Ok(Self::EcdsaP384( p384::ecdsa::VerifyingKey::try_from(value)?, )), - oid => unimplemented!("{:?}", oid), + oid => Err(Self::Error::OidUnknown { oid }), } } - oid => unimplemented!("{:?}", oid), + oid => Err(Self::Error::OidUnknown { oid }), } } } @@ -1178,7 +1182,7 @@ impl PublicKey { signature: &[u8], ) -> bool { match self { - PublicKey::Rsa(key) => { + Self::Rsa(key) => { if Pkcs1v15Sign::new::() .verify(key, hashed, signature) .is_ok() @@ -1189,14 +1193,12 @@ impl PublicKey { .verify(key, hashed, signature) .is_ok() } - PublicKey::EcdsaP256(key) => ecdsa::Signature::from_der(signature) - .is_ok_and(|signature| { - key.verify_prehash(hashed, &signature).is_ok() - }), - PublicKey::EcdsaP384(key) => ecdsa::Signature::from_der(signature) - .is_ok_and(|signature| { - key.verify_prehash(hashed, &signature).is_ok() - }), + Self::Dsa(key) => dsa::Signature::from_der(signature) + .is_ok_and(|s| key.verify_prehash(hashed, &s).is_ok()), + Self::EcdsaP256(key) => ecdsa::Signature::from_der(signature) + .is_ok_and(|s| key.verify_prehash(hashed, &s).is_ok()), + Self::EcdsaP384(key) => ecdsa::Signature::from_der(signature) + .is_ok_and(|s| key.verify_prehash(hashed, &s).is_ok()), } } } From 2d2229e9ffc399af7f2be7aea29f6ae5d6f14f50 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Fri, 19 Apr 2024 12:36:42 +0200 Subject: [PATCH 17/38] chore: don't include default features for `x509-verify` crate --- Cargo.lock | 70 ------------------------------------------------------ Cargo.toml | 2 +- 2 files changed, 1 insertion(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b0d8346a4..050ed075f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -962,33 +962,6 @@ dependencies = [ "phf 0.11.2", ] -[[package]] -name = "curve25519-dalek" -version = "4.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" -dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "digest 0.10.7", - "fiat-crypto", - "platforms", - "rustc_version", - "subtle", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.55", -] - [[package]] name = "darling" version = "0.14.4" @@ -1170,27 +1143,6 @@ dependencies = [ "spki", ] -[[package]] -name = "ed25519" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" -dependencies = [ - "signature", -] - -[[package]] -name = "ed25519-dalek" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" -dependencies = [ - "curve25519-dalek", - "ed25519", - "sha2 0.10.8", - "subtle", -] - [[package]] name = "either" version = "1.10.0" @@ -1330,12 +1282,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "fiat-crypto" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c007b1ae3abe1cb6f85a16305acd418b7ca6343b953633fee2b76d8f108b830f" - [[package]] name = "filedescriptor" version = "0.8.2" @@ -2673,12 +2619,6 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" -[[package]] -name = "platforms" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" - [[package]] name = "powerfmt" version = "0.2.0" @@ -3096,15 +3036,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver 1.0.22", -] - [[package]] name = "rustix" version = "0.38.32" @@ -4703,7 +4634,6 @@ dependencies = [ "der", "dsa", "ecdsa", - "ed25519-dalek", "k256", "p192", "p224", diff --git a/Cargo.toml b/Cargo.toml index afb7efb74..fe0e5ea03 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -102,7 +102,7 @@ walrus = "0.20.2" wasmtime = "19.0.1" x509-cert = "0.2.5" x509-tsp = "0.1.0" -x509-verify = "0.4.5" +x509-verify = { version = "0.4.5", default-features = false } yaml-rust = "0.4.5" yansi = "1.0.1" yara-x = { path = "lib" } From 551c459d180799b84b9de7f457708ea5f6fe2141 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Fri, 19 Apr 2024 13:06:42 +0200 Subject: [PATCH 18/38] feat: add support for SHA-512. --- lib/src/modules/pe/authenticode.rs | 12 +- ...6df8c1ed548b36888e95f8a5b581fc4b35e.in.zip | Bin 0 -> 8378 bytes ...45c6df8c1ed548b36888e95f8a5b581fc4b35e.out | 295 ++++++++++++++++++ 3 files changed, 305 insertions(+), 2 deletions(-) create mode 100644 lib/src/modules/pe/tests/testdata/7bd1de9bcd32c628d326e7647645c6df8c1ed548b36888e95f8a5b581fc4b35e.in.zip create mode 100644 lib/src/modules/pe/tests/testdata/7bd1de9bcd32c628d326e7647645c6df8c1ed548b36888e95f8a5b581fc4b35e.out diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index b8923c6a1..8c9e4dc05 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -26,7 +26,7 @@ use rsa::traits::SignatureScheme; use rsa::Pkcs1v15Sign; use sha1::digest::Output; use sha1::Sha1; -use sha2::{Sha256, Sha384}; +use sha2::{Sha256, Sha384, Sha512}; use x509_cert::spki::{AlgorithmIdentifierOwned, SubjectPublicKeyInfoRef}; use x509_tsp::TstInfo; use x509_verify::{VerifyInfo, VerifyingKey}; @@ -484,6 +484,11 @@ impl AuthenticodeParser { pe.authenticode_hash(&mut sha384); sha384.finalize().to_vec() } + rfc5912::ID_SHA_512 => { + let mut sha512 = Sha512::default(); + pe.authenticode_hash(&mut sha512); + sha512.finalize().to_vec() + } rfc5912::ID_MD_5 => { let mut md5 = Md5::default(); pe.authenticode_hash(&mut md5); @@ -913,8 +918,9 @@ fn verify_message_digest( rfc5912::ID_SHA_1 => Sha1::digest(message).as_slice() == digest, rfc5912::ID_SHA_256 => Sha256::digest(message).as_slice() == digest, rfc5912::ID_SHA_384 => Sha384::digest(message).as_slice() == digest, + rfc5912::ID_SHA_512 => Sha512::digest(message).as_slice() == digest, rfc5912::ID_MD_5 => Md5::digest(message).as_slice() == digest, - _ => unimplemented!(), + oid => unimplemented!("{:?}", oid), } } @@ -923,6 +929,7 @@ fn verify_signer_info(si: &SignerInfo, certs: &[Certificate]) -> bool { rfc5912::ID_SHA_1 => verify_signed_data_impl::(si, certs), rfc5912::ID_SHA_256 => verify_signed_data_impl::(si, certs), rfc5912::ID_SHA_384 => verify_signed_data_impl::(si, certs), + rfc5912::ID_SHA_512 => verify_signed_data_impl::(si, certs), rfc5912::ID_MD_5 => verify_signed_data_impl::(si, certs), oid => unimplemented!("{:?}", oid), } @@ -1006,6 +1013,7 @@ fn oid_to_str(oid: &ObjectIdentifier) -> &'static str { &rfc5912::ID_SHA_1 => "sha1", &rfc5912::ID_SHA_256 => "sha256", &rfc5912::ID_SHA_384 => "sha384", + &rfc5912::ID_SHA_512 => "sha512", &rfc5912::ID_MD_5 => "md5", // OIDs related to issuer and subject names. &JURISDICTION_C => "jurisdictionC", diff --git a/lib/src/modules/pe/tests/testdata/7bd1de9bcd32c628d326e7647645c6df8c1ed548b36888e95f8a5b581fc4b35e.in.zip b/lib/src/modules/pe/tests/testdata/7bd1de9bcd32c628d326e7647645c6df8c1ed548b36888e95f8a5b581fc4b35e.in.zip new file mode 100644 index 0000000000000000000000000000000000000000..aa8597e12b86f6f50213e873a05ac767b75b2109 GIT binary patch literal 8378 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 literal 0 HcmV?d00001 diff --git a/lib/src/modules/pe/tests/testdata/7bd1de9bcd32c628d326e7647645c6df8c1ed548b36888e95f8a5b581fc4b35e.out b/lib/src/modules/pe/tests/testdata/7bd1de9bcd32c628d326e7647645c6df8c1ed548b36888e95f8a5b581fc4b35e.out new file mode 100644 index 000000000..bff43dde0 --- /dev/null +++ b/lib/src/modules/pe/tests/testdata/7bd1de9bcd32c628d326e7647645c6df8c1ed548b36888e95f8a5b581fc4b35e.out @@ -0,0 +1,295 @@ +is_pe: true +machine: MACHINE_AMD64 +subsystem: SUBSYSTEM_WINDOWS_GUI +os_version: + major: 6 + minor: 0 +subsystem_version: + major: 6 + minor: 0 +image_version: + major: 0 + minor: 0 +linker_version: + major: 14 + minor: 38 +opthdr_magic: IMAGE_NT_OPTIONAL_HDR64_MAGIC +characteristics: 8226 +dll_characteristics: 352 +timestamp: 1709628808 # 2024-03-05 08:53:28 UTC +image_base: 6442450944 +checksum: 59800 +base_of_code: 4096 +entry_point: 1024 +entry_point_raw: 4096 +dll_name: "vcruntime140_1.dll" +export_timestamp: 4294967295 # 2106-02-07 06:28:15 UTC +section_alignment: 4096 +file_alignment: 512 +loader_flags: 0 +size_of_optional_header: 240 +size_of_code: 1024 +size_of_initialized_data: 5632 +size_of_uninitialized_data: 0 +size_of_image: 24576 +size_of_headers: 1024 +size_of_stack_reserve: 1048576 +size_of_stack_commit: 4096 +size_of_heap_reserve: 1048576 +size_of_heap_commit: 4096 +pointer_to_symbol_table: 0 +win32_version_value: 0 +number_of_symbols: 0 +number_of_rva_and_sizes: 16 +number_of_sections: 5 +number_of_imported_functions: 10 +number_of_delayed_imported_functions: 0 +number_of_resources: 2 +number_of_version_infos: 8 +number_of_imports: 2 +number_of_delayed_imports: 0 +number_of_exports: 3 +number_of_signatures: 1 +version_info: + "CompanyName": "TEAM R2R" + "FileDescription": "Witches\' Magic For Ableton Live" + "FileVersion": "1.0.0.1" + "InternalName": "vcruntime140_1.dll" + "LegalCopyright": "Copyright (C) 2024 TEAM R2R" + "OriginalFilename": "vcruntime140_1.dll" + "ProductName": "Witches\' Magic For Ableton Live" + "ProductVersion": "1.0.0.1" +version_info_list: + - key: "CompanyName" + value: "TEAM R2R" + - key: "FileDescription" + value: "Witches\' Magic For Ableton Live" + - key: "FileVersion" + value: "1.0.0.1" + - key: "InternalName" + value: "vcruntime140_1.dll" + - key: "LegalCopyright" + value: "Copyright (C) 2024 TEAM R2R" + - key: "OriginalFilename" + value: "vcruntime140_1.dll" + - key: "ProductName" + value: "Witches\' Magic For Ableton Live" + - key: "ProductVersion" + value: "1.0.0.1" +rich_signature: + offset: 128 + length: 72 + key: 3048884457 + raw_data: "\xad)\xd4\xe6\xe9H\xba\xb5\xe9H\xba\xb5\xe9H\xba\xb5\xa20\xbb\xb4\xecH\xba\xb5\xe9H\xbb\xb5\xe3H\xba\xb5\x84\xc9\xbe\xb4\xe8H\xba\xb5\x84\xc9\xba\xb4\xe8H\xba\xb5\x84\xc9E\xb5\xe8H\xba\xb5\xe9H-\xb5\xe8H\xba\xb5\x84\xc9\xb8\xb4\xe8H\xba\xb5" + clear_data: "DanS\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Kx\x01\x01\x05\x00\x00\x00\x00\x00\x01\x00\n\x00\x00\x00m\x81\x04\x01\x01\x00\x00\x00m\x81\x00\x01\x01\x00\x00\x00m\x81\xff\x00\x01\x00\x00\x00\x00\x00\x97\x00\x01\x00\x00\x00m\x81\x02\x01\x01\x00\x00\x00" + tools: + - toolid: 257 + version: 30795 + times: 5 + - toolid: 1 + version: 0 + times: 10 + - toolid: 260 + version: 33133 + times: 1 + - toolid: 256 + version: 33133 + times: 1 + - toolid: 255 + version: 33133 + times: 1 + - toolid: 151 + version: 0 + times: 1 + - toolid: 258 + version: 33133 + times: 1 +sections: + - name: ".text" + full_name: ".text" + characteristics: 1610612768 + raw_data_size: 1024 + raw_data_offset: 1024 + virtual_address: 4096 + virtual_size: 602 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: ".rdata" + full_name: ".rdata" + characteristics: 1073741888 + raw_data_size: 3072 + raw_data_offset: 2048 + virtual_address: 8192 + virtual_size: 2862 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: ".data" + full_name: ".data" + characteristics: 3221225536 + raw_data_size: 512 + raw_data_offset: 5120 + virtual_address: 12288 + virtual_size: 104 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: ".pdata" + full_name: ".pdata" + characteristics: 1073741888 + raw_data_size: 512 + raw_data_offset: 5632 + virtual_address: 16384 + virtual_size: 36 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: ".rsrc" + full_name: ".rsrc" + characteristics: 1073741888 + raw_data_size: 1536 + raw_data_offset: 6144 + virtual_address: 20480 + virtual_size: 1360 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 +data_directories: + - virtual_address: 10560 + size: 140 + - virtual_address: 10700 + size: 60 + - virtual_address: 20480 + size: 1360 + - virtual_address: 16384 + size: 36 + - virtual_address: 7680 + size: 1432 + - virtual_address: 0 + size: 0 + - virtual_address: 10144 + size: 28 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 8192 + size: 96 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 +resource_timestamp: 0 # 1970-01-01 00:00:00 UTC +resource_version: + major: 0 + minor: 0 +resources: + - length: 816 + rva: 20640 + offset: 6304 + type: RESOURCE_TYPE_VERSION + id: 1 + language: 1033 + - length: 381 + rva: 21456 + offset: 7120 + type: RESOURCE_TYPE_MANIFEST + id: 2 + language: 1033 +import_details: + - library_name: "SHLWAPI.dll" + number_of_functions: 1 + functions: + - name: "PathStripPathW" + rva: 8272 + - library_name: "KERNEL32.dll" + number_of_functions: 9 + functions: + - name: "GetModuleHandleA" + rva: 8192 + - name: "lstrcatW" + rva: 8200 + - name: "GetSystemDirectoryW" + rva: 8208 + - name: "VirtualProtect" + rva: 8216 + - name: "FreeLibrary" + rva: 8224 + - name: "GetModuleFileNameW" + rva: 8232 + - name: "LoadLibraryW" + rva: 8240 + - name: "GetProcAddress" + rva: 8248 + - name: "lstrcmpW" + rva: 8256 +export_details: + - name: "__CxxFrameHandler4" + ordinal: 1 + rva: 4140 + offset: 1068 + - name: "__NLG_Dispatch2" + ordinal: 2 + rva: 4148 + offset: 1076 + - name: "__NLG_Return2" + ordinal: 3 + rva: 4156 + offset: 1084 +is_signed: true +signatures: + - subject: "/C=JP/O=R2R/CN=R2R" + issuer: "/CN=R2RCA" + thumbprint: "004d47889e493832b4fe1db48e95ba7c0dcaa83a" + version: 3 + algorithm: "sha512WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.13" + serial: "a2:30:db:c7:17:28:5b:a2:4d:01:a0:7d:03:79:12:ce" + not_before: 1609426800 # 2020-12-31 15:00:00 UTC + not_after: 4102326000 # 2099-12-30 15:00:00 UTC + verified: true + digest_alg: "sha512" + digest: "9d8c6f3e677451a7a20c4b7ec6d0b27f8247483f2024a27c8e29c29cd8d8354e3cf2f206c262403bb2fda6112596f2ededd0a5d4af365f81da47c20aa7564b2f" + file_digest: "9d8c6f3e677451a7a20c4b7ec6d0b27f8247483f2024a27c8e29c29cd8d8354e3cf2f206c262403bb2fda6112596f2ededd0a5d4af365f81da47c20aa7564b2f" + number_of_certificates: 1 + number_of_countersignatures: 0 + signer_info: + digest: "b4db2dd0c6c7f015cbdbc469536fc4665d9f0c16fdc3fc73e7d49bfb97ac4dcbdd194a4614a2bbb80c8b1632ba0c0d80bf2cedd6f51497010ad6fd87f05c8882" + digest_alg: "sha512" + chain: + - issuer: "/CN=R2RCA" + subject: "/C=JP/O=R2R/CN=R2R" + thumbprint: "004d47889e493832b4fe1db48e95ba7c0dcaa83a" + version: 3 + algorithm: "sha512WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.13" + serial: "a2:30:db:c7:17:28:5b:a2:4d:01:a0:7d:03:79:12:ce" + not_before: 1609426800 # 2020-12-31 15:00:00 UTC + not_after: 4102326000 # 2099-12-30 15:00:00 UTC + certificates: + - issuer: "/CN=R2RCA" + subject: "/C=JP/O=R2R/CN=R2R" + thumbprint: "004d47889e493832b4fe1db48e95ba7c0dcaa83a" + version: 3 + algorithm: "sha512WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.13" + serial: "a2:30:db:c7:17:28:5b:a2:4d:01:a0:7d:03:79:12:ce" + not_before: 1609426800 # 2020-12-31 15:00:00 UTC + not_after: 4102326000 # 2099-12-30 15:00:00 UTC +overlay: + offset: 7680 + size: 1432 \ No newline at end of file From 94cfd394f5d8d6ed840612104eaae28ae1fa373d Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Fri, 19 Apr 2024 13:29:23 +0200 Subject: [PATCH 19/38] fix: add support for legacy object identifier `1.3.14.3.2.29` --- lib/src/modules/pe/authenticode.rs | 14 +- ...f9ee3cc0a56ce31e4da0068cf6b474c3288.in.zip | Bin 0 -> 386220 bytes ...12af9ee3cc0a56ce31e4da0068cf6b474c3288.out | 734 ++++++++++++++++++ 3 files changed, 744 insertions(+), 4 deletions(-) create mode 100644 lib/src/modules/pe/tests/testdata/111aeddc6a6dbf64b28cb565aa12af9ee3cc0a56ce31e4da0068cf6b474c3288.in.zip create mode 100644 lib/src/modules/pe/tests/testdata/111aeddc6a6dbf64b28cb565aa12af9ee3cc0a56ce31e4da0068cf6b474c3288.out diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 8c9e4dc05..92a1d094d 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -56,6 +56,11 @@ pub const JURISDICTION_ST: ObjectIdentifier = pub const JURISDICTION_C: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.60.2.1.3"); +/// Similar to 1.2.840.113549.1.1.5. Obsolete, but still present in some files +/// like: 111aeddc6a6dbf64b28cb565aa12af9ee3cc0a56ce31e4da0068cf6b474c3288 +pub const SHA1_WITH_RSA_ENCRYPTION: ObjectIdentifier = + ObjectIdentifier::new_unwrap("1.3.14.3.2.29"); + /// ASN.1 SpcIndirectDataContent /// /// SpcIndirectDataContent ::= SEQUENCE { @@ -1015,15 +1020,16 @@ fn oid_to_str(oid: &ObjectIdentifier) -> &'static str { &rfc5912::ID_SHA_384 => "sha384", &rfc5912::ID_SHA_512 => "sha512", &rfc5912::ID_MD_5 => "md5", - // OIDs related to issuer and subject names. - &JURISDICTION_C => "jurisdictionC", - &JURISDICTION_L => "jurisdictionL", - &JURISDICTION_ST => "jurisdictionST", &rfc4519::C => "C", &rfc4519::COMMON_NAME => "CN", &rfc4519::O => "O", &rfc4519::OU => "OU", &rfc4519::ST => "ST", + // OIDs not included in const_oid. + &JURISDICTION_C => "jurisdictionC", + &JURISDICTION_L => "jurisdictionL", + &JURISDICTION_ST => "jurisdictionST", + &SHA1_WITH_RSA_ENCRYPTION => "sha1WithRSAEncryption", // In the default case try to use the string representation provided by // the `const-oid` crate. Panics if this fails. oid => { diff --git a/lib/src/modules/pe/tests/testdata/111aeddc6a6dbf64b28cb565aa12af9ee3cc0a56ce31e4da0068cf6b474c3288.in.zip b/lib/src/modules/pe/tests/testdata/111aeddc6a6dbf64b28cb565aa12af9ee3cc0a56ce31e4da0068cf6b474c3288.in.zip new file mode 100644 index 0000000000000000000000000000000000000000..02c07cf5888ffa1b9731fe0a300342f43bcb76bf GIT binary patch literal 386220 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

5ul?cF@BMXK6R#sp#)}nj7N$jLyXMG(Q-qkN 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�>X><@XUP;KKE`^ok2mi=500Qea4L2y0s_V#zeo9vkTv0B0Mf> zu`7zrMcUg=OLw8k=E~;rvWA5|1+pQh*Q%GGk=t| zh)JQ|aB%7?rMJ7~WFs#uQA=mQY}sNinnHn5EoetWMQG4RY=)ph$Rm^(jM~(PV}3Rp zK+lRS$4I>1eZ$no)UFpDPoMFF1AkP9D$7C)Ztjlzq(k@8a4VsXZjJ&E&%)&%PDcFa z)qA@Q-k>PT_%<{k_rBy&^d8&Jn=p65qyrGvUpAN|1dV-yGsMoST7p)U$93NET8& zW2O)DyZX%;|GVbV2HvNpy<(H1^kyZ7*#nq^AF9yZ>ng)7ScgE@UGJ|Der)8TSzKTl zy81Z})jv}YJHj_F<0y{79KemWT@@JB^YJ@T;?4nahw#gOUFbhNg&Zf7<8p5?O7S1F ziKzENdUu!Ehfw{MqH{I_h-7fzvmKg%CGfb6qV)?xeHh6q6D_ zfb}L|o8qg&;U0(Yu?|j;3?u!&<&NidQ{VkXWGN9_18d0~M|%W!odSN;p&lPG!Hom4 zAH>zxqQNRqnoD0M$8ufYbgOoOa;TTF7$;K%X}#f&0aC-n7Rwp|USF$u^ z;KsV+d&UPsQzI05%Sw;~?3v+i7s~DidM#tLp6T(&|CCAI{EE~CaJPoji6pr0^(SvN&nc@*KGrbJ97w@x;`P_ zR?o3;c;>1msxA*MKXa_^7g?BE%zs_b+m{l6hQ?>CgU9ug8X}KD0ai|P9I4uWm$$5V zz@uN(V0lKKqoXqp^9F`e&;vB;H$|)VsgF}*r z588@j!d&31>y3UGZUw&f*fJnyuomIl2aFy`EU9MO%}fUe0dKnPk&fLmc{fEP7oy(+D`vy= zbXl}=rWP*T#uE$5diBpfq+{~TzVG9|Cs?Fhc{%Tm7FsSHUSwjAwtSCG))wMS9@wLPNoas>kdx4$%l*n%&_=o@+ehVsBm@7n=2u$>NJ_9=K1S{B=DeeB?$ zh+ECh4FBx{5?h@h_kQe1jj(dwqmfnGo2JXnb2v1I@~9|61c(*JPi20#un#h+L45~6 zQcTFB;v;a4{5$+vF~RCn-dlNBzSS#yy6|^p!@xarNY4F8u5ueJZ{qafYbId)(WWVX zW5{KQFZl=_-l{kC;9{>sZhLVCu6JYeiUFn)LlR7|XfcvF8wVCjtM>0u>)bFz1YR}i zP(?+e=R@BCa+40=q+)qwiP*f6k7(Z$665l20GAtX}ABt+P zxc3UcyLXgIobZ%8l8E&=;~-@qF03v;5JZP@xzWU9E0mwk9d(EXWe7OW1)YEsjJ!_W zIa~!<0sljZ@mj1*u{R^M|IU}aCKzIH#!!@J11Jyz0d_YnXljg07rNG7cDd=rJG z03{Z2%JO_)?7K#SGmROj2J!Np0^Dd?9&uC&rrLh2M9$Mi zU_~UulKmjN9g)^H-ZhJhwTnJ%RZUcx(QyIA$y3&;%R@g>*vhRWAmukdMxLI)XDV=?3AX@rF%sCD*(^(i%*IVJyt)xBQf)Kl}Rq1mD0GS59C}ZX@Yu6{er#es1zHXW^uVBFsD& z-gH5eA2wumVdGLj$`Y4W?cS3BL)Yh;gDF@JJX6M!cUmT2jdz7@O~DJevAo3T|Eou# zm1Uw_8xVe0x%ob_F$T~*ZkVAyFzZFPgl~7i(3t-D*1hUN&pGs_R*}i>Fo%nngDPF+ z%~+Wn>fI>1pD6}NQg%5iJJqR1CC?i^X;8P@BewpMS?x9q;LS4jCOxu{Urz)t5=wIK zTs))kJf9?*;Qu9b4@@#l7Qt@F!?AHlMBU3aLajlVE3Jf)g#8&*yEeh(tFpH*La4Ih zqPO|$wgrD911m35lfvzRb?V_^$^(4Ze2-_pL0Uhs_^ILq=|}oS*3$LpZ;#Xitpk{Z z`yMh^o>v{#^c&wx;G_)x))FYF)l`x?DE$SAobKG>k<7ybC>xe?X2R0Y&hwlgI(}HO z`Y>SilnEMDI=7jskEZZYW}FS4tNN;Gqh?~UyYNIbFCs0I0EY#}wO*>AIAJ=V7bka8 z$T+JInAsq_4rDr}?LP=J;xRL4p*_Am+4(;Yo^U2zMEa#RH-7_{*And4xxZ@(W{{(H zZb92DJ&?43DAM=dFhc6k->%W*B%{!M+-9CtskH{Kk(#W zqD%;T09G)zcJ2foLo$ItkuNxr&+$T+UsD~b{Lby(sjbTRp1(&Ae=ksla#kW`545j# z!J51H&;Ma38kxg7*T>uK9x>QeOPUs=O1KRl0(|XD+V`m1vgwm@5=i2nwS;pArJ$2b z69B#3Y@l#UcdWxbWuimvA=CSrW_Rcl;~=yjL&12K9|g6D9ib1tz)j3o-cF;E z0?Ff`?{w4mTr-H83f?d``|ChJ?wJV>85#cNf4ZIswPokUw~73`Eu+F z-Or}rZjdwsy0D+pIR~l(J?3)Q94lhe;MkU@i*yI0DSc5}_W+cHS1TxE8b0tId(%mx z?k>}ncLU9afICRdBrPr=I4;t_iU@o4Mh3xMP&26dH1vRcbx)AZ|+YprzZC$$AAD3 z&6Hs(iQ*_n9lr=lK(hrRNyJw<x^NVmj9Vyfzd&575FhJ>^@ad{_V0_t#Wq=g#49Nh^IEAxrLW%fEiNZ zcfB-vF1>+AmApQA*dIQa_2{H%dx|1*pp7?*_o2Q*y=P0~Ou#ReEXKw1VkW?X%K}4YS?Zp;X3qZydSM|4)q?4dV{nUM&C73VcZa)!AT!2O~@D`50h8Y?nVHaN+UKk3*}Lwr#^c z-RB*G3OJ;8b7y{{-IUy5XcE$}i{O~c>|&EJnTBlXbIaXw#?TO&KN+k)HKzc5r|8Eo z8&VE&h;a}}G4z)z>9P+Baqs09)XRFpOGZ&jjhn`!xeAYCEl@;+bL<=H`S@2TBtrUJ z>%lVUZx+^MrS?0mHk_|@&=N-yt;l5#W|Ha&u-<|!kArl--suw*9*#c2*Af0Czpof@ zWo5o0^$GF-zP5g)){!8lQFJILDb1fK;K?Okt-hw{Sr1Nh_U=LEajOGXQ#2l5t_jH~A~grzuiBA} z==A0X>GJnETcG7KoQkzFj^d(Tl`y0uowy{Z9_l`jJ zVJ}@}dj|~p(aM=*!Hkz!Zpy=7#Vc;eI-RGEIpl#X=kUcw@p@XJS+)y0CCg$_Ql1S@ zUiH@QiYGolv71fiZvLYufg9c`i8YkXydOj>wieo_7%fVq0R?yb=r2pIPrQCr74BuQz!&MJ52y%|oGz&6x==R1vz2E@Sf1_ZSV?9cH zyrAd>L+CsycSvtj6VHinJ{_MmCc%8rT`CIM%&;V3e3QSi@5^;|{Kbg!?aJ(Klyd_W zeCqxr@@@U)dUtqsSQbX5TeCF-Wf_%vP)>Z)aUaLCf$;*+`khJ3Yg#}@hUq$Q??|~_ zUCe;eua)9H%Xw{kZNY`7`kaQmm6LBCLk7b5mC^W4rz&zOvWhh?x?Kb%s^{8zd)wB3 zIR^n0V^IsGKy{V=bO}{akwirkoqWD7fNa`k&uDMb)nyzT^<1T`9YAa@xrYeQpsw~c za1$Vb3v79Yn$0xJ|J^l+8vX%d%Y0u;L7EKZj2cy3C$`pz?ORhs*AZ1xl5Q!TV*i}z z6|Btj5oAX4s4&JxTsEfj0ZV!2=gE5+^Mkv?$eZQ8FBho{k8XDz06;w9C2R}U>hfsK z6FWDup?(5K-~2p9vC6@2m2lYy6icEizQw$z_Ivd=Rg6XUR0qO8` zp4+l}@$$BNA2^=GnMRc> z!HKEL{y@BD=hnSJGcVxc^=7|SDc2w|1!rH^0-~?vHub3fpkY00zSQJq3@*PH&!CO~ zgn&olPVP4LB*yP&2fFvE2CI)^iJGLZ!kJt99LmHK;0Ds4@Ou?=$om2^#4PLMeb&$W zp$*1^@R2`2&lKvuWFPI55PEK#7V?4InKH1S*|<;*XJ1Ug%%q{?vamAKIiQ;~9#$sG za5be6Y>eLzZl+2?Ub#Yly$FZySC++T+f7nS_T3e*#UPrTXjZNO=v?dSK@mE?kX})ThtX>;>jkzRlIKjtlb%SBm@O1Av|etf+k|Wvk5)-SN^5Nu(b&$qO3YH7exE~h+NnnVKg60Jc9iCM3+-^Pvm11F;3s2EIi7NoZhUW9(8<70;6|V{T7P zyG_NDy8pHquwK8NIF=enb?M6$PF@&L(9DK8kyOT<+bnvmS>sM83VH}(S+AxE2#0AH zf9bnK=MfHIu|dG4;KkO+k;20T#V{hB>g?xRB7_=N`a)+w3zK zS;otr;l$?zzro8YQD>iE|FpCesKtH=wV@)+OIU(K&6y z}wYkS0NL@ZnnN4a9 zj3wtaq-8JUUb`Lna_O9ATw!lt=Kr6-d&9`@5PzY{Ql#%|@&??D-U3*K=FgvDn45p97_&#b4%p z#iwN^Slxf3V9zc>c9g{8-@|iA5>r`LL7S?-XtQ(=bQt!y1O``$Z6Apt0-@+nxios| z(n_DMqnmBr+|RuyY@g9+?!_iT)xxhL1=U)aV3};B6cN{f)K@Y_B=~W(;%#KfJ#tU7 zW4g4xYls=J?=yW7--V?dB|n;sq-J2Q`s>UY60bQ6FmO^#qjvhhp@%r*~vRZ46}#-Uj7cP3krw%mJ8! zoVr|E?&Wxf(9Qn#6;&E2n0WIi!z};@c%IU$6OVO`1OY+En z3rh^`#S{#Ro6;=}#tqm6Fp!YGowTmM9Av7lz}*S_EhJ)Q|GXa(#m+>q5LxY*v9>Dj zRbo|+@UI0M{-rs~&LZ9-D)yZJ|moMH5Tiv`N<(4#QG`~W< zy&jEUeLq9!hTJASZ#?3Fr~my{Rb7BJHUH#RS<|T_7H%T{{g~=2d`JLgGba|+Nhh|! zzZ^4yX6Aa14g8h(CY2{x3u%XC3_n~IBh_#1%mY#Mt`uYVG+m zg!K&NJqxRJizVK*EQ+h0{>2zUW*H|bpvMpJv03(eGFK;?D~D}7cvW@ zi;1`ECIE%^1CaEwBtPL%*uTf?!ig}zDW$}PlQI*RY??K4V)0yT7Rh^r1Z3&V**~GWU9qjhm{bj@nH^&C>yg1cPM^SZqmx|bFb;v3Wa zG9C1W`lT%BwfUD$+d_zf*ytdkmB>e=hODX*BX04+W=<^a)8bsy6>b7{@U=|6EVxAk z)9TRLojLA%^`w%g0l(~qrg?$Ui?aMo9Z$3cXd^-ehg5?DzgMc<=ZK8sy{GVEiqv+%V= zXq`bPStlaeMaXys>wDmbhl_X1*fG*2{v0ak!z3BL>UIIshqR*kbp=sCuJK)nkr|6X z`m>UJ(6~B*l4#ViwluJMmFbu+HMYRXa-TvJDHiV^Lb#h23J-wwB_7MP@2i?m4Z}XZ z%>s`2+`fv~Yv>N-9RRhQMmH1Po8e5^Rr~qGcFe8qapHDY`nvQZq4(f@q^l_X9!)6P zwf?A$v>wlUNryw+UnsVyT?x)^Aa1l zpP;98ypv+bMOOfE51H-g41CLm-XMME2tr?TmPq$L%7i7TiT&sL6EP^P)AS24fMq&9 z9rH2BjoT=0O@s5SytH~3Q_?a~j%-44~4*$+c{H$grY zcL$&Hf7a?89i*k)jRIm`bz_xkwGEkHZfJe@SU3aIoTf(rKiL4vQA|mIr%3w;mrs3; zKW-;Uc-#5&p$LW|3ha2WHKGDZ#h*2+8$GsZK_K$PVjtB;H(Qxg!#T!x6%Q;vgjDB_)1aa* z6KPnK+}xJ;Y1wgLx#*vZeXTY7ZhQBB^}9;C7#7VhRW;()E#{RaVEpsM+L?7x2c-Qk8Bbo?2Sj26PdnEj_Pl(GZ~G6nGT3j7h!zEK zc3#WJFgg%rP~yLh==`_54CBCc(tfsi?(Ya0-3`?0|IMQ>0mC>mQQ^GWo7^4({7-F@ z2PGfL>zlAYOXo`AnRjd!1C7cfF%}s-&q%z32&Y{18VW*stDuabkq{t1QnrE?lVfUk z8eSSXeidd$EFsjTipc%teuC~&JN?UqUbEP+cfqka+Ve%b;Pjdp4$veIiP(cA}^61OG^AS$%gyAK~GZgTeCf zNc91}Sb4Vs>ZeWgDMnoD@-3rRK<*^0W60=WK=^nMe2*6=%F`%FlTFyUYxb2L@b6-@ z>_P`_CPEu0;Bdd~=(T!ak35;TB1m7aS$(5YWnwRE@FpVJ=a??2c{}TVIJ}~E3hzSL zr$Mn}t*Yg9^{#FxT32WRtP;J;gt_$_d!F?umja5!L2f zwBh0LAgjh+0Xm!V{X=wu!5KFq@k<8g6{eRHnO0)F2Oz(PAq^UKh!jp@CsNome{rf( z2v=%-f&CfvG;9SYHwWa}r=>=je%rF0M6$7Pe~ldDZzvWWve?$>-h-ts#tqx_S8(yM zb*gpk!@pQIi|L81nx@9ndGG6enz7chQ1520Du@|J?b7mRspKoGX8=hf32ZL**!ZPl zhG27q$K1c=2Uv(vdcmuJhw&=Ml141{Z}opPq7}X9bb3KVF}~Se`Y&kLrx6{!-+~W7 zs!rVA|Ker_j;pSLbXXmn{r`rT;6PZROm-U~DmcIXkusN80h)SzD_x`c+~V2#Jbldw z?u7CETQHE_iCQsPd*G&7Tj)?v-2~#=9jIti2FR9p#81!g2nPw$Ntt|Xk}!2a{XkyH zd@&tP(zq-^6cO6Mx#SN#fkopukYD!r_%Yv?K%(F~Ht&I?V|qA^(GuLkbM{C=K;*CM_fIH&jfNw`Wbo zG@Lpk1iWa_&?DN*OXAI?^Jpx1OxIgyxchp>U#?;7$t*-EH^0gWFtPEn%g%&4k2<%y z0Z-tm;MlM;3}00$aKLs3&R6h)!SKI?$IEQFg}q|#@_D_?)REadnqVwuNfd{cQ-5W1 zkOPFAYedKX+UDSjVu55ab?dt)aH*lD)e9zgzKWrC28TnJACF-T3OUTB`e#-zVNGWa z5nKHX*|eBILtps&cXv($FamITtJoro@rlckV3^3tN6iSWjuQx?Jn%~yl3)kGfe8!g zC_gq=y8V}Z@Xs0e_`%OnRuIFI0CjWA(0{*L3S)aS@BDy%Aze#)(sk0&sbsH{XI?^W zwN|!E$B!RZhj@;0f$LH;|IQC+Nlb!+{c#2o5~@AqxB(hs$E)GLJNGZWw;8&vV>o< zmC#cx0whC7-9Y#`Wfunj_PhL7YF7sRgpUL3ddpstCXtgrYdw3<04UiBXB;!+t(+=# zIg>8V4Y2AFC%fwLpHt z_diS$tYRjV6%HG9_(Et?s{0`ogkV*W!lY zj2^U4fW>3&J|sy_yNZDxj&&KCb^%rJX06vhg$s(8G`>99QQeU7A&C?AEaavkrHs*N z(9N}oTz$I6COyzL*UA`kE_Brnad7WFbBCTO#eG}JlNz>?8HVi2^+#@@$1)I}C3<(9F7C0Z}vFqtZa~6I3SQy;F)11RoDdQ8qk~jtQe&&h{T_b+% zg{j$=@lCl9VAV5Ew7)n2lOc0HLtE?Ej_7=}yIPG|^!wvF6gQA<3ayYL`gW-=m|O`z zrmP}U>*PlQL_zs}DI|rR3z@@glaJ`@$uM3hx=5~4Qg{Nut=sz1#c-9rV0sMo8knZJ zc9oO&%%F~XS0`x!$s>5GGNTy`o0sKcdEn3FE%{8bB>0>i>I%kgjadYlW#6qV%=>3& zJy6oeLklr~FjIcqGTSyPzhbpZzs%;IL0Ye=cDI80YV=nGcRA|Qzdgt<(6i9G#*^jp z`0&UUuZku6G3`I}`)z-eKhLz+IEr1PxkTvoa`$3~@i{%&UvAD*fx28;gwCGGKu2*z z{!(zve7Jj|_R2yH8jDs9>-5>G({gup=G%pS!ujtIK*Q}icB3g^e9G_S3MNsjK$X#> zJa=vc{+4fej9zUK)jVLU={9s17}`V?t@n~E7A8TnRir8f{V=J{Uu+KeEwipS(oye$ zWk}8{##PJl3>)le>rLv`v3I@|P(Qe%3bJu!aY4{G{G)2qkvI~sMnejG%xi?(Urx=x zp%jhA$Ez3%0hCBoQ<#Mytzk4A94UDb02zC! zZkrS*)kn+`<3kpv_?81b+}$4#BJ$Rqn}*&>;F^t_aQ(e+4$U-LZo?mtDW*e$O1mo< z^pUeock}uWF}OydrXPX6lJ;*wT_l{Vi8Rv~tzUV8`f)w7mx_0T0Y%3;+$jbWlnMCl zA$sP__I?W+Zm|xpx4OAvi*_QEgtpiz5xtBNXlXv3w$B1{5Jq%9V$q@s2t6MhZ|1$7MG!PLb{#z|>1&a4 zLYxBM7;Cy=qQ{iJ>9%JdvEwFCbL;d824x)UQ?3%#uN<95=*kUFT@hOr&WqIGKrCSg z%)roL@Hy|}&U3nb83GngrdF95t~ng@%{od9`i4mR%>AB7C(p-;`n?7j$BE-T#KM5R z1CEu$^VH5CVeWiT{28x|2tKPd7i<8}d8*wH!LTjJDJ;EtMP3Xs1scsL`Uk4tai?XY ze_6(jH-BT`?-pn(*(;(f(&4F+J>L)!eX2)PQ_WpSrZ{nw1=sJ5QOHMhxUEb;J7kv6tq`RXO*n17w$R!U z(Y*gE0ybHcVudRi^|F@oEblQ2c#n7UKWKmvNDX3?bSvxXP(#&Ni@;e)<_DH|jXaVy zK~D)xeka;Oey<0g>3QG);5STCIhXqfq&~^3{*3^P=8L6<21ItSEjaNQz~XR}5r4Vd zC{0V{qojX=f3ujp&tr7S=uiV?&@xfvGzHdEF$kc4z+VxHR$b@5 z)%dtN0Da-{;tE~E5p51%r_ZWR`S|uR+(7K2k6VnVNgccvRr}9ci`uU1y*3@B!|-6G zH|^w3WRr-)&A)Y&{}zambBHH|?)(AZrkq%Q{wba@CzU{FF{X1@Z20X43N*kUtV81N zhcCvqFP~urW91?HE4LWl+5&221TNP4s_F~;MHT&xm%Ihc?kS)w^SocOEsv-`-zq;A zwV%)_igHPbl3Vm%C(B6QiCB1IkbnqJB_X=FaMJO?Jltb*zpt}Q%7@LyX-t#*ig%?m z!dbJ;6U#XO;^P=E*cWU>CY+Ezb=ixhIDus_A_Gi>*KZg58p#nnPWjvtt+Gm---p9) zUFXt(d)~++Xtge1_i>wNen&9bD$IFx+WHp!hWVa1 zY)r;VUz-R}$w2qXQy1&qS1ottlV=H8fFlT8;?I91z7Z{b1H94jR&scg^ z@6QC_yK=@x=g5~^iSfqQ^l)BxmYxGOhGQ=ZlW^>^h@ANNMr3{7Q;e^vtLL_TN%|dz z^ofs(+!>R!H(}(BW*|?X%{xBBHT%h6%73ylybt`v1KXy+iS2zme85h$FoF}${T-x_ z58IIpkDzg73}9)cSk__2bbVNp>yz@XF``T|@YAd(Fa5n1r!@D~y0l2^W9g@zKIb!A z`W$EO@&G79O89=`WKBjdy%NU<6a>{rl#KboUSOaUEsVY`E*#cJ%o*e`l_V5pvptrT z%>!};m>viAh2#kJ?zkEsjpTTxEsMl9K;*4;fO*r7Sj*t%E`dU$B9Ml+?)|w*s@(5+ zKXp)i$=|Gsq*O%wYd&6aCkt7L{X3l+kMl+jgS&XCtMK z7Y)V@>#3rM=0JL>ij~twXX#ko_kNMI_Z1=x1%gW(AAf1g8R8CY$(NKx;Q#+joTEd7 zJBF>}>qKY+B4>z$>C0!au|LecS2;u+51In34FDGY+q7 z<|KM~c#l`zTkeAAF?8b$^{5e94tnWHRo-rC>q~r#Eq@c=x>(q$Ar%M|JbViNih^MM z_dx?iIDOa4IkvaL6EJWtY(6PgJlU5#z*~t?yiy14YDje$?Aw? z*$=9dnu7I?jnvr)O5=OEY>m_;t!R3Tcsm?>Ddlp3tlvxPnCSC zAFHZvaK1eo1iCQ*v#zkOH^%Z#deeBbNE`7#ZDIyvebv3!8mvX)Qyku12e`F(fp zJ92_vMYMS;>V`7IQQkvU?cN!w3OhdY?UBJk)?s@=0Tw2rs7{{w5_rC_o1;($vaRAM zX)=b!%$Ua`S%ZOQozuMtbeH^wX}S|nL+L%TW?CcpZ(9dUt&x{Il>q{)>70LHb1UL; zSv)l&e*`)S(lkT*d^9gqW!CswAR7*rhLSI_HwkwN*^;`Lr7Kf*`BNh9YXk%hA=<(>s&UZ-m@bCpb)Zwqqe<^d8U zGeAefhl>V#a%(p$ldD)|Ab;u(C9=J=7E}`suEcf4X3=wB(O9}!(f|uvEnK-J%nCg- z{wO0wKq!ESsYZr)wV5bgLj%q8?&C74vh(-DLyrM}aY zYKO$5pmAJ8P6C_eboDkbNh+5W4El0Gr;KLHWAj__{A!b@CN9O?s9CHV2yHS)d64`(?FNdStX>RjhjfYoAJQoB{t&Z<83s=}AprBuv`rYvNF^C6byjs- zGSy?S9ywgLndL>u@HaXGD4ev*8LhW#WZZy$=5l)#rk;dlN%eR=*rLk$ zVr~u~(NIH-`Oto$pR*&hH?gOqXWhIa!Xd5DG*X^uX|!oOAqtQH;=_%-%F5xI5) z=Wr4+*dWjx3{Ke3?g;l!7eKL4eM%%!AJ4pxZffvvND?lBiW;wJrv+D6V5~EQifI@1 zCApCSV~QysH7#>})9Wj@u@GH4*}^bfjtAa9@avkTefJN*S~J)k7=b31X5Qb^Cl9)a#Cn&Lt*4z(DD@u6y@ zkkrNM$RIH?u!}q>1PNkaBW;$`=WOYP7!X^aYmL{(#7)O#3Zs2r(ZLiNwHf#1>E`mJ zwgt*N>`PnPiKKMK%M^4u$RWHTpm6XW>2s{|wEoYgdAN##0!ZZGZ%lPrMxkqiSM!|9Zqd)>^F;%AzR>FDGn=~K+41G@qnED_N^#gQ-VqodO`<;tYDL3fku2cr z(yXX;LGT6qtorY#wUf}5&{Nrasm@A3O-xBnYQ@Df zHU42W18ekG{2L+@2Q571^XT}#`@~!z&j|i}T2BOEv_mZenSb}ENKi6l6+#*}NE?Eq z6#xj(N_nnd6AUtGSta4%NDa7XS|TV;{bsS8#8hFcZykl&ZB?rU=u68Pu+ztLj{L6=Z{>m1CsnNa>5R+6r z{Z3l^$+Nu4`)PMVE8e`w11kdDL`@{#cyk4S0Ifdl`ULS}hh_|aBY9RyfvhH2!xfTU;U`w@ zZK!rRab5nCHHyWlf|ZvW(%T-rm71+NirO&;uaZps!^WcGSsoG@8pynE7H$DVmkBm= zvFJ7i*Y2@1(FG0*6@>?$$Hioh84r)!;jO(y7OD->-?kD8T#%j)raA4d z(}L}a=NZgTNqz#V6Vpw?H{RshpS94^mi--nj~nwx^JZ@3K{bH7$k-4G2HhBpXPnNm zg+dQ2TG6@P+djAhY~x@lVQI8wmVXOGYPX>?glfBNR^1Tb59D~oC-7}=(Tg1`z+vcv zb%Y4);ZT z+7?dVRp+M3z!D-7F=a9UhP$V3w)EdjACr&vw@>->Ca%Bw(%b;5@#8dt;f44B8JiU; zjM6R?s>IqL%H}Wte0&0inVCTWWdc$tstJ~eOY>2sJn3hsL~j{-0roR0>G$S#D1RWW z;@IB1ZyOSC2f_rX5Cs$gaowXBp-;w^U0GxWoq*}6MVN}rh3LnBd7#=@lOACHwEol3 z)1Tk}0ilHaU}Yp<`8cbrvK{Go=OR_?e&}wZq$eQt!ZC(Fv^qKoOh9)FlA=BSb~gYt zU|!=;}X_ePk!(HbOwHE zKV>sT^Leml&TD{c@c0#Hyb>Vqj0+}_Kco1;MZ23(-3d~DQt=6@2!&3pM^`Pjwo<2sB0XOk#3k}|rJHNSB-mRz_W zGhRb~_GhPoPx{&FpX!sI0cANA`iBNeS0<;P4G&=cK=bcH>g=rur>{v-(@&ftWs8!r z@*(c!;qRbTQ8e=gOpRpgCHhzt9wgR7nCy4q*Yi#iJf$v^T8KG|B`nkYQWW?X!y8aF z@TZ`QhMULR`r%|sq)TOuo?8ig)1tP@mRqE3Nr9wlMN2hZWK zW@>?TCFLmtVxX&ispyq_I=yAZA-sCS2P^%^D;DDhtiWkY?H?)YfmH~1=vP>`XktB> z2fjuCw&@4AvqV&Lz6$9bkxDGCB}XnY{}~4`Atl<8LWJex?*lvE_G3m&d*w{OWj!|9 zwc9g3CzPCMRa*h725w>Mx73LI{vBb@d(Fp*(y?@o^)H!B%#JW8o~GJ=g`FYa9;a0i z!3X?e?0I%ITFE+`LZ+#W97q=H+>nLc7f75eW6t?_6iK!9H z-TWFD6V98!N_D$vNB&}A7gATo4?*Kj`{4OQ6hlyAln$p%s*{^@?S7ioa%VW&VrW)P zjRIT5G97-#WPo?~y+7&xTuu}XCy4tBTkn7X!&%*_>=kG1?Mo-_kq3`u)mfgv^LZ4~ zhzN64zuA6~OGymrb`eM9rz&jOZ{75@rG9?uurLIEzo#l#<6w0~T)B`GVibgbr2$d1 z33j6hi%&pC3 zO3ToHuLVukn`FKS%oDZl8g73J&SU=)&K0sPfVi$&q1O9cg=O46A((=C;AV9OEp<>y z{KRJ?Jy6C>P6OOZVD*yCvFr@~Y{A8RM)|Z!EO`QpZgMrK;WCG&$1;%p3C7doMzm>o z37BY@o~4`<g((&dO=>T{+fk-8`;(am&`6v@u?9$?PIF;(~+cPEP~Yu74( z0W`+-uVU9m`|e=Oa?8j#kIx1rUSVFYKOo}YhvGrtWj#oNk>@s+S}J5na86WCf;U19 zodB~v_nk5|RkY%lKAo;x5>&Aq=rJa!O?N=o!uHsq3BE~$1g@#&mm(wn(r(Q61U$+v z9)6BH^~s^PV7M8Fbo+g_T!Nz+kjDWQ8~;s=SxT031HaR<#Xo>2(4%oqjgFL6BkeURb(Jx# z(J43*w%F444jjvXH6D^38-&9+S)Dxtht{M5N6pqX_^O{V4^U5c<`+?ey0x6i!XkNw zG!=!jTqSGYeWy@T6bcVE5WPdl=ufbcIpx(`+f)I6DJQbVxlIgd%L8O8IrV+2ju_wT zuAlqBfSKM#3K8u+_gw4W2k%CMlcHd+d|mEW_M3C8O{eP!4}HhB&!Sp;Mm^V0UZ@oa z2^hU@u-)X)*vFUocXW*o$2uF##C`(jXeA&!w6O85zNetf?Emi(s`qJaeAyW89?4B_Nl13fOYy47Yc9dsat)2(!j^$VJvSnu2AS;?$xyyL7S`^yObHFeyofla8%UN7J%GSHar%v$@+NP)!L>8#`P ziMb@ZUTvc~&wrHqN_hrNSQjRtrj=&OPh`!u>C)tUQi9w|0Nx01FcSMel}QziUs*8f z;v*4z=k^%GZh%O6Y9k?JNv-rqmlq44QOow(XPUGeI7nkf_+JnsJgiaAgjMAPrubtV z-q^JRb$HNJx^#e|Xg9fyuVg!kujRf~?lnO!pfu8ynt*AQWB#LZI6xAy_({?>6L9%^m=k*q`8pqkLw_*pKyxlhq`V*-gk^ z1oZ7G2*v}eLG^%YIthCb@e{*eZHFtIziZ%>I;7_qAdh`zhbN6HlpGn-18dBCF3#s@ zvQTyWcL>CfU(UZk5SJB$RiDzn2NM!|!zn!%O(v^clc#*S0}&Y)iXc{ z=_Hkgx;q_kG(y<3fU~zDCvxq)z%V)k2!P*6p*cM#$$lk>vJmlD!N!lDp>e(8>T2To z`mSDW)mId^unH_t<856W{df=en|!bEREjqQyz$}@5sK;Y1CBSoG1oU3jzl54(xSaX z`QYN7K?ZCxh19b#*|+;?JPZoNkwz%`VO59&Zx%eSpFXrPFy6gQg^m6E)4O19AU&&S zKMr4c;`I-pviRa^4N-K9&zwM^wooKSkzhv0?hXR_dwnU;e9OA^KFWgv2R-@-fl}Rx zQ$Wm>bEAupG{Tivm;XcLpK^dJVeR*k%g0k25=(1_wv^%8wsPa<%EXotF@Op#D8FiDbKZ3aUj<#De3R)$u11_UCV?dt?QhV zSAq8{YJ$*{9CbSxEUV6*kyp9v6Yav;VzaWUK`3 z?%wYp=;!T=F|u#ZnL)kgsEfP#Md7&9@n(%4SlQCGmUe&1*NDa+^{*|_$}%PLDZ30` zAC2o+mg={JjJ`KK#^fFoLH6KIrYkyt0pM*X>T<@?dqpMrvdUgAS{HaMS%beTl z9I+;Uj`|=fQF{3y==G#5V(Fo*Df?6f$bKZ|4saBA_6tJ$#8fSmQh8y@W*xFy*V~T- zvL62OUm=iuP|AkEcVNqt&F==VHh;LIgS5%}>;gi+mOT5|R`tE9f5pAbSjx0a&gg=+ zbac5Jb*U`cqET4o&|JpOUxSsZ({@ zPb6R@CJxc6U|vmPPcel+s@?aD;jnR4VC`yKp6CpU)-C7}%2NPI#fE^))8bZZ z?#A+oM=Cr9hd1}MScLo4X-+Qt<;M^U`3-5SwxUWm_`s#T_Y?>Q4ST0*4#-9ne?RYs zCoSK54F1(twuA5SU7j4`TB^)6w3W8dQf2N9VwLsycJQ_Psc%$q>SH>eXz|<;{WJ4| z+G<_5(Bmu6+^eq8R?11OS9s8E)&pe|JZ-MPIs+kH#ut>T;c7{{d%R@=>`$vrBnUY>||V6s4Ub3+hzi&N2kd( zlsOGs-Leu)Wnn=u=3=@HmUqAqY1!s~q{YEg1x7C>kA%edY9}Kv3xH9~VXFx@kMGKK zkWEvovDAoN-ph?xU+Ei(DAp)y;X>KXwYUy4^{%Ey{ogQPzaZgHRl%BIF^dd;Ouda% ze@56W1GUwT0Cg>Aq+1jo+$amU);X5=-+wth72d~68^lT}C>|X_oLp7Hp8BnO0Y-A| z-9d^ywl~#qmB}>Av0tSI0#Z*cYF3psP%3<_alV9s%z$ z#PZ}EHk!omUm5kLQM285>;!%77Ibo9D!ys%*`#O^+VNz-hCUUh`AC+E^`@p<#&JE0MX*c{_EP18* zwhaGRYG~k>&vJ5Na0sXmKQ?d)7N3)@MsDH;JebUKl*v6GH?7hqBwuhI&Cgz&QsPD|t_PKqJ@2n=L+Zx0p(UP>v{-0Kq^LCTGvm6JDlF{ zFUZB|!;P3tN?A?2Crjq*G0GYAqZc2yLs4w175)4|E}AJ^g00Q2%@IG_RuNAQWEfI$85U8Tq5#c^ z{e@cBFhOg^>(*P53AB~U^Yj#co`Y-%)TvV4wzhCBCJD=N0ZBU{qP1h~C|2`V3{N`4M$Uzy#TIa}?u+=Wg1tiwvn+qM4ikz9Qtz=S}8$8f`qt8x*{lpP`}IZ}*v zN6~7~Rhm!bTfdt`qt4JE<7z&3rzbgtAW`NQU-A zlyT;6$$ZfNHlf^35pSJDqhApJIQmFDN`YF>|I3T63bG#TD18(>PX+k)0WGV^Z0gNQ zUbk_Le&W##$Mnd|jrUZ}b|n+~pJl~IV*?hPT@o}+o85#lV2fpLuX`J99fV_f-GX*T z7-I7=EgrFUTmf>$+D=V(=p2>L9$8mXqORbMdjaMiA)&6C-v3^r1D924U@G#8OL;v~NOawD-)t${c|eevBDGD6;wqAE4z?e?upn&3ug^3^>oKq6We+K8fR!LZitR_ zCUD>a$q*rFH>d_xsOP(bAA;8CGoU>2D>}5TudUkDfyE$ZU>X^axt9E~V{{6&{Reho z8Q*>UVA1*7-EgpUVxU&?IZ>%|49me;;7BD!DbXj+_)!J|HqM&)udx0@u}ELFI687v zKS0zxurm^<#AfN;1u$pwv^4NqQYlxl@377-4f-u(gYxH1>s4p5=)bLFTNJy*0GBbw zGlO&STN+|)zI6B+5pNU*8#EV5Z6vvh)5;L zIlaCSZE#w8RWlbh*-HL;(^QX$5+3n4C|zoo%?ir0X;w=)P3ouu&IL_* zk<#+9N{pvT?RS~dk^(+rlYJXS+HVx_MwkQ+!${CALZ#pOt@?3vi*HJhfPCAPlOQSe zI`Hv}tw1a__K!KEpFIRwhHEjnQd;TOA*i?xWxtaTof3tf^kjxN?kQ_Uel}VKgN8wN z=^J*I%a(>i%|MvMn1E=4BL*pHpjKdsBJn?4@4jRMBoq&$Gi*gf1(lO46-P6Z)`IxI zFJQeU#tU(cP0T9f7vfAQJaOa%Xd{x@vY9r106M%#*GNRnC@q@S{Hqn+!S`E0Kd1C5 zaEjkOxV{Kc*>@$iv=qD4K&q*6_*&!K1GquAkeonqQlY2QwT^68v#DA1h#dp)L=KWx zia}mgj0Bd-FBF!_{8K0Vz^}Mwv20b{BzAesK!&-kc? z>)DS@IO$rsSmMWQdAAlmc+!hi0ODh3u#(v*kQOhr^4xfs-`m4S5XG)y$3xUZQGdeQ z_;n@A3^e4W=iDZoSxWjB21H@88W?CiQj*5Moxwe6{WkgoW~a@{bfIy>Da}eJnwxcb zANRUwWn7HlsukJDGKZ%efh|V_zj3d*=Cbi$J}6z7No=M4QVhiORWXTbwd=HKzNthc zV7>G2mAi943jD`j)-7%|*hL3)v7mVHKkA4t z&xf!6TFP5qKX$kRM;a>Bz*E=x5|9;25l02BJZ7|NhVQ$ZDJg`3#5}*EK{!pHoLGlJ zY|7&~=H;Pj_A+{qS*QYrAEtBAO8)IYPnfkB$f*dzNkUJhk4F`>W|sYTnYA5!&(cnK zgz_PDWv%ve+RKcaQ!SgQ*21lSBbQLc5K%l_`|Ji8S{c;t-j^DJ zaIu*AslZhGQmA*}_uK+UcxJ(=O<5$J*~ErsX*?h#?7sRf#UAA5QGXsfV&7y%IRJVA z^8{-X)*+|J8SjQBO+>OeI+q5D8}KQ(mLuyqGu-d7Znh}0giA!9y9Il zY7rg;B9UQWM~%s(5>5Qc!^xE2zNM{p!8)+)#frbWRP5-g5J#^=4}Fho{6cnYrw0sR z1;{&9)?>+I6tO0WS#s9Z7x>*Coz4IEz^*7b9)rx)2y0eF(TBc3tqo@xBP0Z%e7C4g z=we-rS#NeW%QQ$1aAG&#`|eNzb4x=G=%YiaAt>sbg64nwPd8t(S%torg%s(0J zg_0xr>0kM{0fQbPeEZfzonl7iZ1ThpzZBRd_E?7C^?1vwa4t7}bCPNT;UW!dr*Vxf z!I{mpYp`Ui~fNaXzIlpgKfOkY&KthjIdH*^1cH(*Qn zjVqE%W$5nAeG*kO&fY-4(mxMyNdYc!9oI?EWBFDv=)%v)*0V@M#7G$i6Rj*W>z zX&BEjy=1^_tUcQ;Etr1U=Tk$$Gd~Wc20tgM^zYO5<+Yr-93yT~p)zPs7t*A_22)o5XG2q%z!XVh*?* zt6!>-VF&J~QJ6wI$;EWPDLT~w>oh;{C)A137&+#DNba&zO(>yk`)i#RulEIG*Z$z7 zZ$+B03WlO>DQim$MUe3q z@3*)5DvK!vpCGNG?Qkw9nYnpU>ptnF4Q)V2HMoGM$xKhhc1gpp$My9{#B9X?=ytwh z#c4z_d}=j%tq75<&R>S=mG2I!0z6#*_)$IFj1*MqC%&9x^q;=CRWt*oyX|V~(wV@5 z55Mc6mfguNL_8~qk)QW4?H3H~=FYyA$uJ2= zA~}O+_}wRa0K!~~$I42)pFvGf<^dVxR9tWLyj_qWeZ4vh^@%G9>So$W6f|f&#Z z1CGGT%B1G0Ri;AWn7SeHHI_ILCTVH>K=wkD&{#r>EDOfV*~~k?WpmKZR6UD00-lzC z-J+#LTXeO;Z)zTw>o8tz?_$)$Qi*2egbnW5=B( z=EOQDLnDR)TH>BLNDZa^44y?Q1ZDyK@yk00_dioSi#b^|rh{4y{%r~e1^;3p#ot&$ ze%dbtHj2fFSHzfVTS{Cmcq08?M{t0DICaA=yi&Wm$1jxV*^6ofAqShZyIry9xVK88 zoKVqH3u$78>tBVRL-f zZQ9SgeI5J>pFV7-o$5lGAGTCxQ(j$@xsM28K8L+nr75 z11pa!>_2Ugzv^` z8l$Gb)JTLg%?e780)xX%_BU$1zfmMnyBrO!p$LSMdv@Od&5@jHWS4#_=c=aP*NqbT zYNxjjJas@{1wen3IA7}_BL#6-(EW>ziJ!ZY;@<>o0851ud0WbRtjpgcawMB{$-q9^ z;Lzm>bWzdqT)(j$q)+Davdw_@NEu;ajn04@fSBX5j?b=whVi{s3)U_}xz3?FPymK9 z3YIm2+eQ$D?p9f;w450idXDewxX@1#GRr~ zU%Wl|iyu7R?j|btGH&`a!9zHnl)hqV<*LsT)XyU=5`a)3U-y^Dqic>34oTZwSZOJw z*Q<&h$fuC7*IKfc82Vg%z6W!=VSPfwDZR0)H8TyM8+JMTgeNNY2Ldh7ts@EtB2odg z-A5X>yofGhuGEy%DV^PVu}hYxOn^9DnMn$dI1-@|F>eCqgc+h?w}PK}{cdJlxu@?g zjXUHYdFn1HFfyMuZf4xd&G~Nr(1Qp!aGQ$tjO?C5Qb|Z$H8vgU9I4TP>~>p8%< zhfnxkba&A0yPQ6{mU&J-5;@wnB~Ui0wn7^ zO&;wwspm!Ue&4u3va@zk4C9`KkYg`NYt2G z8g^;v@%pQLR)OZJ4|k`#BSW%bw9tknmyNj`1+4GTHI~rY0-=0N&AhlT-{1T(l!&H%%vrZ(|{O2BO7;;1Ux%u3*&e@@bEU94;pLy4FCcP!~Gj$BrmR+ zulLlY1?6FQb*Eo;5bbFr9O_iTXUl^Y!C-Axnfi5Qp6N4eL`(Yb+vJ^r^ z^ps;J$CySY02pfX@?aMQkujx^^D`8eB}?Tf&kXF|O&nGD`^Jx3?|4`KX(AjWPIW@F z=|KZl&UUacEM9ic zVkEnRfTud*(LG~QjxBF}?50NvWG5$;)d;6^9mw^0Hd4}1auQkCHlR1((%jHT%B(vVLA(KGkK%Jwq7z28YK&&h%7h8D|e+ZVl6VP2~8yC_2Cg=-jQ*8)CD$<(8 zb@}lMun(Sj_r)D-P`1U?2kjmg!Fn!V+{r!x01Q&(DD#+Taa{O9(t)M#Yu@Z#^YVb2 zcD$VA-YL79+-?f>$9zMj&l59n2*{unhwAm^SX(8;?#4g^k(P9(p02F{2XXZFFBcz( zshO5fjxJ#R7~uN5{t^Kz4eoMB!po5!Eh!jZygvt;PAkDqExPAo#}gmV3$H-oHaIaR zIYSz$$`H?|aIDr@qskFN0G9nxi4bEqb-3i{P4?0J^1HX(Z%4RcRx}|z$8eExeE2N9 zj#B>R=Y0f|6L*C#RsGF>>NM~$X=dF%-nm)<#7sCe0Q*z+@Wp%lYkbrhagN~ zgRq7DiKJvs^rm+JJ8~w6Uc~tjS_4Q6oub13h>H#=9_7aV{<|+x?)1OQl>F`E1e_sm3GBJw7pGk0=WJlizVY$QC~6wb+8B;+i>KezKU|f%^0VMtQ9j{ZV!I+MWh4HEFX%ATFY1 z@oqI+cmh0=VxPQmR|K<~q~6V1Xw_bIrq`^YNs;+8_BXJxUglt6fcFZZR z=834nQMS^&>MkT(YAb~}on(sK5KdTNOUM;TD_5N=fW=uNz$1&K>z?voM3EZh{!hsy za?~^_6NN84)fN5?{DB0B(@xbDj6#T?PS30W&6j(S<@|O}DhiR^)u-64S#3?%?uNNS zpCb>doA5ZDub2$r>(dqVPdICT$j*|gsQ>Ns_670gG+rA8$JDlpAw_~->NkOJr70Kd z#}eBW2`9rP$jwHyVBP5KX2}_VWExUZA(d+h9bqbHF0VY=MqJ4mHVvE(h2~ydN)nEf zLOGP!DLA{AyCM&lc;*5{w}OK<+)RgABNr$-zTJu5nd@C(DnhHQlY~4cgsbh`1V5Y+ z(M2oEuUcphNDdS|p_)RTw$CdpU!s#<%es{o)l)D@gZ)K8GpUtc-}|3Xj%R06<|XU^F~Kwf5>I) z>gNd~;AJD8qLc3&Nd|TVnPi0;HaSU^fPF&PUWF1FBz(COpP-kcb4N&}7k&Jks$#V6 z%DuT{(u>FW9Dq}67nHEF!GN2YO~Pz^RkngA#zUt$8w%xa6eiNFklqE|*nfll%n5I< zVLb?bIn)UgkaC}M~MB6Bq8^9!m^e69EJ4*!mhy%IPZ!sNPi z#f|8U8}}5K&yiB7s~<2wRL)U~FzvkKv-WZ|FR*W0AU=!NM&ASODj)tm^8Is(*6-_S zWgL-`N@?ks%k~myo_r0TLf!q<{3+vSBO24_1>8q={mP7wNI#%!AbIwB?g6u-X(4EA z*U^c{^@**dXbsaiZ*eIpauxECM0YJtU{i=*a%2lH5I z58Zs#b7p+2+aD-K!yoVpd-P++GPCS}jTa%Oa-NaQLO7FW$i?}S#lEUza?(=rVi z#?dBhDTWHJTh?g)ad5bm2!bi%5wc(BpZiA_cN7Gu1}Z{yzp3o$bK6qR{!V1jz;_I1 zPl~3cL_A}E88L0jN7+*B&l_&UuIs;a@rQX)6)>4G8?cdMAVO4MzMK_ndk?p$POr0` zMP00rknGYAll)y7sW4{xM9*r4Vol1rhtj322kmKJ^m72~0uAoAo8VHa&2{kky9!gq z1PI6XW9fdTp*O&(dB$ZqjUKNNb?I8f@U2E-u1X&U&yw%(D?dD#V#ch**0C)Zro;xb zFsSzv2m^Wk?J-7^er z!fwW;sgT0`tsbJt>mW4JMVc^o^8+*NA{Wqu*9`9|%bH|Nzp$pzH$LLZoQ$H3hzD-VareWWKc!$Z8EJpo2y&k=3$l^#=pQvDsB?$zUL@($R^_i<>mkdgRb98>}6WpuG4j41w%M}weC3a#2qrYh&N)7uG@FiNJZ@hyR zEsfU0#giUbBz;>yXrn?<`S-I|qhgpdgQ;iZv$52ptItY2lUU3BdOtq zUV)&M+!RRkKg4sr7pM2SQ^WVa1M1@HibmaSYn7}K=tc+Ar zl{A#k0`3;vqu$j7nlfc91c&1|+-mJhlv@XzF;tGs&971mHuSMLFJT1X91YXh`F3I zIDZ(8&CF_ht|gxR=WEP+YI@YOSwJyWjsS)Bi(Rt~_FELMM^CBo>KM?9pEpQCKx&3#kvYIKNin0Br0&ysY{3XOf zGYvcBG?_V?-g7v%Bh$oEEatJDTFcU@Ef&$>vr1_x)nWnYqLeNy9ec9fq~QH2LX_zJ z5bvY+;?vjkJjbso$fYbR-Dn7gaD-_I0Xb(TJ5eBKhFV%CA6*`ncItiQW(<@ zzw|@rkiP~Li5)G+I&tHbXejmdMuP85DEp`1gLIkrF1E01F(6RIkKaKgM(gsC0`O`R)Gknrg z=}whibwd^=N2}vqLdNW(<95VH$4PaUU6;1G+#%4b%9y4U&;J_R1QvXD#INO&g-?%x z8bSjoH;W1>%L#2Q{5C&_n5gsX!o54G7EsrT89k_;>r|z`7%jx1_Aijpo$jyzFscsL zdMNU=rYrMr_$5WV81(mZZn}#N^KjcMeZSX37}N`-10jh{ zU5sg%qS9{RBaK2Xg0VC~pX@QJ=l&D4T!q-?SzNTmvxUA+HgfJ4ZD*rul+wF3*3xgT zR6XiIkl2Z}2oXPtzN8>5({(c6D)|^c=6Cme!L9AsS}Fz?Ax9XQ$T2|`$?GBb1=umc z)<}EF=~Q2{&&O)zhl$|GVc<8;h88zQA1Buos)fx3Q}UoYsl0;WVQ)semd`^+%0@m; zi1nq$TGybpHF9M1$(|Kw)#w-KglZ+ZLKfvM5GqPWzOfW(3Ft~agg8CVoig+^#xr3_ z8KL$fDZ463o;eI~gnrZ(@o&fsFSYLkbsr#>qb_A@+Y*=%g-p#J!K0yQnq(D~&h2nD z*?Hc-a#fT9^N6=UTzx6mMe8x3yIoc)`UP+J=#_z5$){&n4*w505pV*9nTc_yu(7+v z$O=G-CY?B2-EPj*tr8>+#n(>|h4hwm2Upb-;9qo_$F>}{Mjv^|Yw?1#-FyV>yZ?;g zHtSR%JZaWU4&TEuJ{J1!Uk`cJ-Efco{!cXvevl$rc|VH3C&Tfpa)CDhsD7C%Zd#8( zF!O%~6U|{n6vf+D73=}CA9)MnMw1h?f!0camlAHeomVd0jJY|I02 zS6RV5cV5mwH)iTHayrFJuu=7E23J^rOm`h9{%$NZmv!Y2;= zz7610rFNTXVNv{$ZB`H7atAQr z{Z?eQj84(wvc=;<;SzJ$){F0401_eH8eM_okKNhZZ~l9w1VH3|eKG*x3^dMXA185% zC}BCjp&V=f#9G|IQ^`L4*>Z^hy_JzMV0zuD8z5VNfHd0fUG#7uY+BpP>$_wiW}1a5 z3)|ZDFdeP;`~9(lU{mDfHdkU0RB@SBf|4;gnMi@O?AL%vTM5O;r#BVZ$3iJ=wZHf3 z(;lmfGl0dRvK=l4t|t;~i3I7}q$Dsl%(b!zmqHAo5gdE`nVki3ZBa5jv* z#CZ+X6idjcS6xCfoDxppINbn9)s%<1b|TqCO#NY%`uITj)(>a-h=l)FBrVs-8%Vgt zZAD`8%SM#&vp`t~Vc#7I2d&g?8khGxlk@`bT`}PRVW0Dl)M=^>hIHek2H)1FZ;yR$ z%k}{3A9HGU_zvt6uM#5muwC>V-Dv!~o7vLSkP*WI_J@yjG0L+T0^eZdx2mpzv;$#3 z?b4>uM%bi|sIQ+4n4~^oOis1j1G`b|4w;-hxTEiS)aAvc z5MAklUs44Wp6zK7+385pTVZ8SA2v&IdIfqG(Ht2eN*eq$r$I=@D+<;*#DMJ-Ny-T5 z9wkc2%(_xMUZnSe?@!!Xl&~-bQ#I_9z;;O)6(^}%JERe!?Lg)WjJ!^x^!!3^u>Gk= zx3@1n-J|oic>)|aVaOVVjVB#PtD;2G$6x#Z$R);oW(OdDzZ&h47vf;UZvGDbNYo+j z!@2f51M2H!)L(v*_V3N~J<{;%_~< z>GOwDqy8v#cM@mT&esoYC?Q%n(5)6Dz%nC|IdGuAW>8#;aH+#D_}V-`vh|nXs2^|_ z1Xorqv3^}j1HT0Dhjt^6r+L0{V-UTyp-S463M3^nrg)_0j0Z~D64MUp4Jhph4{&S# z%1WWq8nFfQmr`Gj(V0b0Uzq_bDo@I;xkj#E1Et*+m?n0mQSo0lfWQLF%F=}5&Y?ZML zFW#h~CbV*Q>+b1@oWi#Ts2w4(^vj)0?&Yj(SOLpPY&n4nP8S4R89LcUlj1 z7ao#f) z^W(aZeh?K%`j62co{G%gLALG2r;2AJjV(X6Wj2zr+-SG6Qz}KE z4xnldwv+0Pj^vl83uzGBZ!T23ZMPCQ_Z;pi$Kz`Kq;$Q;Oc)`P8mbSz2&lh3)@ZgB zbC28h0E@S6;~i<26!i&o;jj2IC-hQJEG062_{iiYq9s<5=^XWF3pfBWt#C>0hi(w$ zkY{Hq_5?4%xiPil6Rl&`|0NMQVbF57RS^!gBsD>C>tQWudG%c~`i>K9Wp!OFP4gJ;FF{jX55`rJ$9X(~@!}3}R z>D(VzT$C|^Eo+wt8zDFJ1>>+PAFdeVD*N8HX??)y*~-#28V{nMVJ3rzbe>42Nu)6L zNk0eRig+_(eM$(i$b`Ix-$>5p&bFz1?sfuX)vv)GV1xM|o?e7HtM7w8ZuyLcEVVCQ zG?28a?3V<)|D85Q`eG}@Bbh!jmkYd)qjw(T^;D%4yoOU|`Pny)rN1dFmAQZ_%>kn~ zsQ<8vY2KzrCenVwvX2nvQCtDaAeoXc7MaC375QSjLjQax4}dWdy7;=SVgX~w z%RGJV8BP77qT2b-6+Rt|LWhipIM?OtIU}AGBc?xy2}*lTt_F*I~nnhYCbO@Cxa#RZ>ACGre(5Mf&9A+9#R$`09X11#G*P#~3D76KX zaHtLrQu5jT>Cdz~b>0s{s5cx40;P|SquN-kI^8%m7`1pJ1P35IEj+;Z4Xb+6T-f9x zMk3;Z<`f4H9p#@S?xd>Kc4!;>s0CGelR8Rh1^F4DhG<^85 zTMbh-h7T|QybRALdbE@!KfQ2LJcK04$R5>VhoGgD;99bIY~YaJ_`Va3M!`byGlHW^ zV`$O4wV3pJ3D@?JIs+j$c=TB(7b>+`S;iDXdSu!6DBY{y%^aqlCFpT&I72A4wVbka zKgVfkT-qFL{A0yY$=K8(gim-n>9#t}ZPn$QrcABY>&_B}S(94jM4c-34(Hyc<7=wDbHF(^X1=KGNP$wH{Lc^rr}ALw^B zVyj4JA1ymVIgV^xt&EuPI-yd>Lh-#YJ%G!Ps^QU`oLINM;V^opF@{p( zjG}#S2GkZbqFy)`*Xua0!@W$(<%Uq+y!1t%W->h-3LZh_9km@;{kMoO`%3v(g0rDa zDI_jLLkQ?TO+6?$SS!*LCk{e%YZheX77rtvqi4 z%3QCF@976X+xjEt974-bEf0+3NHM{O6ylrK>taC6tfEK#S4B?*yZWH2*Y^p*`nCl6 zrT>}eYW!LS%l+yUw%1vVO%Li9LPp5|K`n9_T72rl+9MWb8Ad@?!dVlvsZPOkny_OeGfv$rfc1P;2kgP`4(5bXCW+-r&g!=9>oB#Q70 zpPT*XVbwBK6Zrn}8{vm6Wn^?4YVX9bGtFh$IrA;tWO8pbIpEWG{Ka`9Y?v?oOGZuS z;MUdhRlUO({(2^e*_xQY7?bxClF@}QzgtF3xjZM3w!itXyL5yya3RT2UpYq;6gJ|Z zly4f@`@)a0r7J+L3?oX6^O2r2OvE1+H-Kh*jIinoZX0|6%xQQ&yIN|~l`?j)?+?>k za;^6au#Qd9L*n0A8MZ&}xu@=2&egtTMeU{F&}gZtCVmNvORqu{PVNuD4|?IZ7>C>4 z#>gXH6ARwqAy#NY$J#eC=xU)DPSwClAuBAJd?Tch+(L!LUV=&#&AjtHP} z(Q!#Tql&lXD)f@U63oKF-GcYXfm_3*aHQdT@U_Xqu^?X~WhbS^{PlrBd`;*oTqE2M zp&;5(LrTTxn1tV3ji*NT*9-*B0tb``Nb(MS*Ky+1mM4vz)5qdK-^oZ$vVPH2pm4O` zeUCd6>Ut!wW2H8b!~(QOci8H_ecLaRk||N93%%BiNSivEQQQwgn{xqS@&gENyppzW`fEQe?r8wMEB=wS1?T#Xa*Hpu^k^{O6nF&E4`o z@uI7w7hK(*tpGY~6+e9aZe~W@3Iw$+!O60re&~3-1cp)mGXz2^Y~_YT8FP1ADGufs zry8wYPhY!-**kbNkvG=gf4Jdi>w5Uxs8aL{aUe36FGheo;;{ryKfSqh4^@!@&kvas z!{FfaG&4d4{4T*d)jzqhw6Eoh$rVMLPObn73QMGE4kvQi0FkSZ4Kw; z)cZpI#`A@72(Pd}M#^0E8pKb(Ihwt%8SL z94Rz;oyMf*f<823t+HJsk>=wHm)mo{f0q^t%13(p8t;S!fzB@EUg=m}h|5{~Vwv<{tVx|W2X7g~YElVo;&>u

zY0WADKAWT<0OF%w#ffAXg?lacF!T2=wfq9TWYi{NFEk;R4lP+$^3K zzjyTnhV|}OLNb&ao(Sz3NjP142ps|z7~+))+-MAI{A~*nN3`yK&GkGWWk-~^>JcRo{@lGgH%}xD%4N4 zIDZl+x2YEhW?97M^f+Z{V$bCfoRgNpJHk*8 z@fjVEn&dhdwK&4{$X<>F2%;;6)wjp|OCfusEE{of8(d7b#_N)`iwToqePF)=KYuhs z4TQ&8Setk+!MLyaktZ@t^XJ-HXHD({25$8D4O*MouW$mJ7}c9*uRgoy1Br&V)XMkg z8lK3AG6@64PzA+TNZLR~K7nEYN+#LeK{48f5Zx-_5;StG7V-c%xhdxC6&&k^+!@fY z03*%il`4)K(6ztDU}ZBk z-cHi#w3AC|w*E{a|6+`3sWfa(=qEomvj3$|)Ivc;rBdl0w0sD=W%2pyRQ%x|u}@2d zFZ&(eZhKJnGXp{o{($ymo$lE{^NFDPs2)71(Qq&ERq?Y|u_q&F<#r2z#R~{gh!LZc zi4$<=>=8ezp=9WX_jkvlWr^Oe8amsW^M2HcO}GL-6y%Wv_3O@zCv*(G7xhNEezzGb zYUYV5LbT^)a5)HkF-?*+&!7;W7l$YAPGPyy(hXE)g(5Nq6bm_iT#f4T)I-32|i*<7X2W*8;WA zMlgPwX}?S5~=hx|U_^2@}i@>?sHI|5zjd$7WQ zYPhK;b>z0nb$|`<=Q0C@3BAppu}Soq=ar5T`a=Y_VYb?Dd=(nAlGSqRFmq?(j1rrVdmG+ z8RUR>N$2e83~|A${rO}epxhhdmtS-uXDLgARuuaOA)nAq88ZzCJOj!|!0^qcic#@H zQIw003YT2awvqj1YbF{^W@&LjLmr0}m}DHbl%9u#1&|IedSo!o3FVdP?R_Uw{Ds_1 zowqy84?y~5Nr;_l!MBh_x;uw8m|@dtv~VYS5zPmoFJCP~4U2C2U2-PQQC7*EPEpQWaQ(e+y`c$$M#<3+PqN+rd~Pf z_$JnlVr%kz>mFEG3D4G=VVc1=jyLwD3_TWPqRR^v6yBIYEG;G$B{Yv7nOVI$j$eXIn!)I6mwtN?z6)^ z0Le4eM?y?&wSWFyaqw!Lc&>LYm`8nkg;s5w1X(_?wAH{0#wy2U_+YIoX#uM^^M2YB5;-j8OAbzq+b}{$Ka5`WPQgzRysa z@Xk=qf7;*?29|un)=3}N+#Z7Rt-hFCZNbuAtXS{YxyOp{e8mhR2rZ+IfO1wmLcrq% z?g);jRA(wOG_6PKH#P%;G=EP#?<;%Z3gK86eikX!u8gHntoRu7jeQ*_KjT|Pe8L6| zVD`$5q~X(8&iNY>JN(-lmqas_$N0_2{+=+`cHChnk7AKG^+{vP>)WLc4$s}Tb!|0r zsiV9F4mdsI(3zmIX$UU9)6Y_K3Nh2D- nkM6P?U?Zw*zPZRiOL*!83Zd;No)Q)~D5R&LgPH>t6 zvM~-NN*R1Z*b`aV@hYL7ST`^O8CeMcOU%@Uwa}tp9)@{&E4B?yivoL;N0H#I^>7|8 zi;88D*m1SxY#h4$r@i?_Z%qiEq~#24BjXs zu0P`uFovE(bsp)OKVb4dSX=Tzg=1S*5&Gps&)apxL{upWtuPoY zv2K2}jzT;8FZUuuTwT|E&b$>rqhJhIt82s^~;t4Vht0#hlIX>&SdP- zQ4Wp{psfw39scEJ18fanH8QHa7v~s>b>`mxct2tOfmwxSNlR>=$SL;l&TO$pXebF6 zK$#K87A*a~s|pTtls-h-ci?@xqYfZ^d%#KX{v>5yedK`p)mhsf({}IYn^e)oL%@Cr ztLGvCDy%rJ_WnEJxpNpc0Mrm@sI4TvKno!)<*|I6Th@O}|HToY-2X_lU#xi8hoD}g zqQj6SZL$Q(^sl}%yUtPxyb#fZXEg2z7Gvw0eW>mLyQHnk3FcjOnx&E zCj{4m$zT6n(2-C^$u}W{!IlApj5~0jaAk1@-FN+_<)|H6Z92$ZLe@%Q8C06@B143z8xV-D`tU0bVddGm=+s+LUYZ z?S#s@r0vj~zjRf1G0k$(_*9*?1H&{cN=dF>T<=GPBAi+2zMfeutmJ=fB+q3kkr~|M zKK8hGRW?IANXl(d0Ft5uUh`#3RPOd10y(gevHfLz;xFTd__CSUWcvyfKzVUw2l-$+mA?_)#F|h>_(t~uJa`WD)AR64pQjX2k0YFR6x`*TD6a{`SdWF;YTiDy zsFl(QDt0=#niNmQa+}wkNnQhw7@Knl-5xQ312>tm?-mo+qiL1U-vvlco#6IY+=J>q z?s_ZCP+98yEyY7M{5L|Widhkbi~MoR`dc?uEb3@S0p;3N3AoSU@!*CNL^rBo(xP2W zdrCKOJ&d>R@6_yt=t7)^qCcC^pdHBbYhhZZrZUE@yEWgAeyHpcfrXdPC_DB&aW8rE(~$S8n!}kR#`Jc_PKEF$OFuI z68d>G=(302?>EZE@X2?dAXft)ec=V}R_LQbgpH;7-$bKEJOc@X!rdn|pz7BsXfhCK zCKF$|Z=WbBz!q28sQLMuEUz1WuuUk%qw>9J8iKb(HwW&Qn%0$(yj;}T>@bve7->7v z7leJ0<$W2yXG0)Ep%}MUJEQ*O)tFDU9Monw2*Y9r?0Fv#9TI&zWm%d0c$@xc^KnT- zMfz*U#pgd%Bnq?<5MGW@=Xa{|W}D6sgNZ#u`-3q3xnv`Z_x0A=X1CIB&eMja8JD?{ z16G4ojZrsA$flcEn)@SPLQl#vy8!#KgHf?R_W5}v@RYYurV>pGN|wU+|Cp&xjs9?N z0cD^OUrcfPWzxc(2O+FmU?B3=$|JgfGb@}G8MG)n%yo~64nIQV3N+n|Ke~6EA={Fa z61kn1nAzb7Doy)LEIq3S{z2p;0HcB}Ly|(L5hba`1UR?O2R3}-ov#2um= zcRn8gge_D4Fis{beeh%FE8F%iSZ@(BIPMWQR3GI~0>a5-Z%e{M!p~VM-yxvk8x(ltARR3q3s%xe88b>;tAv0q_ zD4gfRiWNOhz2B2I5X=bc66zWQY}uDg$3K`4mPoNo2yy^BSopB&PGMuar(brNqdRmA zBXiX|e=YV@kcLVTS@Z8gN_}XcLVEgQJX{&1I~EXD7Nnbbr-R@yuO{7k{~dM&hZAT%&PrB0IS`1etr_1mh3Mbo!GF(}Z^&|rk@wWlaFT?Obu%+tM!=zCV$J=C}9C+0{j>(O+c1l#&CM+rHzE{50UGlM6GPWe@lu3 zWk^13EB#lfpVM1KB5usEmjUdaC#KXhQ)8A8R>3Q9c`hj#5Pm&jnH{{oT%b- zVt*_9O0QJWn4{p2M-%*5W>696-A_^Rw-DM{!Fe#+K?QW#iNT@>;Mt=LlWx`Oza|#s zsxz1fb-0BS8V1#@JQ8_AH95o#Df2E(vZP`$6y3^w*X;z5eOEzMS<(bQ#T4Y=fvmZ* zTASMY?s*JjoB;N9w2u`=4Pt~cYH1nVRw~+tztWM4X@Qp?zSbXZk$GrrLE{smjex&i z*x-A?8zMWqJ5xk+C~zRwlaR-z$lUE{xYr$hMX+n+{m8Lp<7wSJC9O8t>30EC6W-i- z@w?I+Vhl|{2I8l>#hJ^R%oiF0T_2@WZkR8Rw^3O2mLNYQNAK3r1qc)PS>|Fr%|@7x z^(eE5Gf2K7RDFFy0IuoV>iFcE>?uSU(%rR&oKh420^(^_!A}i5a6TQu z*5Q?^cM@^hK$Bc;e$Y~3C?b#I+sM*Ar*Y<`FmQw^*ZrZbC><(<(z8B;_-tX1##c5R z7JVJjxNWxYe><&Vs%OfzkdH1WZThnej3dHRL)Li;I$_?vbuq}O6TNhK31h-fi1eZ)#h^EKteWG^?K-s03j%E)mV272 z?m6z6b)sta&><%%?c1IYR9baw;yYqXRTD-kog))Lq0*2qHMQpg4do&ty02Xo>jysp zX|sWJ%D05yPg`g}^=lGve5gZNVT>hfBU^0mfcNd`p1HYyTGIWHRq9gxXLj>V`S(cc~gggIWX33*Z2bgP(LY(}!v$Q>^$^tx#}S85;5&~Byc{E$ULu;FZC z;;9b7=BI)9fD)KrBf62yhj6ez4Zl*6ir$k4{Pg$sr-hp17-@MuBl=~Atww5{5llNZ zO)@efU}V3<_u;(J89uM6JMM!zUW$2K;7#g=L%LCQ7rA07IK5a9hk}Di1yK_BQHifp z#tN`DpjR@6R%3`iixDixl$tsgn6R7>GH&PbKKK2- z4ndKsb zBFdE4jcxNKlDhuhT?d>@9Htq}m>XSqyS~d-b4MHIm}L$xj0ELGRVdDyd_OTny=Y<| zg|_}W$}Zv!p`b@1aiT|wD6yFWuXKq?Ib%WVg29N zyo?AVOWFyYEtF$uv6tsr%_TW-h#z?W+AF;#!-)jWbwX6W(FEF#`y{P4eEp!XWc27V zdF0V4dN%q6hsGj2Jgu6~0Mu1zDKfGcO6~!-Ga?>CULG^#OL!v6CBq!IyH%qwqSgV- ze%s~RmMCZbSsPU~5EMzZk!##*Z^u;7l=7tlbDXVF&zgGU-xPRC7FF{A&2@)u4P2gQ zR({f*ub0Adv+1rojn^iD5eafU$z5@H8E0KKXW^-Y&9M86b=z z0Qq?oDzjLf#UwS4=k=#E<>6sU|4Wovb?!oF{Dn@&@#G)ivzFH1v&c z5>n*n{ixQGKCSS(D?n>7R~@B|M+$pp?vF1`L;qU2I4R`TSldDP6@l@7Zj{C6DJz!_ zlY#NRq=LE`=s;nT4MlwtfCt|f?m%=7JtU?7>R-y7;B3eS;u zYVK?XU*=uU`y$kkdVl{0dsLRWFXMyPw6%ft_jz2squ%j0xTS)z?9k?GYUsP}ZsD(N zi6rY-u{(B_oDrPg`$GG$(jI7Rx&}jC_Djrd zz%bRRXc4kbNGPW6mSxRk>^}@6ep4~lmD=`#RS2mFQ0G|e^>+N$2LH02d!Y|CA>&$H zmN0f(KbB;hPkib(B74)_Fd~=ZUA4pD2B~*GU-gUpc2bBx8yGyW>LN+|v92?hXkrV7 ziG+%{Q|pwtvkQ3im@=3{Z$|f{UhU@(6kpz-gdzP}hwhi_(fYxFR`NKx)FtVvk%qA1 z*G<9s05=8`wUUVxwR$u{^C2svXwMbf`1RS+{WApKbJp^ginW5Qf=E?OfG4uvYt2u< z9kK;cT0;nDLEq9gg<2j~h-TdXjOZEio|-wzBxnhRw8Sw#>j#2rK0Q=tX|Jy^5j?3e zU)rotc`i7j8+R@?ZN`XY7`S<1lyh)P@8T!5x0&c;WZE=BwSrjojz#RCEe0tQVy56V z9V;xw>E_r{yoBP?s)|N+am++PG9Jp6NSStwlH3jZR-KXnGKMxt`Z`;dVc@e4NIq2o zUc4EPwL2MroP>TSmLnBycvlNz(Y#Dmw=iW;`07Z?NeO{MM}%S|YlJ7VBIUDdk}A`n z<@I#};%mU?a1e+43ZBXu&aMj5f*+n>^krQGkkAKXZt^YbKVZ={9#c80%bvILpmxQ* z*$1DLW`9e6zag>{V#hO<$HoU=bT)vO2Q34m&)7z(#n=}oTWR)w2QG8)cP%i=97Y`^ zHW{3(WzO(HP4RGJfgxQ`@C1^l5JVAA2}KJ!8lIURiQ94b=djgwv>m4&3^QA8GA5IS zt!Yv*hhfH2@-Bdlaec;ptRaWm>)21Cq5Is>%5IB#x7+m{kQzT4NBs!P@W@tv9FY!^ zxdWlUh;6_8p$ai>g{@L|XUJEdgh%db z8*qNZh%Mgbh%RAwZ)9y%lST0w1?~*Oc?+;=m*Q~tjQ^HfYUtyj?2<9~qyEzc3`Vs& z_Ky4}lk*yHKxWR0!Iz-4kjjDy^b0Rb6J2)t%QhC zEX=e)(di5G>-|JZsILhuydU0Y?A+lKUuxw$V3htGZ=V{>ULX8LeSo{g#jai>B+=LE z5-2kXp;Rj+%usIwQq3aHV74(tC}*1RbpbvNgbFTpj6oHXgFSgt(*>-Om_7QB4LhEF zWOsnk{4mEK%Sd3+29^pkQcZ3pd(`RoO&$gKVzqcq)JB>-~Kf*L#I{Hx*5 z@2~D8=v9!kJ(?(SpkIybU)nbIKm6E1sZdEs4W$!CDUn=3aH7Z{!;Ei|4E7SGe5C46O`e$ zs9k4nzIc{M%y#F~lPBhar00C(hZo4SeDRVvdkqM@S!R>PgP*(lp!_IIoWVMDm_M=x zkd62??6=^)gy_cK8(J^e&K0bdm-=Q<0Q&yUHiFI6!(9dMS$cGm@I*yLDgJgSb9aE9 zTyd!2X(*1V?6@LsQPjoz95}jxc2y1~RirzFwl?UFo0atkp^UCdG!TxRepat_5(NB3 z-r_3iiqT)rj`n-oZ(rOuEi9NfQ)>s0Z_%GhDQs5N1RA@r)TYuqjHsG0CFp!u;6Dz)_+(YKUf&3ku zmT*AT3?zmeD67+ljRkfe(2CcG>-tA{{}{zJ0)3hQ5{1~OMp`V^Hb^g1SOvKzhY0g|2ti@}; znL#n_w}9?4&{2NaViSWCg9FmGHqU;**vTx(taPW8SmQ4^5TZX%zvJBlM(&?x;V-(1 zy`i{?`ISdi!G*Q;lZGB={S#7q(^?+K+1oz-n5sW83p8mJ&H!-Jn?I7Z%$EYz)Wh(r zY)nF7{WUjlpMMAqKB%lvt1*qtm|w06GAp=dNB&lsz*4!dW{!~kfEWLc&+U5HD<#4- zD6xmf1^i<23S13B4s$XT7kXDLlg00;+-3nxG(*5YBS&K7i%zlf%u;Bko~xp3S7T2* zo-|5VF{E((6h@(0;Z^0z%gD@LI+dGWBe{iFYi9VyqIAC)BACM~UFx}dI<xp(o6or(ld8`##NPhWw}9zyIjMv0HTb!}Dz9 z|3yD49ZYBKE_AC?VHb2SdZY^#;BN#(&`p`qCl-U zFf_YMNQLB|)`;n8@lYGcFi@M_B)_9u&Hq-IFAg0#qaTCi1{4#Y`qy7~sBC8Vwlrxv z^9>O6Q>e;{PvedEb3U%UKI+dY6Cp<`A%%PHhTl%Uyen!2g=t*jFM@%lBM)xx!YOm)++GL zwnXg!J9T*lK7^t-6f{6(+r;jqTK963?Fw)sI$jKvCoRcqHrAAGeaO=(3>|g4!q}7LI*yPF((On z15At^pS6{ntP}Ru^5F%n6FtBIqx_1QaF$k&rEEg^M_%tf1!cUG99wvf(e3lbO}umN zY@sT-R21q?p@HL_DZB#kyVWo-HI_`ngGhA$Rwymt^bE6 zrVTkm@b+!hE`*pzK+q}mFnf0$b`nqq9k0pQdD|=RvptH+7mdQZARXV5`)&`+oS}bG zBta|7&LQ81GSdINTed(yd(ZC#FiV5cGYW7FNI&CJryf2ay;;MSD|Mm(6!@*t!eu3~ z6GW0)dR*q`1p6@cw>7{E&8mck`<7W+X5VrV9CtHdk@31eUC?})_x;ZfQ^XimZ6Qr( z3K^YN0-@u$K-S`55UE~K3N#uMaX@+XPnuC-(79Mecemf`qesAFiw%X{^wRniy$%2v{iNajlm#GoJETLINnWeEEd`Kk0r#auVekdoaf*V z4=h?%oiM%sNCdITIl{r*+n~Njr4<-OG>uYREL@8S1I^5OSkmK87L~Xwd}3dc z$gRKT6u-lwKn8Lw6sC<?m~Yl zhz~*gY+E_+HPWaVs+KYj#M7~pAtw`f8eHn-pJ)HVA5lGzMg6Cjfx8ub;!%b9b5*5t zISjC^1_-)QC_BiR)%hy=N3=A|v+_Ra|I1qlEIxdogSr;!u)kH(jAwlZV)f5^{u8j( zSqb|t zr*nj(MdAYahbw-2eyE%O2vU)p-zkIMM18n{`>KO_lg$g9f5 zmF!Tx7&Vd{1?+;J4|t={j>}urq~Z)in$I~;H*6dlfKGr{;Zlvjv=VyT`i%8YwlKaC zoCD*3sLul6Ihj~{EB-dNQHr*b(Ej_FJ=uQ&$2-Qyaj)}?V%%`5b=hhLci^50u1R)QW$>^9!G5J{O=@kG^MJS_k;0Wl?Z ziA#xCFG8U~e)O+^kL4`8srW{0cVJE}shRBSrd-GpbhebEo^eCPDn~%5|Wj zY;Z}iNWNCVs&|`d-O!M)(KD;f3}`)?7(z?yzPf#3qr)f9#DgYy*}X%kGN!X%x(O~x z1GraC7>2!61rM4sKE{(bJa972t%Ib3by)gS$33>*jPt#?&&;oanQfSg)g*p+oz)y> zQVuBGEg+%2?@!sk7tp>i!rl(>1`QyI4I`)C*2kIb7ZbC4xPP2Xr=N zKoOgf(HlZ>gs5awWvY{5h@M_Cmw9p|v^>YhBael{9hK{2TN*V9nCn6-zFL2=AU}ya~I3-GsOnHe4LjvCR62pBjRTS|RT8%1r0{T{#H${Hki0+I~9- zD_Ol}6@uuuN!?*o4bYKZWxMgfI-~S)ls${X#xV-DZ$@7LuwJL`_C3oqY3RKd&R@#7 zbNW?jA8!`m#`4A%c28(#XP%MDmsXY7#QoyHCO{-P=lmucAH8j(@RnxZ z3IWc;0K!UJMbs$ZAH(HkM*PBkw15r5tFrdBDi(a}1#TIUNUVFSxv#R(s}a3|uymWH zT<#1LnNg`;&6EACLZVGPW8CCLq=i9ReBYwEi?(~MsW&~9*=d%i_GZ8W6pMBt!;Ent zc%P3!h#^PYC;nla=L1?8;^bP-$T5eZ#g8HNnzl-dT>cvyehl+9>hR$Q zSX|VtwtPQ<%pk0JE-44?ubB?hIviw;SX9RAbKV-@uWE5w*Ub$1L>ZN9O_-1lXg#G?Jgnq^sL@-ggw4<_>rn#JvsU&J!R@S5X}?7U_RfbD^lqv z=6ZalMJa_ZB5cGkUIW%Jyk0TydT8p?U>3%n$Pa=FPNHQ%NaX>`V)E%1*NX`t0Is!DZ-;Ey4OFSA`C>RU`&TgV{iK|q5;f>V|76> zpt8 zKn;b;>$|*dqKX(!FQ5A^dr<_KsrJ!&Co?Ib3`dTmmeoLVQeY73&F`iH9w$N-uvEW^ zHIyE}*cp&k8Td^X>%RTk!{1dste4Z!iEJ#jT>_B?bM_;IwAmQRB9@;}{Pz27--d zHe2AtA9b^6HJeXCGqtB!7juD~0t5FGP@;1pn6P7L)){BrFph-QFevE2;LzWh_i)q# zk7!cu0doJVwi;IE6&jKV&^cm2Ee((&=}44?PvLSr=6g2(^L?2x=FlKKTIVYKig&k& zA2Aj6@9q#5fSEyBXq0*ut9cYtd<6>3uhTpJ6#y}X<0h37gw8SXiB%lRuAI_t9gO5J z5dygPQe)%E)e;K!`=L9AtXI_1ZXcaD-i&{Hzy*Z<{j<#?J}6NNhLXrl90gtt16J+&}kviA!1_UDJ~M8s~nJ$1%>q^oKmDJT-@<%xb})@QbP7IrGW74t3`ZCD>86_ zkG+-n1?1SpkY88DtsopaXd%xe?!g%9#M*>MBopZ;r#IR(Mip;})`h#khGSHD@WrDbo_pjX@ z7`_GWUf_bakMsGtB=4W)`?GO7I*`#iR`rq#!8Sdq%o^AlDZ!Os6?;+f5v zzjH?x*wuP-m-$NJh^rd*c8H1y-99mmljnv1%pVcXsv!$Hh!4&Q`5>{Wn$6kzb2y-7 z;s(b<4`O<|lcRFoMvL^v4L|KP8kz$T=^nAd474*KoD(GEkAoD{0?3-@sKfUYtSOUO zOkyDPd`9`JWGEqctZGKCvRKjt|a~Ls2Vr58=$NbmTbD{Fd<2}7w3XujHM{y zQ?fdXyod&Cux00`o3>Qf3Wc3n)%GgnX8^9uI4v-nhYquo$oZM-iR_!ta7Orb8!Y^f z0@)j+fbB6D(&$JKyogD6i@n%r6jkr=e9%8H=`-@7kpwq?Q-~*Otl-`2zl1MWk=)sI zpQ3SxA8)b*)ri;Fby$5p_E_7u%zfcFOF?{Ujd=Kunz!F@&1|Z*%|b1{&JEt zTi#)C+t5g)lyOIhUw;B?2A38Jn^BARJrXg0EyY;I72~7w8{vX(Z(4P#NL{1w{!8Bl#uD0 zHgmx90UWMmG1FSWG+jz~btTL<&Bd1-WWV5B7vft@rRrZ?@DNa^NsJVaL{WlEuGsxP5<^3!iPggl8^Z@ z#)+^L=TtIQ>n zM;?i$6vJN4ryrR~B}^}?XD>coN1Z;ZE2V@h2+oTtYMT7y^e+3lUV{ddQT-MRXci10Y#_-qIFyK@8`KQG8c` zEBnQM>=MOq9B6115J@eu|B>oLN`P0c4lz;n2*S_Gjq7t3&7F`~Q6Y(`oSL-U!ADbh z>Rh}TB|IFTEkcEL)xhz(h7n~HzS*3gJ6Z+sl%qDFj4j_yLVcV?rx?QJbv&p4$ubaS z-de5R9FDeceLltLc_am9Vp1VRz>g|7Nlc&R9*Y5X+&YZH##TIVV`6(5la!>kj^DN+IRi0hM3w-OAKd zN@SiY)7XuY0XKn#&=tW$my!r6*OF51^h!IGwDnJQ*Jm-=Z+yI%&`6rZWW+h6-SNv0 zLTwl#b`;}zJ}pPkl@s7f=B#a~qm6q2Oa#qR+PRBmWf$-vRoQYMl{^PmXxFdq4{nOi zmO27FwdK91^fbwsL!#F2wuz;*>xprTbi{dXvSpJ)Q>wpyjVm|)BTexF!1kjD~k`j!bWvrH=;-aLu z_?lM&CQ-DLo#z83R!T4VoLOOi5fI>D)_GU*U#ntQZYlWyS_x5E_R~2T3|Coe1=5lD zBz-{1O}oM@Aa`1cSOJo%$u6!b=5a|>iphjf!%zv_nayn6o01Xm$io|b4mIyNK}uz0 zCt2Gm<|G5qvVE<>v@RoHBdN3sWd7DJKG^EcP8RF?2WvN!Xe7qe%Ix9fc6n5EaAD$u z3k+~W;<|@BA{9WeDMW3-XK?+-TgDG1zzeR!#QZdBL|LeRQ1x(?e9aoc04EpwU7hEO zbXk80gZ{dOxhhI6$rGZ)dwh0>ATeJ0cCtD6x$&VB`MGrsZmN?>$*)mZx%wK=C;?`y zy*B{{F`G>bq7|yeT#m6XLRMMIrmrCMduYkMjV3( zeSKh;(<>0CH{0}_0SB(-CuXx)Qg+fX7`PZE-=Anc2MNm0zyPW+w=Oo@0A$D8MB*79(f>Qr*-E?-AaO>0W@gbT*I|#B(&eCT&wUX!2-C5efbL z6&KRij&>}{P~nJoB-&q zZ16(b{*+1!X&|74Q}LGdA1M#WcN#Q6`(|6jyX z6USvln$B2^6f0$f*Qb_`*A~` z3x0ng#0Mxcwbm1^i~i&2EW@H~n=t%RvUD!p-QC?F-Kn&IgmibqN()MNEK7HHBhn=u z(o)hPe2?E>k3AN5cb=KK=f19U_MSgr055+vFEWpa_7ltvMlJM%EaT4&el%FV3V1#! zF5a7t*HC7^2{9!i&@Ytor{1{g1KtSkv#(g{#q6aBn=&YTy;=#69IVCRi!s&#jQOt$5F&`GUuH9G)Iu2)}HyEnQj!PnmR zKSnX^Htjm7lY-yB146uG3xmXKoDGSEIRXorn>1ys^erHIe#O@-fJV8$ux#~=rNU0V zb<5EL|2)D0pTId1zLO|%F`R;Hgb%XhLxi~ZxBj>TV_=FZw_OX=E0#TW1N9IZlZ3qG z?Gd!QVphQaQ2t`y^o7{*DRoQh)gHF9Ax;`ZaWB?iCZ=kP%63!%6653h)dVc{=6>Nt z|9mlE$ISF`bu|4G>x^^(?7P9nX~0R$&;fpQL~uq$ubhOg5>7gHkQ^;d423l z=pDk%D*9$8aqkT?bXQwNI@q z?*E?8A-@VR3BEgVTn3xvw@-T`%;!08C4sWiu0b!`^?R~=iNLxYF;L?aDWT;2A3d^a zpx{C>Sx%ccOd&LOms#4GDEiLw^Hdz0>M+lZF5_^6Prie{12TPJ)un06<%3@GaRq%N zw&sIg07o2`O{rf13osiIbOx8^sJ^T$`^^YzndKWnb$O@QfEW)R=!2lB3#qJ9cs6m5 zjWmWqD2}TVrht>uh`c=d=zvg-tB|zbtSjT>3C5K1NBP*Y76PJr)neJ_@p;7PEGgiZWmVOd-#dNI9x%hwL11>_FKmEOlH>5SOQ}`?*bXe4GO9cenR0 zbi~9~)-G7EF<`Kx^r`=DaKzo*sx*C7cMRlIqtNX?x^_PWw_Khkc+-n>ROy6Kun)NK zu1946yi$(`l_@XbL7S#jCXs&@{Q(LtcQ2bKfII^qSwFD zNN^kT_56-AO=Yt&SaKDkhWwU#H)Z3)oOXW0h=t=DL2EuO2& z_XgRiIaH5tBR;b^(c-BY;jUjZSxMXubuit_tDhp_fm|e1C+cU08bk5kcHt}x={XYy zy170{0N8bZS%dvDu^Ze-XS-wu$uSFLQExbAt{=#s@^BsAh7eUkvYShG{=4g;WqvSq z^g$@hu!6ezi~rH*-ml`KxK4C$HoyYhju_OgOE2HqlA0YJP0h0HNi+t!n6_2!-S!({9bIy)KCiP5)hwBCv-fLS_SpxMoyDB(>pD{2mSdoeSY8#JPl#$9#wwaHjTath~ zTSL6FIvF^e{qkr{1gCdXW$~B48Gr{$;y)87Iu?A3_)o?ARz)r#)E;1AyluZ5C&Rua zk&^tUcYKS@8BC=;Kue+j_@da_q2taI$XLvw$=d|Qqp)Zx2>@hc7vE+&c=>B5JeJLw z3U*r6(r#AR05DE&u4p~J4S0*SUfnpBg`LzGixUF4wAtb&G&kPru&Q$@Xkid93r8q! zR|2Am9&Rl{T(&(X*&$Eim@%Kf0uFx`{0!c|Tu=Nwv*DhK{jNDmlx^OsOdq|x@^2uj zM|IM>Trz~+Nl{>nKex|oj^Fj!XeyMp8|747zs3>~cStLzvZ*}FNVMm`@lk05-)3Sz z^)l9-DES7$%rbF&{wki8$B^PfZCjPCD&Dh;|GSLXP|soRJ)k~*$j4R?m_yXvG0-Nj zFlI%yQ^lV?CKs-wfU$&$N3OWWiLhGty?LW_)No?K9ppJTSoX^HUoP38_J;y&yKB`% z(IP5`$Z6LBKx(3gE4ox$zmUlF=Rgn_al(VSXZ8+o3I;&zm&a67+?;a_`}K8$xApc4 zgS$skflQ3*IXTxHVz>noGu+~y+fQMM_bHnKVm{I;TAS5o1BsFvE5Cet*d<2_uogN7 zyb#UYF<(=X{YK3;qb-6+Ruc4|09$^4O5^b7s35s=7OzV)z4hg@sL`RY1loAhKlqDF z#)qtyq=i!Z;WCF@p9>#pfHO<1whd0d2WT$#{Y8qO=uRg*>psBO;7Olq?HVS5eZ9HK zu<*PHLAwrVa{dJ@Fjb7hbtPE3)1YjRU_gauFdXEk&hjQzh#D2grxBVFDSBTF6Vb_S z!4-(;0UU(3*K0^*#xcs`v0;?oEWTcaRXoxFYT9z2>s(zSd)t#SuC0io5`r=}#9X1f z9jk>1;T$_Nw3K5NS7lB^M;-^!5At8mEsMsWhr4SQv@>1;QByt;7Bb#soqnHxER?c= zcOwO&Ee5JdBuH$LaQgbC=P!|f;5BQBwTvBP{v2_0N%NaXr#L=HIk4rj%2sSgGh{LI z;u#XzNy(s(aUICW1AM_MLN**4iSN&=6jKwD#-$H%M&h2@ff;gleoUGIksDF2DxSYS z_K8O!#Uo(Rd^YR_aI8qo+PhDmM#<3b{}`F_&tV_|R|YZauJh)rB_S#ZU!Y#gw8TNPWdJ^1l3 z^>CQGl1WorE5h4b{i^Z2GmC_!G}%a263yRuPFWp1TjdSF_5Iqw>{G5u%=#IXiKyIh z8)?B)Ta|af9S-w2Oh&^kt0LDMw-)L{#>vr9I-W)qX0OpPnGAs_jkm4OLjS>OS4 z_9~iVM*`)pK8Uc=!ao1of>ryKK2QN)$yg~8q~h#sWM$vJ%}@|k+dB@Zm^_w__}=ao zU-qdz^Zk?$ zRINym@^7Szk9_l84AFAiloQG<7l55?sCv`G2UH98F{u21 z&N#3?{m(wEZFWcc+pt^ZPGE2B8}Zhd>IAn_DPjNK$r^^fpxZ!T-lmX*z>q^QtH1W$ z528A@HQS~niFHN#n&Hd4UXg-BriEm$5qlg#@zCA)4xr`+E8L2M1PwaL*45FPB>YNO z?E1-$0_%U6VAKSP)$cKm#l zdJiYAl`&J>+3ntnKg}x<^u8Al6+igmJ+5{lynnJQ*yecTpR~%lTbHIB#D)^y zsbLzQu^kQA=-Ai@UGKCPil3fc83byhvV?1B`Sv%5hHE~DNcRcxaWth(-<=M8yds&R z>$(9@GrRc_&n~l8OZ`$R+#lcm((8-1>I8Jd)hoR!1y;M%qpE89Vzz893I;AMfIR6r z#LrqO|7oE9Vj}4;HgXN}7vH~APu5v2+V2IqeihEtcLc$SG*+a=9!QfIjQ{zUZA35C z_eK=ro(PGEBe62YV1s-0sZ;mQE3;TDEQ`jVQjd}4SQ%4D9I4n?5pcBAp<`hyKofV+ zfA?;@f{iiq%h1gBzgn$IBE4y?R9{$Ab&d2<=WVSO*B^<8-K%p*Hj_MEiq*XJcC;wj z$S?j*F}s$^_Oc>UN?XVXz7G>P!YVoE23>jWvy=Foglq=JCgO9vI0p%bJA92(UA5FE z_ltWWMsb#Eq%=j}Y=}hov_A(IbAJv3;1+03hP5YW>>np^TP@#f4}3dGg!%%CWI~$d z$#%=6X>|IX-tw9A>p)y6KC$;NRzyBv_tCRImp2iR0 zh`Ctn7|=Hr_R=qd)n4>*j7d|%`|&qGG#`=ySFF5%-1VKr)~Z}q6YM%~R5E}87sXG8 zn)Mlb{d}}+SJsa_AEJ!T-U1wBal_^U>}MORN6);M8P88YXRib>bF_~*#E(T@sgbh2 zPJR=k>uMJrJJ;E(r^hXp`tOF|*-Mnd%eCttSN#Kpm0AUYzm)a2ZE}sd5!i|L{$xu9 zO~B2JR9^1zg8DMm_GmTW>lSK2PWz^Q)7{lhITzMPK3`=xMXenT3d_GV4v zF{K#!kU2Wtx)pTbra|@mH#~ri%EVjY5YBl|5xT@*dM3R3z{=Xu7Onb|5VycS?@y52} zV<2j}p?LS3y!ck+_9#o~vdPys2nGG^S&v87c2YI}P8skN^>d`Xi(s2MtpMs%EJF~} zIk4}51eYk$U76LGzi0~*eL|bEZ~WEaozunDQ3Ch*iE!W6TMLvy)q&}elN+ne07~Gd zrb01gj$dhTgG2zFtg0F|?H_Ct33Q|HL8bolsi|38fkN-lJZAFwbZ)%1Jgox{sm8WlnHm3zerIzQLr8$^I`8G>3nBu6LMu3HHx^7 zV~u!(zTimi2e}16l_yJj(U5!XYvm-->ws_NPQ0}p)9(tpC>;;=&0MVMH_*L$(fD{8BcZ9nrMr zU3#SUT<#ZL0##7(vF%Q1EOixbkgvml-`#yHiViosPJzF0fY9#NVP1SzkoTpD6(4MT zxuL*Ms8IHph=2OcH{B1qnoXXZfa1JKr7A*{1WzdZ(r{u{%jUoK^&CrjaZ*37cZG5# zs`ZDmsF|wb-a%VIKkO^M!Eo#Jj|%;lh0t~fX_@c1B75OZ{5=FDq43F0o=_wq`Z)>L z1Vq!q#bCd9v+vi~hgur%kwjN_2>h1RiMsxjb%{%Tu)wF5+mkk=V^y^!|FA&yf$Yt2 zSjSx7LBQj4Cw|pO@lmz&02F@B+K=Bkcmo%Q6tn~wwV}(mOPf8@^Uii^74XgyE^84v zO0E?%-xkOeZl7KkXB>RJZ9=y0MYvK!Q<_n&4bcZWHuY=zit zem;$%{OS7Kh9B&TnQdL~RLG&!g!T;R3H}Snj6B3judpk`VEH{s9{KmXPyfCDC1Gu3 zG%?5Gsw@ZkfMvRkADlAA)kFMq9QJ!02Fm{^Yz#yl@%cnDlQ`AQ+&dNTP-L9JXB>_T z#FBBFCogQ-mqd%RZ09q9h_eukPHk$-PpJGlbz_L}dTYY-B*2}qc}y320?6)&HKII9 zF{Pva=a$H3r$zrA%Vi7pZx^4nvlJ3o{YNdypM&G)cfg{|pGjhLoN(}6(N5O%1k?mb zVSW$rNt=vv-B_?T7I{PntA3u}7i0KwO-cN%GmAe{pqY6~`5Va}wbqKE!db1RDtazA zMmx)>^u~?3M-Z&i9x>SsV-5trWV63Ba6y#R#*u1a-zo%S1WlJ27EHGKtlE4M1A-M| zs+r=Mb6nPo4ISi`y>0mLGL|m;_eQolN)H>k2ZAc@mR^jDP;Xo zI2@3C=5a7M2vxoZr$_d~J#o;{$`u9FVChGFcHJNAl;9YQW_H;Ay{U)xL`-dLq}Hl( zAF!ihaP!9yit#Z>FRh1B^~Qb4(Hq*nxQNNzaCO6U{mVdiA^B#r@-91G3YHm}M2x!P zBgsI|8<_+IeJc!1y`S}MkE{gu)#2x{1H zX;h4e1^$=b<}u}sMO^s!%zp4DuY|2I%?{nTo=9utEmC(HcAANao00^HmijtM_;!x3 zt6eX|)FQBE6N;fAs548t4?|XiW1z@N^xa3p(M4s-I7xYh#|Sb6-Som$jE_(e-*!Jq zTDdvOm|S9A610Pn)U#{QG`HxnZEND>Y=|4>%YQysuvGBmp^a;0W7Q}m{-GoNCOd)C zzp*l%8xez;+v1kG_r(##cm3a%kN*l%tf(`Q-yCe&K+m{Q6HEZ9JaW`ToE1m)&PtyS z$V&mDWS|J<1H^lXrl{>?A# zz>ktVxYGU|iaUupaN<*$Dov8D&ul}yZbey&BC5}#IAT`P2U%XiAxq>?nI%K-QndqVX^d%0vt2|hV+SVgs3tYXO(?0kP614Z(bF(iBHasc3J4?DcH(#Jh zaf)gogx}3~2}DkpZVA=T6ynlZTWMXw7}-th`&I7;;0L5D&CfYDv_X=+aV4&UWV~93 zf4#FLO^P>y(&euYrhnS`?8&&Hz+e%$;q)QmkTPn^5Y9dQe&8`(J-yxo7d>wqpRC!;bf zg@H8d-S>{5_KONrhFV<%kbmDLE1TlbyZP}YJQG$l41rekTAdM}mP?e0Y5Hm80)#M@ zM2B?pX|n`)CEoR+SDeDPg)T3+G+D~#CI0Lv5$$@$d7iQDHl)acH+;ng!H2Wnet4*V zCIpf0`}aD(St78m{7y4!607vBsy%C&-7<>P1%2(Jv^yat2%~BJuiX;&kcn3yE(@H!d~>5tn?VdCRTZF%b`>5USqsfvcAg@ zUZ|>c=oVbKvnF$++QGv19Fo3(7Hr5DgmJ{cR}BA7NNY@J>$&lQ365aEtsA=^G$XT( z_c1n)=Zi@UKPTJ-IHEz*v%-7%+BU+DfOmHRGLp`3FsYEN5Bkqwe`W&!#kR^Ma)@*q zVe#dGb!XI`!@#|!%{(%VA?-_yRMY7q9Poyv7Gnirt?YU;f)EmFj4 z!dEH!5ATl8P6T8c=OjaZEk?u_{qR%RVflc--n8`PU!J-bm%_cav)&ryJAI=^BQ;H- z!TDetakz&r!nFL+$yg;T`ERwOhC@%A!8{Rld!6&g_f&F+T6q|(w7;I`@{XwAbB6%G zVG%_nqsUR{s*lK=&FBSnh1^lvyfRBbVM9NyGk8{2bLH?RdPIa_9W?O zx0ES|ETXFl*VoU<+&%WpUV6mfMAU`e{#a0DN;^*u!olt8x}at96wleaF)wo^yK1!-+;qB~LocYE>VIdkm>XROi9qoS;@>rdb6WY1pe$zUS=^Ed ztR6!wh-_J_i7Or~zh8{@y6-jkzFq2eYcd5?75}$_RBUH<8i-Ix>;SE*b=S%1Unx

D?Py)SFmSp!aUiw5e7t8 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 literal 0 HcmV?d00001 diff --git a/lib/src/modules/pe/tests/testdata/111aeddc6a6dbf64b28cb565aa12af9ee3cc0a56ce31e4da0068cf6b474c3288.out b/lib/src/modules/pe/tests/testdata/111aeddc6a6dbf64b28cb565aa12af9ee3cc0a56ce31e4da0068cf6b474c3288.out new file mode 100644 index 000000000..0c6f7d249 --- /dev/null +++ b/lib/src/modules/pe/tests/testdata/111aeddc6a6dbf64b28cb565aa12af9ee3cc0a56ce31e4da0068cf6b474c3288.out @@ -0,0 +1,734 @@ +is_pe: true +machine: MACHINE_I386 +subsystem: SUBSYSTEM_WINDOWS_GUI +os_version: + major: 5 + minor: 1 +subsystem_version: + major: 4 + minor: 0 +image_version: + major: 5 + minor: 1 +linker_version: + major: 7 + minor: 0 +opthdr_magic: IMAGE_NT_OPTIONAL_HDR32_MAGIC +characteristics: 271 +dll_characteristics: 32768 +timestamp: 998098977 # 2001-08-18 01:42:57 UTC +image_base: 16777216 +checksum: 330575 +base_of_code: 4096 +base_of_data: 40960 +entry_point: 20062 +entry_point_raw: 23134 +section_alignment: 4096 +file_alignment: 512 +loader_flags: 0 +size_of_optional_header: 224 +size_of_code: 34816 +size_of_initialized_data: 246272 +size_of_uninitialized_data: 0 +size_of_image: 294912 +size_of_headers: 1024 +size_of_stack_reserve: 262144 +size_of_stack_commit: 4096 +size_of_heap_reserve: 1048576 +size_of_heap_commit: 4096 +pointer_to_symbol_table: 0 +win32_version_value: 0 +number_of_symbols: 0 +number_of_rva_and_sizes: 16 +number_of_sections: 3 +number_of_imported_functions: 126 +number_of_delayed_imported_functions: 0 +number_of_resources: 31 +number_of_version_infos: 8 +number_of_imports: 6 +number_of_delayed_imports: 0 +number_of_exports: 0 +number_of_signatures: 1 +version_info: + "CompanyName": "Microsoft Corporation" + "FileDescription": "DirectX 9.0 Web setup" + "FileVersion": "9.29.1962.0" + "InternalName": "DXWebSetup" + "LegalCopyright": "Copyright (c) Microsoft Corporation. All rights reserved." + "OriginalFilename": "dxwebsetup.exe" + "ProductName": "Microsoft® Windows® Operating System" + "ProductVersion": "9.29.1962.0" +version_info_list: + - key: "CompanyName" + value: "Microsoft Corporation" + - key: "FileDescription" + value: "DirectX 9.0 Web setup" + - key: "FileVersion" + value: "9.29.1962.0" + - key: "InternalName" + value: "DXWebSetup" + - key: "LegalCopyright" + value: "Copyright (c) Microsoft Corporation. All rights reserved." + - key: "OriginalFilename" + value: "dxwebsetup.exe" + - key: "ProductName" + value: "Microsoft® Windows® Operating System" + - key: "ProductVersion" + value: "9.29.1962.0" +rich_signature: + offset: 128 + length: 56 + key: 2278776681 + raw_data: "->\xbd\xd4i_\xd3\x87i_\xd3\x87i_\xd3\x87\x93|\xca\x87d_\xd3\x87i_\xd2\x87\x17_\xd3\x87\xfe|\x96\x87h_\xd3\x87\xb3|\xcf\x87q_\xd3\x87\x93|\xee\x87h_\xd3\x87" + clear_data: "DanS\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfa#\x19\x00\r\x00\x00\x00\x00\x00\x01\x00~\x00\x00\x00\x97#E\x00\x01\x00\x00\x00\xda#\x1c\x00\x18\x00\x00\x00\xfa#=\x00\x01\x00\x00\x00" + tools: + - toolid: 25 + version: 9210 + times: 13 + - toolid: 1 + version: 0 + times: 126 + - toolid: 69 + version: 9111 + times: 1 + - toolid: 28 + version: 9178 + times: 24 + - toolid: 61 + version: 9210 + times: 1 +pdb_path: "wextract.pdb" +sections: + - name: ".text" + full_name: ".text" + characteristics: 1610612768 + raw_data_size: 34816 + raw_data_offset: 1024 + virtual_address: 4096 + virtual_size: 34330 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: ".data" + full_name: ".data" + characteristics: 3221225536 + raw_data_size: 1024 + raw_data_offset: 35840 + virtual_address: 40960 + virtual_size: 7140 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: ".rsrc" + full_name: ".rsrc" + characteristics: 1073741888 + raw_data_size: 245248 + raw_data_offset: 36864 + virtual_address: 49152 + virtual_size: 245760 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 +data_directories: + - virtual_address: 0 + size: 0 + - virtual_address: 35504 + size: 140 + - virtual_address: 49152 + size: 245128 + - virtual_address: 0 + size: 0 + - virtual_address: 282112 + size: 5976 + - virtual_address: 0 + size: 0 + - virtual_address: 4624 + size: 28 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 4096 + size: 528 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 +resource_timestamp: 1773781709 # 2026-03-17 21:08:29 UTC +resource_version: + major: 4 + minor: 0 +resources: + - length: 11802 + rva: 51104 + offset: 38816 + id: 3001 + language: 1033 + type_string: "A\x00V\x00I\x00" + - length: 744 + rva: 62908 + offset: 50620 + type: RESOURCE_TYPE_ICON + id: 1 + language: 1033 + - length: 296 + rva: 63652 + offset: 51364 + type: RESOURCE_TYPE_ICON + id: 2 + language: 1033 + - length: 716 + rva: 63948 + offset: 51660 + type: RESOURCE_TYPE_DIALOG + id: 2001 + language: 1033 + - length: 394 + rva: 64664 + offset: 52376 + type: RESOURCE_TYPE_DIALOG + id: 2002 + language: 1033 + - length: 320 + rva: 65060 + offset: 52772 + type: RESOURCE_TYPE_DIALOG + id: 2003 + language: 1033 + - length: 406 + rva: 65380 + offset: 53092 + type: RESOURCE_TYPE_DIALOG + id: 2004 + language: 1033 + - length: 270 + rva: 65788 + offset: 53500 + type: RESOURCE_TYPE_DIALOG + id: 2005 + language: 1033 + - length: 250 + rva: 66060 + offset: 53772 + type: RESOURCE_TYPE_DIALOG + id: 2006 + language: 1033 + - length: 140 + rva: 66312 + offset: 54024 + type: RESOURCE_TYPE_STRING + id: 63 + language: 1033 + - length: 1312 + rva: 66452 + offset: 54164 + type: RESOURCE_TYPE_STRING + id: 76 + language: 1033 + - length: 1484 + rva: 67764 + offset: 55476 + type: RESOURCE_TYPE_STRING + id: 77 + language: 1033 + - length: 1200 + rva: 69248 + offset: 56960 + type: RESOURCE_TYPE_STRING + id: 80 + language: 1033 + - length: 1098 + rva: 70448 + offset: 58160 + type: RESOURCE_TYPE_STRING + id: 83 + language: 1033 + - length: 974 + rva: 71548 + offset: 59260 + type: RESOURCE_TYPE_STRING + id: 85 + language: 1033 + - length: 30 + rva: 72524 + offset: 60236 + type: RESOURCE_TYPE_RCDATA + language: 1033 + name_string: "A\x00D\x00M\x00Q\x00C\x00M\x00D\x00" + - length: 220645 + rva: 72556 + offset: 60268 + type: RESOURCE_TYPE_RCDATA + language: 1033 + name_string: "C\x00A\x00B\x00I\x00N\x00E\x00T\x00" + - length: 4 + rva: 293204 + offset: 280916 + type: RESOURCE_TYPE_RCDATA + language: 1033 + name_string: "E\x00X\x00T\x00R\x00A\x00C\x00T\x00O\x00P\x00T\x00" + - length: 36 + rva: 293208 + offset: 280920 + type: RESOURCE_TYPE_RCDATA + language: 1033 + name_string: "F\x00I\x00L\x00E\x00S\x00I\x00Z\x00E\x00S\x00" + - length: 7 + rva: 293244 + offset: 280956 + type: RESOURCE_TYPE_RCDATA + language: 1033 + name_string: "F\x00I\x00N\x00I\x00S\x00H\x00M\x00S\x00G\x00" + - length: 7 + rva: 293252 + offset: 280964 + type: RESOURCE_TYPE_RCDATA + language: 1033 + name_string: "L\x00I\x00C\x00E\x00N\x00S\x00E\x00" + - length: 4 + rva: 293260 + offset: 280972 + type: RESOURCE_TYPE_RCDATA + language: 1033 + name_string: "P\x00A\x00C\x00K\x00I\x00N\x00S\x00T\x00S\x00P\x00A\x00C\x00E\x00" + - length: 7 + rva: 293264 + offset: 280976 + type: RESOURCE_TYPE_RCDATA + language: 1033 + name_string: "P\x00O\x00S\x00T\x00R\x00U\x00N\x00P\x00R\x00O\x00G\x00R\x00A\x00M\x00" + - length: 4 + rva: 293272 + offset: 280984 + type: RESOURCE_TYPE_RCDATA + language: 1033 + name_string: "R\x00E\x00B\x00O\x00O\x00T\x00" + - length: 15 + rva: 293276 + offset: 280988 + type: RESOURCE_TYPE_RCDATA + language: 1033 + name_string: "R\x00U\x00N\x00P\x00R\x00O\x00G\x00R\x00A\x00M\x00" + - length: 4 + rva: 293292 + offset: 281004 + type: RESOURCE_TYPE_RCDATA + language: 1033 + name_string: "S\x00H\x00O\x00W\x00W\x00I\x00N\x00D\x00O\x00W\x00" + - length: 22 + rva: 293296 + offset: 281008 + type: RESOURCE_TYPE_RCDATA + language: 1033 + name_string: "T\x00I\x00T\x00L\x00E\x00" + - length: 7 + rva: 293320 + offset: 281032 + type: RESOURCE_TYPE_RCDATA + language: 1033 + name_string: "U\x00P\x00R\x00O\x00M\x00P\x00T\x00" + - length: 30 + rva: 293328 + offset: 281040 + type: RESOURCE_TYPE_RCDATA + language: 1033 + name_string: "U\x00S\x00R\x00Q\x00C\x00M\x00D\x00" + - length: 34 + rva: 293360 + offset: 281072 + type: RESOURCE_TYPE_GROUP_ICON + id: 3000 + language: 1033 + - length: 884 + rva: 293396 + offset: 281108 + type: RESOURCE_TYPE_VERSION + id: 1 + language: 1033 +import_details: + - library_name: "ADVAPI32.dll" + number_of_functions: 14 + functions: + - name: "FreeSid" + rva: 4096 + - name: "AllocateAndInitializeSid" + rva: 4100 + - name: "EqualSid" + rva: 4104 + - name: "GetTokenInformation" + rva: 4108 + - name: "OpenProcessToken" + rva: 4112 + - name: "AdjustTokenPrivileges" + rva: 4116 + - name: "LookupPrivilegeValueA" + rva: 4120 + - name: "RegCloseKey" + rva: 4124 + - name: "RegDeleteValueA" + rva: 4128 + - name: "RegOpenKeyExA" + rva: 4132 + - name: "RegSetValueExA" + rva: 4136 + - name: "RegQueryValueExA" + rva: 4140 + - name: "RegCreateKeyExA" + rva: 4144 + - name: "RegQueryInfoKeyA" + rva: 4148 + - library_name: "KERNEL32.dll" + number_of_functions: 76 + functions: + - name: "LocalFree" + rva: 4172 + - name: "LocalAlloc" + rva: 4176 + - name: "GetLastError" + rva: 4180 + - name: "GetCurrentProcess" + rva: 4184 + - name: "GetModuleFileNameA" + rva: 4188 + - name: "lstrlenA" + rva: 4192 + - name: "GetSystemDirectoryA" + rva: 4196 + - name: "RemoveDirectoryA" + rva: 4200 + - name: "FindClose" + rva: 4204 + - name: "FindNextFileA" + rva: 4208 + - name: "DeleteFileA" + rva: 4212 + - name: "SetFileAttributesA" + rva: 4216 + - name: "lstrcmpA" + rva: 4220 + - name: "FindFirstFileA" + rva: 4224 + - name: "lstrcatA" + rva: 4228 + - name: "lstrcpyA" + rva: 4232 + - name: "_lclose" + rva: 4236 + - name: "_llseek" + rva: 4240 + - name: "_lopen" + rva: 4244 + - name: "WritePrivateProfileStringA" + rva: 4248 + - name: "GetWindowsDirectoryA" + rva: 4252 + - name: "CreateDirectoryA" + rva: 4256 + - name: "GetFileAttributesA" + rva: 4260 + - name: "ExpandEnvironmentStringsA" + rva: 4264 + - name: "IsDBCSLeadByte" + rva: 4268 + - name: "GetShortPathNameA" + rva: 4272 + - name: "GetPrivateProfileStringA" + rva: 4276 + - name: "GetPrivateProfileIntA" + rva: 4280 + - name: "lstrcmpiA" + rva: 4284 + - name: "GetProcAddress" + rva: 4288 + - name: "GlobalUnlock" + rva: 4292 + - name: "GlobalLock" + rva: 4296 + - name: "GlobalAlloc" + rva: 4300 + - name: "FreeResource" + rva: 4304 + - name: "CloseHandle" + rva: 4308 + - name: "LoadResource" + rva: 4312 + - name: "SizeofResource" + rva: 4316 + - name: "FindResourceA" + rva: 4320 + - name: "ReadFile" + rva: 4324 + - name: "WriteFile" + rva: 4328 + - name: "SetFilePointer" + rva: 4332 + - name: "SetFileTime" + rva: 4336 + - name: "LocalFileTimeToFileTime" + rva: 4340 + - name: "DosDateTimeToFileTime" + rva: 4344 + - name: "SetCurrentDirectoryA" + rva: 4348 + - name: "GetTempFileNameA" + rva: 4352 + - name: "ExitProcess" + rva: 4356 + - name: "CreateFileA" + rva: 4360 + - name: "LoadLibraryExA" + rva: 4364 + - name: "lstrcpynA" + rva: 4368 + - name: "GetVolumeInformationA" + rva: 4372 + - name: "FormatMessageA" + rva: 4376 + - name: "GetCurrentDirectoryA" + rva: 4380 + - name: "GetVersionExA" + rva: 4384 + - name: "GetExitCodeProcess" + rva: 4388 + - name: "WaitForSingleObject" + rva: 4392 + - name: "CreateProcessA" + rva: 4396 + - name: "GetTempPathA" + rva: 4400 + - name: "GetSystemInfo" + rva: 4404 + - name: "CreateMutexA" + rva: 4408 + - name: "SetEvent" + rva: 4412 + - name: "CreateEventA" + rva: 4416 + - name: "CreateThread" + rva: 4420 + - name: "ResetEvent" + rva: 4424 + - name: "TerminateThread" + rva: 4428 + - name: "GetDriveTypeA" + rva: 4432 + - name: "GetModuleHandleA" + rva: 4436 + - name: "GetStartupInfoA" + rva: 4440 + - name: "GetCommandLineA" + rva: 4444 + - name: "LockResource" + rva: 4448 + - name: "LoadLibraryA" + rva: 4452 + - name: "GetDiskFreeSpaceA" + rva: 4456 + - name: "MulDiv" + rva: 4460 + - name: "EnumResourceLanguagesA" + rva: 4464 + - name: "FreeLibrary" + rva: 4468 + - name: "GlobalFree" + rva: 4472 + - library_name: "GDI32.dll" + number_of_functions: 1 + functions: + - name: "GetDeviceCaps" + rva: 4164 + - library_name: "USER32.dll" + number_of_functions: 31 + functions: + - name: "ExitWindowsEx" + rva: 4480 + - name: "wsprintfA" + rva: 4484 + - name: "CharNextA" + rva: 4488 + - name: "CharUpperA" + rva: 4492 + - name: "CharPrevA" + rva: 4496 + - name: "SetWindowLongA" + rva: 4500 + - name: "GetWindowLongA" + rva: 4504 + - name: "CallWindowProcA" + rva: 4508 + - name: "DispatchMessageA" + rva: 4512 + - name: "MsgWaitForMultipleObjects" + rva: 4516 + - name: "PeekMessageA" + rva: 4520 + - name: "SendMessageA" + rva: 4524 + - name: "SetWindowPos" + rva: 4528 + - name: "ReleaseDC" + rva: 4532 + - name: "GetDC" + rva: 4536 + - name: "GetWindowRect" + rva: 4540 + - name: "SendDlgItemMessageA" + rva: 4544 + - name: "GetDlgItem" + rva: 4548 + - name: "SetForegroundWindow" + rva: 4552 + - name: "SetWindowTextA" + rva: 4556 + - name: "MessageBoxA" + rva: 4560 + - name: "DialogBoxIndirectParamA" + rva: 4564 + - name: "ShowWindow" + rva: 4568 + - name: "EnableWindow" + rva: 4572 + - name: "GetDlgItemTextA" + rva: 4576 + - name: "EndDialog" + rva: 4580 + - name: "GetDesktopWindow" + rva: 4584 + - name: "MessageBeep" + rva: 4588 + - name: "SetDlgItemTextA" + rva: 4592 + - name: "LoadStringA" + rva: 4596 + - name: "GetSystemMetrics" + rva: 4600 + - library_name: "COMCTL32.dll" + number_of_functions: 1 + functions: + - name: "ord17" + ordinal: 17 + rva: 4156 + - library_name: "VERSION.dll" + number_of_functions: 3 + functions: + - name: "GetFileVersionInfoA" + rva: 4608 + - name: "VerQueryValueA" + rva: 4612 + - name: "GetFileVersionInfoSizeA" + rva: 4616 +is_signed: true +signatures: + - subject: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/OU=MOPR/CN=Microsoft Corporation" + issuer: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Code Signing PCA" + thumbprint: "9617094a1cfb59ae7c1f7dfdb6739e4e7c40508f" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "61:01:cf:3e:00:00:00:00:00:0f" + not_before: 1260225629 # 2009-12-07 22:40:29 UTC + not_after: 1299537629 # 2011-03-07 22:40:29 UTC + verified: true + digest_alg: "sha1" + digest: "47b88536046e466d2f58b318fd1843f0b84b28d3" + file_digest: "47b88536046e466d2f58b318fd1843f0b84b28d3" + number_of_certificates: 4 + number_of_countersignatures: 1 + signer_info: + program_name: "DirectX SDK" + digest: "44238f27912fcf43d31b231b3615db4f4cd51eb6" + digest_alg: "sha1" + chain: + - issuer: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Code Signing PCA" + subject: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/OU=MOPR/CN=Microsoft Corporation" + thumbprint: "9617094a1cfb59ae7c1f7dfdb6739e4e7c40508f" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "61:01:cf:3e:00:00:00:00:00:0f" + not_before: 1260225629 # 2009-12-07 22:40:29 UTC + not_after: 1299537629 # 2011-03-07 22:40:29 UTC + - issuer: "/OU=Copyright (c) 1997 Microsoft Corp./OU=Microsoft Corporation/CN=Microsoft Root Authority" + subject: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Code Signing PCA" + thumbprint: "3036e3b25b88a55b86fc90e6e9eaad5081445166" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.3.14.3.2.29" + serial: "2e:ab:11:dc:50:ff:5c:9d:cb:c0" + not_before: 1187821862 # 2007-08-22 22:31:02 UTC + not_after: 1345878000 # 2012-08-25 07:00:00 UTC + certificates: + - issuer: "/OU=Copyright (c) 1997 Microsoft Corp./OU=Microsoft Corporation/CN=Microsoft Root Authority" + subject: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Code Signing PCA" + thumbprint: "3036e3b25b88a55b86fc90e6e9eaad5081445166" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.3.14.3.2.29" + serial: "2e:ab:11:dc:50:ff:5c:9d:cb:c0" + not_before: 1187821862 # 2007-08-22 22:31:02 UTC + not_after: 1345878000 # 2012-08-25 07:00:00 UTC + - issuer: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Code Signing PCA" + subject: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/OU=MOPR/CN=Microsoft Corporation" + thumbprint: "9617094a1cfb59ae7c1f7dfdb6739e4e7c40508f" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "61:01:cf:3e:00:00:00:00:00:0f" + not_before: 1260225629 # 2009-12-07 22:40:29 UTC + not_after: 1299537629 # 2011-03-07 22:40:29 UTC + - issuer: "/OU=Copyright (c) 1997 Microsoft Corp./OU=Microsoft Corporation/CN=Microsoft Root Authority" + subject: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Timestamping PCA" + thumbprint: "3ea99a60058275e0ed83b892a909449f8c33b245" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "6a:0b:99:4f:c0:00:25:ab:11:db:45:1f:58:7a:67:a2" + not_before: 1158368687 # 2006-09-16 01:04:47 UTC + not_after: 1568530800 # 2019-09-15 07:00:00 UTC + - issuer: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Timestamping PCA" + subject: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/OU=MOPR/OU=nCipher DSE ESN:85D3-305C-5BCF/CN=Microsoft Time-Stamp Service" + thumbprint: "4d6f357f0e6434da97b1afc540fb6fdd0e85a89f" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "61:05:a2:30:00:00:00:00:00:08" + not_before: 1217012475 # 2008-07-25 19:01:15 UTC + not_after: 1374779475 # 2013-07-25 19:11:15 UTC + countersignatures: + - verified: true + sign_time: 1275479951 # 2010-06-02 11:59:11 UTC + digest: "8816bffcc2a048cf661dc8d8b32648bdc20ab06e" + digest_alg: "sha1" + chain: + - issuer: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Timestamping PCA" + subject: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/OU=MOPR/OU=nCipher DSE ESN:85D3-305C-5BCF/CN=Microsoft Time-Stamp Service" + thumbprint: "4d6f357f0e6434da97b1afc540fb6fdd0e85a89f" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "61:05:a2:30:00:00:00:00:00:08" + not_before: 1217012475 # 2008-07-25 19:01:15 UTC + not_after: 1374779475 # 2013-07-25 19:11:15 UTC + - issuer: "/OU=Copyright (c) 1997 Microsoft Corp./OU=Microsoft Corporation/CN=Microsoft Root Authority" + subject: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Timestamping PCA" + thumbprint: "3ea99a60058275e0ed83b892a909449f8c33b245" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "6a:0b:99:4f:c0:00:25:ab:11:db:45:1f:58:7a:67:a2" + not_before: 1158368687 # 2006-09-16 01:04:47 UTC + not_after: 1568530800 # 2019-09-15 07:00:00 UTC +overlay: + offset: 282112 + size: 5976 \ No newline at end of file From 42c73fa9e6f4c68b686c4ab15c83d149ebc9b8a6 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Fri, 19 Apr 2024 14:47:58 +0200 Subject: [PATCH 20/38] fix: prevent panic in `oid_to_str` when the OID is not known. --- lib/src/modules/pe/authenticode.rs | 67 +++++++++++++++++------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 92a1d094d..6494ee366 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::fmt::{Display, Write}; use crate::modules::pe::parser::PE; @@ -571,7 +572,7 @@ impl AuthenticodeParser { pub struct AuthenticodeCountersign { signer: IssuerAndSerialNumber, - digest_alg: &'static str, + digest_alg: Cow<'static, str>, digest: Option, signing_time: Option, verified: bool, @@ -601,7 +602,7 @@ impl AuthenticodeSignature { } /// Get the name of the Authenticode hash algorithm. - pub fn authenticode_hash_algorithm(&self) -> &'static str { + pub fn authenticode_hash_algorithm(&self) -> Cow<'static, str> { oid_to_str(&self.indirect_data.message_digest.digest_algorithm.oid) } @@ -614,8 +615,8 @@ impl AuthenticodeSignature { } #[inline] - pub fn signer_info_digest_alg(&self) -> String { - oid_to_str(&self.signer_info().digest_alg.oid).to_string() + pub fn signer_info_digest_alg(&self) -> Cow<'static, str> { + oid_to_str(&self.signer_info().digest_alg.oid) } #[inline] @@ -712,7 +713,7 @@ impl From<&AuthenticodeSignature> for protos::pe::Signature { let mut sig = protos::pe::Signature::new(); sig.set_digest(bytes2hex("", value.stored_authenticode_hash())); - sig.set_digest_alg(value.authenticode_hash_algorithm().to_string()); + sig.set_digest_alg(value.authenticode_hash_algorithm().into_owned()); sig.set_file_digest(bytes2hex("", value.computed_authenticode_hash())); sig.set_verified(value.verify()); @@ -742,7 +743,9 @@ impl From<&AuthenticodeSignature> for protos::pe::Signature { let mut signer_info = protos::pe::SignerInfo::new(); - signer_info.set_digest_alg(value.signer_info_digest_alg()); + signer_info + .set_digest_alg(value.signer_info_digest_alg().into_owned()); + signer_info.set_digest(value.signer_info_digest()); if let Some(program_name) = &value.program_name { @@ -807,7 +810,7 @@ impl From<&Certificate> for protos::pe::Certificate { cert.set_algorithm_oid(format!("{}", value.signature_algorithm.oid)); cert.set_algorithm( - oid_to_str(&value.signature_algorithm.oid).to_string(), + oid_to_str(&value.signature_algorithm.oid).into_owned(), ); // The certificate thumbprint is the SHA1 of the DER-encoded certificate. @@ -966,6 +969,7 @@ fn verify_signed_data_impl( // Compute the digest for the DER encoding of the signed attributes, this // digest is signed, and its signature is in SignerInfo.signature. let mut attrs_digest = DerDigest::::default(); + si.signed_attrs.encode(&mut attrs_digest).unwrap(); let attrs_digest = attrs_digest.finalize(); @@ -1008,33 +1012,36 @@ fn format_serial_number( result } -/// Given an OID returns a string that describes it. -/// -/// # Panics +/// Returns a string that describes an OID. /// -/// If the OID is unknown. -fn oid_to_str(oid: &ObjectIdentifier) -> &'static str { - match oid { - &rfc5912::ID_SHA_1 => "sha1", - &rfc5912::ID_SHA_256 => "sha256", - &rfc5912::ID_SHA_384 => "sha384", - &rfc5912::ID_SHA_512 => "sha512", - &rfc5912::ID_MD_5 => "md5", - &rfc4519::C => "C", - &rfc4519::COMMON_NAME => "CN", - &rfc4519::O => "O", - &rfc4519::OU => "OU", - &rfc4519::ST => "ST", +/// When the OID is unknown, returns the numeric representation for +/// the OID (i.e: "1.3.14.3.2.29"). +fn oid_to_str(oid: &ObjectIdentifier) -> Cow<'static, str> { + let oid_str = match oid { + &rfc5912::ID_SHA_1 => Some("sha1"), + &rfc5912::ID_SHA_256 => Some("sha256"), + &rfc5912::ID_SHA_384 => Some("sha384"), + &rfc5912::ID_SHA_512 => Some("sha512"), + &rfc5912::ID_MD_5 => Some("md5"), + &rfc4519::C => Some("C"), + &rfc4519::COMMON_NAME => Some("CN"), + &rfc4519::O => Some("O"), + &rfc4519::OU => Some("OU"), + &rfc4519::ST => Some("ST"), // OIDs not included in const_oid. - &JURISDICTION_C => "jurisdictionC", - &JURISDICTION_L => "jurisdictionL", - &JURISDICTION_ST => "jurisdictionST", - &SHA1_WITH_RSA_ENCRYPTION => "sha1WithRSAEncryption", + &JURISDICTION_C => Some("jurisdictionC"), + &JURISDICTION_L => Some("jurisdictionL"), + &JURISDICTION_ST => Some("jurisdictionST"), + &SHA1_WITH_RSA_ENCRYPTION => Some("sha1WithRSAEncryption"), // In the default case try to use the string representation provided by // the `const-oid` crate. Panics if this fails. - oid => { - DB.by_oid(oid).unwrap_or_else(|| panic!("unknown OID: {:?}", oid)) - } + oid => DB.by_oid(oid), + }; + + if let Some(oid) = oid_str { + Cow::Borrowed(oid) + } else { + Cow::Owned(oid.to_string()) } } From 8772e204c43c47c72f287b8d83d149f64375347c Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Fri, 19 Apr 2024 16:41:18 +0200 Subject: [PATCH 21/38] fix: add missing import --- lib/src/modules/pe/parser.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/modules/pe/parser.rs b/lib/src/modules/pe/parser.rs index 4da4456d3..9f0e7d944 100644 --- a/lib/src/modules/pe/parser.rs +++ b/lib/src/modules/pe/parser.rs @@ -15,7 +15,8 @@ use nom::bytes::complete::{take, take_till}; use nom::combinator::{cond, consumed, iterator, map, opt, success, verify}; use nom::error::ErrorKind; use nom::multi::{ - count, fold_many0, fold_many1, length_data, many0, many1, many_m_n, + count, fold_many0, fold_many1, fold_many_m_n, length_data, many0, many1, + many_m_n, }; use nom::number::complete::{le_u16, le_u32, le_u64, u8}; use nom::sequence::tuple; From 32b3453d33dd91b762d5f3e38a0259d1c0dc44fa Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Fri, 19 Apr 2024 20:07:10 +0200 Subject: [PATCH 22/38] refactor: simplify `parse_content_info` --- lib/src/modules/pe/authenticode.rs | 213 +++++++++++++++-------------- 1 file changed, 108 insertions(+), 105 deletions(-) diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 6494ee366..56b6487da 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -28,6 +28,7 @@ use rsa::Pkcs1v15Sign; use sha1::digest::Output; use sha1::Sha1; use sha2::{Sha256, Sha384, Sha512}; +use x509_cert::attr::Attribute; use x509_cert::spki::{AlgorithmIdentifierOwned, SubjectPublicKeyInfoRef}; use x509_tsp::TstInfo; use x509_verify::{VerifyInfo, VerifyingKey}; @@ -357,113 +358,20 @@ impl AuthenticodeParser { } } SPC_MS_COUNTERSIGN => { - for value in attr.values.iter() { - if let Ok(signed_data) = value - .decode_as::() - .and_then(|content_info| { - content_info - .content - .decode_as::() - }) - { - certificates.extend( - signed_data - .certificates - .as_ref() - .map(Self::certificate_set_to_iter) - .unwrap() - .cloned() - .collect::>(), - ); - - let cs = signed_data - .signer_infos - .as_ref() - .get(0) - .unwrap(); - - let mut countersignature = - Self::pkcs9_countersignature(cs); - - let tst_info = signed_data - .encap_content_info - .econtent - .and_then(|content| { - content.decode_as::().ok() - }) - .and_then(|octet_string| { - TstInfo::from_der( - octet_string.as_bytes(), - ) - .ok() - }); - - let tst_info = match tst_info { - Some(tst_info) => tst_info, - None => continue, - }; - - countersignature.digest_alg = oid_to_str( - &tst_info - .message_imprint - .hash_algorithm - .oid, - ); - - countersignature.digest = Some(bytes2hex( - "", - tst_info - .message_imprint - .hashed_message - .as_bytes(), - )); - - countersignature.verified = - verify_message_digest( - &tst_info - .message_imprint - .hash_algorithm, - signer_info.signature.as_bytes(), - tst_info - .message_imprint - .hashed_message - .as_bytes(), - ) && verify_signer_info( - cs, - certificates.as_slice(), - ); - - countersignatures.push(countersignature); - } - } + Self::parse_ms_countersignature_attr( + signer_info, + attr, + &mut certificates, + &mut countersignatures, + ); } rfc5911::ID_COUNTERSIGNATURE => { - for value in attr.values.iter() { - if let Ok(cs) = - value.decode_as::().as_ref() - { - let mut countersignature = - Self::pkcs9_countersignature(cs); - - let message_digest = - match get_message_digest(cs) { - Some(digest) => digest, - None => continue, - }; - - countersignature.verified = - verify_message_digest( - &cs.digest_alg, - signer_info.signature.as_bytes(), - message_digest.as_bytes(), - ) && verify_signer_info( - cs, - certificates.as_slice(), - ); - - countersignatures.push(countersignature); - } - } + Self::parse_pcks9_countersignature_attr( + signer_info, + attr, + &mut certificates, + &mut countersignatures, + ); } _ => {} } @@ -518,6 +426,101 @@ impl AuthenticodeParser { Ok(signatures) } + fn parse_ms_countersignature_attr( + si: &SignerInfo, + attr: &Attribute, + certificates: &mut Vec, + countersignatures: &mut Vec, + ) { + for value in attr.values.iter() { + let content_info = match value.decode_as::() { + Ok(content_info) => content_info, + Err(_) => continue, + }; + + println!("{:?}", content_info.content_type); + + let x = content_info.content.decode_as::(); + + println!("{:?}", x); + + if let Ok(signed_data) = x { + certificates.extend( + signed_data + .certificates + .as_ref() + .map(Self::certificate_set_to_iter) + .unwrap() + .cloned() + .collect::>(), + ); + + let cs = signed_data.signer_infos.as_ref().get(0).unwrap(); + + let mut countersignature = Self::pkcs9_countersignature(cs); + + let tst_info = signed_data + .encap_content_info + .econtent + .and_then(|content| { + content.decode_as::().ok() + }) + .and_then(|octet_string| { + TstInfo::from_der(octet_string.as_bytes()).ok() + }); + + let tst_info = match tst_info { + Some(tst_info) => tst_info, + None => continue, + }; + + countersignature.digest_alg = + oid_to_str(&tst_info.message_imprint.hash_algorithm.oid); + + countersignature.digest = Some(bytes2hex( + "", + tst_info.message_imprint.hashed_message.as_bytes(), + )); + + countersignature.verified = + verify_message_digest( + &tst_info.message_imprint.hash_algorithm, + si.signature.as_bytes(), + tst_info.message_imprint.hashed_message.as_bytes(), + ) && verify_signer_info(cs, certificates.as_slice()); + + countersignatures.push(countersignature); + } + } + } + + fn parse_pcks9_countersignature_attr( + si: &SignerInfo, + attr: &Attribute, + certificates: &mut Vec, + countersignatures: &mut Vec, + ) { + for value in attr.values.iter() { + if let Ok(cs) = value.decode_as::().as_ref() { + let mut countersignature = Self::pkcs9_countersignature(cs); + + let message_digest = match get_message_digest(cs) { + Some(digest) => digest, + None => continue, + }; + + countersignature.verified = + verify_message_digest( + &cs.digest_alg, + si.signature.as_bytes(), + message_digest.as_bytes(), + ) && verify_signer_info(cs, certificates.as_slice()); + + countersignatures.push(countersignature); + } + } + } + fn pkcs9_countersignature( cs: &Countersignature, ) -> AuthenticodeCountersign { From 998ed3df045183a8b9d4db4d105c5bc699d1e45e Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Fri, 19 Apr 2024 20:08:21 +0200 Subject: [PATCH 23/38] fix: broken code --- lib/src/modules/pe/authenticode.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 56b6487da..356f4ab63 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -438,13 +438,9 @@ impl AuthenticodeParser { Err(_) => continue, }; - println!("{:?}", content_info.content_type); - - let x = content_info.content.decode_as::(); - - println!("{:?}", x); - - if let Ok(signed_data) = x { + if let Ok(signed_data) = + content_info.content.decode_as::() + { certificates.extend( signed_data .certificates From dd7e7e75b1fe55b12c4de089bdad8df56fcc4008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Milkovi=C4=8D?= Date: Mon, 22 Apr 2024 08:54:26 +0200 Subject: [PATCH 24/38] feat: Added support for non-canonically DER encoded (counter)signatures (#99) This adds deferred parsing of SignedAttributes field of SignedInfo structure within CMS, allowing us to directly access the raw data of this field so that it can be properly verified without canonical DER decoder in the way. To make things easier and avoid rewrite of as many code as possible, there's option to turn `DeferSignerInfo` structure directly into `SignerInfo` structure. On top of that, all other fields are decoded as usual, making deferred structure still useful in cases where non-deferred attributes are needed. Affected binary added to tests. --- lib/src/modules/pe/authenticode.rs | 300 +++++++-- ...5d1d4ddd53f0aefa976216c46e6ba39a9f4.in.zip | Bin 0 -> 43628 bytes ...3075d1d4ddd53f0aefa976216c46e6ba39a9f4.out | 634 ++++++++++++++++++ 3 files changed, 875 insertions(+), 59 deletions(-) create mode 100644 lib/src/modules/pe/tests/testdata/70211a3f90376bbc61f49c22a63075d1d4ddd53f0aefa976216c46e6ba39a9f4.in.zip create mode 100644 lib/src/modules/pe/tests/testdata/70211a3f90376bbc61f49c22a63075d1d4ddd53f0aefa976216c46e6ba39a9f4.out diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 356f4ab63..02db0d770 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -3,17 +3,16 @@ use std::fmt::{Display, Write}; use crate::modules::pe::parser::PE; use array_bytes::bytes2hex; -use cms::attr::Countersignature; use cms::cert::x509::{spki, Certificate}; use cms::cert::IssuerAndSerialNumber; use cms::content_info::CmsVersion; use cms::content_info::ContentInfo; use cms::signed_data::{ - CertificateSet, SignedData, SignerIdentifier, SignerInfo, + CertificateSet, SignedAttributes, SignedData, SignerIdentifier, SignerInfo, SignerInfos }; use const_oid::db::{rfc4519, rfc5911, rfc5912, rfc6268, DB}; use const_oid::{AssociatedOid, ObjectIdentifier}; -use der::asn1; +use der::{asn1, FixedTag, Reader}; use der::asn1::OctetString; use der::referenced::OwnedToRef; use der::{Choice, Sequence, SliceReader}; @@ -158,6 +157,161 @@ pub enum SpcLink { Url(asn1::Ia5String), } +/// ASN.1 SignerInfo +/// +/// SignerInfo ::= SEQUENCE { +/// version CMSVersion, +/// sid SignerIdentifier, +/// digestAlgorithm DigestAlgorithmIdentifier, +/// signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, +/// signatureAlgorithm SignatureAlgorithmIdentifier, +/// signature SignatureValue, +/// unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL +/// } +/// +/// This is a custom deferred structure which delays decoding of [`signerInfos`] +/// to deal with mixed BER/DER encoding issues. We need to obtain the same data +/// during verification that was used during signing. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct DeferSignerInfo { + pub version: cms::content_info::CmsVersion, + pub sid: cms::signed_data::SignerIdentifier, + pub digest_alg: spki::AlgorithmIdentifierOwned, + pub signed_attrs: Option>, + pub signature_algorithm: spki::AlgorithmIdentifierOwned, + pub signature: cms::signed_data::SignatureValue, + pub unsigned_attrs: Option, +} + +/// ASN.1 SignerInfos +/// +/// SignerInfos ::= SET OF SignerInfo +/// +/// This is a custom deferred structure which delays decoding of [`signerInfos`] +/// to deal with mixed BER/DER encoding issues. We need to obtain the same data +/// during verification that was used during signing. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct DeferSignerInfos(pub Vec); + +/// ASN.1 SignedData +/// +/// SignedData ::= SEQUENCE { +/// version CMSVersion, +/// digestAlgorithms DigestAlgorithmIdentifiers, +/// encapContentInfo EncapsulatedContentInfo, +/// certificates [0] IMPLICIT CertificateSet OPTIONAL, +/// crls [1] IMPLICIT RevocationInfoChoices OPTIONAL, +/// signerInfos SignerInfos +/// } +/// +/// This is a custom deferred structure which delays decoding of [`signerInfos`] +/// to deal with mixed BER/DER encoding issues. We need to obtain the same data +/// during verification that was used during signing. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct DeferSignedData { + pub version: cms::content_info::CmsVersion, + pub digest_algorithms: cms::signed_data::DigestAlgorithmIdentifiers, + pub encap_content_info: cms::signed_data::EncapsulatedContentInfo, + pub certificates: Option, + pub crls: Option, + pub signer_infos: DeferSignerInfos, +} + +impl der::FixedTag for DeferSignerInfo { + const TAG: Tag = SignerInfo::TAG; +} + +impl<'a> der::DecodeValue<'a> for DeferSignerInfo { + fn decode_value>(reader: &mut R, header: der::Header) -> der::Result { + reader.read_nested(header.length, |reader| { + let version = reader.decode()?; + let sid = reader.decode()?; + let digest_alg = reader.decode()?; + let signed_attrs = reader.peek_header() + .and_then(|header| + // Signer attributes are implicitly tagged which means that the original tag + // for SET OF is not present. We therefore need to swap the tag to SET due to: + // * Verification - we need to verify against the original data + // * Reencoding - we need to able to reencode this back to SignedAttributes + if header.tag.is_context_specific() && header.tag.is_constructed() && header.tag.number() == der::TagNumber::N0 { + reader.read_slice(header.encoded_len()?)?; + let new_header = der::Header { + tag: SignedAttributes::TAG, + length: header.length + }; + + let mut result = Vec::new(); + new_header.encode_to_vec(&mut result)?; + result.extend(reader.read_slice(header.length)?); + Ok(Some(result)) + } else { + Ok(None) + })?; + let signature_algorithm = reader.decode()?; + let signature = reader.decode()?; + let unsigned_attrs = reader.context_specific(der::TagNumber::N1, der::TagMode::Implicit)?; + + Ok(Self { + version, + sid, + digest_alg, + signed_attrs, + signature_algorithm, + signature, + unsigned_attrs, + }) + }) + } +} + +impl TryFrom<&DeferSignerInfo> for SignerInfo { + type Error = der::Error; + + fn try_from(value: &DeferSignerInfo) -> Result { + Ok(Self { + version: value.version, + sid: value.sid.clone(), + digest_alg: value.digest_alg.clone(), + signed_attrs: value.signed_attrs.as_ref().map(|data| SignedAttributes::from_der(data)).transpose()?, + signature_algorithm: value.signature_algorithm.clone(), + signature: value.signature.clone(), + unsigned_attrs: value.unsigned_attrs.clone(), + }) + } +} + +impl der::FixedTag for DeferSignerInfos { + const TAG: Tag = SignerInfos::TAG; +} + +impl<'a> der::DecodeValue<'a> for DeferSignerInfos { + fn decode_value>(reader: &mut R, header: der::Header) -> der::Result { + reader.read_nested(header.length, |reader| { + Ok(Self(std::iter::from_fn(|| reader.decode().ok()).collect())) + }) + + } +} + +impl der::FixedTag for DeferSignedData { + const TAG: Tag = SignedData::TAG; +} + +impl<'a> der::DecodeValue<'a> for DeferSignedData { + fn decode_value>(reader: &mut R, header: der::Header) -> der::Result { + reader.read_nested(header.length, |reader| { + Ok(Self { + version: reader.decode()?, + digest_algorithms: reader.decode()?, + encap_content_info: reader.decode()?, + certificates: reader.context_specific(der::TagNumber::N0, der::TagMode::Implicit)?, + crls: reader.context_specific(der::TagNumber::N1, der::TagMode::Implicit)?, + signer_infos: reader.decode()?, + }) + }) + } +} + /// Error returned by [`AuthenticodeParser::parse`]. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum ParseError { @@ -173,6 +327,9 @@ pub enum ParseError { /// The content info is not valid [`SignedData`]. InvalidSignedData(der::Error), + /// The signer info is not valid [`SignerInfo`]. + InvalidSignerInfo(der::Error), + /// The version of [`SignedData`] is not 1. InvalidSignedDataVersion(CmsVersion), @@ -243,7 +400,7 @@ impl AuthenticodeParser { ) -> Result, ParseError> { let signed_data = content_info .content - .decode_as::() + .decode_as::() .map_err(ParseError::InvalidSignedData)?; if signed_data.version != CmsVersion::V1 { @@ -284,6 +441,8 @@ impl AuthenticodeParser { .map_err(ParseError::InvalidSpcIndirectDataContent)?; let signer_info = &signed_data.signer_infos.0.as_slice()[0]; + let decoded_signer_info = SignerInfo::try_from(signer_info) + .map_err(ParseError::InvalidSignerInfo)?; if signer_info.version != CmsVersion::V1 { return Err(ParseError::InvalidSignerInfoVersion( @@ -298,7 +457,7 @@ impl AuthenticodeParser { } let signed_attrs = - if let Some(signed_attrs) = &signer_info.signed_attrs { + if let Some(signed_attrs) = &decoded_signer_info.signed_attrs { signed_attrs } else { return Err(ParseError::EmptyAuthenticatedAttributes); @@ -314,7 +473,7 @@ impl AuthenticodeParser { // Get the message digest attribute stored in `SignerInfo`, this is // the digest of `SignedData.EncapsulatedContentInfo.econtent`. - let signer_info_digest = get_message_digest(signer_info) + let signer_info_digest = get_message_digest(signed_attrs) .ok_or(ParseError::MissingMessageDigestAuthenticatedAttribute)?; // Get the opus info attribute and decode it. @@ -363,15 +522,15 @@ impl AuthenticodeParser { attr, &mut certificates, &mut countersignatures, - ); + )?; } rfc5911::ID_COUNTERSIGNATURE => { - Self::parse_pcks9_countersignature_attr( + Self::parse_pkcs9_countersignature_attr( signer_info, attr, &mut certificates, &mut countersignatures, - ); + )?; } _ => {} } @@ -414,9 +573,10 @@ impl AuthenticodeParser { signatures.push(AuthenticodeSignature { program_name: opus_info.and_then(|oi| oi.program_name), signer_info_digest, + indirect_data, signed_data, + signer_info: decoded_signer_info, computed_authenticode_hash: file_digest, - indirect_data, countersignatures, certificates, }); @@ -427,11 +587,11 @@ impl AuthenticodeParser { } fn parse_ms_countersignature_attr( - si: &SignerInfo, + si: &DeferSignerInfo, attr: &Attribute, certificates: &mut Vec, countersignatures: &mut Vec, - ) { + ) -> Result<(), ParseError> { for value in attr.values.iter() { let content_info = match value.decode_as::() { Ok(content_info) => content_info, @@ -439,7 +599,7 @@ impl AuthenticodeParser { }; if let Ok(signed_data) = - content_info.content.decode_as::() + content_info.content.decode_as::() { certificates.extend( signed_data @@ -451,9 +611,14 @@ impl AuthenticodeParser { .collect::>(), ); - let cs = signed_data.signer_infos.as_ref().get(0).unwrap(); + let cs_si = signed_data + .signer_infos + .0 + .first() + .unwrap(); - let mut countersignature = Self::pkcs9_countersignature(cs); + let mut countersignature = + Self::pkcs9_countersignature(cs_si)?; let tst_info = signed_data .encap_content_info @@ -462,7 +627,10 @@ impl AuthenticodeParser { content.decode_as::().ok() }) .and_then(|octet_string| { - TstInfo::from_der(octet_string.as_bytes()).ok() + TstInfo::from_der( + octet_string.as_bytes(), + ) + .ok() }); let tst_info = match tst_info { @@ -471,11 +639,19 @@ impl AuthenticodeParser { }; countersignature.digest_alg = - oid_to_str(&tst_info.message_imprint.hash_algorithm.oid); + oid_to_str( + &tst_info + .message_imprint + .hash_algorithm + .oid, + ); countersignature.digest = Some(bytes2hex( "", - tst_info.message_imprint.hashed_message.as_bytes(), + tst_info + .message_imprint + .hashed_message + .as_bytes(), )); countersignature.verified = @@ -483,47 +659,60 @@ impl AuthenticodeParser { &tst_info.message_imprint.hash_algorithm, si.signature.as_bytes(), tst_info.message_imprint.hashed_message.as_bytes(), - ) && verify_signer_info(cs, certificates.as_slice()); + ) && verify_signer_info(cs_si, certificates.as_slice()); countersignatures.push(countersignature); } } + + Ok(()) } - fn parse_pcks9_countersignature_attr( - si: &SignerInfo, + fn parse_pkcs9_countersignature_attr( + si: &DeferSignerInfo, attr: &Attribute, certificates: &mut Vec, countersignatures: &mut Vec, - ) { + ) -> Result<(), ParseError> { for value in attr.values.iter() { - if let Ok(cs) = value.decode_as::().as_ref() { - let mut countersignature = Self::pkcs9_countersignature(cs); + if let Ok(cs_si) = value.decode_as::().as_ref() { + let mut countersignature = + Self::pkcs9_countersignature(cs_si)?; - let message_digest = match get_message_digest(cs) { - Some(digest) => digest, - None => continue, - }; + let cs_signed_attrs = countersignature.signer_info.signed_attrs + .as_ref() + .ok_or(ParseError::EmptyAuthenticatedAttributes)?; + + let message_digest = + match get_message_digest(cs_signed_attrs) { + Some(digest) => digest, + None => continue, + }; countersignature.verified = verify_message_digest( - &cs.digest_alg, + &cs_si.digest_alg, si.signature.as_bytes(), message_digest.as_bytes(), - ) && verify_signer_info(cs, certificates.as_slice()); + ) && verify_signer_info(cs_si, certificates.as_slice()); countersignatures.push(countersignature); } } + + Ok(()) } fn pkcs9_countersignature( - cs: &Countersignature, - ) -> AuthenticodeCountersign { + cs: &DeferSignerInfo, + ) -> Result { let mut digest = None; let mut signing_time = None; - if let Some(signed_attrs) = &cs.signed_attrs { + let decoded_cs = SignerInfo::try_from(cs) + .map_err(ParseError::InvalidSignerInfo)?; + + if let Some(signed_attrs) = &decoded_cs.signed_attrs { for attr in signed_attrs.iter() { match attr.oid { rfc6268::ID_MESSAGE_DIGEST => { @@ -547,13 +736,14 @@ impl AuthenticodeParser { _ => unreachable!(), }; - AuthenticodeCountersign { + Ok(AuthenticodeCountersign { signer: signer.clone(), + signer_info: decoded_cs, digest_alg: oid_to_str(&cs.digest_alg.oid), digest, signing_time, verified: false, - } + }) } fn certificate_set_to_iter( @@ -571,6 +761,7 @@ impl AuthenticodeParser { pub struct AuthenticodeCountersign { signer: IssuerAndSerialNumber, + signer_info: SignerInfo, digest_alg: Cow<'static, str>, digest: Option, signing_time: Option, @@ -580,7 +771,8 @@ pub struct AuthenticodeCountersign { pub struct AuthenticodeSignature { signer_info_digest: OctetString, indirect_data: SpcIndirectDataContent, - signed_data: SignedData, + signed_data: DeferSignedData, + signer_info: SignerInfo, certificates: Vec, countersignatures: Vec, program_name: Option, @@ -605,17 +797,9 @@ impl AuthenticodeSignature { oid_to_str(&self.indirect_data.message_digest.digest_algorithm.oid) } - /// Get the [`SignerInfo`] struct. - #[inline] - pub fn signer_info(&self) -> &SignerInfo { - // The parser validates that exactly one signer info is present, so - // this won't panic. - &self.signed_data.signer_infos.0.as_ref()[0] - } - #[inline] pub fn signer_info_digest_alg(&self) -> Cow<'static, str> { - oid_to_str(&self.signer_info().digest_alg.oid) + oid_to_str(&self.signer_info.digest_alg.oid) } #[inline] @@ -644,7 +828,7 @@ impl AuthenticodeSignature { pub fn signer(&self) -> &IssuerAndSerialNumber { if let SignerIdentifier::IssuerAndSerialNumber(signer) = - &self.signer_info().sid + &self.signer_info.sid { signer } else { @@ -685,13 +869,13 @@ impl AuthenticodeSignature { return false; } - let message_digest = match get_message_digest(self.signer_info()) { + let message_digest = match get_message_digest(self.signer_info.signed_attrs.as_ref().unwrap()) { Some(digest) => digest, None => return false, }; if !verify_message_digest( - &self.signer_info().digest_alg, + &self.signer_info.digest_alg, self.signed_data .encap_content_info .econtent @@ -703,7 +887,10 @@ impl AuthenticodeSignature { return false; } - verify_signer_info(self.signer_info(), self.certificates()) + verify_signer_info( + &self.signed_data.signer_infos.0[0], + self.certificates() + ) } } @@ -904,10 +1091,8 @@ fn format_name(name: &x509_cert::name::Name) -> String { } /// Given a [`SignerInfo`] returns the value of the message digest attribute. -fn get_message_digest(si: &SignerInfo) -> Option { - si.signed_attrs - .as_ref() - .unwrap() +fn get_message_digest(signed_attrs: &SignedAttributes) -> Option { + signed_attrs .iter() .find(|attr| attr.oid == rfc6268::ID_MESSAGE_DIGEST) .and_then(|attr| attr.values.get(0)) @@ -931,7 +1116,7 @@ fn verify_message_digest( } } -fn verify_signer_info(si: &SignerInfo, certs: &[Certificate]) -> bool { +fn verify_signer_info(si: &DeferSignerInfo, certs: &[Certificate]) -> bool { match si.digest_alg.oid { rfc5912::ID_SHA_1 => verify_signed_data_impl::(si, certs), rfc5912::ID_SHA_256 => verify_signed_data_impl::(si, certs), @@ -943,7 +1128,7 @@ fn verify_signer_info(si: &SignerInfo, certs: &[Certificate]) -> bool { } fn verify_signed_data_impl( - si: &SignerInfo, + si: &DeferSignerInfo, certs: &[Certificate], ) -> bool { // Find the certificate that signed the data in `content`. @@ -967,10 +1152,7 @@ fn verify_signed_data_impl( // Compute the digest for the DER encoding of the signed attributes, this // digest is signed, and its signature is in SignerInfo.signature. - let mut attrs_digest = DerDigest::::default(); - - si.signed_attrs.encode(&mut attrs_digest).unwrap(); - let attrs_digest = attrs_digest.finalize(); + let attrs_digest = D::digest(si.signed_attrs.as_ref().unwrap()); // Search for the certificate that signed the digest. let signing_cert = match certs diff --git a/lib/src/modules/pe/tests/testdata/70211a3f90376bbc61f49c22a63075d1d4ddd53f0aefa976216c46e6ba39a9f4.in.zip b/lib/src/modules/pe/tests/testdata/70211a3f90376bbc61f49c22a63075d1d4ddd53f0aefa976216c46e6ba39a9f4.in.zip new file mode 100644 index 0000000000000000000000000000000000000000..a5ace81cdb670be00ab36c458369f2bd8f0e7e43 GIT binary patch literal 43628 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 H0>b|R1A*0k literal 0 HcmV?d00001 diff --git a/lib/src/modules/pe/tests/testdata/70211a3f90376bbc61f49c22a63075d1d4ddd53f0aefa976216c46e6ba39a9f4.out b/lib/src/modules/pe/tests/testdata/70211a3f90376bbc61f49c22a63075d1d4ddd53f0aefa976216c46e6ba39a9f4.out new file mode 100644 index 000000000..bb5f17c96 --- /dev/null +++ b/lib/src/modules/pe/tests/testdata/70211a3f90376bbc61f49c22a63075d1d4ddd53f0aefa976216c46e6ba39a9f4.out @@ -0,0 +1,634 @@ +is_pe: true +machine: MACHINE_AMD64 +subsystem: SUBSYSTEM_NATIVE +os_version: + major: 6 + minor: 1 +subsystem_version: + major: 6 + minor: 1 +image_version: + major: 6 + minor: 1 +linker_version: + major: 9 + minor: 0 +opthdr_magic: IMAGE_NT_OPTIONAL_HDR64_MAGIC +characteristics: 34 +dll_characteristics: 0 +timestamp: 1459189242 # 2016-03-28 18:20:42 UTC +image_base: 65536 +checksum: 81108 +base_of_code: 4096 +entry_point: 23652 +entry_point_raw: 36964 +section_alignment: 4096 +file_alignment: 512 +loader_flags: 0 +size_of_optional_header: 240 +size_of_code: 21504 +size_of_initialized_data: 5632 +size_of_uninitialized_data: 0 +size_of_image: 45056 +size_of_headers: 1024 +size_of_stack_reserve: 262144 +size_of_stack_commit: 4096 +size_of_heap_reserve: 1048576 +size_of_heap_commit: 4096 +pointer_to_symbol_table: 0 +win32_version_value: 0 +number_of_symbols: 0 +number_of_rva_and_sizes: 16 +number_of_sections: 7 +number_of_imported_functions: 83 +number_of_delayed_imported_functions: 0 +number_of_resources: 1 +number_of_version_infos: 7 +number_of_imports: 2 +number_of_delayed_imports: 0 +number_of_exports: 0 +number_of_signatures: 2 +version_info: + "CompanyName": "wj32" + "FileDescription": "KProcessHacker" + "FileVersion": "3.0" + "LegalCopyright": "Licensed under the GNU GPL, v3." + "OriginalFilename": "kprocesshacker.sys" + "ProductName": "KProcessHacker" + "ProductVersion": "3.0" +version_info_list: + - key: "CompanyName" + value: "wj32" + - key: "FileDescription" + value: "KProcessHacker" + - key: "FileVersion" + value: "3.0" + - key: "LegalCopyright" + value: "Licensed under the GNU GPL, v3." + - key: "OriginalFilename" + value: "kprocesshacker.sys" + - key: "ProductName" + value: "KProcessHacker" + - key: "ProductVersion" + value: "3.0" +rich_signature: + offset: 128 + length: 72 + key: 4259651297 + raw_data: "\xa5\x7f\x8b\xae\xe1\x1e\xe5\xfd\xe1\x1e\xe5\xfd\xe1\x1e\xe5\xfd\xe1\x1e\xe4\xfd\xb5\x1e\xe5\xfd\xe8fv\xfd\xe4\x1e\xe5\xfd\xe8fp\xfd\xe2\x1e\xe5\xfd\xe8ff\xfd\xe4\x1e\xe5\xfd\xe8fl\xfd\xea\x1e\xe5\xfd\xe8fq\xfd\xe0\x1e\xe5\xfd\xe8ft\xfd\xe0\x1e\xe5\xfd" + clear_data: "DanS\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00T\x00\x00\x00\tx\x93\x00\x05\x00\x00\x00\tx\x95\x00\x03\x00\x00\x00\tx\x83\x00\x05\x00\x00\x00\tx\x89\x00\x0b\x00\x00\x00\tx\x94\x00\x01\x00\x00\x00\tx\x91\x00\x01\x00\x00\x00" + tools: + - toolid: 1 + version: 0 + times: 84 + - toolid: 147 + version: 30729 + times: 5 + - toolid: 149 + version: 30729 + times: 3 + - toolid: 131 + version: 30729 + times: 5 + - toolid: 137 + version: 30729 + times: 11 + - toolid: 148 + version: 30729 + times: 1 + - toolid: 145 + version: 30729 + times: 1 +pdb_path: "d:\\projects\\processhacker2\\kprocesshacker\\bin\\amd64\\kprocesshacker.pdb" +sections: + - name: ".text" + full_name: ".text" + characteristics: 1744830496 + raw_data_size: 4096 + raw_data_offset: 1024 + virtual_address: 4096 + virtual_size: 4000 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: ".rdata" + full_name: ".rdata" + characteristics: 1207959616 + raw_data_size: 2560 + raw_data_offset: 5120 + virtual_address: 8192 + virtual_size: 2516 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: ".data" + full_name: ".data" + characteristics: 3355443264 + raw_data_size: 512 + raw_data_offset: 7680 + virtual_address: 12288 + virtual_size: 728 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: ".pdata" + full_name: ".pdata" + characteristics: 1207959616 + raw_data_size: 1024 + raw_data_offset: 8192 + virtual_address: 16384 + virtual_size: 564 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: "PAGE" + full_name: "PAGE" + characteristics: 1610612768 + raw_data_size: 14336 + raw_data_offset: 9216 + virtual_address: 20480 + virtual_size: 13902 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: "INIT" + full_name: "INIT" + characteristics: 3791650848 + raw_data_size: 3072 + raw_data_offset: 23552 + virtual_address: 36864 + virtual_size: 2720 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: ".rsrc" + full_name: ".rsrc" + characteristics: 1107296320 + raw_data_size: 1024 + raw_data_offset: 26624 + virtual_address: 40960 + virtual_size: 760 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 +data_directories: + - virtual_address: 0 + size: 0 + - virtual_address: 36996 + size: 60 + - virtual_address: 40960 + size: 760 + - virtual_address: 16384 + size: 564 + - virtual_address: 27648 + size: 17560 + - virtual_address: 0 + size: 0 + - virtual_address: 8880 + size: 28 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 8192 + size: 680 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 +resource_timestamp: 0 # 1970-01-01 00:00:00 UTC +resource_version: + major: 0 + minor: 0 +resources: + - length: 664 + rva: 41056 + offset: 26720 + type: RESOURCE_TYPE_VERSION + id: 1 + language: 1033 +import_details: + - library_name: "ntoskrnl.exe" + number_of_functions: 73 + functions: + - name: "SePrivilegeCheck" + rva: 8280 + - name: "ZwOpenKey" + rva: 8288 + - name: "ProbeForRead" + rva: 8296 + - name: "RtlGetVersion" + rva: 8304 + - name: "PsProcessType" + rva: 8312 + - name: "ObOpenObjectByName" + rva: 8320 + - name: "ObGetObjectType" + rva: 8328 + - name: "PsReleaseProcessExitSynchronization" + rva: 8336 + - name: "ZwQueryObject" + rva: 8344 + - name: "RtlEqualUnicodeString" + rva: 8352 + - name: "KeUnstackDetachProcess" + rva: 8360 + - name: "ExEnumHandleTable" + rva: 8368 + - name: "ObQueryNameString" + rva: 8376 + - name: "IoFileObjectType" + rva: 8384 + - name: "IoDriverObjectType" + rva: 8392 + - name: "ExfUnblockPushLock" + rva: 8400 + - name: "ObReferenceObjectByHandle" + rva: 8408 + - name: "PsAcquireProcessExitSynchronization" + rva: 8416 + - name: "PsInitialSystemProcess" + rva: 8424 + - name: "ObSetHandleAttributes" + rva: 8432 + - name: "ZwQueryInformationProcess" + rva: 8440 + - name: "ObfDereferenceObject" + rva: 8448 + - name: "ExAllocatePoolWithQuotaTag" + rva: 8456 + - name: "ZwQueryInformationThread" + rva: 8464 + - name: "ObOpenObjectByPointer" + rva: 8472 + - name: "KeStackAttachProcess" + rva: 8480 + - name: "PsLookupProcessByProcessId" + rva: 8488 + - name: "PsJobType" + rva: 8496 + - name: "PsReferencePrimaryToken" + rva: 8504 + - name: "SeTokenObjectType" + rva: 8512 + - name: "IoCreateDevice" + rva: 8520 + - name: "PsGetProcessJob" + rva: 8528 + - name: "PsLookupProcessThreadByCid" + rva: 8536 + - name: "ZwTerminateProcess" + rva: 8544 + - name: "PsDereferencePrimaryToken" + rva: 8552 + - name: "IoThreadToProcess" + rva: 8560 + - name: "RtlWalkFrameChain" + rva: 8568 + - name: "KeInitializeApc" + rva: 8576 + - name: "KeSetEvent" + rva: 8584 + - name: "KeInsertQueueApc" + rva: 8592 + - name: "KeWaitForSingleObject" + rva: 8600 + - name: "PsThreadType" + rva: 8608 + - name: "PsLookupThreadByThreadId" + rva: 8616 + - name: "ZwQuerySystemInformation" + rva: 8624 + - name: "ZwQueryVirtualMemory" + rva: 8632 + - name: "ExReleaseFastMutex" + rva: 8640 + - name: "ExAcquireFastMutex" + rva: 8648 + - name: "ZwReadFile" + rva: 8656 + - name: "MmHighestUserAddress" + rva: 8664 + - name: "SeLocateProcessImageName" + rva: 8672 + - name: "KeDelayExecutionThread" + rva: 8680 + - name: "ZwCreateFile" + rva: 8688 + - name: "RtlRandomEx" + rva: 8696 + - name: "ZwQueryInformationFile" + rva: 8704 + - name: "MmUnmapLockedPages" + rva: 8712 + - name: "ExRaiseStatus" + rva: 8720 + - name: "MmMapLockedPagesSpecifyCache" + rva: 8728 + - name: "MmProbeAndLockPages" + rva: 8736 + - name: "MmUnlockPages" + rva: 8744 + - name: "MmIsAddressValid" + rva: 8752 + - name: "KeBugCheckEx" + rva: 8760 + - name: "PsGetCurrentProcessId" + rva: 8768 + - name: "IofCompleteRequest" + rva: 8776 + - name: "ZwClose" + rva: 8784 + - name: "ZwQueryValueKey" + rva: 8792 + - name: "KeInitializeEvent" + rva: 8800 + - name: "ProbeForWrite" + rva: 8808 + - name: "IoDeleteDevice" + rva: 8816 + - name: "RtlInitUnicodeString" + rva: 8824 + - name: "ExFreePoolWithTag" + rva: 8832 + - name: "IoGetCurrentProcess" + rva: 8840 + - name: "ExAllocatePoolWithTag" + rva: 8848 + - name: "__C_specific_handler" + rva: 8856 + - library_name: "ksecdd.sys" + number_of_functions: 10 + functions: + - name: "BCryptCreateHash" + rva: 8192 + - name: "BCryptDestroyKey" + rva: 8200 + - name: "BCryptImportKeyPair" + rva: 8208 + - name: "BCryptCloseAlgorithmProvider" + rva: 8216 + - name: "BCryptVerifySignature" + rva: 8224 + - name: "BCryptFinishHash" + rva: 8232 + - name: "BCryptHashData" + rva: 8240 + - name: "BCryptDestroyHash" + rva: 8248 + - name: "BCryptOpenAlgorithmProvider" + rva: 8256 + - name: "BCryptGetProperty" + rva: 8264 +is_signed: true +signatures: + - subject: "/C=AU/ST=New South Wales/L=Sydney/O=Wen Jia Liu/CN=Wen Jia Liu" + issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance Code Signing CA-1" + thumbprint: "32387aec09eb287f202e98398189b460f4c61a0d" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "0f:f1:ef:66:bd:62:1c:65:b7:4b:4d:e4:14:25:71:7f" + not_before: 1383091200 # 2013-10-30 00:00:00 UTC + not_after: 1483531200 # 2017-01-04 12:00:00 UTC + verified: true + digest_alg: "sha1" + digest: "c2b8c1b34f09a91efe196f646ef7f9a11190fb8e" + file_digest: "c2b8c1b34f09a91efe196f646ef7f9a11190fb8e" + number_of_certificates: 5 + number_of_countersignatures: 1 + signer_info: + digest: "9bb6c4bf0a838bf7ea75e48e9e82581deb6d48ed" + digest_alg: "sha1" + chain: + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance Code Signing CA-1" + subject: "/C=AU/ST=New South Wales/L=Sydney/O=Wen Jia Liu/CN=Wen Jia Liu" + thumbprint: "32387aec09eb287f202e98398189b460f4c61a0d" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "0f:f1:ef:66:bd:62:1c:65:b7:4b:4d:e4:14:25:71:7f" + not_before: 1383091200 # 2013-10-30 00:00:00 UTC + not_after: 1483531200 # 2017-01-04 12:00:00 UTC + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA" + subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance Code Signing CA-1" + thumbprint: "e308f829dc77e80af15edd4151ea47c59399ab46" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "02:c4:d1:e5:8a:4a:68:0c:56:8d:a3:04:7e:7e:4d:5f" + not_before: 1297425600 # 2011-02-11 12:00:00 UTC + not_after: 1770724800 # 2026-02-10 12:00:00 UTC + - issuer: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Code Verification Root" + subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA" + thumbprint: "2f2513af3992db0a3f79709ff8143b3f7bd2d143" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "61:20:4d:b4:00:00:00:00:00:27" + not_before: 1302896733 # 2011-04-15 19:45:33 UTC + not_after: 1618516533 # 2021-04-15 19:55:33 UTC + certificates: + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance Code Signing CA-1" + subject: "/C=AU/ST=New South Wales/L=Sydney/O=Wen Jia Liu/CN=Wen Jia Liu" + thumbprint: "32387aec09eb287f202e98398189b460f4c61a0d" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "0f:f1:ef:66:bd:62:1c:65:b7:4b:4d:e4:14:25:71:7f" + not_before: 1383091200 # 2013-10-30 00:00:00 UTC + not_after: 1483531200 # 2017-01-04 12:00:00 UTC + - issuer: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Code Verification Root" + subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA" + thumbprint: "2f2513af3992db0a3f79709ff8143b3f7bd2d143" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "61:20:4d:b4:00:00:00:00:00:27" + not_before: 1302896733 # 2011-04-15 19:45:33 UTC + not_after: 1618516533 # 2021-04-15 19:55:33 UTC + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID CA-1" + subject: "/C=US/O=DigiCert/CN=DigiCert Timestamp Responder" + thumbprint: "614d271d9102e30169822487fde5de00a352b01d" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "03:01:9a:02:3a:ff:58:b1:6b:d6:d5:ea:e6:17:f0:66" + not_before: 1413936000 # 2014-10-22 00:00:00 UTC + not_after: 1729555200 # 2024-10-22 00:00:00 UTC + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA" + subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance Code Signing CA-1" + thumbprint: "e308f829dc77e80af15edd4151ea47c59399ab46" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "02:c4:d1:e5:8a:4a:68:0c:56:8d:a3:04:7e:7e:4d:5f" + not_before: 1297425600 # 2011-02-11 12:00:00 UTC + not_after: 1770724800 # 2026-02-10 12:00:00 UTC + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA" + subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID CA-1" + thumbprint: "19a09b5a36f4dd99727df783c17a51231a56c117" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "06:fd:f9:03:96:03:ad:ea:00:0a:eb:3f:27:bb:ba:1b" + not_before: 1163116800 # 2006-11-10 00:00:00 UTC + not_after: 1636502400 # 2021-11-10 00:00:00 UTC + countersignatures: + - verified: true + sign_time: 1459189265 # 2016-03-28 18:21:05 UTC + digest: "e0e1b26a21dda2a4d57236182a51cd3162e502fa" + digest_alg: "sha1" + chain: + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID CA-1" + subject: "/C=US/O=DigiCert/CN=DigiCert Timestamp Responder" + thumbprint: "614d271d9102e30169822487fde5de00a352b01d" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "03:01:9a:02:3a:ff:58:b1:6b:d6:d5:ea:e6:17:f0:66" + not_before: 1413936000 # 2014-10-22 00:00:00 UTC + not_after: 1729555200 # 2024-10-22 00:00:00 UTC + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA" + subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID CA-1" + thumbprint: "19a09b5a36f4dd99727df783c17a51231a56c117" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "06:fd:f9:03:96:03:ad:ea:00:0a:eb:3f:27:bb:ba:1b" + not_before: 1163116800 # 2006-11-10 00:00:00 UTC + not_after: 1636502400 # 2021-11-10 00:00:00 UTC + - subject: "/C=AU/ST=New South Wales/L=Sydney/O=Wen Jia Liu/CN=Wen Jia Liu" + issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Code Signing CA" + thumbprint: "190d956129dde6972d46f46ef98bd86b982e6633" + version: 3 + algorithm: "sha256WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.11" + serial: "04:0c:b4:1e:4f:b3:70:c4:5c:43:44:76:51:62:58:2f" + not_before: 1383091200 # 2013-10-30 00:00:00 UTC + not_after: 1483531200 # 2017-01-04 12:00:00 UTC + verified: true + digest_alg: "sha256" + digest: "4ee2a56c1592ff0e951b452c0de064eba05b7c98e3add04c8aa3b4a84eb797a5" + file_digest: "4ee2a56c1592ff0e951b452c0de064eba05b7c98e3add04c8aa3b4a84eb797a5" + number_of_certificates: 5 + number_of_countersignatures: 1 + signer_info: + digest: "1939ad5ec9ec5c1ac5b360973aadb5b2308b8e98f36f9684bc874b56b67d6657" + digest_alg: "sha256" + chain: + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Code Signing CA" + subject: "/C=AU/ST=New South Wales/L=Sydney/O=Wen Jia Liu/CN=Wen Jia Liu" + thumbprint: "190d956129dde6972d46f46ef98bd86b982e6633" + version: 3 + algorithm: "sha256WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.11" + serial: "04:0c:b4:1e:4f:b3:70:c4:5c:43:44:76:51:62:58:2f" + not_before: 1383091200 # 2013-10-30 00:00:00 UTC + not_after: 1483531200 # 2017-01-04 12:00:00 UTC + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA" + subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Code Signing CA" + thumbprint: "f7e0f449f1a2594f88856c0758f8e6f627e5f5a2" + version: 3 + algorithm: "sha256WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.11" + serial: "0b:7e:10:90:3c:38:49:0f:fa:2f:67:9a:87:a1:a7:b9" + not_before: 1382443200 # 2013-10-22 12:00:00 UTC + not_after: 1855828800 # 2028-10-22 12:00:00 UTC + - issuer: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Code Verification Root" + subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA" + thumbprint: "2f2513af3992db0a3f79709ff8143b3f7bd2d143" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "61:20:4d:b4:00:00:00:00:00:27" + not_before: 1302896733 # 2011-04-15 19:45:33 UTC + not_after: 1618516533 # 2021-04-15 19:55:33 UTC + certificates: + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Code Signing CA" + subject: "/C=AU/ST=New South Wales/L=Sydney/O=Wen Jia Liu/CN=Wen Jia Liu" + thumbprint: "190d956129dde6972d46f46ef98bd86b982e6633" + version: 3 + algorithm: "sha256WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.11" + serial: "04:0c:b4:1e:4f:b3:70:c4:5c:43:44:76:51:62:58:2f" + not_before: 1383091200 # 2013-10-30 00:00:00 UTC + not_after: 1483531200 # 2017-01-04 12:00:00 UTC + - issuer: "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Code Verification Root" + subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA" + thumbprint: "2f2513af3992db0a3f79709ff8143b3f7bd2d143" + version: 3 + algorithm: "sha1WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.5" + serial: "61:20:4d:b4:00:00:00:00:00:27" + not_before: 1302896733 # 2011-04-15 19:45:33 UTC + not_after: 1618516533 # 2021-04-15 19:55:33 UTC + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA" + subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Code Signing CA" + thumbprint: "f7e0f449f1a2594f88856c0758f8e6f627e5f5a2" + version: 3 + algorithm: "sha256WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.11" + serial: "0b:7e:10:90:3c:38:49:0f:fa:2f:67:9a:87:a1:a7:b9" + not_before: 1382443200 # 2013-10-22 12:00:00 UTC + not_after: 1855828800 # 2028-10-22 12:00:00 UTC + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA" + subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Assured ID Timestamping CA" + thumbprint: "3ba63a6e4841355772debef9cdcf4d5af353a297" + version: 3 + algorithm: "sha256WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.11" + serial: "0a:a1:25:d6:d6:32:1b:7e:41:e4:05:da:36:97:c2:15" + not_before: 1452168000 # 2016-01-07 12:00:00 UTC + not_after: 1925553600 # 2031-01-07 12:00:00 UTC + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Assured ID Timestamping CA" + subject: "/C=US/O=DigiCert, Inc./CN=DigiCert SHA2 Timestamp Responder" + thumbprint: "c636f4dda87cee3d8263bf9a2514b4533468d75e" + version: 3 + algorithm: "sha256WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.11" + serial: "02:ce:42:94:59:02:a4:f3:c0:40:b0:ff:77:93:d1:4f" + not_before: 1450915200 # 2015-12-24 00:00:00 UTC + not_after: 1736208000 # 2025-01-07 00:00:00 UTC + countersignatures: + - verified: true + sign_time: 1459189265 # 2016-03-28 18:21:05 UTC + digest: "8d2adfc11c43947d5ea6b7e81429acf0429930be60fd70c41c26e8e7c5b17aee" + digest_alg: "sha256" + chain: + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Assured ID Timestamping CA" + subject: "/C=US/O=DigiCert, Inc./CN=DigiCert SHA2 Timestamp Responder" + thumbprint: "c636f4dda87cee3d8263bf9a2514b4533468d75e" + version: 3 + algorithm: "sha256WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.11" + serial: "02:ce:42:94:59:02:a4:f3:c0:40:b0:ff:77:93:d1:4f" + not_before: 1450915200 # 2015-12-24 00:00:00 UTC + not_after: 1736208000 # 2025-01-07 00:00:00 UTC + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA" + subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Assured ID Timestamping CA" + thumbprint: "3ba63a6e4841355772debef9cdcf4d5af353a297" + version: 3 + algorithm: "sha256WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.11" + serial: "0a:a1:25:d6:d6:32:1b:7e:41:e4:05:da:36:97:c2:15" + not_before: 1452168000 # 2016-01-07 12:00:00 UTC + not_after: 1925553600 # 2031-01-07 12:00:00 UTC +overlay: + offset: 27648 + size: 17560 \ No newline at end of file From f6a42d582f711f2753f73dd2bdb0a76040b74b7c Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Mon, 22 Apr 2024 23:07:31 +0200 Subject: [PATCH 25/38] style: apply rustfmt and minor refactor --- lib/src/modules/pe/authenticode.rs | 112 ++++++++++++++++------------- 1 file changed, 62 insertions(+), 50 deletions(-) diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 02db0d770..ac374a059 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -8,13 +8,14 @@ use cms::cert::IssuerAndSerialNumber; use cms::content_info::CmsVersion; use cms::content_info::ContentInfo; use cms::signed_data::{ - CertificateSet, SignedAttributes, SignedData, SignerIdentifier, SignerInfo, SignerInfos + CertificateSet, SignedAttributes, SignedData, SignerIdentifier, + SignerInfo, SignerInfos, }; use const_oid::db::{rfc4519, rfc5911, rfc5912, rfc6268, DB}; use const_oid::{AssociatedOid, ObjectIdentifier}; -use der::{asn1, FixedTag, Reader}; use der::asn1::OctetString; use der::referenced::OwnedToRef; +use der::{asn1, FixedTag, Reader}; use der::{Choice, Sequence, SliceReader}; use der::{Decode, Encode, Tag, Tagged}; use digest::Digest; @@ -222,7 +223,10 @@ impl der::FixedTag for DeferSignerInfo { } impl<'a> der::DecodeValue<'a> for DeferSignerInfo { - fn decode_value>(reader: &mut R, header: der::Header) -> der::Result { + fn decode_value>( + reader: &mut R, + header: der::Header, + ) -> der::Result { reader.read_nested(header.length, |reader| { let version = reader.decode()?; let sid = reader.decode()?; @@ -272,7 +276,11 @@ impl TryFrom<&DeferSignerInfo> for SignerInfo { version: value.version, sid: value.sid.clone(), digest_alg: value.digest_alg.clone(), - signed_attrs: value.signed_attrs.as_ref().map(|data| SignedAttributes::from_der(data)).transpose()?, + signed_attrs: value + .signed_attrs + .as_ref() + .map(|data| SignedAttributes::from_der(data)) + .transpose()?, signature_algorithm: value.signature_algorithm.clone(), signature: value.signature.clone(), unsigned_attrs: value.unsigned_attrs.clone(), @@ -285,11 +293,13 @@ impl der::FixedTag for DeferSignerInfos { } impl<'a> der::DecodeValue<'a> for DeferSignerInfos { - fn decode_value>(reader: &mut R, header: der::Header) -> der::Result { + fn decode_value>( + reader: &mut R, + header: der::Header, + ) -> der::Result { reader.read_nested(header.length, |reader| { Ok(Self(std::iter::from_fn(|| reader.decode().ok()).collect())) }) - } } @@ -298,14 +308,23 @@ impl der::FixedTag for DeferSignedData { } impl<'a> der::DecodeValue<'a> for DeferSignedData { - fn decode_value>(reader: &mut R, header: der::Header) -> der::Result { + fn decode_value>( + reader: &mut R, + header: der::Header, + ) -> der::Result { reader.read_nested(header.length, |reader| { Ok(Self { version: reader.decode()?, digest_algorithms: reader.decode()?, encap_content_info: reader.decode()?, - certificates: reader.context_specific(der::TagNumber::N0, der::TagMode::Implicit)?, - crls: reader.context_specific(der::TagNumber::N1, der::TagMode::Implicit)?, + certificates: reader.context_specific( + der::TagNumber::N0, + der::TagMode::Implicit, + )?, + crls: reader.context_specific( + der::TagNumber::N1, + der::TagMode::Implicit, + )?, signer_infos: reader.decode()?, }) }) @@ -611,11 +630,7 @@ impl AuthenticodeParser { .collect::>(), ); - let cs_si = signed_data - .signer_infos - .0 - .first() - .unwrap(); + let cs_si = signed_data.signer_infos.0.first().unwrap(); let mut countersignature = Self::pkcs9_countersignature(cs_si)?; @@ -627,10 +642,7 @@ impl AuthenticodeParser { content.decode_as::().ok() }) .and_then(|octet_string| { - TstInfo::from_der( - octet_string.as_bytes(), - ) - .ok() + TstInfo::from_der(octet_string.as_bytes()).ok() }); let tst_info = match tst_info { @@ -639,19 +651,11 @@ impl AuthenticodeParser { }; countersignature.digest_alg = - oid_to_str( - &tst_info - .message_imprint - .hash_algorithm - .oid, - ); + oid_to_str(&tst_info.message_imprint.hash_algorithm.oid); countersignature.digest = Some(bytes2hex( "", - tst_info - .message_imprint - .hashed_message - .as_bytes(), + tst_info.message_imprint.hashed_message.as_bytes(), )); countersignature.verified = @@ -679,15 +683,17 @@ impl AuthenticodeParser { let mut countersignature = Self::pkcs9_countersignature(cs_si)?; - let cs_signed_attrs = countersignature.signer_info.signed_attrs + let cs_signed_attrs = countersignature + .signer_info + .signed_attrs .as_ref() .ok_or(ParseError::EmptyAuthenticatedAttributes)?; - let message_digest = - match get_message_digest(cs_signed_attrs) { - Some(digest) => digest, - None => continue, - }; + let message_digest = match get_message_digest(cs_signed_attrs) + { + Some(digest) => digest, + None => continue, + }; countersignature.verified = verify_message_digest( @@ -709,8 +715,8 @@ impl AuthenticodeParser { let mut digest = None; let mut signing_time = None; - let decoded_cs = SignerInfo::try_from(cs) - .map_err(ParseError::InvalidSignerInfo)?; + let decoded_cs = + SignerInfo::try_from(cs).map_err(ParseError::InvalidSignerInfo)?; if let Some(signed_attrs) = &decoded_cs.signed_attrs { for attr in signed_attrs.iter() { @@ -869,7 +875,9 @@ impl AuthenticodeSignature { return false; } - let message_digest = match get_message_digest(self.signer_info.signed_attrs.as_ref().unwrap()) { + let message_digest = match get_message_digest( + self.signer_info.signed_attrs.as_ref().unwrap(), + ) { Some(digest) => digest, None => return false, }; @@ -889,7 +897,7 @@ impl AuthenticodeSignature { verify_signer_info( &self.signed_data.signer_infos.0[0], - self.certificates() + self.certificates(), ) } } @@ -1150,10 +1158,6 @@ fn verify_signed_data_impl( return false; } - // Compute the digest for the DER encoding of the signed attributes, this - // digest is signed, and its signature is in SignerInfo.signature. - let attrs_digest = D::digest(si.signed_attrs.as_ref().unwrap()); - // Search for the certificate that signed the digest. let signing_cert = match certs .iter() @@ -1172,7 +1176,7 @@ fn verify_signed_data_impl( }; // Verify that the signature in SignerInfo.signature is correct. - key.verify::(attrs_digest.as_slice(), si.signature.as_bytes()) + key.verify::(si.signed_attrs.as_ref().unwrap(), si.signature.as_bytes()) } /// Produces a printable string of a serial number. @@ -1380,27 +1384,35 @@ impl TryFrom> for PublicKey { impl PublicKey { fn verify( &self, - hashed: &[u8], + message: &[u8], signature: &[u8], ) -> bool { + let digest = D::digest(message); match self { Self::Rsa(key) => { if Pkcs1v15Sign::new::() - .verify(key, hashed, signature) + .verify(key, digest.as_slice(), signature) .is_ok() { return true; } Pkcs1v15Sign::new_unprefixed() - .verify(key, hashed, signature) + .verify(key, digest.as_slice(), signature) .is_ok() } - Self::Dsa(key) => dsa::Signature::from_der(signature) - .is_ok_and(|s| key.verify_prehash(hashed, &s).is_ok()), + Self::Dsa(key) => { + dsa::Signature::from_der(signature).is_ok_and(|s| { + key.verify_prehash(digest.as_slice(), &s).is_ok() + }) + } Self::EcdsaP256(key) => ecdsa::Signature::from_der(signature) - .is_ok_and(|s| key.verify_prehash(hashed, &s).is_ok()), + .is_ok_and(|s| { + key.verify_prehash(digest.as_slice(), &s).is_ok() + }), Self::EcdsaP384(key) => ecdsa::Signature::from_der(signature) - .is_ok_and(|s| key.verify_prehash(hashed, &s).is_ok()), + .is_ok_and(|s| { + key.verify_prehash(digest.as_slice(), &s).is_ok() + }), } } } From 455fd3e83bf39192aa7e146a8e36ee66fe1503ef Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Thu, 25 Apr 2024 18:27:10 +0200 Subject: [PATCH 26/38] feat: draft implementation of authenticode parser using `der-parser` --- Cargo.lock | 280 +++---- Cargo.toml | 5 +- lib/Cargo.toml | 10 +- lib/src/modules/pe/asn1.rs | 581 ++++++++++++++ lib/src/modules/pe/authenticode.rs | 1127 ++++++++-------------------- lib/src/modules/pe/mod.rs | 1 + lib/src/modules/pe/parser.rs | 6 +- 7 files changed, 1071 insertions(+), 939 deletions(-) create mode 100644 lib/src/modules/pe/asn1.rs diff --git a/Cargo.lock b/Cargo.lock index 050ed075f..0d9059a73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -170,6 +170,45 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca6c635b3aa665c649ad1415f1573c85957dfa47690ec27aebe7ec17efe3c643" +[[package]] +name = "asn1-rs" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ad1373757efa0f70ec53939aabc7152e1591cb485208052993070ac8d2429d" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom 7.1.3", + "num-traits", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7378575ff571966e99a744addeff0bff98b8ada0dedf1956d59e634db95eaac1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + [[package]] name = "async-trait" version = "0.1.79" @@ -566,18 +605,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" -[[package]] -name = "cmpv2" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "961b955a666e25ee5a1091d219128d6e6401e3dab84efb1a2bf6b4035d797b39" -dependencies = [ - "crmf", - "der", - "spki", - "x509-cert", -] - [[package]] name = "cms" version = "0.2.3" @@ -815,18 +842,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crmf" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36fe21b96d5b87f5de4b5b7202ec41c00110ac817ce6728fe75fb2fe5962ed92" -dependencies = [ - "cms", - "der", - "spki", - "x509-cert", -] - [[package]] name = "crossbeam" version = "0.8.4" @@ -997,6 +1012,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "data-encoding" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" + [[package]] name = "debugid" version = "0.8.0" @@ -1025,6 +1046,20 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der-parser" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom 7.1.3", + "num-bigint", + "num-traits", + "rusticata-macros", +] + [[package]] name = "der_derive" version = "0.7.2" @@ -1113,6 +1148,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + [[package]] name = "dsa" version = "0.6.3" @@ -1812,18 +1858,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "k256" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "sha2 0.10.8", -] - [[package]] name = "lab" version = "0.11.0" @@ -1836,7 +1870,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" dependencies = [ - "spin", + "spin 0.5.2", ] [[package]] @@ -2306,6 +2340,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "oid-registry" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c958dd45046245b9c3c2547369bb634eb461670b2e7e0de552905801a648d1d" +dependencies = [ + "asn1-rs", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -2342,30 +2385,6 @@ version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" -[[package]] -name = "p192" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b0533bc6c238f2669aab8db75ae52879dc74e88d6bd3685bd4022a00fa85cd2" -dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", - "sec1", -] - -[[package]] -name = "p224" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30c06436d66652bc2f01ade021592c80a2aad401570a18aa18b82e440d2b9aa1" -dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", - "sha2 0.10.8", -] - [[package]] name = "p256" version = "0.13.2" @@ -2998,6 +3017,21 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "roxmltree" version = "0.19.0" @@ -3036,6 +3070,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom 7.1.3", +] + [[package]] name = "rustix" version = "0.38.32" @@ -3316,6 +3359,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "spki" version = "0.7.3" @@ -3471,6 +3520,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + [[package]] name = "tap" version = "1.0.1" @@ -3601,10 +3661,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ "deranged", + "itoa", "num-conv", "powerfmt", "serde", "time-core", + "time-macros", ] [[package]] @@ -3614,33 +3676,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tls_codec" -version = "0.4.1" +name = "time-macros" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e78c9c330f8c85b2bae7c8368f2739157db9991235123aa1b15ef9502bfb6a" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" dependencies = [ - "tls_codec_derive", - "zeroize", + "num-conv", + "time-core", ] [[package]] -name = "tls_codec_derive" -version = "0.4.1" +name = "tiny-keccak" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9ef545650e79f30233c0003bcc2504d7efac6dad25fca40744de773fe2049c" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.55", + "crunchy", ] [[package]] @@ -3743,6 +3794,12 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "utf8parse" version = "0.2.1" @@ -4610,40 +4667,24 @@ dependencies = [ "const-oid", "der", "spki", - "tls_codec", -] - -[[package]] -name = "x509-tsp" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5ceece934a21607055b7ac5c25adb56a2ff559804b10705dc674d1d838c15e1" -dependencies = [ - "cmpv2", - "cms", - "der", ] [[package]] -name = "x509-verify" -version = "0.4.5" +name = "x509-parser" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e407b6fb3a8638bc7af2216647e045f3ce6cd71235e84ada35dd03c77a6cd6d" +checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" dependencies = [ - "const-oid", - "der", - "dsa", - "ecdsa", - "k256", - "p192", - "p224", - "p256", - "p384", - "rsa", - "sha1", - "sha2 0.10.8", - "signature", - "spki", + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom 7.1.3", + "oid-registry", + "ring", + "rusticata-macros", + "thiserror", + "time", ] [[package]] @@ -4684,6 +4725,7 @@ dependencies = [ "const-oid", "crc32fast", "der", + "der-parser", "digest 0.10.7", "dsa", "ecdsa", @@ -4727,9 +4769,7 @@ dependencies = [ "uuid", "walrus", "wasmtime", - "x509-cert", - "x509-tsp", - "x509-verify", + "x509-parser", "yansi 1.0.1", "yara-x-macros", "yara-x-parser", @@ -4880,20 +4920,6 @@ name = "zeroize" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.55", -] [[package]] name = "zip" diff --git a/Cargo.toml b/Cargo.toml index fe0e5ea03..d50cea1ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,7 @@ cms = "0.2.3" const-oid = "0.9.6" crc32fast = "1.4.0" der = "0.7.9" +der-parser = "9.0.0" digest = "0.10.7" dsa = "0.6.3" ecdsa = "0.16.9" @@ -100,9 +101,7 @@ thiserror = "1.0.58" uuid = "1.4.1" walrus = "0.20.2" wasmtime = "19.0.1" -x509-cert = "0.2.5" -x509-tsp = "0.1.0" -x509-verify = { version = "0.4.5", default-features = false } +x509-parser = "0.16.0" yaml-rust = "0.4.5" yansi = "1.0.1" yara-x = { path = "lib" } diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 02850b0ed..526fc57cf 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -105,6 +105,7 @@ math-module = [] pe-module = [ "dep:cms", "dep:const-oid", + "dep:der-parser", "dep:digest", "dep:dsa", "dep:ecdsa", @@ -115,9 +116,7 @@ pe-module = [ "dep:p384", "dep:sha1", "dep:sha2", - "dep:x509-cert", - "dep:x509-tsp", - "dep:x509-verify", + "dep:x509-parser" ] # The `string` modules offer some functions for parsing strings as integers, @@ -172,6 +171,7 @@ cms = { workspace = true, optional = true } const-oid = { workspace = true, optional = true } crc32fast = { workspace = true, optional = true } der = { workspace = true, features = ["derive"] } +der-parser = { workspace = true, optional = true, features = ["bigint"] } digest = { workspace = true, optional = true } dsa = { workspace = true, optional = true } ecdsa = { workspace = true, optional = true } @@ -207,9 +207,7 @@ tlsh-fixed = { workspace = true, optional = true } uuid = { workspace = true, optional = true, features = ["v4"] } walrus = { workspace = true } wasmtime = { workspace = true, features = ["cranelift", "parallel-compilation"] } -x509-cert = { workspace = true, optional = true } -x509-tsp = { workspace = true, optional = true } -x509-verify = { workspace = true, optional = true, features = ["sha1", "dsa", "ecdsa", "rsa"] } +x509-parser = { workspace = true, optional = true, features = ["verify"] } yansi = { workspace = true } yara-x-macros = { workspace = true } yara-x-parser = { workspace = true } diff --git a/lib/src/modules/pe/asn1.rs b/lib/src/modules/pe/asn1.rs new file mode 100644 index 000000000..3551d8f2b --- /dev/null +++ b/lib/src/modules/pe/asn1.rs @@ -0,0 +1,581 @@ +use const_oid::db::{rfc4519, rfc5912}; +use const_oid::ObjectIdentifier; +use der_parser::der::{ + parse_der_integer, parse_der_octetstring, parse_der_oid, + parse_der_sequence_defined_g, parse_der_set_of_v, + parse_der_tagged_explicit_g, DerObject, +}; +use std::borrow::Cow; + +use der_parser::asn1_rs::{Any, OptTaggedParser}; +use der_parser::ber::parse_ber_any; +use der_parser::error::BerResult; +use der_parser::nom::Err::Incomplete; +use der_parser::nom::{IResult, Parser}; +use der_parser::num_bigint::BigUint; +use der_parser::{asn1_rs, parse_der, Oid}; +use nom::combinator::map_res; +use x509_parser::certificate::X509Certificate; +use x509_parser::error::X509Error; +use x509_parser::prelude::{ + AlgorithmIdentifier, FromDer, X509CertificateParser, +}; +use x509_parser::x509::X509Name; + +#[rustfmt::skip] +#[allow(dead_code)] +pub mod oid { + use const_oid::ObjectIdentifier; + use der_parser::{oid, Oid}; + + pub const MD5: Oid = oid!(1.2.840.113549.2.5); + pub const MD5_B: &[u8] = &oid!(raw 1.2.840.113549.2.5); + + pub const SHA_1: Oid = oid!(1.3.14.3.2.26); + pub const SHA_1_B: &[u8] = &oid!(raw 1.3.14.3.2.26); + + pub const SHA_256: Oid = oid!(2.16.840.1.101.3.4.2.1); + pub const SHA_256_B: &[u8] = &oid!(raw 2.16.840.1.101.3.4.2.1); + + pub const SHA_384: Oid = oid!(2.16.840.1.101.3.4.2.2); + pub const SHA_384_B: &[u8] = &oid!(raw 2.16.840.1.101.3.4.2.2); + + pub const SHA_512: Oid = oid!(2.16.840.1.101.3.4.2.3); + pub const SHA_512_B: &[u8] = &oid!(raw 2.16.840.1.101.3.4.2.3); + + pub const MD5_WITH_RSA_ENCRYPTION: Oid = oid!(1.2.840.113549.1.1.4); + pub const MD5_WITH_RSA_ENCRYPTION_B: &[u8] = &oid!(raw 1.2.840.113549.1.1.4); + + pub const SHA_1_WITH_RSA_ENCRYPTION: Oid = oid!(1.2.840.113549.1.1.5); + pub const SHA_1_WITH_RSA_ENCRYPTION_B: &[u8] = &oid!(raw 1.2.840.113549.1.1.5); + + pub const SHA_256_WITH_RSA_ENCRYPTION: Oid = oid!(1.2.840.113549.1.1.11); + pub const SHA_256_WITH_RSA_ENCRYPTION_B: &[u8] = &oid!(raw 1.2.840.113549.1.1.11); + + pub const SHA_384_WITH_RSA_ENCRYPTION: Oid = oid!(1.2.840.113549.1.1.12); + pub const SHA_384_WITH_RSA_ENCRYPTION_B: &[u8] = &oid!(raw 1.2.840.113549.1.1.12); + + pub const SHA_512_WITH_RSA_ENCRYPTION: Oid = oid!(1.2.840.113549.1.1.13); + pub const SHA_512_WITH_RSA_ENCRYPTION_B: &[u8] = &oid!(raw 1.2.840.113549.1.1.13); + + pub const RSA_ENCRYPTION: Oid = oid!(1.2.840.113549.1.1.1); + pub const RSA_ENCRYPTION_B: &[u8] = &oid!(raw 1.2.840.113549.1.1.1); + + pub const SIGNED_DATA: Oid = oid!(1.2.840.113549.1.7.2); + pub const SIGNED_DATA_B: &[u8] = &oid!(raw 1.2.840.113549.1.7.2); + + pub const MESSAGE_DIGEST: Oid = oid!(1.2.840.113549.1.9.4); + pub const MESSAGE_DIGEST_B: &[u8] = &oid!(raw 1.2.840.113549.1.9.4); + + pub const INDIRECT_DATA_OBJID: Oid = oid!(1.3.6.1.4.1.311.2.1.4); + pub const INDIRECT_DATA_OBJID_B: &[u8] = &oid!(raw 1.3.6.1.4.1.311.2.1.4); + + pub const CONTENT_TYPE: Oid = oid!(1.2.840.113549.1.9.3); + pub const CONTENT_TYPE_B: &[u8] = &oid!(raw 1.2.840.113549.1.9.3); + + pub const OPUS_INFO_OBJID: Oid = oid!(1.3.6.1.4.1.311.2.1.12); + pub const OPUS_INFO_OBJID_B: &[u8] = &oid!(raw 1.3.6.1.4.1.311.2.1.12); + + pub const MS_NESTED_SIGNATURE: Oid = oid!(1.3.6.1.4.1.311.2.4.1); + pub const MS_NESTED_SIGNATURE_B: &[u8] = &oid!(raw 1.3.6.1.4.1.311.2.4.1); + + pub const MS_COUNTERSIGN: Oid = oid!(1.3.6.1.4.1.311.3.3.1); + pub const MS_COUNTERSIGN_B: &[u8] = &oid!(raw 1.3.6.1.4.1.311.3.3.1); + + pub const PKCS9_COUNTERSIGN: Oid = oid!(1.2.840.113549.1.9.6); + pub const PKCS9_COUNTERSIGN_B: &[u8] = &oid!(raw 1.2.840.113549.1.9.6); + + pub const COUNTRY: Oid = oid!(2.5.4.6); + pub const COUNTRY_B: &[u8] = &oid!(raw 2.5.4.6); + + pub const JURISDICTION_L: ObjectIdentifier = + ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.60.2.1.1"); + + pub const JURISDICTION_ST: ObjectIdentifier = + ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.60.2.1.2"); + + pub const JURISDICTION_C: ObjectIdentifier = + ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.60.2.1.3"); + + /// Similar to 1.2.840.113549.1.1.5. Obsolete, but still present in some files + /// like: 111aeddc6a6dbf64b28cb565aa12af9ee3cc0a56ce31e4da0068cf6b474c3288 + pub const SHA1_WITH_RSA_ENCRYPTION: ObjectIdentifier = + ObjectIdentifier::new_unwrap("1.3.14.3.2.29"); + +} + +#[inline] +pub fn oid_to_object_identifier(oid: &Oid) -> ObjectIdentifier { + ObjectIdentifier::from_bytes(oid.as_bytes()).unwrap() +} + +pub fn oid_to_str(oid: &Oid) -> Cow<'static, str> { + match oid_to_object_identifier(oid) { + rfc5912::ID_MD_5 => Cow::Borrowed("md5"), + rfc5912::ID_SHA_1 => Cow::Borrowed("sha1"), + rfc5912::ID_SHA_256 => Cow::Borrowed("sha256"), + rfc5912::ID_SHA_384 => Cow::Borrowed("sha384"), + rfc5912::ID_SHA_512 => Cow::Borrowed("sha512"), + rfc5912::MD_5_WITH_RSA_ENCRYPTION => { + Cow::Borrowed("md5WithRSAEncryption") + } + oid::SHA1_WITH_RSA_ENCRYPTION | rfc5912::SHA_1_WITH_RSA_ENCRYPTION => { + Cow::Borrowed("sha1WithRSAEncryption") + } + rfc5912::SHA_256_WITH_RSA_ENCRYPTION => { + Cow::Borrowed("sha256WithRSAEncryption") + } + rfc5912::SHA_384_WITH_RSA_ENCRYPTION => { + Cow::Borrowed("sha384WithRSAEncryption") + } + rfc5912::SHA_512_WITH_RSA_ENCRYPTION => { + Cow::Borrowed("sha512WithRSAEncryption") + } + rfc4519::C => Cow::Borrowed("C"), + rfc4519::COMMON_NAME => Cow::Borrowed("CN"), + rfc4519::O => Cow::Borrowed("O"), + rfc4519::OU => Cow::Borrowed("OU"), + rfc4519::ST => Cow::Borrowed("ST"), + // OIDs not included in const_oid. + oid::JURISDICTION_C => Cow::Borrowed("jurisdictionC"), + oid::JURISDICTION_L => Cow::Borrowed("jurisdictionL"), + oid::JURISDICTION_ST => Cow::Borrowed("jurisdictionST"), + // In the default case try to use the string representation provided by + // the `const-oid` crate. Panics if this fails. + oid => { + if let Some(name) = const_oid::db::DB.by_oid(&oid) { + Cow::Borrowed(name) + } else { + Cow::Owned(oid.to_string()) + } + } + } +} + +pub struct ContentInfo<'a> { + pub content_type: Oid<'a>, + pub content: Any<'a>, +} + +impl<'a> ContentInfo<'a> { + pub fn parse(data: &'a [u8]) -> BerResult { + parse_der_sequence_defined_g(|i, _| Self::parse_inner(i))(data) + } + + pub fn from_der( + data: &'a [u8], + ) -> Result> { + Self::parse(data).map(|(_, content_info)| content_info) + } + + fn parse_inner(data: &'a [u8]) -> BerResult { + let (remainder, content_type) = parse_der_oid(data)?; + let (remainder, content) = + parse_der_tagged_explicit_g(0, |content, _| { + parse_ber_any(content) + })(remainder)?; + + Ok(( + remainder, + Self { content_type: content_type.as_oid_val()?, content }, + )) + } +} + +impl<'a> TryFrom<&Any<'a>> for ContentInfo<'a> { + type Error = asn1_rs::Error; + + fn try_from(any: &Any<'a>) -> Result { + any.tag().assert_eq(asn1_rs::Tag::Sequence)?; + Ok(Self::parse_inner(any.data).map(|(_, ci)| ci)?) + } +} + +/// ```text +/// SignedData ::= SEQUENCE { +/// version CMSVersion, +/// digestAlgorithms DigestAlgorithmIdentifiers, +/// encapContentInfo EncapsulatedContentInfo, +/// certificates [0] IMPLICIT CertificateSet OPTIONAL, +/// crls [1] IMPLICIT RevocationInfoChoices OPTIONAL, +/// signerInfos SignerInfos } +/// ``` +/// +/// https://datatracker.ietf.org/doc/html/rfc5652#section-5.1 +pub struct SignedData<'a> { + pub version: i32, + pub digest_algorithms: Vec>, + pub content_info: ContentInfo<'a>, + pub certificates: Vec>, + pub signer_infos: Vec>, +} + +impl<'a> SignedData<'a> { + pub fn parse(input: &'a [u8]) -> BerResult { + parse_der_sequence_defined_g(|input: &[u8], _| { + Self::parse_inner(input) + })(input) + } + + fn parse_inner(input: &'a [u8]) -> BerResult { + let (remainder, version) = parse_der_integer(input)?; + + let (remainder, digest_algorithms) = + parse_der_set_of_v(AlgorithmIdentifier::from_der)(remainder) + .unwrap(); // TODO: handle error + + let (remainder, content_info) = ContentInfo::parse(remainder)?; + + let (remainder, certificates) = OptTaggedParser::from(0) + .parse_der(remainder, |_, raw_certs| { + Self::parse_certificates(raw_certs) + }) + .unwrap(); // TODO:: handle error + + let (remainder, _revocation_info) = OptTaggedParser::from(1) + .parse_der(remainder, |_, data| parse_der(data))?; + + let (remainder, signer_infos) = + parse_der_set_of_v(SignerInfo::parse)(remainder)?; + + Ok(( + remainder, + Self { + version: version.as_i32()?, + certificates: certificates.unwrap_or_default(), + signer_infos, + digest_algorithms, + content_info, + }, + )) + } + + fn parse_certificates( + input: &[u8], + ) -> IResult<&[u8], Vec, X509Error> { + let mut remainder = input; + let mut certificates = Vec::new(); + loop { + remainder = match X509CertificateParser::new().parse(remainder) { + Ok((remainder, cert)) => { + certificates.push(cert); + remainder + } + Err(Incomplete(_)) => return Ok((remainder, certificates)), + Err(err) => return Err(err), + } + } + } +} + +impl<'a> TryFrom> for SignedData<'a> { + type Error = asn1_rs::Error; + + fn try_from(any: Any<'a>) -> Result { + any.tag().assert_eq(asn1_rs::Tag::Sequence)?; + Ok(Self::parse_inner(any.data).map(|(_, ci)| ci)?) + } +} + +/// ```text +/// SignerInfo ::= SEQUENCE { +/// version CMSVersion, +/// sid SignerIdentifier, +/// digestAlgorithm DigestAlgorithmIdentifier, +/// signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, +/// signatureAlgorithm SignatureAlgorithmIdentifier, +/// signature SignatureValue, +/// unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL } +/// ``` +/// +/// https://datatracker.ietf.org/doc/html/rfc5652#section-5.3 +pub struct SignerInfo<'a> { + pub version: i32, + pub issuer: X509Name<'a>, + pub serial_number: BigUint, + pub digest_algorithm: AlgorithmIdentifier<'a>, + pub signature_algorithm: AlgorithmIdentifier<'a>, + pub signature_value: &'a [u8], + pub raw_signed_attrs: &'a [u8], + pub signed_attrs: Vec>, + pub unsigned_attrs: Vec>, +} + +impl<'a> SignerInfo<'a> { + pub fn parse(input: &'a [u8]) -> BerResult { + parse_der_sequence_defined_g(|input: &[u8], _| { + Self::parse_inner(input) + })(input) + } + + pub fn parse_inner(input: &'a [u8]) -> BerResult { + let (remainder, version) = parse_der_integer(input)?; + + let (remainder, (issuer, serial_number)) = + Self::parse_issuer_and_serial_number(remainder)?; + + let (remainder, digest_algorithm) = + AlgorithmIdentifier::from_der(remainder).unwrap(); // TODO: handle error + + let (remainder, signed_attrs) = OptTaggedParser::from(0).parse_der( + remainder, + |_, raw_attrs| { + let (remainder, parsed_attrs) = + Self::parse_attributes(raw_attrs)?; + + Ok((remainder, (raw_attrs, parsed_attrs))) + }, + )?; + + let (remainder, signature_algorithm) = + AlgorithmIdentifier::from_der(remainder).unwrap(); // TODO: handle error + + let (remainder, signature) = parse_der_octetstring(remainder)?; + + let (remainder, unsigned_attrs) = OptTaggedParser::from(1) + .parse_der(remainder, |_, raw_attrs| { + Self::parse_attributes(raw_attrs) + })?; + + let (raw_signed_attrs, signed_attrs) = + signed_attrs.unwrap_or_default(); + + Ok(( + remainder, + Self { + version: version.as_i32()?, + signed_attrs, + raw_signed_attrs, + unsigned_attrs: unsigned_attrs.unwrap_or_default(), + signature_value: signature.content.as_slice()?, + issuer, + serial_number, + digest_algorithm, + signature_algorithm, + }, + )) + } + + pub fn get_signed_attr(&self, oid: &Oid) -> Option<&Attribute<'a>> { + self.signed_attrs.iter().find(|attr| attr.attr_type.eq(oid)) + } + + pub fn get_unsigned_attr(&self, oid: &Oid) -> Option<&Attribute<'a>> { + self.unsigned_attrs.iter().find(|attr| attr.attr_type.eq(oid)) + } + + fn parse_issuer_and_serial_number( + input: &[u8], + ) -> BerResult<(X509Name, BigUint)> { + parse_der_sequence_defined_g(|input: &[u8], _| { + let (remainder, issuer) = X509Name::from_der(input).unwrap(); // TODO: handle error + let (remainder, serial_number) = map_res( + parse_der_integer, + |serial| serial.as_biguint(), + )(remainder)?; + + Ok((remainder, (issuer, serial_number))) + })(input) + } + + fn parse_attributes(input: &[u8]) -> BerResult> { + let mut remainder = input; + let mut attributes = Vec::new(); + loop { + remainder = match Attribute::parse(remainder) { + Ok((remainder, attr)) => { + attributes.push(attr); + remainder + } + Err(Incomplete(_)) => return Ok((remainder, attributes)), + Err(err) => return Err(err), + } + } + } +} + +impl<'a> TryFrom<&Any<'a>> for SignerInfo<'a> { + type Error = asn1_rs::Error; + + fn try_from(any: &Any<'a>) -> Result { + any.tag().assert_eq(asn1_rs::Tag::Sequence)?; + Ok(Self::parse_inner(any.data).map(|(_, si)| si)?) + } +} + +/// ```text +/// AlgorithmIdentifier ::= SEQUENCE { +/// algorithm OBJECT IDENTIFIER, +/// parameters ANY DEFINED BY algorithm OPTIONAL } +/// ``` +/// +/// https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.1.2 +#[derive(Debug)] +pub struct MyAlgorithmIdentifier<'a> { + pub oid: Oid<'a>, + pub parameters: DerObject<'a>, +} + +impl<'a> MyAlgorithmIdentifier<'a> { + pub fn parse(input: &'a [u8]) -> BerResult { + parse_der_sequence_defined_g(|input: &[u8], _| { + let (remainder, algorithm) = parse_der_oid(input)?; + let (remainder, parameters) = parse_der(remainder)?; + Ok((remainder, Self { oid: algorithm.as_oid_val()?, parameters })) + })(input) + } +} + +/// ```text +/// Attribute ::= SEQUENCE { +/// attrType OBJECT IDENTIFIER, +/// attrValues SET OF AttributeValue } +/// +/// AttributeValue ::= ANY +/// ``` +/// +/// https://datatracker.ietf.org/doc/html/rfc5652#section-5.3 +pub struct Attribute<'a> { + pub attr_type: Oid<'a>, + pub attr_values: Vec>, +} + +impl<'a> Attribute<'a> { + pub fn parse(input: &'a [u8]) -> BerResult { + parse_der_sequence_defined_g(|data: &[u8], _| { + let (remainder, attr_type) = parse_der_oid(data)?; + let (remainder, attr_values) = + parse_der_set_of_v(parse_ber_any)(remainder)?; + + Ok(( + remainder, + Self { attr_type: attr_type.as_oid_val()?, attr_values }, + )) + })(input) + } +} + +/// ASN.1 SpcIndirectDataContent +/// +/// SpcIndirectDataContent ::= SEQUENCE { +/// data SpcAttributeTypeAndOptionalValue, +/// messageDigest DigestInfo +/// } +/// +pub struct IndirectDataContent<'a> { + pub message_digest: DigestInfo<'a>, +} + +impl<'a> IndirectDataContent<'a> { + pub fn parse(input: &'a [u8]) -> BerResult { + parse_der_sequence_defined_g(|input: &[u8], _| { + Self::parse_inner(input) + })(input) + } + + pub fn parse_inner(input: &'a [u8]) -> BerResult { + let (remainder, _data) = parse_der(input)?; + let (remainder, message_digest) = DigestInfo::parse(remainder)?; + + Ok((remainder, Self { message_digest })) + } +} + +impl<'a> TryFrom> for IndirectDataContent<'a> { + type Error = asn1_rs::Error; + + fn try_from(any: Any<'a>) -> Result { + any.tag().assert_eq(asn1_rs::Tag::Sequence)?; + Ok(Self::parse_inner(any.data).map(|(_, ci)| ci)?) + } +} + +/// ASN.1 DigestInfo +/// +/// DigestInfo ::= SEQUENCE { +/// digestAlgorithm AlgorithmIdentifier, +/// digest OCTETSTRING +/// } +pub struct DigestInfo<'a> { + pub algorithm: AlgorithmIdentifier<'a>, + pub digest: &'a [u8], +} + +impl<'a> DigestInfo<'a> { + pub fn parse(input: &'a [u8]) -> BerResult { + parse_der_sequence_defined_g(|input: &[u8], _| { + let (remainder, algorithm) = + AlgorithmIdentifier::from_der(input).unwrap(); // TODO: handler error + let (remainder, digest) = parse_der_octetstring(remainder)?; + Ok((remainder, Self { algorithm, digest: digest.as_slice()? })) + })(input) + } +} + +/// ASN.1 TSTInfo +/// +/// ```text +/// TSTInfo ::= SEQUENCE { +/// version INTEGER { v1(1) }, +/// policy TSAPolicyId, +/// messageImprint MessageImprint, +/// -- MUST have the same value as the similar field in +/// -- TimeStampReq +/// serialNumber INTEGER, +/// -- Time-Stamping users MUST be ready to accommodate integers +/// -- up to 160 bits. +/// genTime GeneralizedTime, +/// accuracy Accuracy OPTIONAL, +/// ordering BOOLEAN DEFAULT FALSE, +/// nonce INTEGER OPTIONAL, +/// -- MUST be present if the similar field was present +/// -- in TimeStampReq. In that case it MUST have the same value. +/// tsa [0] GeneralName OPTIONAL, +/// extensions [1] IMPLICIT Extensions OPTIONAL } +/// +/// +/// MessageImprint ::= SEQUENCE { +/// hashAlgorithm AlgorithmIdentifier, +/// hashedMessage OCTET STRING } +/// ``` +/// +/// https://datatracker.ietf.org/doc/html/rfc3161 + +pub struct TstInfo<'a> { + pub hash_algorithm: AlgorithmIdentifier<'a>, + pub hashed_message: &'a [u8], +} + +impl<'a> TstInfo<'a> { + pub fn from_der( + data: &'a [u8], + ) -> Result> { + Self::parse(data).map(|(_, tst_info)| tst_info) + } + + pub fn parse(input: &'a [u8]) -> BerResult { + parse_der_sequence_defined_g(|input: &[u8], _| { + let (remainder, _version) = parse_der_integer(input)?; + let (remainder, _policy) = parse_der(remainder)?; + + let (remainder, (hash_algorithm, hashed_message)) = + Self::parse_message_imprint(remainder)?; + + // Ignore the remaining fields, we don't need them. + + Ok((remainder, Self { hash_algorithm, hashed_message })) + })(input) + } + + fn parse_message_imprint( + input: &'a [u8], + ) -> BerResult<(AlgorithmIdentifier, &'a [u8])> { + parse_der_sequence_defined_g(|input: &[u8], _| { + let (remainder, hash_algorithm) = + AlgorithmIdentifier::from_der(input).unwrap(); // TODO: handle error + let (remainder, hashed_message) = parse_der(remainder)?; + + Ok((remainder, (hash_algorithm, hashed_message.as_slice()?))) + })(input) + } +} diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index ac374a059..3e5dbfe21 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -1,374 +1,70 @@ use std::borrow::Cow; -use std::fmt::{Display, Write}; +use std::fmt::Write; -use crate::modules::pe::parser::PE; use array_bytes::bytes2hex; -use cms::cert::x509::{spki, Certificate}; -use cms::cert::IssuerAndSerialNumber; -use cms::content_info::CmsVersion; -use cms::content_info::ContentInfo; -use cms::signed_data::{ - CertificateSet, SignedAttributes, SignedData, SignerIdentifier, - SignerInfo, SignerInfos, -}; -use const_oid::db::{rfc4519, rfc5911, rfc5912, rfc6268, DB}; -use const_oid::{AssociatedOid, ObjectIdentifier}; -use der::asn1::OctetString; -use der::referenced::OwnedToRef; -use der::{asn1, FixedTag, Reader}; -use der::{Choice, Sequence, SliceReader}; -use der::{Decode, Encode, Tag, Tagged}; +use const_oid::AssociatedOid; +use der::asn1; +use der::Decode; +use der_parser::asn1_rs::{Set, ToDer}; use digest::Digest; use ecdsa::signature::hazmat::PrehashVerifier; use itertools::Itertools; use md5::Md5; +use nom::AsBytes; use protobuf::MessageField; use rsa::traits::SignatureScheme; use rsa::Pkcs1v15Sign; -use sha1::digest::Output; use sha1::Sha1; use sha2::{Sha256, Sha384, Sha512}; -use x509_cert::attr::Attribute; -use x509_cert::spki::{AlgorithmIdentifierOwned, SubjectPublicKeyInfoRef}; -use x509_tsp::TstInfo; -use x509_verify::{VerifyInfo, VerifyingKey}; +use x509_parser::num_bigint::BigUint; +use x509_parser::prelude::{AlgorithmIdentifier, X509Certificate}; +use x509_parser::x509::X509Name; +use crate::modules::pe::asn1::{ + oid, oid_to_str, Attribute, ContentInfo, DigestInfo, IndirectDataContent, + SignedData, SignerInfo, TstInfo, +}; +use crate::modules::pe::parser::PE; use crate::modules::protos; -/// OID for [`SpcIndirectDataContent`]. -pub const SPC_INDIRECT_DATA_OBJID: ObjectIdentifier = - ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.2.1.4"); - -/// OID for [`SpcSpOpusInfo`]. -pub const SPC_SP_OPUS_INFO_OBJID: ObjectIdentifier = - ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.2.1.12"); - -pub const SPC_MS_NESTED_SIGNATURE: ObjectIdentifier = - ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.2.4.1"); - -pub const SPC_MS_COUNTERSIGN: ObjectIdentifier = - ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.3.3.1"); - -pub const JURISDICTION_L: ObjectIdentifier = - ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.60.2.1.1"); - -pub const JURISDICTION_ST: ObjectIdentifier = - ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.60.2.1.2"); - -pub const JURISDICTION_C: ObjectIdentifier = - ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.60.2.1.3"); - -/// Similar to 1.2.840.113549.1.1.5. Obsolete, but still present in some files -/// like: 111aeddc6a6dbf64b28cb565aa12af9ee3cc0a56ce31e4da0068cf6b474c3288 -pub const SHA1_WITH_RSA_ENCRYPTION: ObjectIdentifier = - ObjectIdentifier::new_unwrap("1.3.14.3.2.29"); - -/// ASN.1 SpcIndirectDataContent -/// -/// SpcIndirectDataContent ::= SEQUENCE { -/// data SpcAttributeTypeAndOptionalValue, -/// messageDigest DigestInfo -/// } -#[derive(Clone, Debug, Eq, PartialEq, Sequence)] -pub struct SpcIndirectDataContent { - /// Image data. - pub data: SpcAttributeTypeAndOptionalValue, - - /// Authenticode digest. - pub message_digest: DigestInfo, -} - -/// ASN.1 SpcAttributeTypeAndOptionalValue -/// -/// SpcAttributeTypeAndOptionalValue ::= SEQUENCE { -/// type ObjectID, -/// value [0] EXPLICIT ANY OPTIONAL -/// } -#[derive(Clone, Debug, Eq, PartialEq, Sequence)] -pub struct SpcAttributeTypeAndOptionalValue { - /// Type of data stored in the `value` field. - pub value_type: ObjectIdentifier, - pub value: der::Any, -} - -/// ASN.1 DigestInfo -/// -/// DigestInfo ::= SEQUENCE { -/// digestAlgorithm AlgorithmIdentifier, -/// digest OCTETSTRING -/// } -#[derive(Clone, Debug, Eq, PartialEq, Sequence)] -pub struct DigestInfo { - /// Authenticode digest algorithm. - pub digest_algorithm: spki::AlgorithmIdentifierOwned, - - /// Authenticode digest. - pub digest: OctetString, -} - -/// ASN.1 SpcSpOpusInfo -/// -/// SpcSpOpusInfo ::= SEQUENCE { -/// programName [0] EXPLICIT SpcString OPTIONAL, -/// moreInfo [1] EXPLICIT SpcLink OPTIONAL, -/// } -#[derive(Clone, Debug, Eq, PartialEq, Sequence)] -pub struct SpcSpOpusInfo { - #[asn1(context_specific = "0", optional = "true")] - pub program_name: Option, - #[asn1(context_specific = "1", optional = "true")] - pub more_info: Option, -} - -/// ASN.1 SpcString -/// -/// SpcString ::= CHOICE { -/// unicode [0] IMPLICIT BMPSTRING, -/// ascii [1] IMPLICIT IA5STRING -/// } -#[derive(Clone, Debug, Eq, PartialEq, Choice)] -pub enum SpcString { - #[asn1(context_specific = "0", tag_mode = "IMPLICIT")] - Unicode(asn1::BmpString), - #[asn1(context_specific = "1", tag_mode = "IMPLICIT", type = "IA5String")] - Ascii(asn1::Ia5String), -} - -impl Display for SpcString { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let str = match self { - SpcString::Unicode(unicode) => unicode.to_string(), - SpcString::Ascii(ascii) => ascii.to_string(), - }; - write!(f, "{}", str) - } -} - -/// ASN.1 SpcLink -/// -/// SpcLink ::= CHOICE { -/// url [0] IMPLICIT IA5STRING, -/// moniker [1] IMPLICIT SpcSerializedObject, -/// file [2] EXPLICIT SpcString -/// } -/// -#[derive(Clone, Debug, Eq, PartialEq, Choice)] -pub enum SpcLink { - #[asn1(context_specific = "0", tag_mode = "IMPLICIT", type = "IA5String")] - Url(asn1::Ia5String), -} - -/// ASN.1 SignerInfo -/// -/// SignerInfo ::= SEQUENCE { -/// version CMSVersion, -/// sid SignerIdentifier, -/// digestAlgorithm DigestAlgorithmIdentifier, -/// signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, -/// signatureAlgorithm SignatureAlgorithmIdentifier, -/// signature SignatureValue, -/// unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL -/// } -/// -/// This is a custom deferred structure which delays decoding of [`signerInfos`] -/// to deal with mixed BER/DER encoding issues. We need to obtain the same data -/// during verification that was used during signing. -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct DeferSignerInfo { - pub version: cms::content_info::CmsVersion, - pub sid: cms::signed_data::SignerIdentifier, - pub digest_alg: spki::AlgorithmIdentifierOwned, - pub signed_attrs: Option>, - pub signature_algorithm: spki::AlgorithmIdentifierOwned, - pub signature: cms::signed_data::SignatureValue, - pub unsigned_attrs: Option, -} - -/// ASN.1 SignerInfos -/// -/// SignerInfos ::= SET OF SignerInfo -/// -/// This is a custom deferred structure which delays decoding of [`signerInfos`] -/// to deal with mixed BER/DER encoding issues. We need to obtain the same data -/// during verification that was used during signing. -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct DeferSignerInfos(pub Vec); - -/// ASN.1 SignedData -/// -/// SignedData ::= SEQUENCE { -/// version CMSVersion, -/// digestAlgorithms DigestAlgorithmIdentifiers, -/// encapContentInfo EncapsulatedContentInfo, -/// certificates [0] IMPLICIT CertificateSet OPTIONAL, -/// crls [1] IMPLICIT RevocationInfoChoices OPTIONAL, -/// signerInfos SignerInfos -/// } -/// -/// This is a custom deferred structure which delays decoding of [`signerInfos`] -/// to deal with mixed BER/DER encoding issues. We need to obtain the same data -/// during verification that was used during signing. -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct DeferSignedData { - pub version: cms::content_info::CmsVersion, - pub digest_algorithms: cms::signed_data::DigestAlgorithmIdentifiers, - pub encap_content_info: cms::signed_data::EncapsulatedContentInfo, - pub certificates: Option, - pub crls: Option, - pub signer_infos: DeferSignerInfos, -} - -impl der::FixedTag for DeferSignerInfo { - const TAG: Tag = SignerInfo::TAG; -} - -impl<'a> der::DecodeValue<'a> for DeferSignerInfo { - fn decode_value>( - reader: &mut R, - header: der::Header, - ) -> der::Result { - reader.read_nested(header.length, |reader| { - let version = reader.decode()?; - let sid = reader.decode()?; - let digest_alg = reader.decode()?; - let signed_attrs = reader.peek_header() - .and_then(|header| - // Signer attributes are implicitly tagged which means that the original tag - // for SET OF is not present. We therefore need to swap the tag to SET due to: - // * Verification - we need to verify against the original data - // * Reencoding - we need to able to reencode this back to SignedAttributes - if header.tag.is_context_specific() && header.tag.is_constructed() && header.tag.number() == der::TagNumber::N0 { - reader.read_slice(header.encoded_len()?)?; - let new_header = der::Header { - tag: SignedAttributes::TAG, - length: header.length - }; - - let mut result = Vec::new(); - new_header.encode_to_vec(&mut result)?; - result.extend(reader.read_slice(header.length)?); - Ok(Some(result)) - } else { - Ok(None) - })?; - let signature_algorithm = reader.decode()?; - let signature = reader.decode()?; - let unsigned_attrs = reader.context_specific(der::TagNumber::N1, der::TagMode::Implicit)?; - - Ok(Self { - version, - sid, - digest_alg, - signed_attrs, - signature_algorithm, - signature, - unsigned_attrs, - }) - }) - } -} - -impl TryFrom<&DeferSignerInfo> for SignerInfo { - type Error = der::Error; - - fn try_from(value: &DeferSignerInfo) -> Result { - Ok(Self { - version: value.version, - sid: value.sid.clone(), - digest_alg: value.digest_alg.clone(), - signed_attrs: value - .signed_attrs - .as_ref() - .map(|data| SignedAttributes::from_der(data)) - .transpose()?, - signature_algorithm: value.signature_algorithm.clone(), - signature: value.signature.clone(), - unsigned_attrs: value.unsigned_attrs.clone(), - }) - } -} - -impl der::FixedTag for DeferSignerInfos { - const TAG: Tag = SignerInfos::TAG; -} - -impl<'a> der::DecodeValue<'a> for DeferSignerInfos { - fn decode_value>( - reader: &mut R, - header: der::Header, - ) -> der::Result { - reader.read_nested(header.length, |reader| { - Ok(Self(std::iter::from_fn(|| reader.decode().ok()).collect())) - }) - } -} - -impl der::FixedTag for DeferSignedData { - const TAG: Tag = SignedData::TAG; -} - -impl<'a> der::DecodeValue<'a> for DeferSignedData { - fn decode_value>( - reader: &mut R, - header: der::Header, - ) -> der::Result { - reader.read_nested(header.length, |reader| { - Ok(Self { - version: reader.decode()?, - digest_algorithms: reader.decode()?, - encap_content_info: reader.decode()?, - certificates: reader.context_specific( - der::TagNumber::N0, - der::TagMode::Implicit, - )?, - crls: reader.context_specific( - der::TagNumber::N1, - der::TagMode::Implicit, - )?, - signer_infos: reader.decode()?, - }) - }) - } -} - /// Error returned by [`AuthenticodeParser::parse`]. -#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq)] pub enum ParseError { /// The signature data is empty. Empty, /// The signature data is not valid [`ContentInfo`]. - InvalidContentInfo(der::Error), + InvalidContentInfo, - /// The content type does not match [`rfc6268::ID_SIGNED_DATA`]. - InvalidContentType(ObjectIdentifier), + /// The content type is not signed data (1.2.840.113549.1.7.2) + InvalidContentType(String), /// The content info is not valid [`SignedData`]. - InvalidSignedData(der::Error), + InvalidSignedData, /// The signer info is not valid [`SignerInfo`]. InvalidSignerInfo(der::Error), /// The version of [`SignedData`] is not 1. - InvalidSignedDataVersion(CmsVersion), + InvalidSignedDataVersion(i32), /// The number of digest algorithms is not 1. InvalidNumDigestAlgorithms(usize), /// The encapsulated content type does not match [`SPC_INDIRECT_DATA_OBJID`]. - InvalidEncapsulatedContentType(ObjectIdentifier), + InvalidEncapsulatedContentType(String), /// The encapsulated content is empty. EmptyEncapsulatedContent, /// The encapsulated content is not valid [`SpcIndirectDataContent`]. - InvalidSpcIndirectDataContent(der::Error), + InvalidSpcIndirectDataContent, /// The number of signer infos is not 1. InvalidNumSignerInfo(usize), /// The version of [`SignerInfo`] is not 1. - InvalidSignerInfoVersion(CmsVersion), + InvalidSignerInfoVersion(i64), /// The digest algorithm is not internally consistent. AlgorithmMismatch, @@ -393,36 +89,32 @@ pub struct AuthenticodeParser {} impl AuthenticodeParser { /// Parses Authenticode signatures from DER-encoded bytes. - pub fn parse( - input: &[u8], + pub fn parse<'a>( + input: &'a [u8], pe: &PE, - ) -> Result, ParseError> { - // Use a reader rather than using `Decode::from_der`, because - // there may be unused trailing data in `input`, which causes a - // `TrailingData` error. - let mut reader = - SliceReader::new(input).map_err(|_| ParseError::Empty)?; + ) -> Result>, ParseError> { + let content_info = ContentInfo::from_der(input) + .map_err(|_| ParseError::InvalidContentInfo)?; - let content_info = ContentInfo::decode(&mut reader) - .map_err(ParseError::InvalidContentInfo)?; - - if content_info.content_type == rfc6268::ID_SIGNED_DATA { + if content_info.content_type == oid::SIGNED_DATA { Self::parse_content_info(content_info, pe) } else { - Err(ParseError::InvalidContentType(content_info.content_type)) + Err(ParseError::InvalidContentType( + content_info.content_type.to_id_string(), + )) } } - fn parse_content_info( - content_info: ContentInfo, + fn parse_content_info<'a>( + content_info: ContentInfo<'a>, pe: &PE, - ) -> Result, ParseError> { - let signed_data = content_info + ) -> Result>, ParseError> { + let mut signed_data: SignedData = content_info .content - .decode_as::() - .map_err(ParseError::InvalidSignedData)?; + .try_into() + .map_err(|_| ParseError::InvalidSignedData)?; - if signed_data.version != CmsVersion::V1 { + if signed_data.version != 1 { return Err(ParseError::InvalidSignedDataVersion( signed_data.version, )); @@ -437,165 +129,148 @@ impl AuthenticodeParser { } // Exactly one SignerInfo, as required by the specification. - if signed_data.signer_infos.0.len() != 1 { + if signed_data.signer_infos.len() != 1 { return Err(ParseError::InvalidNumSignerInfo( - signed_data.signer_infos.0.len(), + signed_data.signer_infos.len(), )); } - if signed_data.encap_content_info.econtent_type - != SPC_INDIRECT_DATA_OBJID - { + if signed_data.content_info.content_type != oid::INDIRECT_DATA_OBJID { return Err(ParseError::InvalidEncapsulatedContentType( - signed_data.encap_content_info.econtent_type, + signed_data.content_info.content_type.to_id_string(), )); } - let indirect_data = signed_data - .encap_content_info - .econtent - .as_ref() - .ok_or(ParseError::EmptyEncapsulatedContent)? - .decode_as::() - .map_err(ParseError::InvalidSpcIndirectDataContent)?; - - let signer_info = &signed_data.signer_infos.0.as_slice()[0]; - let decoded_signer_info = SignerInfo::try_from(signer_info) - .map_err(ParseError::InvalidSignerInfo)?; - - if signer_info.version != CmsVersion::V1 { - return Err(ParseError::InvalidSignerInfoVersion( - signer_info.version, - )); - } + // According to the Authenticode specification there's exactly one + // signer info. + let signer_info = match signed_data.signer_infos.pop() { + Some(si) => si, + None => { + return Err(ParseError::InvalidNumSignerInfo( + signed_data.signer_infos.len(), + )) + } + }; - if signer_info.digest_alg - != signed_data.digest_algorithms.as_slice()[0] + let signer_info_digest = match signer_info + .get_signed_attr(&oid::MESSAGE_DIGEST) + .and_then(|attr| attr.attr_values.first()) + .map(|value| value.data.as_bytes()) { - return Err(ParseError::AlgorithmMismatch); - } + Some(md) => md, + None => { + return Err( + ParseError::MissingMessageDigestAuthenticatedAttribute, + ) + } + }; - let signed_attrs = - if let Some(signed_attrs) = &decoded_signer_info.signed_attrs { - signed_attrs - } else { - return Err(ParseError::EmptyAuthenticatedAttributes); - }; + let signer_info_verified = verify_message_digest( + &signer_info.digest_algorithm, + signed_data.content_info.content.data, + signer_info_digest, + ) && verify_signer_info( + &signer_info, + signed_data.certificates.as_slice(), + ); - // The content type attribute must be present. - if !signed_attrs - .iter() - .any(|attr| attr.oid == rfc6268::ID_CONTENT_TYPE) - { + if signer_info.get_signed_attr(&oid::CONTENT_TYPE).is_none() { return Err(ParseError::MissingContentTypeAuthenticatedAttribute); } - // Get the message digest attribute stored in `SignerInfo`, this is - // the digest of `SignedData.EncapsulatedContentInfo.econtent`. - let signer_info_digest = get_message_digest(signed_attrs) - .ok_or(ParseError::MissingMessageDigestAuthenticatedAttribute)?; - - // Get the opus info attribute and decode it. - let opus_info = signed_attrs - .iter() - .find(|attr| attr.oid == SPC_SP_OPUS_INFO_OBJID) - .and_then(|attr| attr.values.get(0)) - .and_then(|value| value.decode_as::().ok()); + let indirect_data: IndirectDataContent = + match signed_data.content_info.content.try_into() { + Ok(idc) => idc, + Err(_) => { + return Err(ParseError::InvalidSpcIndirectDataContent) + } + }; // Get all the certificates contained in `SignedData`, more // certificates from nested signatures and countersignatures will // be added later to this vector. - let mut certificates: Vec = signed_data - .certificates - .as_ref() - .map(Self::certificate_set_to_iter) - .unwrap() - .cloned() - .collect(); + let mut certificates: Vec = signed_data.certificates; let mut nested_signatures = Vec::new(); let mut countersignatures = Vec::new(); - if let Some(attrs) = &signer_info.unsigned_attrs { - for attr in attrs.iter() { - match attr.oid { - // An Authenticode signature can contain nested signatures in - // an unsigned attribute with OID 1.3.6.1.4.1.311.2.4.1. - SPC_MS_NESTED_SIGNATURE => { - if let Some(signatures) = attr - .values - .get(0) - .and_then(|value| { - value.decode_as::().ok() - }) - .and_then(|content_info| { - Self::parse_content_info(content_info, pe).ok() - }) - { - nested_signatures.extend(signatures); - } + for attr in signer_info.unsigned_attrs.iter() { + match attr.attr_type.as_bytes() { + // SignerInfo can have attributes containing nested Authenticode + // signatures. The type of those attributes is 1.3.6.1.4.1.311.2.4.1 + // and their content is a ContentInfo structure. Find those attributes, + // parse their first (and only) value, and append resulting signatures + // to `nested_signatures`. + oid::MS_NESTED_SIGNATURE_B => { + if let Some(nested) = + attr.attr_values.first().and_then(|first_value| { + let content_info = first_value.try_into().ok()?; + Self::parse_content_info(content_info, pe).ok() + }) + { + nested_signatures.extend(nested); } - SPC_MS_COUNTERSIGN => { - Self::parse_ms_countersignature_attr( - signer_info, - attr, - &mut certificates, - &mut countersignatures, - )?; - } - rfc5911::ID_COUNTERSIGNATURE => { - Self::parse_pkcs9_countersignature_attr( - signer_info, - attr, - &mut certificates, - &mut countersignatures, - )?; - } - _ => {} } + oid::MS_COUNTERSIGN_B => { + Self::parse_ms_countersignature_attr( + &signer_info, + attr, + &mut certificates, + &mut countersignatures, + )?; + } + oid::PKCS9_COUNTERSIGN_B => { + Self::parse_pkcs9_countersignature_attr( + &signer_info, + attr, + &mut certificates, + &mut countersignatures, + )?; + } + _ => {} } } - let mut signatures = Vec::with_capacity(nested_signatures.len() + 1); - // Compute the Authenticode hash by ourselves. This hash will be // compared later with the one included in the PE file. - let file_digest = match signer_info.digest_alg.oid { - rfc5912::ID_SHA_1 => { + let file_digest = match signer_info.digest_algorithm.oid().as_bytes() { + oid::MD5_B => { + let mut md5 = Md5::default(); + pe.authenticode_hash(&mut md5); + md5.finalize().to_vec() + } + oid::SHA_1_B => { let mut sha1 = Sha1::default(); pe.authenticode_hash(&mut sha1); sha1.finalize().to_vec() } - rfc5912::ID_SHA_256 => { + oid::SHA_256_B => { let mut sha256 = Sha256::default(); pe.authenticode_hash(&mut sha256); sha256.finalize().to_vec() } - rfc5912::ID_SHA_384 => { + oid::SHA_384_B => { let mut sha384 = Sha384::default(); pe.authenticode_hash(&mut sha384); sha384.finalize().to_vec() } - rfc5912::ID_SHA_512 => { + oid::SHA_512_B => { let mut sha512 = Sha512::default(); pe.authenticode_hash(&mut sha512); sha512.finalize().to_vec() } - rfc5912::ID_MD_5 => { - let mut md5 = Md5::default(); - pe.authenticode_hash(&mut md5); - md5.finalize().to_vec() - } oid => unimplemented!("{:?}", oid), }; + let mut signatures = Vec::with_capacity(nested_signatures.len() + 1); + signatures.push(AuthenticodeSignature { - program_name: opus_info.and_then(|oi| oi.program_name), - signer_info_digest, - indirect_data, - signed_data, - signer_info: decoded_signer_info, computed_authenticode_hash: file_digest, + //program_name: None, //opus_info.and_then(|oi| oi.program_name), + authenticode_digest: indirect_data.message_digest, + signer_info, + signer_info_digest, + signer_info_verified, countersignatures, certificates, }); @@ -605,102 +280,72 @@ impl AuthenticodeParser { Ok(signatures) } - fn parse_ms_countersignature_attr( - si: &DeferSignerInfo, - attr: &Attribute, - certificates: &mut Vec, - countersignatures: &mut Vec, + fn parse_ms_countersignature_attr<'a>( + si: &SignerInfo<'a>, + attr: &Attribute<'a>, + certificates: &mut Vec>, + countersignatures: &mut Vec>, ) -> Result<(), ParseError> { - for value in attr.values.iter() { - let content_info = match value.decode_as::() { - Ok(content_info) => content_info, + for value in &attr.attr_values { + let content_info: ContentInfo = match value.try_into() { + Ok(ci) => ci, Err(_) => continue, }; - if let Ok(signed_data) = - content_info.content.decode_as::() + let signed_data: SignedData = match content_info.content.try_into() { - certificates.extend( - signed_data - .certificates - .as_ref() - .map(Self::certificate_set_to_iter) - .unwrap() - .cloned() - .collect::>(), - ); - - let cs_si = signed_data.signer_infos.0.first().unwrap(); + Ok(sd) => sd, + Err(_) => continue, + }; - let mut countersignature = - Self::pkcs9_countersignature(cs_si)?; - - let tst_info = signed_data - .encap_content_info - .econtent - .and_then(|content| { - content.decode_as::().ok() - }) - .and_then(|octet_string| { - TstInfo::from_der(octet_string.as_bytes()).ok() - }); - - let tst_info = match tst_info { - Some(tst_info) => tst_info, - None => continue, - }; - - countersignature.digest_alg = - oid_to_str(&tst_info.message_imprint.hash_algorithm.oid); - - countersignature.digest = Some(bytes2hex( - "", - tst_info.message_imprint.hashed_message.as_bytes(), - )); + certificates.extend(signed_data.certificates); - countersignature.verified = - verify_message_digest( - &tst_info.message_imprint.hash_algorithm, - si.signature.as_bytes(), - tst_info.message_imprint.hashed_message.as_bytes(), - ) && verify_signer_info(cs_si, certificates.as_slice()); + let cs_si = signed_data.signer_infos.first().unwrap(); - countersignatures.push(countersignature); - } + let mut countersignature = Self::pkcs9_countersignature(cs_si)?; + + let tst_info = match TstInfo::from_der( + signed_data.content_info.content.as_bytes(), + ) { + Ok(tst_info) => tst_info, + Err(_) => continue, + }; + + countersignature.digest_alg = + oid_to_str(tst_info.hash_algorithm.oid()); + + countersignature.digest = tst_info.hashed_message; + + countersignature.verified = + verify_message_digest( + &tst_info.hash_algorithm, + si.signature_value, + tst_info.hashed_message, + ) && verify_signer_info(cs_si, certificates.as_slice()); + + countersignatures.push(countersignature); } Ok(()) } - fn parse_pkcs9_countersignature_attr( - si: &DeferSignerInfo, - attr: &Attribute, - certificates: &mut Vec, - countersignatures: &mut Vec, + fn parse_pkcs9_countersignature_attr<'a>( + si: &SignerInfo<'a>, + attr: &Attribute<'a>, + certificates: &mut Vec>, + countersignatures: &mut Vec>, ) -> Result<(), ParseError> { - for value in attr.values.iter() { - if let Ok(cs_si) = value.decode_as::().as_ref() { + for value in &attr.attr_values { + if let Ok(cs_si) = value.try_into() { let mut countersignature = - Self::pkcs9_countersignature(cs_si)?; - - let cs_signed_attrs = countersignature - .signer_info - .signed_attrs - .as_ref() - .ok_or(ParseError::EmptyAuthenticatedAttributes)?; - - let message_digest = match get_message_digest(cs_signed_attrs) - { - Some(digest) => digest, - None => continue, - }; + Self::pkcs9_countersignature(&cs_si)?; countersignature.verified = verify_message_digest( - &cs_si.digest_alg, - si.signature.as_bytes(), - message_digest.as_bytes(), - ) && verify_signer_info(cs_si, certificates.as_slice()); + &cs_si.digest_algorithm, + si.signature_value, + countersignature.digest, + ) && verify_signer_info(&cs_si, certificates.as_slice()); countersignatures.push(countersignature); } @@ -709,87 +354,72 @@ impl AuthenticodeParser { Ok(()) } - fn pkcs9_countersignature( - cs: &DeferSignerInfo, - ) -> Result { + fn pkcs9_countersignature<'a>( + si: &SignerInfo<'a>, + ) -> Result, ParseError> { let mut digest = None; let mut signing_time = None; - let decoded_cs = - SignerInfo::try_from(cs).map_err(ParseError::InvalidSignerInfo)?; - - if let Some(signed_attrs) = &decoded_cs.signed_attrs { - for attr in signed_attrs.iter() { - match attr.oid { - rfc6268::ID_MESSAGE_DIGEST => { - if let Some(value) = attr.values.get(0) { - digest = Some(bytes2hex("", value.value())); - } + for attr in &si.signed_attrs { + match attr.attr_type.as_bytes() { + oid::MESSAGE_DIGEST_B => { + if let Some(value) = attr.attr_values.first() { + digest = Some(value.data) } - rfc6268::ID_SIGNING_TIME => { - if let Some(value) = attr.values.get(0) { - signing_time = - value.decode_as::().ok(); - } - } - _ => {} } + /* => { + if let Some(value) = attr.values.get(0) { + signing_time = + value.decode_as::().ok(); + } + }*/ + _ => {} } } - let signer = match &cs.sid { - SignerIdentifier::IssuerAndSerialNumber(signer) => signer, - _ => unreachable!(), + let digest = match digest { + Some(digest) => digest, + None => { + return Err( + ParseError::MissingMessageDigestAuthenticatedAttribute, + ) + } }; Ok(AuthenticodeCountersign { - signer: signer.clone(), - signer_info: decoded_cs, - digest_alg: oid_to_str(&cs.digest_alg.oid), + signer: si.serial_number.clone(), + digest_alg: oid_to_str(&si.digest_algorithm.oid()), digest, signing_time, verified: false, }) } - - fn certificate_set_to_iter( - cs: &CertificateSet, - ) -> impl Iterator { - cs.0.iter().map(|cert| { - if let cms::cert::CertificateChoices::Certificate(cert) = cert { - cert - } else { - panic!() - } - }) - } } -pub struct AuthenticodeCountersign { - signer: IssuerAndSerialNumber, - signer_info: SignerInfo, +pub struct AuthenticodeCountersign<'a> { + signer: BigUint, digest_alg: Cow<'static, str>, - digest: Option, + digest: &'a [u8], signing_time: Option, verified: bool, } -pub struct AuthenticodeSignature { - signer_info_digest: OctetString, - indirect_data: SpcIndirectDataContent, - signed_data: DeferSignedData, - signer_info: SignerInfo, - certificates: Vec, - countersignatures: Vec, - program_name: Option, +pub struct AuthenticodeSignature<'a> { + signer_info: SignerInfo<'a>, + signer_info_digest: &'a [u8], + signer_info_verified: bool, + authenticode_digest: DigestInfo<'a>, + certificates: Vec>, + countersignatures: Vec>, + //program_name: Option, computed_authenticode_hash: Vec, } -impl AuthenticodeSignature { +impl<'a> AuthenticodeSignature<'a> { /// Get the Authenticode hash stored in the PE file. #[inline] pub fn stored_authenticode_hash(&self) -> &[u8] { - self.indirect_data.message_digest.digest.as_bytes() + self.authenticode_digest.digest } /// Get the Authenticode hash computed by ourselves. @@ -800,12 +430,12 @@ impl AuthenticodeSignature { /// Get the name of the Authenticode hash algorithm. pub fn authenticode_hash_algorithm(&self) -> Cow<'static, str> { - oid_to_str(&self.indirect_data.message_digest.digest_algorithm.oid) + oid_to_str(&self.authenticode_digest.algorithm.oid()) } #[inline] pub fn signer_info_digest_alg(&self) -> Cow<'static, str> { - oid_to_str(&self.signer_info.digest_alg.oid) + oid_to_str(&self.signer_info.digest_algorithm.oid()) } #[inline] @@ -814,32 +444,26 @@ impl AuthenticodeSignature { } #[inline] - pub fn certificates(&self) -> &[Certificate] { + pub fn certificates(&self) -> &[X509Certificate<'a>] { self.certificates.as_slice() } #[inline] - pub fn chain(&self) -> impl Iterator { - CertificateChain::new(self.certificates.as_slice(), |cert| { - cert.tbs_certificate.serial_number == self.signer().serial_number + pub fn chain(&self) -> impl Iterator> { + CertificateChain::new(self.certificates(), |cert| { + cert.tbs_certificate.issuer.eq(self.issuer()) }) } #[inline] pub fn countersignatures( &self, - ) -> impl Iterator { + ) -> impl Iterator> { self.countersignatures.iter() } - pub fn signer(&self) -> &IssuerAndSerialNumber { - if let SignerIdentifier::IssuerAndSerialNumber(signer) = - &self.signer_info.sid - { - signer - } else { - unreachable!() - } + pub fn issuer(&self) -> &X509Name<'a> { + &self.signer_info.issuer } /// Returns `true` if the [`AuthenticodeSignature`] is valid. @@ -870,39 +494,25 @@ impl AuthenticodeSignature { /// that is not included in the PE file. This last certificate is always /// considered valid. pub fn verify(&self) -> bool { - if self.computed_authenticode_hash() != self.stored_authenticode_hash() + if !self.signer_info_verified + || self.computed_authenticode_hash() + != self.stored_authenticode_hash() { return false; } - let message_digest = match get_message_digest( - self.signer_info.signed_attrs.as_ref().unwrap(), - ) { - Some(digest) => digest, - None => return false, - }; - - if !verify_message_digest( - &self.signer_info.digest_alg, - self.signed_data - .encap_content_info - .econtent - .as_ref() - .unwrap() - .value(), - message_digest.as_ref(), - ) { - return false; - } + return true; + // TODO + /* verify_signer_info( &self.signed_data.signer_infos.0[0], self.certificates(), - ) + )*/ } } -impl From<&AuthenticodeSignature> for protos::pe::Signature { +impl From<&AuthenticodeSignature<'_>> for protos::pe::Signature { fn from(value: &AuthenticodeSignature) -> Self { let mut sig = protos::pe::Signature::new(); @@ -919,8 +529,7 @@ impl From<&AuthenticodeSignature> for protos::pe::Signature { let mut pbcs = protos::pe::CounterSignature::from(cs); pbcs.chain = CertificateChain::new(value.certificates.as_slice(), |cert| { - cert.tbs_certificate.serial_number - == cs.signer.serial_number + cert.tbs_certificate.serial == cs.signer }) .map(protos::pe::Certificate::from) .collect(); @@ -942,9 +551,9 @@ impl From<&AuthenticodeSignature> for protos::pe::Signature { signer_info.set_digest(value.signer_info_digest()); - if let Some(program_name) = &value.program_name { - signer_info.set_program_name(program_name.to_string()) - } + //if let Some(program_name) = &value.program_name { + // signer_info.set_program_name(program_name.to_string()) + //} signer_info .chain @@ -974,11 +583,11 @@ impl From<&AuthenticodeSignature> for protos::pe::Signature { } } -impl From<&AuthenticodeCountersign> for protos::pe::CounterSignature { - fn from(value: &AuthenticodeCountersign) -> Self { +impl From<&AuthenticodeCountersign<'_>> for protos::pe::CounterSignature { + fn from(value: &AuthenticodeCountersign<'_>) -> Self { let mut cs = protos::pe::CounterSignature::new(); - cs.digest = value.digest.clone(); + cs.set_digest(bytes2hex("", value.digest)); cs.set_digest_alg(value.digest_alg.to_string()); cs.set_verified(value.verified); @@ -989,50 +598,39 @@ impl From<&AuthenticodeCountersign> for protos::pe::CounterSignature { } } -impl From<&Certificate> for protos::pe::Certificate { - fn from(value: &Certificate) -> Self { +impl From<&X509Certificate<'_>> for protos::pe::Certificate { + fn from(value: &X509Certificate) -> Self { let mut cert = protos::pe::Certificate::new(); // Versions are 0-based, add 1 for getting the actual version. - cert.set_version(value.tbs_certificate.version as i64 + 1); + cert.set_version(value.tbs_certificate.version.0 as i64 + 1); cert.set_issuer(format_name(&value.tbs_certificate.issuer)); cert.set_subject(format_name(&value.tbs_certificate.subject)); - cert.set_serial(format_serial_number( - &value.tbs_certificate.serial_number, + cert.set_serial(format_serial_number(&value.tbs_certificate.serial)); + + cert.set_algorithm_oid(format!( + "{}", + value.signature_algorithm.algorithm )); - cert.set_algorithm_oid(format!("{}", value.signature_algorithm.oid)); cert.set_algorithm( - oid_to_str(&value.signature_algorithm.oid).into_owned(), + oid_to_str(&value.signature_algorithm.algorithm).into_owned(), ); // The certificate thumbprint is the SHA1 of the DER-encoded certificate. - let mut hasher = DerDigest::::default(); - value.encode(&mut hasher).unwrap(); - cert.set_thumbprint(format!("{:x}", hasher.finalize())); - - if let Ok(time) = value - .tbs_certificate - .validity - .not_before - .to_unix_duration() - .as_secs() - .try_into() - { - cert.set_not_before(time); - } + // TODO + //let mut hasher = DerDigest::::default(); + //value.encode(&mut hasher).unwrap(); + //cert.set_thumbprint(format!("{:x}", hasher.finalize())); - if let Ok(time) = value - .tbs_certificate - .validity - .not_after - .to_unix_duration() - .as_secs() - .try_into() - { - cert.set_not_after(time); - } + cert.set_not_before( + value.tbs_certificate.validity.not_before.timestamp(), + ); + + cert.set_not_after( + value.tbs_certificate.validity.not_after.timestamp(), + ); cert } @@ -1055,42 +653,18 @@ impl From<&Certificate> for protos::pe::Certificate { /// ``` /// /// [RFC 4514]: https://datatracker.ietf.org/doc/html/rfc4514 -fn format_name(name: &x509_cert::name::Name) -> String { +fn format_name(name: &X509Name) -> String { let mut n = String::new(); - for rdn in &name.0 { + for rdn in name.iter_rdn() { write!(n, "/").unwrap(); - for atv in rdn.0.iter() { - let val = match atv.value.tag() { - Tag::PrintableString => { - asn1::PrintableStringRef::try_from(&atv.value) - .ok() - .map(|s| s.as_str()) - } - Tag::Utf8String => asn1::Utf8StringRef::try_from(&atv.value) - .ok() - .map(|s| s.as_str()), - Tag::Ia5String => asn1::Ia5StringRef::try_from(&atv.value) - .ok() - .map(|s| s.as_str()), - Tag::TeletexString => { - asn1::TeletexStringRef::try_from(&atv.value) - .ok() - .map(|s| s.as_str()) - } - _ => None, - }; - - if let (key, Some(val)) = (oid_to_str(&atv.oid), val) { + for atv in rdn.iter() { + let key = oid_to_str(atv.attr_type()); + let val = atv.as_str().ok(); + if let (key, Some(val)) = (key, val) { write!(n, "{}=", key).unwrap(); for char in val.chars() { n.write_char(char).unwrap(); } - } else { - let value = atv.value.to_der().unwrap(); - write!(n, "{}=#", atv.oid).unwrap(); - for c in value { - write!(n, "{:02x}", c).unwrap(); - } } } } @@ -1098,59 +672,42 @@ fn format_name(name: &x509_cert::name::Name) -> String { n } -/// Given a [`SignerInfo`] returns the value of the message digest attribute. -fn get_message_digest(signed_attrs: &SignedAttributes) -> Option { - signed_attrs - .iter() - .find(|attr| attr.oid == rfc6268::ID_MESSAGE_DIGEST) - .and_then(|attr| attr.values.get(0)) - .and_then(|value| value.decode_as::().ok()) -} - /// Given a hashing algorithm and a message, compute the message's hash /// and compare it with `digest`. The function returns `true` if they match. fn verify_message_digest( - algorithm: &AlgorithmIdentifierOwned, + algorithm: &AlgorithmIdentifier, message: &[u8], digest: &[u8], ) -> bool { - match algorithm.oid { - rfc5912::ID_SHA_1 => Sha1::digest(message).as_slice() == digest, - rfc5912::ID_SHA_256 => Sha256::digest(message).as_slice() == digest, - rfc5912::ID_SHA_384 => Sha384::digest(message).as_slice() == digest, - rfc5912::ID_SHA_512 => Sha512::digest(message).as_slice() == digest, - rfc5912::ID_MD_5 => Md5::digest(message).as_slice() == digest, - oid => unimplemented!("{:?}", oid), + match algorithm.oid().as_bytes() { + oid::SHA_1_B => Sha1::digest(message).as_slice() == digest, + oid::SHA_256_B => Sha256::digest(message).as_slice() == digest, + oid::SHA_384_B => Sha384::digest(message).as_slice() == digest, + oid::SHA_512_B => Sha512::digest(message).as_slice() == digest, + oid::MD5_B => Md5::digest(message).as_slice() == digest, + _ => unimplemented!("{:?}", algorithm.oid()), } } -fn verify_signer_info(si: &DeferSignerInfo, certs: &[Certificate]) -> bool { - match si.digest_alg.oid { - rfc5912::ID_SHA_1 => verify_signed_data_impl::(si, certs), - rfc5912::ID_SHA_256 => verify_signed_data_impl::(si, certs), - rfc5912::ID_SHA_384 => verify_signed_data_impl::(si, certs), - rfc5912::ID_SHA_512 => verify_signed_data_impl::(si, certs), - rfc5912::ID_MD_5 => verify_signed_data_impl::(si, certs), - oid => unimplemented!("{:?}", oid), +fn verify_signer_info(si: &SignerInfo, certs: &[X509Certificate]) -> bool { + match si.digest_algorithm.oid().as_bytes() { + oid::SHA_1_B => verify_signed_data_impl::(si, certs), + oid::SHA_256_B => verify_signed_data_impl::(si, certs), + oid::SHA_384_B => verify_signed_data_impl::(si, certs), + oid::SHA_512_B => verify_signed_data_impl::(si, certs), + oid::MD5_B => verify_signed_data_impl::(si, certs), + _ => unimplemented!("{:?}", si.digest_algorithm.oid()), } } -fn verify_signed_data_impl( - si: &DeferSignerInfo, - certs: &[Certificate], +fn verify_signed_data_impl( + si: &SignerInfo, + certs: &[X509Certificate<'_>], ) -> bool { - // Find the certificate that signed the data in `content`. - let signing_cert_sn = - if let SignerIdentifier::IssuerAndSerialNumber(signer) = &si.sid { - &signer.serial_number - } else { - unreachable!() - }; - // Get a certificate chain that starts with the certificate that signed // data and contains all the certificates in the chain of truth. let cert_chain = CertificateChain::new(certs, |cert| { - cert.tbs_certificate.serial_number.eq(signing_cert_sn) + cert.tbs_certificate.serial.eq(&si.serial_number) }); // Make sure that whole certificate chain is valid. @@ -1161,32 +718,38 @@ fn verify_signed_data_impl( // Search for the certificate that signed the digest. let signing_cert = match certs .iter() - .find(|cert| cert.tbs_certificate.serial_number.eq(signing_cert_sn)) + .find(|cert| cert.tbs_certificate.serial.eq(&si.serial_number)) { Some(cert) => cert, None => return false, }; + let attrs_set = Set::new(Cow::Borrowed(si.raw_signed_attrs)); + let attrs_set_der = attrs_set.to_der_vec_raw().unwrap(); + + false + + // TODO + /* // Obtain the public key included in the certificate. - let key = match PublicKey::try_from( - signing_cert.tbs_certificate.subject_public_key_info.owned_to_ref(), - ) { - Ok(key) => key, - Err(_) => return false, - }; + let key = + match PublicKey::try_from(signing_cert.tbs_certificate.subject_pki) { + Ok(key) => key, + Err(_) => return false, + }; // Verify that the signature in SignerInfo.signature is correct. - key.verify::(si.signed_attrs.as_ref().unwrap(), si.signature.as_bytes()) + key.verify::(attrs_set_der.as_slice(), si.signature_value) + */ } /// Produces a printable string of a serial number. /// /// The [`x509_cert::serial_number::SerialNumber`] type implements the /// [`Display`] trait, but the resulting string is in uppercase. -fn format_serial_number( - sn: &x509_cert::serial_number::SerialNumber, -) -> String { - let mut iter = sn.as_bytes().iter().peekable(); +fn format_serial_number(sn: &BigUint) -> String { + let bytes = sn.to_bytes_be(); + let mut iter = bytes.iter().peekable(); let mut result = String::new(); while let Some(byte) = iter.next() { match iter.peek() { @@ -1197,56 +760,6 @@ fn format_serial_number( result } -/// Returns a string that describes an OID. -/// -/// When the OID is unknown, returns the numeric representation for -/// the OID (i.e: "1.3.14.3.2.29"). -fn oid_to_str(oid: &ObjectIdentifier) -> Cow<'static, str> { - let oid_str = match oid { - &rfc5912::ID_SHA_1 => Some("sha1"), - &rfc5912::ID_SHA_256 => Some("sha256"), - &rfc5912::ID_SHA_384 => Some("sha384"), - &rfc5912::ID_SHA_512 => Some("sha512"), - &rfc5912::ID_MD_5 => Some("md5"), - &rfc4519::C => Some("C"), - &rfc4519::COMMON_NAME => Some("CN"), - &rfc4519::O => Some("O"), - &rfc4519::OU => Some("OU"), - &rfc4519::ST => Some("ST"), - // OIDs not included in const_oid. - &JURISDICTION_C => Some("jurisdictionC"), - &JURISDICTION_L => Some("jurisdictionL"), - &JURISDICTION_ST => Some("jurisdictionST"), - &SHA1_WITH_RSA_ENCRYPTION => Some("sha1WithRSAEncryption"), - // In the default case try to use the string representation provided by - // the `const-oid` crate. Panics if this fails. - oid => DB.by_oid(oid), - }; - - if let Some(oid) = oid_str { - Cow::Borrowed(oid) - } else { - Cow::Owned(oid.to_string()) - } -} - -/// A wrapper that implements the [`der::Writer`] trait for a [`Digest`]. -#[derive(Default)] -struct DerDigest(T); - -impl DerDigest { - pub fn finalize(self) -> Output { - self.0.finalize() - } -} - -impl der::Writer for DerDigest { - fn write(&mut self, slice: &[u8]) -> der::Result<()> { - self.0.update(slice); - Ok(()) - } -} - /// Represents a certificate chain. /// /// A certificate chain starts with an initial certificate, and contains the @@ -1254,21 +767,21 @@ impl der::Writer for DerDigest { /// signed the signer, and so on, until finding a self-signed certificate, or /// a certificate that is signed by some external certificate that is not /// contained in the PE file. -struct CertificateChain<'a> { - certs: &'a [Certificate], - next: Option<&'a Certificate>, +struct CertificateChain<'a, 'b> { + certs: &'b [X509Certificate<'a>], + next: Option<&'b X509Certificate<'a>>, } -impl<'a> CertificateChain<'a> { +impl<'a, 'b> CertificateChain<'a, 'b> { /// Creates a new certificate chain. /// /// This function receives a pool of certificates in the `certs` arguments, /// and a `predicate` that identifies the initial certificate in the chain. /// The initial certificate will be the first certificate in the pool that /// matches the predicate. - pub fn new

(certs: &'a [Certificate], predicate: P) -> Self + pub fn new

(certs: &'b [X509Certificate<'a>], predicate: P) -> Self where - P: Fn(&Certificate) -> bool, + P: Fn(&X509Certificate<'_>) -> bool, { let next = certs.iter().find(|cert| predicate(cert)); Self { certs, next } @@ -1291,6 +804,19 @@ impl<'a> CertificateChain<'a> { // iteration. for (signed, signer) in self.tuple_windows() { // The `signed` certificate is the one that will be verified. + + if x509_parser::verify::verify_signature( + &signer.subject_pki, + &signed.signature_algorithm, + &signed.signature_value, + signed.tbs_certificate.as_ref(), + ) + .is_err() + { + return false; + } + + /* let verify_info = VerifyInfo::new( signed.tbs_certificate.to_der().unwrap().into(), x509_verify::Signature::new( @@ -1313,15 +839,15 @@ impl<'a> CertificateChain<'a> { if key.verify(verify_info).is_err() { return false; - } + }*/ } true } } -impl<'a> Iterator for CertificateChain<'a> { - type Item = &'a Certificate; +impl<'a, 'b> Iterator for CertificateChain<'a, 'b> { + type Item = &'b X509Certificate<'a>; fn next(&mut self) -> Option { let next = self.next; @@ -1348,6 +874,7 @@ enum PublicKey { EcdsaP384(p384::ecdsa::VerifyingKey), } +/* impl TryFrom> for PublicKey { type Error = spki::Error; @@ -1379,7 +906,7 @@ impl TryFrom> for PublicKey { oid => Err(Self::Error::OidUnknown { oid }), } } -} +}*/ impl PublicKey { fn verify( diff --git a/lib/src/modules/pe/mod.rs b/lib/src/modules/pe/mod.rs index 4ca98b997..52b19fec5 100644 --- a/lib/src/modules/pe/mod.rs +++ b/lib/src/modules/pe/mod.rs @@ -23,6 +23,7 @@ use crate::types::Struct; #[cfg(test)] mod tests; +mod asn1; mod authenticode; pub mod parser; mod rva2off; diff --git a/lib/src/modules/pe/parser.rs b/lib/src/modules/pe/parser.rs index cd4515dcf..0a59f52c1 100644 --- a/lib/src/modules/pe/parser.rs +++ b/lib/src/modules/pe/parser.rs @@ -70,7 +70,7 @@ pub struct PE<'a> { resources: OnceCell>)>>, /// PE authenticode signatures. - signatures: OnceCell>>, + signatures: OnceCell>>>, /// PE directory entries. Directory entries are parsed lazily when /// [`PE::get_dir_entries`] is called for the first time. @@ -398,7 +398,7 @@ impl<'a> PE<'a> { } /// Returns the authenticode signatures in this PE. - pub fn get_signatures(&self) -> &[AuthenticodeSignature] { + pub fn get_signatures(&self) -> &[AuthenticodeSignature<'a>] { self.signatures .get_or_init(|| self.parse_signatures()) .as_ref() @@ -1450,7 +1450,7 @@ impl<'a> PE<'a> { } /// Parses the PE Authenticode signatures. - fn parse_signatures(&self) -> Option> { + fn parse_signatures(&self) -> Option>> { let (_, _, cert_table) = self .get_dir_entry_data(Self::IMAGE_DIRECTORY_ENTRY_SECURITY, true)?; From eac72f57f0285ca6050063580b78ac814a328633 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Thu, 25 Apr 2024 21:34:25 +0200 Subject: [PATCH 27/38] feat: advance in the implementation of Authenticode parser --- lib/src/modules/pe/asn1.rs | 48 +++++++++---- lib/src/modules/pe/authenticode.rs | 107 +++++++++++++---------------- 2 files changed, 81 insertions(+), 74 deletions(-) diff --git a/lib/src/modules/pe/asn1.rs b/lib/src/modules/pe/asn1.rs index 3551d8f2b..6edcf8ca5 100644 --- a/lib/src/modules/pe/asn1.rs +++ b/lib/src/modules/pe/asn1.rs @@ -1,3 +1,4 @@ +use array_bytes::bytes2hex; use const_oid::db::{rfc4519, rfc5912}; use const_oid::ObjectIdentifier; use der_parser::der::{ @@ -14,7 +15,9 @@ use der_parser::nom::Err::Incomplete; use der_parser::nom::{IResult, Parser}; use der_parser::num_bigint::BigUint; use der_parser::{asn1_rs, parse_der, Oid}; -use nom::combinator::map_res; +use digest::Digest; +use nom::combinator::consumed; +use sha1::Sha1; use x509_parser::certificate::X509Certificate; use x509_parser::error::X509Error; use x509_parser::prelude::{ @@ -191,6 +194,11 @@ impl<'a> TryFrom<&Any<'a>> for ContentInfo<'a> { } } +pub struct Certificate<'a> { + pub x509: X509Certificate<'a>, + pub thumbprint: String, +} + /// ```text /// SignedData ::= SEQUENCE { /// version CMSVersion, @@ -206,7 +214,10 @@ pub struct SignedData<'a> { pub version: i32, pub digest_algorithms: Vec>, pub content_info: ContentInfo<'a>, - pub certificates: Vec>, + pub certificates: Vec>, + /// In general `SignedData` can be signed by multiple signers and therefore + /// can contain multiple `SignerInfo` structures. However, in the case of + /// Authenticode there's only one signer. pub signer_infos: Vec>, } @@ -252,16 +263,27 @@ impl<'a> SignedData<'a> { fn parse_certificates( input: &[u8], - ) -> IResult<&[u8], Vec, X509Error> { + ) -> IResult<&[u8], Vec, X509Error> { let mut remainder = input; let mut certificates = Vec::new(); + + // A parser that returns both the parsed certificate, and the + // raw bytes consumed by the certificate parser. + let mut cert_parser = + consumed(|input| X509CertificateParser::new().parse(input)); + loop { - remainder = match X509CertificateParser::new().parse(remainder) { - Ok((remainder, cert)) => { - certificates.push(cert); + remainder = match cert_parser(remainder) { + Ok((remainder, (cert_bytes, cert))) => { + certificates.push(Certificate { + x509: cert, + thumbprint: bytes2hex("", Sha1::digest(cert_bytes)), + }); remainder } - Err(Incomplete(_)) => return Ok((remainder, certificates)), + Err(Incomplete(_)) => { + return Ok((remainder, certificates)); + } Err(err) => return Err(err), } } @@ -369,12 +391,12 @@ impl<'a> SignerInfo<'a> { ) -> BerResult<(X509Name, BigUint)> { parse_der_sequence_defined_g(|input: &[u8], _| { let (remainder, issuer) = X509Name::from_der(input).unwrap(); // TODO: handle error - let (remainder, serial_number) = map_res( - parse_der_integer, - |serial| serial.as_biguint(), - )(remainder)?; - - Ok((remainder, (issuer, serial_number))) + let (remainder, serial) = parse_der_integer(remainder)?; + // RFC 5280 4.1.2.2: "The serial number MUST be a positive integer" + // however, many CAs do not respect this and send integers with MSB set, + // so we do not use `as_biguint()`. + let serial = BigUint::from_bytes_be(serial.content.as_slice()?); + Ok((remainder, (issuer, serial))) })(input) } diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 3e5dbfe21..3895e8a58 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -16,13 +16,13 @@ use rsa::traits::SignatureScheme; use rsa::Pkcs1v15Sign; use sha1::Sha1; use sha2::{Sha256, Sha384, Sha512}; -use x509_parser::num_bigint::BigUint; +use x509_parser::der_parser::num_bigint::BigUint; use x509_parser::prelude::{AlgorithmIdentifier, X509Certificate}; use x509_parser::x509::X509Name; use crate::modules::pe::asn1::{ - oid, oid_to_str, Attribute, ContentInfo, DigestInfo, IndirectDataContent, - SignedData, SignerInfo, TstInfo, + oid, oid_to_str, Attribute, Certificate, ContentInfo, DigestInfo, + IndirectDataContent, SignedData, SignerInfo, TstInfo, }; use crate::modules::pe::parser::PE; use crate::modules::protos; @@ -189,7 +189,7 @@ impl AuthenticodeParser { // Get all the certificates contained in `SignedData`, more // certificates from nested signatures and countersignatures will // be added later to this vector. - let mut certificates: Vec = signed_data.certificates; + let mut certificates: Vec = signed_data.certificates; let mut nested_signatures = Vec::new(); let mut countersignatures = Vec::new(); @@ -283,7 +283,7 @@ impl AuthenticodeParser { fn parse_ms_countersignature_attr<'a>( si: &SignerInfo<'a>, attr: &Attribute<'a>, - certificates: &mut Vec>, + certificates: &mut Vec>, countersignatures: &mut Vec>, ) -> Result<(), ParseError> { for value in &attr.attr_values { @@ -332,7 +332,7 @@ impl AuthenticodeParser { fn parse_pkcs9_countersignature_attr<'a>( si: &SignerInfo<'a>, attr: &Attribute<'a>, - certificates: &mut Vec>, + certificates: &mut Vec>, countersignatures: &mut Vec>, ) -> Result<(), ParseError> { for value in &attr.attr_values { @@ -388,7 +388,7 @@ impl AuthenticodeParser { Ok(AuthenticodeCountersign { signer: si.serial_number.clone(), - digest_alg: oid_to_str(&si.digest_algorithm.oid()), + digest_alg: oid_to_str(si.digest_algorithm.oid()), digest, signing_time, verified: false, @@ -409,7 +409,7 @@ pub struct AuthenticodeSignature<'a> { signer_info_digest: &'a [u8], signer_info_verified: bool, authenticode_digest: DigestInfo<'a>, - certificates: Vec>, + certificates: Vec>, countersignatures: Vec>, //program_name: Option, computed_authenticode_hash: Vec, @@ -444,12 +444,12 @@ impl<'a> AuthenticodeSignature<'a> { } #[inline] - pub fn certificates(&self) -> &[X509Certificate<'a>] { + pub fn certificates(&self) -> &[Certificate<'a>] { self.certificates.as_slice() } #[inline] - pub fn chain(&self) -> impl Iterator> { + pub fn chain(&self) -> impl Iterator> { CertificateChain::new(self.certificates(), |cert| { cert.tbs_certificate.issuer.eq(self.issuer()) }) @@ -527,12 +527,11 @@ impl From<&AuthenticodeSignature<'_>> for protos::pe::Signature { for cs in value.countersignatures() { let mut pbcs = protos::pe::CounterSignature::from(cs); - pbcs.chain = - CertificateChain::new(value.certificates.as_slice(), |cert| { - cert.tbs_certificate.serial == cs.signer - }) - .map(protos::pe::Certificate::from) - .collect(); + pbcs.chain = CertificateChain::new(value.certificates(), |cert| { + cert.tbs_certificate.serial == cs.signer + }) + .map(protos::pe::Certificate::from) + .collect(); sig.countersignatures.push(pbcs); } @@ -598,38 +597,36 @@ impl From<&AuthenticodeCountersign<'_>> for protos::pe::CounterSignature { } } -impl From<&X509Certificate<'_>> for protos::pe::Certificate { - fn from(value: &X509Certificate) -> Self { +impl From<&Certificate<'_>> for protos::pe::Certificate { + fn from(value: &Certificate) -> Self { let mut cert = protos::pe::Certificate::new(); + // Versions are 0-based, add 1 for getting the actual version. - cert.set_version(value.tbs_certificate.version.0 as i64 + 1); + cert.set_version(value.x509.tbs_certificate.version.0 as i64 + 1); + + cert.set_issuer(format_name(&value.x509.tbs_certificate.issuer)); - cert.set_issuer(format_name(&value.tbs_certificate.issuer)); - cert.set_subject(format_name(&value.tbs_certificate.subject)); + cert.set_subject(format_name(&value.x509.tbs_certificate.subject)); - cert.set_serial(format_serial_number(&value.tbs_certificate.serial)); + cert.set_serial(value.x509.raw_serial_as_string()); cert.set_algorithm_oid(format!( "{}", - value.signature_algorithm.algorithm + value.x509.signature_algorithm.algorithm )); cert.set_algorithm( - oid_to_str(&value.signature_algorithm.algorithm).into_owned(), + oid_to_str(&value.x509.signature_algorithm.algorithm).into_owned(), ); - // The certificate thumbprint is the SHA1 of the DER-encoded certificate. - // TODO - //let mut hasher = DerDigest::::default(); - //value.encode(&mut hasher).unwrap(); - //cert.set_thumbprint(format!("{:x}", hasher.finalize())); + cert.set_thumbprint(value.thumbprint.clone()); cert.set_not_before( - value.tbs_certificate.validity.not_before.timestamp(), + value.x509.tbs_certificate.validity.not_before.timestamp(), ); cert.set_not_after( - value.tbs_certificate.validity.not_after.timestamp(), + value.x509.tbs_certificate.validity.not_after.timestamp(), ); cert @@ -689,7 +686,7 @@ fn verify_message_digest( } } -fn verify_signer_info(si: &SignerInfo, certs: &[X509Certificate]) -> bool { +fn verify_signer_info(si: &SignerInfo, certs: &[Certificate]) -> bool { match si.digest_algorithm.oid().as_bytes() { oid::SHA_1_B => verify_signed_data_impl::(si, certs), oid::SHA_256_B => verify_signed_data_impl::(si, certs), @@ -702,7 +699,7 @@ fn verify_signer_info(si: &SignerInfo, certs: &[X509Certificate]) -> bool { fn verify_signed_data_impl( si: &SignerInfo, - certs: &[X509Certificate<'_>], + certs: &[Certificate<'_>], ) -> bool { // Get a certificate chain that starts with the certificate that signed // data and contains all the certificates in the chain of truth. @@ -718,6 +715,7 @@ fn verify_signed_data_impl( // Search for the certificate that signed the digest. let signing_cert = match certs .iter() + .map(|cert| &cert.x509) .find(|cert| cert.tbs_certificate.serial.eq(&si.serial_number)) { Some(cert) => cert, @@ -743,23 +741,6 @@ fn verify_signed_data_impl( */ } -/// Produces a printable string of a serial number. -/// -/// The [`x509_cert::serial_number::SerialNumber`] type implements the -/// [`Display`] trait, but the resulting string is in uppercase. -fn format_serial_number(sn: &BigUint) -> String { - let bytes = sn.to_bytes_be(); - let mut iter = bytes.iter().peekable(); - let mut result = String::new(); - while let Some(byte) = iter.next() { - match iter.peek() { - Some(_) => write!(result, "{:02x}:", byte).unwrap(), - None => write!(result, "{:02x}", byte).unwrap(), - } - } - result -} - /// Represents a certificate chain. /// /// A certificate chain starts with an initial certificate, and contains the @@ -768,8 +749,8 @@ fn format_serial_number(sn: &BigUint) -> String { /// a certificate that is signed by some external certificate that is not /// contained in the PE file. struct CertificateChain<'a, 'b> { - certs: &'b [X509Certificate<'a>], - next: Option<&'b X509Certificate<'a>>, + certs: &'b [Certificate<'a>], + next: Option<&'b Certificate<'a>>, } impl<'a, 'b> CertificateChain<'a, 'b> { @@ -779,11 +760,12 @@ impl<'a, 'b> CertificateChain<'a, 'b> { /// and a `predicate` that identifies the initial certificate in the chain. /// The initial certificate will be the first certificate in the pool that /// matches the predicate. - pub fn new

(certs: &'b [X509Certificate<'a>], predicate: P) -> Self + pub fn new

(certs: &'b [Certificate<'a>], predicate: P) -> Self where P: Fn(&X509Certificate<'_>) -> bool, { - let next = certs.iter().find(|cert| predicate(cert)); + let next = certs.iter().find(|cert| predicate(&cert.x509)); + Self { certs, next } } @@ -806,10 +788,10 @@ impl<'a, 'b> CertificateChain<'a, 'b> { // The `signed` certificate is the one that will be verified. if x509_parser::verify::verify_signature( - &signer.subject_pki, - &signed.signature_algorithm, - &signed.signature_value, - signed.tbs_certificate.as_ref(), + &signer.x509.subject_pki, + &signed.x509.signature_algorithm, + &signed.x509.signature_value, + signed.x509.tbs_certificate.as_ref(), ) .is_err() { @@ -847,18 +829,21 @@ impl<'a, 'b> CertificateChain<'a, 'b> { } impl<'a, 'b> Iterator for CertificateChain<'a, 'b> { - type Item = &'b X509Certificate<'a>; + type Item = &'b Certificate<'a>; fn next(&mut self) -> Option { let next = self.next; if let Some(next) = self.next { // When the certificate is self-signed issuer == subject, in that // case we can't keep going up the chain. - if next.tbs_certificate.subject == next.tbs_certificate.issuer { + if next.x509.tbs_certificate.subject + == next.x509.tbs_certificate.issuer + { self.next = None } else { self.next = self.certs.iter().find(|c| { - c.tbs_certificate.subject == next.tbs_certificate.issuer + c.x509.tbs_certificate.subject + == next.x509.tbs_certificate.issuer }); } } From 0f6bfa0dca403e47c2bf12ae9a4192b90f66841b Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Fri, 26 Apr 2024 17:38:24 +0200 Subject: [PATCH 28/38] feat: advance with the implementation of Authenticode parser --- lib/Cargo.toml | 4 +- lib/src/modules/pe/asn1.rs | 117 +++++++-- lib/src/modules/pe/authenticode.rs | 237 +++++++++++------- ...cdf0663afed2728226ad5ec6707d4dd7d2e64e.out | 32 +-- ...3075d1d4ddd53f0aefa976216c46e6ba39a9f4.out | 18 +- 5 files changed, 277 insertions(+), 131 deletions(-) diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 526fc57cf..c93e7afc4 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -183,8 +183,8 @@ lazy_static = { workspace = true } linkme = { workspace = true } log = { workspace = true, optional = true } md-5 = { workspace = true, optional = true, features = ["oid"] } -sha1 = { workspace = true, optional = true } -sha2 = { workspace = true, optional = true } +sha1 = { workspace = true, optional = true, features = ["oid"] } +sha2 = { workspace = true, optional = true, features = ["oid"] } magic = { workspace = true, optional = true } memchr = { workspace = true } memx = { workspace = true } diff --git a/lib/src/modules/pe/asn1.rs b/lib/src/modules/pe/asn1.rs index 6edcf8ca5..d29112381 100644 --- a/lib/src/modules/pe/asn1.rs +++ b/lib/src/modules/pe/asn1.rs @@ -2,27 +2,26 @@ use array_bytes::bytes2hex; use const_oid::db::{rfc4519, rfc5912}; use const_oid::ObjectIdentifier; use der_parser::der::{ - parse_der_integer, parse_der_octetstring, parse_der_oid, - parse_der_sequence_defined_g, parse_der_set_of_v, - parse_der_tagged_explicit_g, DerObject, + parse_der_content, parse_der_integer, parse_der_octetstring, + parse_der_oid, parse_der_sequence_defined_g, parse_der_set_of_v, + parse_der_tagged_explicit_g, parse_der_tagged_implicit, DerObject, }; use std::borrow::Cow; -use der_parser::asn1_rs::{Any, OptTaggedParser}; +use der_parser::asn1_rs::{Any, FromDer, OptTaggedParser}; use der_parser::ber::parse_ber_any; -use der_parser::error::BerResult; +use der_parser::error::{BerError, BerResult}; use der_parser::nom::Err::Incomplete; use der_parser::nom::{IResult, Parser}; use der_parser::num_bigint::BigUint; use der_parser::{asn1_rs, parse_der, Oid}; use digest::Digest; -use nom::combinator::consumed; +use nom::branch::alt; +use nom::combinator::{consumed, map_res}; use sha1::Sha1; use x509_parser::certificate::X509Certificate; use x509_parser::error::X509Error; -use x509_parser::prelude::{ - AlgorithmIdentifier, FromDer, X509CertificateParser, -}; +use x509_parser::prelude::{AlgorithmIdentifier, X509CertificateParser}; use x509_parser::x509::X509Name; #[rustfmt::skip] @@ -378,12 +377,17 @@ impl<'a> SignerInfo<'a> { )) } - pub fn get_signed_attr(&self, oid: &Oid) -> Option<&Attribute<'a>> { - self.signed_attrs.iter().find(|attr| attr.attr_type.eq(oid)) - } - - pub fn get_unsigned_attr(&self, oid: &Oid) -> Option<&Attribute<'a>> { - self.unsigned_attrs.iter().find(|attr| attr.attr_type.eq(oid)) + /// Returns the value of the signed attribute with a given OID. + /// + /// An attribute can have multiple values, but in Authenticode + /// signatures all the attributes we need to work with have a + /// single value. This function retrieves the attribute and its + /// first value in a single step. + pub fn get_signed_attr(&self, oid: &Oid) -> Option<&Any<'a>> { + self.signed_attrs + .iter() + .find(|attr| attr.attr_type.eq(oid)) + .and_then(|attr| attr.attr_values.first()) } fn parse_issuer_and_serial_number( @@ -601,3 +605,86 @@ impl<'a> TstInfo<'a> { })(input) } } + +/// ASN.1 SpcSpOpusInfo +/// +/// SpcSpOpusInfo ::= SEQUENCE { +/// programName [0] EXPLICIT SpcString OPTIONAL, +/// moreInfo [1] EXPLICIT SpcLink OPTIONAL, +/// } +pub struct SpcSpOpusInfo { + pub program_name: Option, +} + +impl SpcSpOpusInfo { + pub fn parse(input: &[u8]) -> BerResult { + parse_der_sequence_defined_g(|input: &[u8], _| { + Self::parse_inner(input) + })(input) + } + + fn parse_inner(input: &[u8]) -> BerResult { + let (remainder, program_name) = OptTaggedParser::from(0) + .parse_der(input, |_, content| Self::parse_spc_string(content))?; + + let (remainder, more_info) = + OptTaggedParser::from(1).parse_der(remainder, |_, content| { + let (rem, value) = parse_der(content)?; + Ok((rem, value)) + })?; + + Ok((remainder, Self { program_name })) + } + + fn parse_spc_string(input: &[u8]) -> BerResult { + alt(( + map_res( + parse_der_tagged_implicit( + 0, + parse_der_content(der_parser::der::Tag::BmpString), + ), + |s| { + string_from_utf16be(s.as_slice()?) + .ok_or(BerError::BerValueError) + }, + ), + map_res( + parse_der_tagged_implicit( + 1, + parse_der_content(der_parser::der::Tag::Ia5String), + ), + |s| Ok::(String::from(s.as_str()?)), + ), + ))(input) + } +} + +impl TryFrom<&Any<'_>> for SpcSpOpusInfo { + type Error = asn1_rs::Error; + + fn try_from(any: &Any) -> Result { + Ok(Self::parse_inner(any.data).map(|(_, ci)| ci)?) + } +} + +/// Tries to create a string from a byte slice that contains the UTF-16BE +/// representation of the string. +/// +/// There's a `String::from_utf16be` function that is currently unstable. If +/// it becomes stable we can use it and remove this function. +/// +/// https://doc.rust-lang.org/alloc/string/struct.String.html#method.from_utf16be +fn string_from_utf16be(v: &[u8]) -> Option { + if v.len() % 2 != 0 { + return None; + } + + let codepoints = v + .chunks_exact(2) + .map(|chunk| u16::from_be_bytes([chunk[0], chunk[1]])); + + let x: String = + char::decode_utf16(codepoints).collect::>().ok()?; + + Some(x) +} diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 3895e8a58..fa1f36085 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -2,27 +2,31 @@ use std::borrow::Cow; use std::fmt::Write; use array_bytes::bytes2hex; -use const_oid::AssociatedOid; -use der::asn1; +use const_oid::db::{rfc5912, rfc6268}; +use const_oid::{AssociatedOid, ObjectIdentifier}; use der::Decode; -use der_parser::asn1_rs::{Set, ToDer}; +use der_parser::asn1_rs::{Set, Tag, ToDer, UtcTime}; use digest::Digest; + use ecdsa::signature::hazmat::PrehashVerifier; use itertools::Itertools; use md5::Md5; use nom::AsBytes; use protobuf::MessageField; + use rsa::traits::SignatureScheme; use rsa::Pkcs1v15Sign; use sha1::Sha1; use sha2::{Sha256, Sha384, Sha512}; +use thiserror::Error; use x509_parser::der_parser::num_bigint::BigUint; use x509_parser::prelude::{AlgorithmIdentifier, X509Certificate}; -use x509_parser::x509::X509Name; +use x509_parser::x509::{SubjectPublicKeyInfo, X509Name}; use crate::modules::pe::asn1::{ - oid, oid_to_str, Attribute, Certificate, ContentInfo, DigestInfo, - IndirectDataContent, SignedData, SignerInfo, TstInfo, + oid, oid_to_object_identifier, oid_to_str, Attribute, Certificate, + ContentInfo, DigestInfo, IndirectDataContent, SignedData, SignerInfo, + SpcSpOpusInfo, TstInfo, }; use crate::modules::pe::parser::PE; use crate::modules::protos; @@ -154,7 +158,6 @@ impl AuthenticodeParser { let signer_info_digest = match signer_info .get_signed_attr(&oid::MESSAGE_DIGEST) - .and_then(|attr| attr.attr_values.first()) .map(|value| value.data.as_bytes()) { Some(md) => md, @@ -165,19 +168,16 @@ impl AuthenticodeParser { } }; - let signer_info_verified = verify_message_digest( - &signer_info.digest_algorithm, - signed_data.content_info.content.data, - signer_info_digest, - ) && verify_signer_info( - &signer_info, - signed_data.certificates.as_slice(), - ); - if signer_info.get_signed_attr(&oid::CONTENT_TYPE).is_none() { return Err(ParseError::MissingContentTypeAuthenticatedAttribute); } + let opus_info: Option = signer_info + .get_signed_attr(&oid::OPUS_INFO_OBJID) + .and_then(|value| value.try_into().ok()); + + let signed_data_raw = signed_data.content_info.content.data; + let indirect_data: IndirectDataContent = match signed_data.content_info.content.try_into() { Ok(idc) => idc, @@ -262,17 +262,37 @@ impl AuthenticodeParser { oid => unimplemented!("{:?}", oid), }; + let authenticode_digest = indirect_data.message_digest; + + // The Authenticode signature is verified if: + // + // * The hash stored in the Authenticode signature matches the actual + // hash that we computed by ourselves. + // * The content of the `SignedData` structure (which contains the + // authenticode hash) has not been tampered. This is verified by + // comparing the hash of the content with the one stored in the + // signed attribute MESSAGE_DIGEST stored in `SignerInfo`. + // * The `SignerInfo` struct has not been tampered, which is verified + // by `verify_signer_info`. + let verified = authenticode_digest.digest == file_digest.as_slice() + && verify_message_digest( + &signer_info.digest_algorithm, + signed_data_raw, + signer_info_digest, + ) + && verify_signer_info(&signer_info, certificates.as_slice()); + let mut signatures = Vec::with_capacity(nested_signatures.len() + 1); signatures.push(AuthenticodeSignature { computed_authenticode_hash: file_digest, - //program_name: None, //opus_info.and_then(|oi| oi.program_name), - authenticode_digest: indirect_data.message_digest, + program_name: opus_info.and_then(|oi| oi.program_name), + authenticode_digest, signer_info, signer_info_digest, - signer_info_verified, countersignatures, certificates, + verified, }); signatures.append(&mut nested_signatures); @@ -361,18 +381,18 @@ impl AuthenticodeParser { let mut signing_time = None; for attr in &si.signed_attrs { - match attr.attr_type.as_bytes() { - oid::MESSAGE_DIGEST_B => { - if let Some(value) = attr.attr_values.first() { - digest = Some(value.data) - } + match oid_to_object_identifier(&attr.attr_type) { + rfc6268::ID_MESSAGE_DIGEST => { + digest = attr.attr_values.first().map(|v| v.data); + } + rfc6268::ID_SIGNING_TIME => { + signing_time = attr + .attr_values + .first() + .and_then(|v| v.try_into().ok()) + .and_then(|t: UtcTime| t.utc_adjusted_datetime().ok()) + .map(|t| t.unix_timestamp()); } - /* => { - if let Some(value) = attr.values.get(0) { - signing_time = - value.decode_as::().ok(); - } - }*/ _ => {} } } @@ -400,19 +420,19 @@ pub struct AuthenticodeCountersign<'a> { signer: BigUint, digest_alg: Cow<'static, str>, digest: &'a [u8], - signing_time: Option, + signing_time: Option, verified: bool, } pub struct AuthenticodeSignature<'a> { signer_info: SignerInfo<'a>, signer_info_digest: &'a [u8], - signer_info_verified: bool, authenticode_digest: DigestInfo<'a>, certificates: Vec>, countersignatures: Vec>, - //program_name: Option, + program_name: Option, computed_authenticode_hash: Vec, + verified: bool, } impl<'a> AuthenticodeSignature<'a> { @@ -493,22 +513,8 @@ impl<'a> AuthenticodeSignature<'a> { /// validated, until we found a self-signed certificate or a certificate /// that is not included in the PE file. This last certificate is always /// considered valid. - pub fn verify(&self) -> bool { - if !self.signer_info_verified - || self.computed_authenticode_hash() - != self.stored_authenticode_hash() - { - return false; - } - - return true; - - // TODO - /* - verify_signer_info( - &self.signed_data.signer_infos.0[0], - self.certificates(), - )*/ + pub fn verified(&self) -> bool { + self.verified } } @@ -519,7 +525,7 @@ impl From<&AuthenticodeSignature<'_>> for protos::pe::Signature { sig.set_digest(bytes2hex("", value.stored_authenticode_hash())); sig.set_digest_alg(value.authenticode_hash_algorithm().into_owned()); sig.set_file_digest(bytes2hex("", value.computed_authenticode_hash())); - sig.set_verified(value.verify()); + sig.set_verified(value.verified()); sig.certificates.extend( value.certificates().iter().map(protos::pe::Certificate::from), @@ -550,9 +556,9 @@ impl From<&AuthenticodeSignature<'_>> for protos::pe::Signature { signer_info.set_digest(value.signer_info_digest()); - //if let Some(program_name) = &value.program_name { - // signer_info.set_program_name(program_name.to_string()) - //} + if let Some(program_name) = &value.program_name { + signer_info.set_program_name(program_name.clone()) + } signer_info .chain @@ -589,9 +595,7 @@ impl From<&AuthenticodeCountersign<'_>> for protos::pe::CounterSignature { cs.set_digest(bytes2hex("", value.digest)); cs.set_digest_alg(value.digest_alg.to_string()); cs.set_verified(value.verified); - - cs.sign_time = - value.signing_time.map(|t| t.to_unix_duration().as_secs() as i64); + cs.sign_time = value.signing_time; cs } @@ -635,15 +639,15 @@ impl From<&Certificate<'_>> for protos::pe::Certificate { /// Produces a printable string for a x509 name. /// -/// The [`x509_cert::name::Name`] type implements the [`std::fmt::Display`] -/// trait, but the resulting string follows the [RFC 4514], resulting in -/// something like: +/// The [`X509Name`] type implements the [`std::fmt::Display`] trait, but the +/// resulting string follows the [RFC 4514], resulting in something like: /// /// ```text /// CN=Thawte Timestamping CA,OU=Thawte Certification,O=Thawte,L=Durbanville,ST=Western Cape,C=ZA /// ``` /// -/// However, the format traditionally used by YARA is inherited from OpenSSL and looks like: +/// However, the format traditionally used by YARA is inherited from OpenSSL +/// and looks like: /// /// ```text /// /C=ZA/ST=Western Cape/L=Durbanville/O=Thawte/OU=Thawte Certification/CN=Thawte Timestamping CA @@ -656,11 +660,36 @@ fn format_name(name: &X509Name) -> String { write!(n, "/").unwrap(); for atv in rdn.iter() { let key = oid_to_str(atv.attr_type()); - let val = atv.as_str().ok(); - if let (key, Some(val)) = (key, val) { - write!(n, "{}=", key).unwrap(); - for char in val.chars() { - n.write_char(char).unwrap(); + let attr_val = atv.attr_value(); + // Not using `atv.as_str()` because it doesn't take into account + // the `Tag::TeletexString` case. + let val = match attr_val.tag() { + Tag::PrintableString => { + attr_val.as_printablestring().ok().map(|s| s.string()) + } + Tag::Utf8String => { + attr_val.as_utf8string().ok().map(|s| s.string()) + } + Tag::Ia5String => { + attr_val.as_ia5string().ok().map(|s| s.string()) + } + Tag::TeletexString => { + attr_val.as_teletexstring().ok().map(|s| s.string()) + } + _ => None, + }; + match (key, val) { + (key, Some(val)) => { + write!(n, "{}=", key).unwrap(); + for char in val.chars() { + n.write_char(char).unwrap(); + } + } + (key, None) => { + write!(n, "{}=#", key).unwrap(); + for c in attr_val.data { + write!(n, "{:02x}", c).unwrap(); + } } } } @@ -697,7 +726,7 @@ fn verify_signer_info(si: &SignerInfo, certs: &[Certificate]) -> bool { } } -fn verify_signed_data_impl( +fn verify_signed_data_impl( si: &SignerInfo, certs: &[Certificate<'_>], ) -> bool { @@ -725,20 +754,15 @@ fn verify_signed_data_impl( let attrs_set = Set::new(Cow::Borrowed(si.raw_signed_attrs)); let attrs_set_der = attrs_set.to_der_vec_raw().unwrap(); - false - - // TODO - /* // Obtain the public key included in the certificate. let key = - match PublicKey::try_from(signing_cert.tbs_certificate.subject_pki) { + match PublicKey::try_from(&signing_cert.tbs_certificate.subject_pki) { Ok(key) => key, Err(_) => return false, }; // Verify that the signature in SignerInfo.signature is correct. key.verify::(attrs_set_der.as_slice(), si.signature_value) - */ } /// Represents a certificate chain. @@ -859,39 +883,74 @@ enum PublicKey { EcdsaP384(p384::ecdsa::VerifyingKey), } -/* -impl TryFrom> for PublicKey { - type Error = spki::Error; +#[derive(Error, Debug)] +enum PublicKeyError { + #[error("PKCS1 error")] + Pkcs1(#[from] rsa::pkcs1::Error), + + #[error("Missing ECDSA algorithm parameters")] + Der(#[from] der_parser::error::Error), - fn try_from(value: SubjectPublicKeyInfoRef) -> Result { - match value.algorithm.oid { + #[error("ECDSA error")] + Ecdsa(#[from] ecdsa::Error), + + #[error("Missing ECDSA algorithm parameters")] + MissingAlgorithmParameters, + + #[error("Unknown ECDSA curve")] + UnknownEcdsaCurve(ObjectIdentifier), + + #[error("Unknown encryption algorithm")] + UnknownAlgorithm(ObjectIdentifier), +} + +impl TryFrom<&SubjectPublicKeyInfo<'_>> for PublicKey { + type Error = PublicKeyError; + + fn try_from( + value: &SubjectPublicKeyInfo<'_>, + ) -> Result { + match oid_to_object_identifier(value.algorithm.oid()) { rfc5912::RSA_ENCRYPTION => { - Ok(Self::Rsa(rsa::RsaPublicKey::try_from(value)?)) + use rsa::pkcs1::DecodeRsaPublicKey; + Ok(Self::Rsa(rsa::RsaPublicKey::from_pkcs1_der( + value.subject_public_key.as_ref(), + )?)) } rfc5912::ID_DSA => { - Ok(Self::Dsa(dsa::VerifyingKey::try_from(value)?)) + todo!() + //use dsa::pkcs8::DecodePublicKey; + //let key = dsa::VerifyingKey::from_public_key_der( + // value.subject_public_key.as_ref(), + //)?; + //Ok(Self::Dsa(key)) } rfc5912::ID_EC_PUBLIC_KEY => { - match value + let curve: der_parser::asn1_rs::Oid = value .algorithm .parameters - .ok_or(Self::Error::AlgorithmParametersMissing)? - .decode_as::() - .map_err(Self::Error::Asn1)? - { + .as_ref() + .ok_or(Self::Error::MissingAlgorithmParameters)? + .try_into()?; + + match oid_to_object_identifier(&curve) { rfc5912::SECP_256_R_1 => Ok(Self::EcdsaP256( - p256::ecdsa::VerifyingKey::try_from(value)?, + p256::ecdsa::VerifyingKey::try_from( + value.subject_public_key.as_ref(), + )?, )), rfc5912::SECP_384_R_1 => Ok(Self::EcdsaP384( - p384::ecdsa::VerifyingKey::try_from(value)?, + p384::ecdsa::VerifyingKey::try_from( + value.subject_public_key.as_ref(), + )?, )), - oid => Err(Self::Error::OidUnknown { oid }), + oid => Err(Self::Error::UnknownEcdsaCurve(oid)), } } - oid => Err(Self::Error::OidUnknown { oid }), + oid => Err(Self::Error::UnknownAlgorithm(oid)), } } -}*/ +} impl PublicKey { fn verify( diff --git a/lib/src/modules/pe/tests/testdata/6d3bbd6f3b6e11d83526c08e3ccdf0663afed2728226ad5ec6707d4dd7d2e64e.out b/lib/src/modules/pe/tests/testdata/6d3bbd6f3b6e11d83526c08e3ccdf0663afed2728226ad5ec6707d4dd7d2e64e.out index a00a07125..23c5760ed 100644 --- a/lib/src/modules/pe/tests/testdata/6d3bbd6f3b6e11d83526c08e3ccdf0663afed2728226ad5ec6707d4dd7d2e64e.out +++ b/lib/src/modules/pe/tests/testdata/6d3bbd6f3b6e11d83526c08e3ccdf0663afed2728226ad5ec6707d4dd7d2e64e.out @@ -234,15 +234,15 @@ signatures: serial: "00:d5:b3:60:02:89:59:a2:7f:84:65:c9:e6:b1:8d:ba:cb" not_before: 1677542400 # 2023-02-28 00:00:00 UTC not_after: 1861919999 # 2028-12-31 23:59:59 UTC - - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA" - subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Trusted Root G4" - thumbprint: "a99d5b79e9f1cda59cdab6373169d5353f5874c6" + - issuer: "/C=US/O=DigiCert, Inc./CN=DigiCert Trusted G4 RSA4096 SHA256 TimeStamping CA" + subject: "/C=US/O=DigiCert, Inc./CN=DigiCert Timestamp 2023" + thumbprint: "66f02b32c2c2c90f825dceaa8ac9c64f199ccf40" version: 3 - algorithm: "sha384WithRSAEncryption" - algorithm_oid: "1.2.840.113549.1.1.12" - serial: "0e:9b:18:8e:f9:d0:2d:e7:ef:db:50:e2:08:40:18:5a" - not_before: 1659312000 # 2022-08-01 00:00:00 UTC - not_after: 1952035199 # 2031-11-09 23:59:59 UTC + algorithm: "sha256WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.11" + serial: "05:44:af:f3:94:9d:08:39:a6:bf:db:3f:5f:e5:61:16" + not_before: 1689292800 # 2023-07-14 00:00:00 UTC + not_after: 2044396799 # 2034-10-13 23:59:59 UTC - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Trusted Root G4" subject: "/C=US/O=DigiCert, Inc./CN=DigiCert Trusted G4 RSA4096 SHA256 TimeStamping CA" thumbprint: "b6c8af834d4e53b673c76872aa8c950c7c54df5f" @@ -252,15 +252,15 @@ signatures: serial: "07:36:37:b7:24:54:7c:d8:47:ac:fd:28:66:2a:5e:5b" not_before: 1647993600 # 2022-03-23 00:00:00 UTC not_after: 2121379199 # 2037-03-22 23:59:59 UTC - - issuer: "/C=US/O=DigiCert, Inc./CN=DigiCert Trusted G4 RSA4096 SHA256 TimeStamping CA" - subject: "/C=US/O=DigiCert, Inc./CN=DigiCert Timestamp 2023" - thumbprint: "66f02b32c2c2c90f825dceaa8ac9c64f199ccf40" + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA" + subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Trusted Root G4" + thumbprint: "a99d5b79e9f1cda59cdab6373169d5353f5874c6" version: 3 - algorithm: "sha256WithRSAEncryption" - algorithm_oid: "1.2.840.113549.1.1.11" - serial: "05:44:af:f3:94:9d:08:39:a6:bf:db:3f:5f:e5:61:16" - not_before: 1689292800 # 2023-07-14 00:00:00 UTC - not_after: 2044396799 # 2034-10-13 23:59:59 UTC + algorithm: "sha384WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.12" + serial: "0e:9b:18:8e:f9:d0:2d:e7:ef:db:50:e2:08:40:18:5a" + not_before: 1659312000 # 2022-08-01 00:00:00 UTC + not_after: 1952035199 # 2031-11-09 23:59:59 UTC countersignatures: - verified: true sign_time: 1712829194 # 2024-04-11 09:53:14 UTC diff --git a/lib/src/modules/pe/tests/testdata/70211a3f90376bbc61f49c22a63075d1d4ddd53f0aefa976216c46e6ba39a9f4.out b/lib/src/modules/pe/tests/testdata/70211a3f90376bbc61f49c22a63075d1d4ddd53f0aefa976216c46e6ba39a9f4.out index bb5f17c96..1ac50de2e 100644 --- a/lib/src/modules/pe/tests/testdata/70211a3f90376bbc61f49c22a63075d1d4ddd53f0aefa976216c46e6ba39a9f4.out +++ b/lib/src/modules/pe/tests/testdata/70211a3f90376bbc61f49c22a63075d1d4ddd53f0aefa976216c46e6ba39a9f4.out @@ -587,15 +587,6 @@ signatures: serial: "0b:7e:10:90:3c:38:49:0f:fa:2f:67:9a:87:a1:a7:b9" not_before: 1382443200 # 2013-10-22 12:00:00 UTC not_after: 1855828800 # 2028-10-22 12:00:00 UTC - - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA" - subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Assured ID Timestamping CA" - thumbprint: "3ba63a6e4841355772debef9cdcf4d5af353a297" - version: 3 - algorithm: "sha256WithRSAEncryption" - algorithm_oid: "1.2.840.113549.1.1.11" - serial: "0a:a1:25:d6:d6:32:1b:7e:41:e4:05:da:36:97:c2:15" - not_before: 1452168000 # 2016-01-07 12:00:00 UTC - not_after: 1925553600 # 2031-01-07 12:00:00 UTC - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Assured ID Timestamping CA" subject: "/C=US/O=DigiCert, Inc./CN=DigiCert SHA2 Timestamp Responder" thumbprint: "c636f4dda87cee3d8263bf9a2514b4533468d75e" @@ -605,6 +596,15 @@ signatures: serial: "02:ce:42:94:59:02:a4:f3:c0:40:b0:ff:77:93:d1:4f" not_before: 1450915200 # 2015-12-24 00:00:00 UTC not_after: 1736208000 # 2025-01-07 00:00:00 UTC + - issuer: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA" + subject: "/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Assured ID Timestamping CA" + thumbprint: "3ba63a6e4841355772debef9cdcf4d5af353a297" + version: 3 + algorithm: "sha256WithRSAEncryption" + algorithm_oid: "1.2.840.113549.1.1.11" + serial: "0a:a1:25:d6:d6:32:1b:7e:41:e4:05:da:36:97:c2:15" + not_before: 1452168000 # 2016-01-07 12:00:00 UTC + not_after: 1925553600 # 2031-01-07 12:00:00 UTC countersignatures: - verified: true sign_time: 1459189265 # 2016-03-28 18:21:05 UTC From 637449661656e4f7873fa2a3941b3642aa1c33c8 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Fri, 26 Apr 2024 21:10:15 +0200 Subject: [PATCH 29/38] refactor: more refactoring and code cleaning --- lib/Cargo.toml | 8 +- lib/src/modules/pe/asn1.rs | 340 +++++++++++++++-------------- lib/src/modules/pe/authenticode.rs | 240 ++++++++++---------- 3 files changed, 303 insertions(+), 285 deletions(-) diff --git a/lib/Cargo.toml b/lib/Cargo.toml index c93e7afc4..846eb796a 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -49,6 +49,12 @@ logging = ["dep:log"] # scan. Notice that profiling itself has a noticeable impact on performance. rules-profiling = ["logging"] + +# When enabled use the logic included in the `x509-parser` crate for verifying +# certificates. If not enabled we use our ouwn logic. This is disabled by +# default. +x509-parser-verify = ['x509-parser/verify'] + # Features for enabling/disabling modules. # # For each module we have a `-module` feature that controls whether @@ -207,7 +213,7 @@ tlsh-fixed = { workspace = true, optional = true } uuid = { workspace = true, optional = true, features = ["v4"] } walrus = { workspace = true } wasmtime = { workspace = true, features = ["cranelift", "parallel-compilation"] } -x509-parser = { workspace = true, optional = true, features = ["verify"] } +x509-parser = { workspace = true, optional = true } yansi = { workspace = true } yara-x-macros = { workspace = true } yara-x-parser = { workspace = true } diff --git a/lib/src/modules/pe/asn1.rs b/lib/src/modules/pe/asn1.rs index d29112381..fa87a6a4c 100644 --- a/lib/src/modules/pe/asn1.rs +++ b/lib/src/modules/pe/asn1.rs @@ -1,24 +1,25 @@ +use std::borrow::Cow; + use array_bytes::bytes2hex; use const_oid::db::{rfc4519, rfc5912}; use const_oid::ObjectIdentifier; -use der_parser::der::{ - parse_der_content, parse_der_integer, parse_der_octetstring, - parse_der_oid, parse_der_sequence_defined_g, parse_der_set_of_v, - parse_der_tagged_explicit_g, parse_der_tagged_implicit, DerObject, -}; -use std::borrow::Cow; -use der_parser::asn1_rs::{Any, FromDer, OptTaggedParser}; -use der_parser::ber::parse_ber_any; +use der_parser::asn1_rs::{Any, FromBer, FromDer, OptTaggedParser}; +use der_parser::ber::*; +use der_parser::error::Error::BerValueError; use der_parser::error::{BerError, BerResult}; +use der_parser::nom; +use der_parser::nom::branch::alt; +use der_parser::nom::combinator::{consumed, map_res}; use der_parser::nom::Err::Incomplete; -use der_parser::nom::{IResult, Parser}; +use der_parser::nom::IResult; +use der_parser::nom::Parser; use der_parser::num_bigint::BigUint; -use der_parser::{asn1_rs, parse_der, Oid}; +use der_parser::{asn1_rs, parse_ber, Oid}; + use digest::Digest; -use nom::branch::alt; -use nom::combinator::{consumed, map_res}; use sha1::Sha1; + use x509_parser::certificate::X509Certificate; use x509_parser::error::X509Error; use x509_parser::prelude::{AlgorithmIdentifier, X509CertificateParser}; @@ -161,19 +162,19 @@ pub struct ContentInfo<'a> { impl<'a> ContentInfo<'a> { pub fn parse(data: &'a [u8]) -> BerResult { - parse_der_sequence_defined_g(|i, _| Self::parse_inner(i))(data) + parse_ber_sequence_defined_g(|i, _| Self::parse_inner(i))(data) } - pub fn from_der( + pub fn from_ber( data: &'a [u8], ) -> Result> { Self::parse(data).map(|(_, content_info)| content_info) } fn parse_inner(data: &'a [u8]) -> BerResult { - let (remainder, content_type) = parse_der_oid(data)?; + let (remainder, content_type) = parse_ber_oid(data)?; let (remainder, content) = - parse_der_tagged_explicit_g(0, |content, _| { + parse_ber_tagged_explicit_g(0, |content, _| { parse_ber_any(content) })(remainder)?; @@ -198,17 +199,24 @@ pub struct Certificate<'a> { pub thumbprint: String, } +/// [SignedData][1] structure. +/// /// ```text /// SignedData ::= SEQUENCE { -/// version CMSVersion, -/// digestAlgorithms DigestAlgorithmIdentifiers, -/// encapContentInfo EncapsulatedContentInfo, -/// certificates [0] IMPLICIT CertificateSet OPTIONAL, -/// crls [1] IMPLICIT RevocationInfoChoices OPTIONAL, -/// signerInfos SignerInfos } +/// version CMSVersion, +/// digestAlgorithms DigestAlgorithmIdentifiers, +/// encapContentInfo EncapsulatedContentInfo, +/// certificates [0] IMPLICIT CertificateSet OPTIONAL, +/// crls [1] IMPLICIT RevocationInfoChoices OPTIONAL, +/// signerInfos SignerInfos +/// } +/// +/// DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier +/// +/// SignerInfos ::= SET OF SignerInfo /// ``` /// -/// https://datatracker.ietf.org/doc/html/rfc5652#section-5.1 +/// [1]: https://datatracker.ietf.org/doc/html/rfc5652#section-5.1 pub struct SignedData<'a> { pub version: i32, pub digest_algorithms: Vec>, @@ -222,31 +230,31 @@ pub struct SignedData<'a> { impl<'a> SignedData<'a> { pub fn parse(input: &'a [u8]) -> BerResult { - parse_der_sequence_defined_g(|input: &[u8], _| { + parse_ber_sequence_defined_g(|input: &[u8], _| { Self::parse_inner(input) })(input) } fn parse_inner(input: &'a [u8]) -> BerResult { - let (remainder, version) = parse_der_integer(input)?; + let (remainder, version) = parse_ber_integer(input)?; let (remainder, digest_algorithms) = - parse_der_set_of_v(AlgorithmIdentifier::from_der)(remainder) - .unwrap(); // TODO: handle error + parse_ber_set_of_v(AlgorithmIdentifier::from_ber)(remainder) + .map_err(|_| BerValueError)?; let (remainder, content_info) = ContentInfo::parse(remainder)?; let (remainder, certificates) = OptTaggedParser::from(0) - .parse_der(remainder, |_, raw_certs| { + .parse_ber(remainder, |_, raw_certs| { Self::parse_certificates(raw_certs) }) - .unwrap(); // TODO:: handle error + .map_err(|_| BerValueError)?; let (remainder, _revocation_info) = OptTaggedParser::from(1) - .parse_der(remainder, |_, data| parse_der(data))?; + .parse_ber(remainder, |_, data| parse_ber(data))?; let (remainder, signer_infos) = - parse_der_set_of_v(SignerInfo::parse)(remainder)?; + parse_ber_set_of_v(SignerInfo::parse)(remainder)?; Ok(( remainder, @@ -298,18 +306,21 @@ impl<'a> TryFrom> for SignedData<'a> { } } +/// [SignerInfo][1] structure. +/// /// ```text /// SignerInfo ::= SEQUENCE { -/// version CMSVersion, -/// sid SignerIdentifier, -/// digestAlgorithm DigestAlgorithmIdentifier, -/// signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, -/// signatureAlgorithm SignatureAlgorithmIdentifier, -/// signature SignatureValue, -/// unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL } +/// version CMSVersion, +/// sid SignerIdentifier, +/// digestAlgorithm DigestAlgorithmIdentifier, +/// signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, +/// signatureAlgorithm SignatureAlgorithmIdentifier, +/// signature SignatureValue, +/// unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL +/// } /// ``` /// -/// https://datatracker.ietf.org/doc/html/rfc5652#section-5.3 +/// [1]: https://datatracker.ietf.org/doc/html/rfc5652#section-5.3 pub struct SignerInfo<'a> { pub version: i32, pub issuer: X509Name<'a>, @@ -324,21 +335,22 @@ pub struct SignerInfo<'a> { impl<'a> SignerInfo<'a> { pub fn parse(input: &'a [u8]) -> BerResult { - parse_der_sequence_defined_g(|input: &[u8], _| { + parse_ber_sequence_defined_g(|input: &[u8], _| { Self::parse_inner(input) })(input) } pub fn parse_inner(input: &'a [u8]) -> BerResult { - let (remainder, version) = parse_der_integer(input)?; + let (remainder, version) = parse_ber_integer(input)?; let (remainder, (issuer, serial_number)) = Self::parse_issuer_and_serial_number(remainder)?; let (remainder, digest_algorithm) = - AlgorithmIdentifier::from_der(remainder).unwrap(); // TODO: handle error + AlgorithmIdentifier::from_ber(remainder) + .map_err(|_| BerValueError)?; - let (remainder, signed_attrs) = OptTaggedParser::from(0).parse_der( + let (remainder, signed_attrs) = OptTaggedParser::from(0).parse_ber( remainder, |_, raw_attrs| { let (remainder, parsed_attrs) = @@ -349,12 +361,13 @@ impl<'a> SignerInfo<'a> { )?; let (remainder, signature_algorithm) = - AlgorithmIdentifier::from_der(remainder).unwrap(); // TODO: handle error + AlgorithmIdentifier::from_ber(remainder) + .map_err(|_| BerValueError)?; - let (remainder, signature) = parse_der_octetstring(remainder)?; + let (remainder, signature) = parse_ber_octetstring(remainder)?; let (remainder, unsigned_attrs) = OptTaggedParser::from(1) - .parse_der(remainder, |_, raw_attrs| { + .parse_ber(remainder, |_, raw_attrs| { Self::parse_attributes(raw_attrs) })?; @@ -393,13 +406,17 @@ impl<'a> SignerInfo<'a> { fn parse_issuer_and_serial_number( input: &[u8], ) -> BerResult<(X509Name, BigUint)> { - parse_der_sequence_defined_g(|input: &[u8], _| { - let (remainder, issuer) = X509Name::from_der(input).unwrap(); // TODO: handle error - let (remainder, serial) = parse_der_integer(remainder)?; + parse_ber_sequence_defined_g(|input: &[u8], _| { + let (remainder, issuer) = + X509Name::from_der(input).map_err(|_| BerValueError)?; + + let (remainder, serial) = parse_ber_integer(remainder)?; + // RFC 5280 4.1.2.2: "The serial number MUST be a positive integer" - // however, many CAs do not respect this and send integers with MSB set, - // so we do not use `as_biguint()`. + // however, many CAs do not respect this and send integers with MSB + // set, so we do not use `as_biguint()`. let serial = BigUint::from_bytes_be(serial.content.as_slice()?); + Ok((remainder, (issuer, serial))) })(input) } @@ -429,38 +446,18 @@ impl<'a> TryFrom<&Any<'a>> for SignerInfo<'a> { } } -/// ```text -/// AlgorithmIdentifier ::= SEQUENCE { -/// algorithm OBJECT IDENTIFIER, -/// parameters ANY DEFINED BY algorithm OPTIONAL } -/// ``` +/// [Attribute][1] structure. /// -/// https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.1.2 -#[derive(Debug)] -pub struct MyAlgorithmIdentifier<'a> { - pub oid: Oid<'a>, - pub parameters: DerObject<'a>, -} - -impl<'a> MyAlgorithmIdentifier<'a> { - pub fn parse(input: &'a [u8]) -> BerResult { - parse_der_sequence_defined_g(|input: &[u8], _| { - let (remainder, algorithm) = parse_der_oid(input)?; - let (remainder, parameters) = parse_der(remainder)?; - Ok((remainder, Self { oid: algorithm.as_oid_val()?, parameters })) - })(input) - } -} - /// ```text /// Attribute ::= SEQUENCE { -/// attrType OBJECT IDENTIFIER, -/// attrValues SET OF AttributeValue } +/// attrType OBJECT IDENTIFIER, +/// attrValues SET OF AttributeValue +/// } /// -/// AttributeValue ::= ANY +/// AttributeValue ::= ANY /// ``` /// -/// https://datatracker.ietf.org/doc/html/rfc5652#section-5.3 +/// [1]: https://datatracker.ietf.org/doc/html/rfc5652#section-5.3 pub struct Attribute<'a> { pub attr_type: Oid<'a>, pub attr_values: Vec>, @@ -468,10 +465,10 @@ pub struct Attribute<'a> { impl<'a> Attribute<'a> { pub fn parse(input: &'a [u8]) -> BerResult { - parse_der_sequence_defined_g(|data: &[u8], _| { - let (remainder, attr_type) = parse_der_oid(data)?; + parse_ber_sequence_defined_g(|data: &[u8], _| { + let (remainder, attr_type) = parse_ber_oid(data)?; let (remainder, attr_values) = - parse_der_set_of_v(parse_ber_any)(remainder)?; + parse_ber_set_of_v(parse_ber_any)(remainder)?; Ok(( remainder, @@ -481,47 +478,54 @@ impl<'a> Attribute<'a> { } } -/// ASN.1 SpcIndirectDataContent +/// [SpcIndirectDataContent][1] structure. /// +/// ```text /// SpcIndirectDataContent ::= SEQUENCE { -/// data SpcAttributeTypeAndOptionalValue, -/// messageDigest DigestInfo +/// data SpcAttributeTypeAndOptionalValue, +/// messageDigest DigestInfo /// } +/// ``` /// -pub struct IndirectDataContent<'a> { +/// [1]: https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-oshared/1537695a-28f0-4828-8b7b-d6dab62b8030 +pub struct SpcIndirectDataContent<'a> { pub message_digest: DigestInfo<'a>, } -impl<'a> IndirectDataContent<'a> { +impl<'a> SpcIndirectDataContent<'a> { pub fn parse(input: &'a [u8]) -> BerResult { - parse_der_sequence_defined_g(|input: &[u8], _| { + parse_ber_sequence_defined_g(|input: &[u8], _| { Self::parse_inner(input) })(input) } pub fn parse_inner(input: &'a [u8]) -> BerResult { - let (remainder, _data) = parse_der(input)?; + let (remainder, _data) = parse_ber(input)?; let (remainder, message_digest) = DigestInfo::parse(remainder)?; Ok((remainder, Self { message_digest })) } } -impl<'a> TryFrom> for IndirectDataContent<'a> { +impl<'a> TryFrom> for SpcIndirectDataContent<'a> { type Error = asn1_rs::Error; fn try_from(any: Any<'a>) -> Result { - any.tag().assert_eq(asn1_rs::Tag::Sequence)?; + any.tag().assert_eq(Tag::Sequence)?; Ok(Self::parse_inner(any.data).map(|(_, ci)| ci)?) } } -/// ASN.1 DigestInfo +/// [DigestInfo][1] structure /// +/// ```text /// DigestInfo ::= SEQUENCE { -/// digestAlgorithm AlgorithmIdentifier, -/// digest OCTETSTRING +/// digestAlgorithm AlgorithmIdentifier, +/// digest OCTETSTRING /// } +/// ``` +/// +/// [1]: https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-oshared/1537695a-28f0-4828-8b7b-d6dab62b8030 pub struct DigestInfo<'a> { pub algorithm: AlgorithmIdentifier<'a>, pub digest: &'a [u8], @@ -529,16 +533,78 @@ pub struct DigestInfo<'a> { impl<'a> DigestInfo<'a> { pub fn parse(input: &'a [u8]) -> BerResult { - parse_der_sequence_defined_g(|input: &[u8], _| { - let (remainder, algorithm) = - AlgorithmIdentifier::from_der(input).unwrap(); // TODO: handler error - let (remainder, digest) = parse_der_octetstring(remainder)?; + parse_ber_sequence_defined_g(|input: &[u8], _| { + let (remainder, algorithm) = AlgorithmIdentifier::from_ber(input) + .map_err(|_| BerValueError)?; + let (remainder, digest) = parse_ber_octetstring(remainder)?; Ok((remainder, Self { algorithm, digest: digest.as_slice()? })) })(input) } } -/// ASN.1 TSTInfo +/// [SpcSpOpusInfo][1] structure +/// +/// ```text +/// SpcSpOpusInfo ::= SEQUENCE { +/// programName [0] EXPLICIT SpcString OPTIONAL, +/// moreInfo [1] EXPLICIT SpcLink OPTIONAL, +/// } +/// ``` +/// +/// [1]: https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-oshared/91755632-4b0d-44ca-89a9-9699afbbd268 +pub struct SpcSpOpusInfo { + pub program_name: Option, +} + +impl SpcSpOpusInfo { + pub fn parse(input: &[u8]) -> BerResult { + parse_ber_sequence_defined_g(|input: &[u8], _| { + Self::parse_inner(input) + })(input) + } + + fn parse_inner(input: &[u8]) -> BerResult { + let (remainder, program_name) = OptTaggedParser::from(0) + .parse_ber(input, |_, content| Self::parse_spc_string(content))?; + + let (remainder, _more_info) = + OptTaggedParser::from(1).parse_ber(remainder, |_, content| { + let (rem, value) = parse_ber(content)?; + Ok((rem, value)) + })?; + + Ok((remainder, Self { program_name })) + } + + fn parse_spc_string(input: &[u8]) -> BerResult { + alt(( + map_res( + parse_ber_tagged_implicit( + 0, + parse_ber_content(Tag::BmpString), + ), + |s| string_from_utf16be(s.as_slice()?).ok_or(BerValueError), + ), + map_res( + parse_ber_tagged_implicit( + 1, + parse_ber_content(Tag::Ia5String), + ), + |s| Ok::(String::from(s.as_str()?)), + ), + ))(input) + } +} + +impl TryFrom<&Any<'_>> for SpcSpOpusInfo { + type Error = asn1_rs::Error; + + fn try_from(any: &Any) -> Result { + Ok(Self::parse_inner(any.data).map(|(_, ci)| ci)?) + } +} + +/// [TSTInfo][1] structure. /// /// ```text /// TSTInfo ::= SEQUENCE { @@ -565,24 +631,23 @@ impl<'a> DigestInfo<'a> { /// hashedMessage OCTET STRING } /// ``` /// -/// https://datatracker.ietf.org/doc/html/rfc3161 - +/// [1]: https://datatracker.ietf.org/doc/html/rfc3161 pub struct TstInfo<'a> { pub hash_algorithm: AlgorithmIdentifier<'a>, pub hashed_message: &'a [u8], } impl<'a> TstInfo<'a> { - pub fn from_der( + pub fn from_ber( data: &'a [u8], ) -> Result> { Self::parse(data).map(|(_, tst_info)| tst_info) } pub fn parse(input: &'a [u8]) -> BerResult { - parse_der_sequence_defined_g(|input: &[u8], _| { - let (remainder, _version) = parse_der_integer(input)?; - let (remainder, _policy) = parse_der(remainder)?; + parse_ber_sequence_defined_g(|input: &[u8], _| { + let (remainder, _version) = parse_ber_integer(input)?; + let (remainder, _policy) = parse_ber(remainder)?; let (remainder, (hash_algorithm, hashed_message)) = Self::parse_message_imprint(remainder)?; @@ -596,75 +661,16 @@ impl<'a> TstInfo<'a> { fn parse_message_imprint( input: &'a [u8], ) -> BerResult<(AlgorithmIdentifier, &'a [u8])> { - parse_der_sequence_defined_g(|input: &[u8], _| { + parse_ber_sequence_defined_g(|input: &[u8], _| { let (remainder, hash_algorithm) = - AlgorithmIdentifier::from_der(input).unwrap(); // TODO: handle error - let (remainder, hashed_message) = parse_der(remainder)?; + AlgorithmIdentifier::from_ber(input) + .map_err(|_| BerValueError)?; - Ok((remainder, (hash_algorithm, hashed_message.as_slice()?))) - })(input) - } -} + let (remainder, hashed_message) = parse_ber(remainder)?; -/// ASN.1 SpcSpOpusInfo -/// -/// SpcSpOpusInfo ::= SEQUENCE { -/// programName [0] EXPLICIT SpcString OPTIONAL, -/// moreInfo [1] EXPLICIT SpcLink OPTIONAL, -/// } -pub struct SpcSpOpusInfo { - pub program_name: Option, -} - -impl SpcSpOpusInfo { - pub fn parse(input: &[u8]) -> BerResult { - parse_der_sequence_defined_g(|input: &[u8], _| { - Self::parse_inner(input) + Ok((remainder, (hash_algorithm, hashed_message.as_slice()?))) })(input) } - - fn parse_inner(input: &[u8]) -> BerResult { - let (remainder, program_name) = OptTaggedParser::from(0) - .parse_der(input, |_, content| Self::parse_spc_string(content))?; - - let (remainder, more_info) = - OptTaggedParser::from(1).parse_der(remainder, |_, content| { - let (rem, value) = parse_der(content)?; - Ok((rem, value)) - })?; - - Ok((remainder, Self { program_name })) - } - - fn parse_spc_string(input: &[u8]) -> BerResult { - alt(( - map_res( - parse_der_tagged_implicit( - 0, - parse_der_content(der_parser::der::Tag::BmpString), - ), - |s| { - string_from_utf16be(s.as_slice()?) - .ok_or(BerError::BerValueError) - }, - ), - map_res( - parse_der_tagged_implicit( - 1, - parse_der_content(der_parser::der::Tag::Ia5String), - ), - |s| Ok::(String::from(s.as_str()?)), - ), - ))(input) - } -} - -impl TryFrom<&Any<'_>> for SpcSpOpusInfo { - type Error = asn1_rs::Error; - - fn try_from(any: &Any) -> Result { - Ok(Self::parse_inner(any.data).map(|(_, ci)| ci)?) - } } /// Tries to create a string from a byte slice that contains the UTF-16BE diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index fa1f36085..c2e9ce833 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -25,7 +25,7 @@ use x509_parser::x509::{SubjectPublicKeyInfo, X509Name}; use crate::modules::pe::asn1::{ oid, oid_to_object_identifier, oid_to_str, Attribute, Certificate, - ContentInfo, DigestInfo, IndirectDataContent, SignedData, SignerInfo, + ContentInfo, DigestInfo, SignedData, SignerInfo, SpcIndirectDataContent, SpcSpOpusInfo, TstInfo, }; use crate::modules::pe::parser::PE; @@ -34,9 +34,6 @@ use crate::modules::protos; /// Error returned by [`AuthenticodeParser::parse`]. #[derive(Clone, Debug, Eq, PartialEq)] pub enum ParseError { - /// The signature data is empty. - Empty, - /// The signature data is not valid [`ContentInfo`]. InvalidContentInfo, @@ -65,7 +62,7 @@ pub enum ParseError { InvalidSpcIndirectDataContent, /// The number of signer infos is not 1. - InvalidNumSignerInfo(usize), + InvalidNumSignerInfo, /// The version of [`SignerInfo`] is not 1. InvalidSignerInfoVersion(i64), @@ -79,8 +76,9 @@ pub enum ParseError { /// The `contentType` authenticated attribute is missing. MissingContentTypeAuthenticatedAttribute, - /// The `messageDigest` authenticated attribute is missing. - MissingMessageDigestAuthenticatedAttribute, + /// The attribute containing the Authenticode digest is + /// missing. + MissingAuthenticodeDigest, } /// Parses Authenticode signatures in a PE file. @@ -97,22 +95,22 @@ impl AuthenticodeParser { input: &'a [u8], pe: &PE, ) -> Result>, ParseError> { - let content_info = ContentInfo::from_der(input) + let content_info = ContentInfo::from_ber(input) .map_err(|_| ParseError::InvalidContentInfo)?; - if content_info.content_type == oid::SIGNED_DATA { - Self::parse_content_info(content_info, pe) - } else { - Err(ParseError::InvalidContentType( - content_info.content_type.to_id_string(), - )) - } + Self::parse_content_info(content_info, pe) } fn parse_content_info<'a>( content_info: ContentInfo<'a>, pe: &PE, ) -> Result>, ParseError> { + if content_info.content_type != oid::SIGNED_DATA { + return Err(ParseError::InvalidContentType( + content_info.content_type.to_id_string(), + )); + } + let mut signed_data: SignedData = content_info .content .try_into() @@ -132,13 +130,8 @@ impl AuthenticodeParser { )); } - // Exactly one SignerInfo, as required by the specification. - if signed_data.signer_infos.len() != 1 { - return Err(ParseError::InvalidNumSignerInfo( - signed_data.signer_infos.len(), - )); - } - + // The content in `SignedData` must be a `SpcIndirectDataContent` + // structure. if signed_data.content_info.content_type != oid::INDIRECT_DATA_OBJID { return Err(ParseError::InvalidEncapsulatedContentType( signed_data.content_info.content_type.to_id_string(), @@ -146,39 +139,42 @@ impl AuthenticodeParser { } // According to the Authenticode specification there's exactly one - // signer info. + // signer info, take it. let signer_info = match signed_data.signer_infos.pop() { Some(si) => si, - None => { - return Err(ParseError::InvalidNumSignerInfo( - signed_data.signer_infos.len(), - )) - } + None => return Err(ParseError::InvalidNumSignerInfo), }; + // No signer infos after taking the only one. + if !signed_data.signer_infos.is_empty() { + return Err(ParseError::InvalidNumSignerInfo); + } + + // `SignerInfo` must have a signed attribute that contains the + // Authenticode digest. This attribute is identified by OID + // 1.2.840.113549.1.9.4. let signer_info_digest = match signer_info .get_signed_attr(&oid::MESSAGE_DIGEST) .map(|value| value.data.as_bytes()) { Some(md) => md, - None => { - return Err( - ParseError::MissingMessageDigestAuthenticatedAttribute, - ) - } + None => return Err(ParseError::MissingAuthenticodeDigest), }; if signer_info.get_signed_attr(&oid::CONTENT_TYPE).is_none() { return Err(ParseError::MissingContentTypeAuthenticatedAttribute); } + // `SignerInfo` can have a signed attribute that contains information + // about the signed program in a `SpcSpOpusInfo` struct. let opus_info: Option = signer_info .get_signed_attr(&oid::OPUS_INFO_OBJID) .and_then(|value| value.try_into().ok()); let signed_data_raw = signed_data.content_info.content.data; - let indirect_data: IndirectDataContent = + // Extract the `SpcIndirectDataContent` structure from `SignedData`. + let indirect_data: SpcIndirectDataContent = match signed_data.content_info.content.try_into() { Ok(idc) => idc, Err(_) => { @@ -186,7 +182,7 @@ impl AuthenticodeParser { } }; - // Get all the certificates contained in `SignedData`, more + // Extract all the certificates contained in `SignedData`, more // certificates from nested signatures and countersignatures will // be added later to this vector. let mut certificates: Vec = signed_data.certificates; @@ -196,11 +192,11 @@ impl AuthenticodeParser { for attr in signer_info.unsigned_attrs.iter() { match attr.attr_type.as_bytes() { - // SignerInfo can have attributes containing nested Authenticode - // signatures. The type of those attributes is 1.3.6.1.4.1.311.2.4.1 - // and their content is a ContentInfo structure. Find those attributes, - // parse their first (and only) value, and append resulting signatures - // to `nested_signatures`. + // SignerInfo can have unsigned attributes containing nested + // Authenticode signatures. These attributes are identified by + // OID 1.3.6.1.4.1.311.2.4.1 and their content is a `ContentInfo` + // structure. Find those attributes, parse their first (and only) + // value, and append resulting signatures to `nested_signatures`. oid::MS_NESTED_SIGNATURE_B => { if let Some(nested) = attr.attr_values.first().and_then(|first_value| { @@ -274,6 +270,7 @@ impl AuthenticodeParser { // signed attribute MESSAGE_DIGEST stored in `SignerInfo`. // * The `SignerInfo` struct has not been tampered, which is verified // by `verify_signer_info`. + // let verified = authenticode_digest.digest == file_digest.as_slice() && verify_message_digest( &signer_info.digest_algorithm, @@ -307,40 +304,36 @@ impl AuthenticodeParser { countersignatures: &mut Vec>, ) -> Result<(), ParseError> { for value in &attr.attr_values { - let content_info: ContentInfo = match value.try_into() { + let ci: ContentInfo = match value.try_into() { Ok(ci) => ci, Err(_) => continue, }; - let signed_data: SignedData = match content_info.content.try_into() - { + let sd: SignedData = match ci.content.try_into() { Ok(sd) => sd, Err(_) => continue, }; - certificates.extend(signed_data.certificates); + certificates.extend(sd.certificates); - let cs_si = signed_data.signer_infos.first().unwrap(); + let cs_si = sd.signer_infos.first().unwrap(); let mut countersignature = Self::pkcs9_countersignature(cs_si)?; - let tst_info = match TstInfo::from_der( - signed_data.content_info.content.as_bytes(), - ) { - Ok(tst_info) => tst_info, - Err(_) => continue, - }; - - countersignature.digest_alg = - oid_to_str(tst_info.hash_algorithm.oid()); + let tst = + match TstInfo::from_ber(sd.content_info.content.as_bytes()) { + Ok(tst_info) => tst_info, + Err(_) => continue, + }; - countersignature.digest = tst_info.hashed_message; + countersignature.digest_alg = oid_to_str(tst.hash_algorithm.oid()); + countersignature.digest = tst.hashed_message; countersignature.verified = verify_message_digest( - &tst_info.hash_algorithm, + &tst.hash_algorithm, si.signature_value, - tst_info.hashed_message, + tst.hashed_message, ) && verify_signer_info(cs_si, certificates.as_slice()); countersignatures.push(countersignature); @@ -399,11 +392,7 @@ impl AuthenticodeParser { let digest = match digest { Some(digest) => digest, - None => { - return Err( - ParseError::MissingMessageDigestAuthenticatedAttribute, - ) - } + None => return Err(ParseError::MissingAuthenticodeDigest), }; Ok(AuthenticodeCountersign { @@ -450,12 +439,12 @@ impl<'a> AuthenticodeSignature<'a> { /// Get the name of the Authenticode hash algorithm. pub fn authenticode_hash_algorithm(&self) -> Cow<'static, str> { - oid_to_str(&self.authenticode_digest.algorithm.oid()) + oid_to_str(self.authenticode_digest.algorithm.oid()) } #[inline] pub fn signer_info_digest_alg(&self) -> Cow<'static, str> { - oid_to_str(&self.signer_info.digest_algorithm.oid()) + oid_to_str(self.signer_info.digest_algorithm.oid()) } #[inline] @@ -607,11 +596,8 @@ impl From<&Certificate<'_>> for protos::pe::Certificate { // Versions are 0-based, add 1 for getting the actual version. cert.set_version(value.x509.tbs_certificate.version.0 as i64 + 1); - cert.set_issuer(format_name(&value.x509.tbs_certificate.issuer)); - cert.set_subject(format_name(&value.x509.tbs_certificate.subject)); - cert.set_serial(value.x509.raw_serial_as_string()); cert.set_algorithm_oid(format!( @@ -715,21 +701,7 @@ fn verify_message_digest( } } -fn verify_signer_info(si: &SignerInfo, certs: &[Certificate]) -> bool { - match si.digest_algorithm.oid().as_bytes() { - oid::SHA_1_B => verify_signed_data_impl::(si, certs), - oid::SHA_256_B => verify_signed_data_impl::(si, certs), - oid::SHA_384_B => verify_signed_data_impl::(si, certs), - oid::SHA_512_B => verify_signed_data_impl::(si, certs), - oid::MD5_B => verify_signed_data_impl::(si, certs), - _ => unimplemented!("{:?}", si.digest_algorithm.oid()), - } -} - -fn verify_signed_data_impl( - si: &SignerInfo, - certs: &[Certificate<'_>], -) -> bool { +fn verify_signer_info(si: &SignerInfo, certs: &[Certificate<'_>]) -> bool { // Get a certificate chain that starts with the certificate that signed // data and contains all the certificates in the chain of truth. let cert_chain = CertificateChain::new(certs, |cert| { @@ -762,7 +734,11 @@ fn verify_signed_data_impl( }; // Verify that the signature in SignerInfo.signature is correct. - key.verify::(attrs_set_der.as_slice(), si.signature_value) + key.verify( + &si.digest_algorithm, + attrs_set_der.as_slice(), + si.signature_value, + ) } /// Represents a certificate chain. @@ -809,43 +785,41 @@ impl<'a, 'b> CertificateChain<'a, 'b> { // Iterate over the chain taking a certificate and its signer on each // iteration. for (signed, signer) in self.tuple_windows() { - // The `signed` certificate is the one that will be verified. - - if x509_parser::verify::verify_signature( - &signer.x509.subject_pki, - &signed.x509.signature_algorithm, - &signed.x509.signature_value, - signed.x509.tbs_certificate.as_ref(), - ) - .is_err() + // When `x509-parser-verify` feature verify certificate signatures + // using the `x509_parser` crate. + #[cfg(feature = "x509-parser-verify")] { - return false; + if x509_parser::verify::verify_signature( + &signer.x509.subject_pki, + &signed.x509.signature_algorithm, + &signed.x509.signature_value, + signed.x509.tbs_certificate.as_ref(), + ) + .is_err() + { + return false; + } } - /* - let verify_info = VerifyInfo::new( - signed.tbs_certificate.to_der().unwrap().into(), - x509_verify::Signature::new( - &signed.signature_algorithm, - signed.signature.as_bytes().unwrap(), - ), - ); - - // The public key in the `signer` certificate is used for - // verifying the signature in the `signed` certificate. - let key: VerifyingKey = match signer - .tbs_certificate - .subject_public_key_info - .owned_to_ref() - .try_into() + // When `x509-parser-verify` feature is not enabled, use our + // own logic. + #[cfg(not(feature = "x509-parser-verify"))] { - Ok(key) => key, - Err(_) => return false, - }; - - if key.verify(verify_info).is_err() { - return false; - }*/ + let key = match PublicKey::try_from( + &signer.x509.tbs_certificate.subject_pki, + ) { + Ok(key) => key, + Err(_) => return false, + }; + + if !key.verify( + &signed.x509.signature_algorithm, + signed.x509.tbs_certificate.as_ref(), + signed.x509.signature_value.as_ref(), + ) { + return false; + } + } } true @@ -953,7 +927,39 @@ impl TryFrom<&SubjectPublicKeyInfo<'_>> for PublicKey { } impl PublicKey { - fn verify( + fn verify( + &self, + digest_algorithm: &AlgorithmIdentifier, + message: &[u8], + signature: &[u8], + ) -> bool { + match oid_to_object_identifier(digest_algorithm.oid()) { + rfc5912::ID_MD_5 | rfc5912::MD_5_WITH_RSA_ENCRYPTION => { + self.verify_impl::(message, signature) + } + rfc5912::ID_SHA_1 | rfc5912::SHA_1_WITH_RSA_ENCRYPTION => { + self.verify_impl::(message, signature) + } + rfc5912::ID_SHA_256 + | rfc5912::SHA_256_WITH_RSA_ENCRYPTION + | rfc5912::ECDSA_WITH_SHA_256 => { + self.verify_impl::(message, signature) + } + rfc5912::ID_SHA_384 + | rfc5912::SHA_384_WITH_RSA_ENCRYPTION + | rfc5912::ECDSA_WITH_SHA_384 => { + self.verify_impl::(message, signature) + } + rfc5912::ID_SHA_512 + | rfc5912::SHA_512_WITH_RSA_ENCRYPTION + | rfc5912::ECDSA_WITH_SHA_512 => { + self.verify_impl::(message, signature) + } + _ => unimplemented!("{:?}", digest_algorithm.oid()), + } + } + + fn verify_impl( &self, message: &[u8], signature: &[u8], From 57bdb3aad0afca942ae88831f67e15bcd56b548e Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Sat, 27 Apr 2024 11:09:42 +0200 Subject: [PATCH 30/38] feat: add support DSA algorithm --- Cargo.lock | 44 -- Cargo.toml | 2 - lib/Cargo.toml | 5 +- lib/src/modules/pe/asn1.rs | 3 + lib/src/modules/pe/authenticode.rs | 142 ++--- ...5c737bc0900393f89f93b8f3c9a265dc790.in.zip | Bin 0 -> 193407 bytes ...6335c737bc0900393f89f93b8f3c9a265dc790.out | 506 ++++++++++++++++++ 7 files changed, 591 insertions(+), 111 deletions(-) create mode 100644 lib/src/modules/pe/tests/testdata/6758569a317d95008a9a5641376335c737bc0900393f89f93b8f3c9a265dc790.in.zip create mode 100644 lib/src/modules/pe/tests/testdata/6758569a317d95008a9a5641376335c737bc0900393f89f93b8f3c9a265dc790.out diff --git a/Cargo.lock b/Cargo.lock index 0d9059a73..a1e59ec08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -605,18 +605,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" -[[package]] -name = "cms" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b77c319abfd5219629c45c34c89ba945ed3c5e49fcde9d16b6c3885f118a730" -dependencies = [ - "const-oid", - "der", - "spki", - "x509-cert", -] - [[package]] name = "colorchoice" version = "1.0.0" @@ -1040,8 +1028,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", - "der_derive", - "flagset", "pem-rfc7468", "zeroize", ] @@ -1060,17 +1046,6 @@ dependencies = [ "rusticata-macros", ] -[[package]] -name = "der_derive" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe87ce4529967e0ba1dcf8450bab64d97dfd5010a6256187ffe2e43e6f0e049" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.55", -] - [[package]] name = "deranged" version = "0.3.11" @@ -1363,12 +1338,6 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" -[[package]] -name = "flagset" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdeb3aa5e95cf9aabc17f060cfa0ced7b83f042390760ca53bf09df9968acaa1" - [[package]] name = "flate2" version = "1.0.28" @@ -4658,17 +4627,6 @@ dependencies = [ "tap", ] -[[package]] -name = "x509-cert" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94" -dependencies = [ - "const-oid", - "der", - "spki", -] - [[package]] name = "x509-parser" version = "0.16.0" @@ -4721,10 +4679,8 @@ dependencies = [ "bitmask", "bitvec", "bstr 1.9.1", - "cms", "const-oid", "crc32fast", - "der", "der-parser", "digest 0.10.7", "dsa", diff --git a/Cargo.toml b/Cargo.toml index d50cea1ff..5d72c17cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,10 +44,8 @@ cbindgen = "0.26.0" chrono = "0.4.35" clap = "4.5.3" clap_complete = "4.5.1" -cms = "0.2.3" const-oid = "0.9.6" crc32fast = "1.4.0" -der = "0.7.9" der-parser = "9.0.0" digest = "0.10.7" dsa = "0.6.3" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 846eb796a..a1cb1a13d 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -109,7 +109,6 @@ math-module = [] # The `pe` module parses PE files. pe-module = [ - "dep:cms", "dep:const-oid", "dep:der-parser", "dep:digest", @@ -173,10 +172,8 @@ bincode = { workspace = true } bitmask = { workspace = true } bitvec = { workspace = true } bstr = { workspace = true, features = ["serde"] } -cms = { workspace = true, optional = true } -const-oid = { workspace = true, optional = true } +const-oid = { workspace = true, optional = true, features = ["db"] } crc32fast = { workspace = true, optional = true } -der = { workspace = true, features = ["derive"] } der-parser = { workspace = true, optional = true, features = ["bigint"] } digest = { workspace = true, optional = true } dsa = { workspace = true, optional = true } diff --git a/lib/src/modules/pe/asn1.rs b/lib/src/modules/pe/asn1.rs index fa87a6a4c..32ac38966 100644 --- a/lib/src/modules/pe/asn1.rs +++ b/lib/src/modules/pe/asn1.rs @@ -134,6 +134,9 @@ pub fn oid_to_str(oid: &Oid) -> Cow<'static, str> { rfc5912::SHA_512_WITH_RSA_ENCRYPTION => { Cow::Borrowed("sha512WithRSAEncryption") } + rfc5912::DSA_WITH_SHA_1 => Cow::Borrowed("dsaWithSHA1"), + rfc5912::DSA_WITH_SHA_224 => Cow::Borrowed("dsa_with_SHA224"), + rfc5912::DSA_WITH_SHA_256 => Cow::Borrowed("dsa_with_SHA256"), rfc4519::C => Cow::Borrowed("C"), rfc4519::COMMON_NAME => Cow::Borrowed("CN"), rfc4519::O => Cow::Borrowed("O"), diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index c2e9ce833..3cc49b1a3 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -4,9 +4,9 @@ use std::fmt::Write; use array_bytes::bytes2hex; use const_oid::db::{rfc5912, rfc6268}; use const_oid::{AssociatedOid, ObjectIdentifier}; -use der::Decode; use der_parser::asn1_rs::{Set, Tag, ToDer, UtcTime}; use digest::Digest; +use dsa::Components; use ecdsa::signature::hazmat::PrehashVerifier; use itertools::Itertools; @@ -43,9 +43,6 @@ pub enum ParseError { /// The content info is not valid [`SignedData`]. InvalidSignedData, - /// The signer info is not valid [`SignerInfo`]. - InvalidSignerInfo(der::Error), - /// The version of [`SignedData`] is not 1. InvalidSignedDataVersion(i32), @@ -55,9 +52,6 @@ pub enum ParseError { /// The encapsulated content type does not match [`SPC_INDIRECT_DATA_OBJID`]. InvalidEncapsulatedContentType(String), - /// The encapsulated content is empty. - EmptyEncapsulatedContent, - /// The encapsulated content is not valid [`SpcIndirectDataContent`]. InvalidSpcIndirectDataContent, @@ -229,34 +223,35 @@ impl AuthenticodeParser { // Compute the Authenticode hash by ourselves. This hash will be // compared later with the one included in the PE file. - let file_digest = match signer_info.digest_algorithm.oid().as_bytes() { - oid::MD5_B => { - let mut md5 = Md5::default(); - pe.authenticode_hash(&mut md5); - md5.finalize().to_vec() - } - oid::SHA_1_B => { - let mut sha1 = Sha1::default(); - pe.authenticode_hash(&mut sha1); - sha1.finalize().to_vec() - } - oid::SHA_256_B => { - let mut sha256 = Sha256::default(); - pe.authenticode_hash(&mut sha256); - sha256.finalize().to_vec() - } - oid::SHA_384_B => { - let mut sha384 = Sha384::default(); - pe.authenticode_hash(&mut sha384); - sha384.finalize().to_vec() - } - oid::SHA_512_B => { - let mut sha512 = Sha512::default(); - pe.authenticode_hash(&mut sha512); - sha512.finalize().to_vec() - } - oid => unimplemented!("{:?}", oid), - }; + let computed_authenticode_hash = + match signer_info.digest_algorithm.oid().as_bytes() { + oid::MD5_B => { + let mut md5 = Md5::default(); + pe.authenticode_hash(&mut md5); + md5.finalize().to_vec() + } + oid::SHA_1_B => { + let mut sha1 = Sha1::default(); + pe.authenticode_hash(&mut sha1); + sha1.finalize().to_vec() + } + oid::SHA_256_B => { + let mut sha256 = Sha256::default(); + pe.authenticode_hash(&mut sha256); + sha256.finalize().to_vec() + } + oid::SHA_384_B => { + let mut sha384 = Sha384::default(); + pe.authenticode_hash(&mut sha384); + sha384.finalize().to_vec() + } + oid::SHA_512_B => { + let mut sha512 = Sha512::default(); + pe.authenticode_hash(&mut sha512); + sha512.finalize().to_vec() + } + oid => unimplemented!("{:?}", oid), + }; let authenticode_digest = indirect_data.message_digest; @@ -271,7 +266,8 @@ impl AuthenticodeParser { // * The `SignerInfo` struct has not been tampered, which is verified // by `verify_signer_info`. // - let verified = authenticode_digest.digest == file_digest.as_slice() + let verified = authenticode_digest.digest + == computed_authenticode_hash.as_slice() && verify_message_digest( &signer_info.digest_algorithm, signed_data_raw, @@ -282,7 +278,7 @@ impl AuthenticodeParser { let mut signatures = Vec::with_capacity(nested_signatures.len() + 1); signatures.push(AuthenticodeSignature { - computed_authenticode_hash: file_digest, + computed_authenticode_hash, program_name: opus_info.and_then(|oi| oi.program_name), authenticode_digest, signer_info, @@ -727,13 +723,13 @@ fn verify_signer_info(si: &SignerInfo, certs: &[Certificate<'_>]) -> bool { let attrs_set_der = attrs_set.to_der_vec_raw().unwrap(); // Obtain the public key included in the certificate. - let key = - match PublicKey::try_from(&signing_cert.tbs_certificate.subject_pki) { - Ok(key) => key, - Err(_) => return false, - }; + let spki = &signing_cert.tbs_certificate.subject_pki; + let key = match PublicKey::try_from(spki) { + Ok(key) => key, + Err(_) => return false, + }; - // Verify that the signature in SignerInfo.signature is correct. + // Verify that the signature in `SignerInfo` is correct. key.verify( &si.digest_algorithm, attrs_set_der.as_slice(), @@ -765,7 +761,6 @@ impl<'a, 'b> CertificateChain<'a, 'b> { P: Fn(&X509Certificate<'_>) -> bool, { let next = certs.iter().find(|cert| predicate(&cert.x509)); - Self { certs, next } } @@ -862,13 +857,19 @@ enum PublicKeyError { #[error("PKCS1 error")] Pkcs1(#[from] rsa::pkcs1::Error), - #[error("Missing ECDSA algorithm parameters")] + #[error("PKCS8 error")] + Pkcs8(#[from] rsa::pkcs8::spki::Error), + + #[error("DER parsing error")] Der(#[from] der_parser::error::Error), #[error("ECDSA error")] Ecdsa(#[from] ecdsa::Error), - #[error("Missing ECDSA algorithm parameters")] + #[error("DER parsing error")] + Nom(#[from] nom::Err), + + #[error("Missing algorithm parameters")] MissingAlgorithmParameters, #[error("Unknown ECDSA curve")] @@ -881,26 +882,41 @@ enum PublicKeyError { impl TryFrom<&SubjectPublicKeyInfo<'_>> for PublicKey { type Error = PublicKeyError; - fn try_from( - value: &SubjectPublicKeyInfo<'_>, - ) -> Result { - match oid_to_object_identifier(value.algorithm.oid()) { + fn try_from(spki: &SubjectPublicKeyInfo<'_>) -> Result { + match oid_to_object_identifier(spki.algorithm.oid()) { rfc5912::RSA_ENCRYPTION => { use rsa::pkcs1::DecodeRsaPublicKey; Ok(Self::Rsa(rsa::RsaPublicKey::from_pkcs1_der( - value.subject_public_key.as_ref(), + spki.subject_public_key.as_ref(), )?)) } rfc5912::ID_DSA => { - todo!() - //use dsa::pkcs8::DecodePublicKey; - //let key = dsa::VerifyingKey::from_public_key_der( - // value.subject_public_key.as_ref(), - //)?; - //Ok(Self::Dsa(key)) + let parameters = spki + .algorithm + .parameters + .as_ref() + .ok_or(Self::Error::MissingAlgorithmParameters)?; + + let key_bytes = spki.subject_public_key.as_ref(); + + use der_parser::ber::parse_ber_integer; + let (_, y) = parse_ber_integer(key_bytes)?; + let (rem, p) = parse_ber_integer(parameters.data)?; + let (rem, q) = parse_ber_integer(rem)?; + let (_, g) = parse_ber_integer(rem)?; + + let p = dsa::BigUint::from_bytes_be(p.content.as_slice()?); + let q = dsa::BigUint::from_bytes_be(q.content.as_slice()?); + let g = dsa::BigUint::from_bytes_be(g.content.as_slice()?); + let y = dsa::BigUint::from_bytes_be(y.content.as_slice()?); + + let components = Components::from_components(p, q, g)?; + let key = dsa::VerifyingKey::from_components(components, y)?; + + Ok(Self::Dsa(key)) } rfc5912::ID_EC_PUBLIC_KEY => { - let curve: der_parser::asn1_rs::Oid = value + let curve: der_parser::asn1_rs::Oid = spki .algorithm .parameters .as_ref() @@ -910,12 +926,12 @@ impl TryFrom<&SubjectPublicKeyInfo<'_>> for PublicKey { match oid_to_object_identifier(&curve) { rfc5912::SECP_256_R_1 => Ok(Self::EcdsaP256( p256::ecdsa::VerifyingKey::try_from( - value.subject_public_key.as_ref(), + spki.subject_public_key.as_ref(), )?, )), rfc5912::SECP_384_R_1 => Ok(Self::EcdsaP384( p384::ecdsa::VerifyingKey::try_from( - value.subject_public_key.as_ref(), + spki.subject_public_key.as_ref(), )?, )), oid => Err(Self::Error::UnknownEcdsaCurve(oid)), @@ -937,11 +953,14 @@ impl PublicKey { rfc5912::ID_MD_5 | rfc5912::MD_5_WITH_RSA_ENCRYPTION => { self.verify_impl::(message, signature) } - rfc5912::ID_SHA_1 | rfc5912::SHA_1_WITH_RSA_ENCRYPTION => { + rfc5912::ID_SHA_1 + | rfc5912::DSA_WITH_SHA_1 + | rfc5912::SHA_1_WITH_RSA_ENCRYPTION => { self.verify_impl::(message, signature) } rfc5912::ID_SHA_256 | rfc5912::SHA_256_WITH_RSA_ENCRYPTION + | rfc5912::DSA_WITH_SHA_256 | rfc5912::ECDSA_WITH_SHA_256 => { self.verify_impl::(message, signature) } @@ -978,6 +997,7 @@ impl PublicKey { .is_ok() } Self::Dsa(key) => { + use dsa::pkcs8::der::Decode; dsa::Signature::from_der(signature).is_ok_and(|s| { key.verify_prehash(digest.as_slice(), &s).is_ok() }) diff --git a/lib/src/modules/pe/tests/testdata/6758569a317d95008a9a5641376335c737bc0900393f89f93b8f3c9a265dc790.in.zip b/lib/src/modules/pe/tests/testdata/6758569a317d95008a9a5641376335c737bc0900393f89f93b8f3c9a265dc790.in.zip new file mode 100644 index 0000000000000000000000000000000000000000..1828b3b4f398ac699bbb98f5b310f7571c347833 GIT binary patch literal 193407 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 z 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

YIR-sIq5#{~DP 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 literal 0 HcmV?d00001 diff --git a/lib/src/modules/pe/tests/testdata/6758569a317d95008a9a5641376335c737bc0900393f89f93b8f3c9a265dc790.out b/lib/src/modules/pe/tests/testdata/6758569a317d95008a9a5641376335c737bc0900393f89f93b8f3c9a265dc790.out new file mode 100644 index 000000000..524b247e4 --- /dev/null +++ b/lib/src/modules/pe/tests/testdata/6758569a317d95008a9a5641376335c737bc0900393f89f93b8f3c9a265dc790.out @@ -0,0 +1,506 @@ +is_pe: true +machine: MACHINE_I386 +subsystem: SUBSYSTEM_WINDOWS_CUI +os_version: + major: 4 + minor: 0 +subsystem_version: + major: 4 + minor: 0 +image_version: + major: 1 + minor: 0 +linker_version: + major: 2 + minor: 26 +opthdr_magic: IMAGE_NT_OPTIONAL_HDR32_MAGIC +characteristics: 783 +dll_characteristics: 1344 +timestamp: 1655157631 # 2022-06-13 22:00:31 UTC +image_base: 4194304 +checksum: 340992 +base_of_code: 4096 +base_of_data: 24576 +entry_point: 1648 +entry_point_raw: 4720 +section_alignment: 4096 +file_alignment: 512 +loader_flags: 0 +size_of_optional_header: 224 +size_of_code: 17920 +size_of_initialized_data: 271872 +size_of_uninitialized_data: 36352 +size_of_image: 344064 +size_of_headers: 1024 +size_of_stack_reserve: 2097152 +size_of_stack_commit: 4096 +size_of_heap_reserve: 1048576 +size_of_heap_commit: 4096 +pointer_to_symbol_table: 0 +win32_version_value: 0 +number_of_symbols: 0 +number_of_rva_and_sizes: 16 +number_of_sections: 6 +number_of_imported_functions: 67 +number_of_delayed_imported_functions: 0 +number_of_resources: 26 +number_of_version_infos: 0 +number_of_imports: 5 +number_of_delayed_imports: 0 +number_of_exports: 0 +number_of_signatures: 1 +sections: + - name: ".text" + full_name: ".text" + characteristics: 1613758496 + raw_data_size: 17920 + raw_data_offset: 1024 + virtual_address: 4096 + virtual_size: 17512 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: ".data" + full_name: ".data" + characteristics: 3224371264 + raw_data_size: 512 + raw_data_offset: 18944 + virtual_address: 24576 + virtual_size: 48 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: ".rdata" + full_name: ".rdata" + characteristics: 1076887616 + raw_data_size: 2048 + raw_data_offset: 19456 + virtual_address: 28672 + virtual_size: 1584 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: ".bss" + full_name: ".bss" + characteristics: 3224371328 + raw_data_size: 0 + raw_data_offset: 0 + virtual_address: 32768 + virtual_size: 36352 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: ".idata" + full_name: ".idata" + characteristics: 3224371264 + raw_data_size: 2560 + raw_data_offset: 21504 + virtual_address: 69632 + virtual_size: 2096 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 + - name: ".rsrc" + full_name: ".rsrc" + characteristics: 3224371264 + raw_data_size: 266752 + raw_data_offset: 24064 + virtual_address: 73728 + virtual_size: 266504 + pointer_to_relocations: 0 + pointer_to_line_numbers: 0 + number_of_relocations: 0 + number_of_line_numbers: 0 +data_directories: + - virtual_address: 0 + size: 0 + - virtual_address: 69632 + size: 2096 + - virtual_address: 73728 + size: 266504 + - virtual_address: 0 + size: 0 + - virtual_address: 290816 + size: 1760 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 70060 + size: 308 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 + - virtual_address: 0 + size: 0 +resource_timestamp: 0 # 1970-01-01 00:00:00 UTC +resource_version: + major: 0 + minor: 0 +resources: + - length: 1128 + rva: 75064 + offset: 25400 + type: RESOURCE_TYPE_ICON + id: 1 + language: 1024 + - length: 2440 + rva: 76192 + offset: 26528 + type: RESOURCE_TYPE_ICON + id: 2 + language: 1024 + - length: 4264 + rva: 78632 + offset: 28968 + type: RESOURCE_TYPE_ICON + id: 3 + language: 1024 + - length: 9640 + rva: 82896 + offset: 33232 + type: RESOURCE_TYPE_ICON + id: 4 + language: 1024 + - length: 16936 + rva: 92536 + offset: 42872 + type: RESOURCE_TYPE_ICON + id: 5 + language: 1024 + - length: 26600 + rva: 109472 + offset: 59808 + type: RESOURCE_TYPE_ICON + id: 6 + language: 1024 + - length: 38056 + rva: 136072 + offset: 86408 + type: RESOURCE_TYPE_ICON + id: 7 + language: 1024 + - length: 52008 + rva: 174128 + offset: 124464 + type: RESOURCE_TYPE_ICON + id: 8 + language: 1024 + - length: 67624 + rva: 226136 + offset: 176472 + type: RESOURCE_TYPE_ICON + id: 9 + language: 1024 + - length: 43190 + rva: 293760 + offset: 244096 + type: RESOURCE_TYPE_ICON + id: 10 + language: 1024 + - length: 6 + rva: 336952 + offset: 287288 + type: RESOURCE_TYPE_RCDATA + id: 2 + language: 1024 + - length: 2 + rva: 336960 + offset: 287296 + type: RESOURCE_TYPE_RCDATA + id: 8 + language: 1024 + - length: 10 + rva: 336968 + offset: 287304 + type: RESOURCE_TYPE_RCDATA + id: 10 + language: 1024 + - length: 18 + rva: 336984 + offset: 287320 + type: RESOURCE_TYPE_RCDATA + id: 14 + language: 1024 + - length: 24 + rva: 337008 + offset: 287344 + type: RESOURCE_TYPE_RCDATA + id: 15 + language: 1024 + - length: 2601 + rva: 337032 + offset: 287368 + type: RESOURCE_TYPE_RCDATA + id: 16 + language: 1024 + - length: 2 + rva: 339640 + offset: 289976 + type: RESOURCE_TYPE_RCDATA + id: 18 + language: 1024 + - length: 4 + rva: 339648 + offset: 289984 + type: RESOURCE_TYPE_RCDATA + id: 20 + language: 1024 + - length: 26 + rva: 339656 + offset: 289992 + type: RESOURCE_TYPE_RCDATA + id: 21 + language: 1024 + - length: 44 + rva: 339688 + offset: 290024 + type: RESOURCE_TYPE_RCDATA + id: 22 + language: 1024 + - length: 2 + rva: 339736 + offset: 290072 + type: RESOURCE_TYPE_RCDATA + id: 30 + language: 1024 + - length: 50 + rva: 339744 + offset: 290080 + type: RESOURCE_TYPE_RCDATA + id: 101 + language: 1024 + - length: 115 + rva: 339800 + offset: 290136 + type: RESOURCE_TYPE_RCDATA + id: 102 + language: 1024 + - length: 53 + rva: 339920 + offset: 290256 + type: RESOURCE_TYPE_RCDATA + id: 103 + language: 1024 + - length: 104 + rva: 339976 + offset: 290312 + type: RESOURCE_TYPE_RCDATA + id: 104 + language: 1024 + - length: 146 + rva: 340080 + offset: 290416 + type: RESOURCE_TYPE_GROUP_ICON + id: 1 + language: 1024 +import_details: + - library_name: "ADVAPI32.DLL" + number_of_functions: 4 + functions: + - name: "RegCloseKey" + rva: 70064 + - name: "RegEnumKeyExA" + rva: 70068 + - name: "RegOpenKeyExA" + rva: 70072 + - name: "RegQueryValueExA" + rva: 70076 + - library_name: "KERNEL32.dll" + number_of_functions: 23 + functions: + - name: "CloseHandle" + rva: 70088 + - name: "CreateMutexA" + rva: 70092 + - name: "CreateProcessA" + rva: 70096 + - name: "ExitProcess" + rva: 70100 + - name: "FindResourceExA" + rva: 70104 + - name: "FormatMessageA" + rva: 70108 + - name: "GetCommandLineA" + rva: 70112 + - name: "GetCurrentDirectoryA" + rva: 70116 + - name: "GetCurrentProcess" + rva: 70120 + - name: "GetEnvironmentVariableA" + rva: 70124 + - name: "GetExitCodeProcess" + rva: 70128 + - name: "GetLastError" + rva: 70132 + - name: "GetModuleFileNameA" + rva: 70136 + - name: "GetModuleHandleA" + rva: 70140 + - name: "GetProcAddress" + rva: 70144 + - name: "GlobalMemoryStatusEx" + rva: 70148 + - name: "LoadResource" + rva: 70152 + - name: "LocalFree" + rva: 70156 + - name: "LockResource" + rva: 70160 + - name: "SetEnvironmentVariableA" + rva: 70164 + - name: "SetLastError" + rva: 70168 + - name: "SetUnhandledExceptionFilter" + rva: 70172 + - name: "WaitForSingleObject" + rva: 70176 + - library_name: "msvcrt.dll" + number_of_functions: 38 + functions: + - name: "__getmainargs" + rva: 70188 + - name: "__p__environ" + rva: 70192 + - name: "__p__fmode" + rva: 70196 + - name: "__set_app_type" + rva: 70200 + - name: "_cexit" + rva: 70204 + - name: "_chdir" + rva: 70208 + - name: "_close" + rva: 70212 + - name: "_findclose" + rva: 70216 + - name: "_findfirst" + rva: 70220 + - name: "_findnext" + rva: 70224 + - name: "_iob" + rva: 70228 + - name: "_itoa" + rva: 70232 + - name: "_onexit" + rva: 70236 + - name: "_open" + rva: 70240 + - name: "_read" + rva: 70244 + - name: "_setmode" + rva: 70248 + - name: "_stat" + rva: 70252 + - name: "atexit" + rva: 70256 + - name: "atoi" + rva: 70260 + - name: "fclose" + rva: 70264 + - name: "fopen" + rva: 70268 + - name: "fprintf" + rva: 70272 + - name: "fwrite" + rva: 70276 + - name: "memset" + rva: 70280 + - name: "printf" + rva: 70284 + - name: "puts" + rva: 70288 + - name: "signal" + rva: 70292 + - name: "strcat" + rva: 70296 + - name: "strchr" + rva: 70300 + - name: "strcmp" + rva: 70304 + - name: "strcpy" + rva: 70308 + - name: "strlen" + rva: 70312 + - name: "strncat" + rva: 70316 + - name: "strncpy" + rva: 70320 + - name: "strpbrk" + rva: 70324 + - name: "strrchr" + rva: 70328 + - name: "strstr" + rva: 70332 + - name: "strtok" + rva: 70336 + - library_name: "SHELL32.DLL" + number_of_functions: 1 + functions: + - name: "ShellExecuteA" + rva: 70348 + - library_name: "USER32.dll" + number_of_functions: 1 + functions: + - name: "MessageBoxA" + rva: 70360 +is_signed: true +signatures: + - subject: "/C=DE/L=Berlin/O=Open Source/OU=JSIDPlay2/CN=JSIDPlay2" + issuer: "/C=DE/L=Berlin/O=Open Source/OU=JSIDPlay2/CN=JSIDPlay2" + thumbprint: "758bc86feadbd23a2c8fbdaa63779115eadbd905" + version: 3 + algorithm: "dsa_with_SHA256" + algorithm_oid: "2.16.840.1.101.3.4.3.2" + serial: "33:82:2c:5d" + not_before: 1655157631 # 2022-06-13 22:00:31 UTC + not_after: 1686693631 # 2023-06-13 22:00:31 UTC + verified: true + digest_alg: "sha256" + digest: "066dd89dfe23283d2feb029bcec19c31e41082584d57bd9940bfcafb83419677" + file_digest: "066dd89dfe23283d2feb029bcec19c31e41082584d57bd9940bfcafb83419677" + number_of_certificates: 1 + number_of_countersignatures: 0 + signer_info: + program_name: "JSIDPlay2" + digest: "01a9b8d4bb48229806d6425d6a1aed0dbdd55f8aaaa6c92c2a450902187abc34" + digest_alg: "sha256" + chain: + - issuer: "/C=DE/L=Berlin/O=Open Source/OU=JSIDPlay2/CN=JSIDPlay2" + subject: "/C=DE/L=Berlin/O=Open Source/OU=JSIDPlay2/CN=JSIDPlay2" + thumbprint: "758bc86feadbd23a2c8fbdaa63779115eadbd905" + version: 3 + algorithm: "dsa_with_SHA256" + algorithm_oid: "2.16.840.1.101.3.4.3.2" + serial: "33:82:2c:5d" + not_before: 1655157631 # 2022-06-13 22:00:31 UTC + not_after: 1686693631 # 2023-06-13 22:00:31 UTC + certificates: + - issuer: "/C=DE/L=Berlin/O=Open Source/OU=JSIDPlay2/CN=JSIDPlay2" + subject: "/C=DE/L=Berlin/O=Open Source/OU=JSIDPlay2/CN=JSIDPlay2" + thumbprint: "758bc86feadbd23a2c8fbdaa63779115eadbd905" + version: 3 + algorithm: "dsa_with_SHA256" + algorithm_oid: "2.16.840.1.101.3.4.3.2" + serial: "33:82:2c:5d" + not_before: 1655157631 # 2022-06-13 22:00:31 UTC + not_after: 1686693631 # 2023-06-13 22:00:31 UTC +overlay: + offset: 290816 + size: 1760 \ No newline at end of file From a9b461a6cc41c697f7fb2142a5724c62820f999a Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Sat, 27 Apr 2024 13:06:03 +0200 Subject: [PATCH 31/38] fix: recognize obsolete OID. --- lib/src/modules/pe/asn1.rs | 5 +++-- lib/src/modules/pe/authenticode.rs | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/src/modules/pe/asn1.rs b/lib/src/modules/pe/asn1.rs index 32ac38966..7fae451bc 100644 --- a/lib/src/modules/pe/asn1.rs +++ b/lib/src/modules/pe/asn1.rs @@ -102,7 +102,7 @@ pub mod oid { /// Similar to 1.2.840.113549.1.1.5. Obsolete, but still present in some files /// like: 111aeddc6a6dbf64b28cb565aa12af9ee3cc0a56ce31e4da0068cf6b474c3288 - pub const SHA1_WITH_RSA_ENCRYPTION: ObjectIdentifier = + pub const SHA1_WITH_RSA_ENCRYPTION_OBSOLETE: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.14.3.2.29"); } @@ -122,7 +122,8 @@ pub fn oid_to_str(oid: &Oid) -> Cow<'static, str> { rfc5912::MD_5_WITH_RSA_ENCRYPTION => { Cow::Borrowed("md5WithRSAEncryption") } - oid::SHA1_WITH_RSA_ENCRYPTION | rfc5912::SHA_1_WITH_RSA_ENCRYPTION => { + oid::SHA1_WITH_RSA_ENCRYPTION_OBSOLETE + | rfc5912::SHA_1_WITH_RSA_ENCRYPTION => { Cow::Borrowed("sha1WithRSAEncryption") } rfc5912::SHA_256_WITH_RSA_ENCRYPTION => { diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 3cc49b1a3..afde6c00d 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -955,7 +955,8 @@ impl PublicKey { } rfc5912::ID_SHA_1 | rfc5912::DSA_WITH_SHA_1 - | rfc5912::SHA_1_WITH_RSA_ENCRYPTION => { + | rfc5912::SHA_1_WITH_RSA_ENCRYPTION + | oid::SHA1_WITH_RSA_ENCRYPTION_OBSOLETE => { self.verify_impl::(message, signature) } rfc5912::ID_SHA_256 From a69140d54cee7a2e87e4d3b0dd655db715b7ffa9 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Sat, 27 Apr 2024 16:34:13 +0200 Subject: [PATCH 32/38] fix: implement the Authenticode hash algorithm according to the specification --- lib/src/modules/pe/parser.rs | 51 +++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/lib/src/modules/pe/parser.rs b/lib/src/modules/pe/parser.rs index 0a59f52c1..f37b286b7 100644 --- a/lib/src/modules/pe/parser.rs +++ b/lib/src/modules/pe/parser.rs @@ -414,16 +414,14 @@ impl<'a> PE<'a> { /// * The security entry in the data directory (which points to the certificate table) /// * The certificate table. /// - /// The algorithm is described in the [PE format specification][1]. + /// The algorithm is described in [1] and [2]. /// /// [1]: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#process-for-generating-the-authenticode-pe-image-hash + /// [2]: https://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/authenticode_pe.docx pub fn authenticode_hash( &self, digest: &mut dyn digest::Update, ) -> Option<()> { - // TODO: according to the specification the sections must be sorted before - // computing the hash. - // Offset within the PE file where the checksum field is located. The // checksum is skipped while computing the digest. let checksum_offset = self.dos_stub.len() @@ -444,6 +442,9 @@ impl<'a> PE<'a> { } + Self::SIZE_OF_DIR_ENTRY * Self::IMAGE_DIRECTORY_ENTRY_SECURITY; + let (_, cert_table_size, _) = self + .get_dir_entry_data(Self::IMAGE_DIRECTORY_ENTRY_SECURITY, true)?; + // Hash from start of the file to the checksum. digest.update(self.data.get(0..checksum_offset)?); @@ -453,20 +454,44 @@ impl<'a> PE<'a> { checksum_offset + mem::size_of::()..security_data_offset, )?); - let (cert_table_offset, cert_table_size, _) = self - .get_dir_entry_data(Self::IMAGE_DIRECTORY_ENTRY_SECURITY, true)?; - - // Hash from the end of the security entry in the data directory, to the - // certificate table. + // Hash from the end of the security entry in the data directory to the + // end of the PE header. digest.update(self.data.get( security_data_offset + Self::SIZE_OF_DIR_ENTRY - ..cert_table_offset as usize, + ..self.optional_hdr.size_of_headers as usize, )?); - // Hash from the end of the certificate table to the end of the file. + // Sections must be sorted by `raw_data_offset`. + let sections = self + .sections + .iter() + .sorted_unstable_by_key(|section| section.raw_data_offset); + + let mut sum_of_bytes_hashed = + self.optional_hdr.size_of_headers as usize; + + // Hash each section's data. + for section in sections { + let section_start = section.raw_data_offset as usize; + let section_size = section.raw_data_size as usize; + let section_end = section_start.saturating_add(section_size); + let section_bytes = self.data.get(section_start..section_end)?; + + digest.update(section_bytes); + + sum_of_bytes_hashed = + sum_of_bytes_hashed.checked_add(section_size)?; + } + + let extra_hash_len = self + .data + .len() + .checked_sub(cert_table_size as usize)? + .checked_sub(sum_of_bytes_hashed)?; + digest.update(self.data.get( - cert_table_offset as usize + cert_table_size as usize - ..self.data.len(), + sum_of_bytes_hashed + ..sum_of_bytes_hashed.checked_add(extra_hash_len)?, )?); Some(()) From 432659f984be12c1a05cc9caf61bc9e62217672c Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Sat, 27 Apr 2024 19:32:53 +0200 Subject: [PATCH 33/38] fix: issue while parsing nested signatures. The attribute containing the nested signatures can have more than one value, each with one signature. --- lib/src/modules/pe/authenticode.rs | 21 +- ...a9e3ddb8b19f6d664e95f8d0e103866ea22.in.zip | Bin 0 -> 179431 bytes ...0efa9e3ddb8b19f6d664e95f8d0e103866ea22.out | 18221 ++++++++++++++++ 3 files changed, 18232 insertions(+), 10 deletions(-) create mode 100644 lib/src/modules/pe/tests/testdata/9d8196aa4afce055daa9edb3130efa9e3ddb8b19f6d664e95f8d0e103866ea22.in.zip create mode 100644 lib/src/modules/pe/tests/testdata/9d8196aa4afce055daa9edb3130efa9e3ddb8b19f6d664e95f8d0e103866ea22.out diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index afde6c00d..77adb6fc5 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -188,17 +188,18 @@ impl AuthenticodeParser { match attr.attr_type.as_bytes() { // SignerInfo can have unsigned attributes containing nested // Authenticode signatures. These attributes are identified by - // OID 1.3.6.1.4.1.311.2.4.1 and their content is a `ContentInfo` - // structure. Find those attributes, parse their first (and only) - // value, and append resulting signatures to `nested_signatures`. + // OID 1.3.6.1.4.1.311.2.4.1 and their values are `ContentInfo` + // structures. Find those attributes, parse their values, and + // append the resulting signatures to `nested_signatures`. oid::MS_NESTED_SIGNATURE_B => { - if let Some(nested) = - attr.attr_values.first().and_then(|first_value| { - let content_info = first_value.try_into().ok()?; - Self::parse_content_info(content_info, pe).ok() - }) - { - nested_signatures.extend(nested); + for value in &attr.attr_values { + if let Ok(content_info) = value.try_into() { + if let Ok(nested) = + Self::parse_content_info(content_info, pe) + { + nested_signatures.extend(nested); + } + }; } } oid::MS_COUNTERSIGN_B => { diff --git a/lib/src/modules/pe/tests/testdata/9d8196aa4afce055daa9edb3130efa9e3ddb8b19f6d664e95f8d0e103866ea22.in.zip b/lib/src/modules/pe/tests/testdata/9d8196aa4afce055daa9edb3130efa9e3ddb8b19f6d664e95f8d0e103866ea22.in.zip new file mode 100644 index 0000000000000000000000000000000000000000..5dc363988431bacf346c6456678000bba0f52f8f GIT binary patch literal 179431 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 Date: Sun, 28 Apr 2024 19:30:58 +0200 Subject: [PATCH 34/38] refactor: some refactor and documentation improvements. --- lib/src/modules/pe/asn1.rs | 24 +++- lib/src/modules/pe/authenticode.rs | 120 ++++++++++++++----- lib/src/modules/pe/parser.rs | 184 ++++++++++++++--------------- 3 files changed, 204 insertions(+), 124 deletions(-) diff --git a/lib/src/modules/pe/asn1.rs b/lib/src/modules/pe/asn1.rs index 7fae451bc..5e9b26c74 100644 --- a/lib/src/modules/pe/asn1.rs +++ b/lib/src/modules/pe/asn1.rs @@ -327,14 +327,32 @@ impl<'a> TryFrom> for SignedData<'a> { /// [1]: https://datatracker.ietf.org/doc/html/rfc5652#section-5.3 pub struct SignerInfo<'a> { pub version: i32, + /// Unsigned attributes that contain information about the signer. + /// These attributes are not protected by the signature, they are usually + /// added after the signature has been generated. For example, they + /// contain countersignatures, which are signatures of the signatures. + pub unsigned_attrs: Vec>, + /// Signed attributes that contain information about the signer. + /// These attributes can't be tampered without invalidating the + /// signature in `signature_value`. + pub signed_attrs: Vec>, + /// The raw bytes of the signed attributes, as they appear in the PE + /// files. Used for computing the digest during the validation process. + pub raw_signed_attrs: &'a [u8], pub issuer: X509Name<'a>, + /// The serial number of the certificate that signed this structure. The + /// produced signature is stored in the `signature_value` field. pub serial_number: BigUint, + /// The digest algorithm used during the signing process. This digest + /// algorithm is applied to the DER encoding of the signed attributes + /// in the `signed_attrs` field. Then the digest itself is signed. pub digest_algorithm: AlgorithmIdentifier<'a>, + /// The signature algorithm (RSA, DSA, ECDSA) used for producing the + /// signature. pub signature_algorithm: AlgorithmIdentifier<'a>, + /// The signature itself. This signature can be validated by using + /// the public key stored in the certified identified by `serial_number`. pub signature_value: &'a [u8], - pub raw_signed_attrs: &'a [u8], - pub signed_attrs: Vec>, - pub unsigned_attrs: Vec>, } impl<'a> SignerInfo<'a> { diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 77adb6fc5..51930389c 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -14,6 +14,12 @@ use md5::Md5; use nom::AsBytes; use protobuf::MessageField; +use crate::modules::pe::asn1::{ + oid, oid_to_object_identifier, oid_to_str, Attribute, Certificate, + ContentInfo, DigestInfo, SignedData, SignerInfo, SpcIndirectDataContent, + SpcSpOpusInfo, TstInfo, +}; +use crate::modules::protos; use rsa::traits::SignatureScheme; use rsa::Pkcs1v15Sign; use sha1::Sha1; @@ -23,14 +29,6 @@ use x509_parser::der_parser::num_bigint::BigUint; use x509_parser::prelude::{AlgorithmIdentifier, X509Certificate}; use x509_parser::x509::{SubjectPublicKeyInfo, X509Name}; -use crate::modules::pe::asn1::{ - oid, oid_to_object_identifier, oid_to_str, Attribute, Certificate, - ContentInfo, DigestInfo, SignedData, SignerInfo, SpcIndirectDataContent, - SpcSpOpusInfo, TstInfo, -}; -use crate::modules::pe::parser::PE; -use crate::modules::protos; - /// Error returned by [`AuthenticodeParser::parse`]. #[derive(Clone, Debug, Eq, PartialEq)] pub enum ParseError { @@ -58,15 +56,6 @@ pub enum ParseError { /// The number of signer infos is not 1. InvalidNumSignerInfo, - /// The version of [`SignerInfo`] is not 1. - InvalidSignerInfoVersion(i64), - - /// The digest algorithm is not internally consistent. - AlgorithmMismatch, - - /// No authenticated attributes are present. - EmptyAuthenticatedAttributes, - /// The `contentType` authenticated attribute is missing. MissingContentTypeAuthenticatedAttribute, @@ -75,6 +64,18 @@ pub enum ParseError { MissingAuthenticodeDigest, } +/// Trait implemented by any type that is able to compute the Authenticode +/// hash for a PE file. +pub trait AuthenticodeHasher { + /// Computes the Authenticode digest. + /// + /// The `digest` argument is any type implementing the [`digest::Update`] + /// trait, like [`Md5`], [`Sha1`] and [`Sha256`]. It should be newly created + /// digest that hasn't being updated with any data yet. When this function + /// returns the digest's output is the Authenticode hash. + fn hash(&self, digest: &mut dyn digest::Update) -> Option<()>; +} + /// Parses Authenticode signatures in a PE file. /// /// Some resources for understanding Authenticode signatures: @@ -87,17 +88,17 @@ impl AuthenticodeParser { /// Parses Authenticode signatures from DER-encoded bytes. pub fn parse<'a>( input: &'a [u8], - pe: &PE, + authenticode_hasher: &impl AuthenticodeHasher, ) -> Result>, ParseError> { let content_info = ContentInfo::from_ber(input) .map_err(|_| ParseError::InvalidContentInfo)?; - Self::parse_content_info(content_info, pe) + Self::parse_content_info(content_info, authenticode_hasher) } fn parse_content_info<'a>( content_info: ContentInfo<'a>, - pe: &PE, + authenticode_hasher: &impl AuthenticodeHasher, ) -> Result>, ParseError> { if content_info.content_type != oid::SIGNED_DATA { return Err(ParseError::InvalidContentType( @@ -194,9 +195,10 @@ impl AuthenticodeParser { oid::MS_NESTED_SIGNATURE_B => { for value in &attr.attr_values { if let Ok(content_info) = value.try_into() { - if let Ok(nested) = - Self::parse_content_info(content_info, pe) - { + if let Ok(nested) = Self::parse_content_info( + content_info, + authenticode_hasher, + ) { nested_signatures.extend(nested); } }; @@ -228,27 +230,27 @@ impl AuthenticodeParser { match signer_info.digest_algorithm.oid().as_bytes() { oid::MD5_B => { let mut md5 = Md5::default(); - pe.authenticode_hash(&mut md5); + authenticode_hasher.hash(&mut md5); md5.finalize().to_vec() } oid::SHA_1_B => { let mut sha1 = Sha1::default(); - pe.authenticode_hash(&mut sha1); + authenticode_hasher.hash(&mut sha1); sha1.finalize().to_vec() } oid::SHA_256_B => { let mut sha256 = Sha256::default(); - pe.authenticode_hash(&mut sha256); + authenticode_hasher.hash(&mut sha256); sha256.finalize().to_vec() } oid::SHA_384_B => { let mut sha384 = Sha384::default(); - pe.authenticode_hash(&mut sha384); + authenticode_hasher.hash(&mut sha384); sha384.finalize().to_vec() } oid::SHA_512_B => { let mut sha512 = Sha512::default(); - pe.authenticode_hash(&mut sha512); + authenticode_hasher.hash(&mut sha512); sha512.finalize().to_vec() } oid => unimplemented!("{:?}", oid), @@ -698,9 +700,32 @@ fn verify_message_digest( } } +/// Verifies that the [`SignerInfo`] struct is valid. +/// +/// `SignerInfo` contains information about the signer of some data stored in +/// the content field of a [`SignedData`] structure. This information is stored +/// in signed and unsigned attributes of `SignerInfo`. Signed attributes are +/// protected from tampering by a digital signature, which is computed by +/// hashing the attributes first, and then signing the hash. The resulting +/// signature is added `SignerInfo` itself. This signature can be verified by +/// using the public key included in the certificate identified by +/// [`SignerInfo::serial_number`]. +/// +/// This function makes sure that: +/// +/// * The signature of `SignerInfo` is correct. +/// * The certificate that produced the signature for `SignerInfo` is also +/// correct. +/// +/// The verification of the certificate includes the verification of the whole +/// certificate chain, until reaching a self-signed certificate or some +/// certificate that was signed by an "external" one (a certificate that is not +/// included in the PE). fn verify_signer_info(si: &SignerInfo, certs: &[Certificate<'_>]) -> bool { // Get a certificate chain that starts with the certificate that signed - // data and contains all the certificates in the chain of truth. + // the data that this SignerInfo refers to. This chain goes from the + // signing certificate up in the chain of truth until a self-signed + // certificate or some "external" certificate. let cert_chain = CertificateChain::new(certs, |cert| { cert.tbs_certificate.serial.eq(&si.serial_number) }); @@ -720,6 +745,43 @@ fn verify_signer_info(si: &SignerInfo, certs: &[Certificate<'_>]) -> bool { None => return false, }; + // We need to compute the hash for the signed attributes. This is a hash of + // the DER encoding of the attributes, however, the computation of the hash + // is not straightforward. One may think that the hash can be computed over + // the bytes in the PE file that correspond to the DER encoding of the + // attributes, but that's not the case. In fact, the PE file doesn't + // contain the exact byte sequence that must be hashed. + // + // This is the ASN.1 definition for the signed attributes: + // + // SignedAttributes ::= SET SIZE (1..MAX) OF Attribute + // + // Normally, the raw bytes of an ASN.1 `SET` start with 0x31 (the tag + // associated to sets), followed by the set size, and the set contents. + // The raw bytes would be `0x31 [size] [content]`. But ASN.1 encoding is + // context-sensitive, which means that the 0x31 tag can be missing if + // SignedAttributes is used in a parent structure using implicit + // tagging, for instance: + // + // signedAttrs `[0]` IMPLICIT SignedAttributes OPTIONAL, + // + // Within the SignerInfo structure, the tag 0 identifies the signedAttrs + // field, when this tag is found, the ASN.1 parser already knows that + // a SignedAttributes follows, and it already knows that it's a SET, + // therefore the 0x31 is not necessary. The raw bytes are: + // + // 0xA0 [size] [content] + // + // `0xA0` is the raw encoding for `[0]`. + // + // In resume, the PE file has: + // + // 0xA0 [size] [content] + // + // But the hash is computed for: + // + // 0x31 [size] [content] + // let attrs_set = Set::new(Cow::Borrowed(si.raw_signed_attrs)); let attrs_set_der = attrs_set.to_der_vec_raw().unwrap(); diff --git a/lib/src/modules/pe/parser.rs b/lib/src/modules/pe/parser.rs index f37b286b7..d972b50b6 100644 --- a/lib/src/modules/pe/parser.rs +++ b/lib/src/modules/pe/parser.rs @@ -8,6 +8,7 @@ use std::str::{from_utf8, FromStr}; use std::sync::OnceLock; use bstr::{BStr, ByteSlice}; +use digest; use itertools::Itertools; use memchr::memmem; use nom::branch::{alt, permutation}; @@ -23,7 +24,7 @@ use nom::{Err, IResult, Parser, ToUsize}; use protobuf::{EnumOrUnknown, MessageField}; use crate::modules::pe::authenticode::{ - AuthenticodeParser, AuthenticodeSignature, + AuthenticodeHasher, AuthenticodeParser, AuthenticodeSignature, }; use crate::modules::pe::rva2off; use crate::modules::protos; @@ -102,6 +103,96 @@ pub struct PE<'a> { pub optional_hdr: OptionalHeader, } +impl AuthenticodeHasher for PE<'_> { + /// Compute an Authenticode hash for this PE file. + /// + /// The Authenticode covers all the data in the PE file except: + /// + /// * The checksum in the PE header + /// * The security entry in the data directory (which points to the certificate table) + /// * The certificate table. + /// + /// The algorithm is described in [1] and [2]. + /// + /// [1]: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#process-for-generating-the-authenticode-pe-image-hash + /// [2]: https://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/authenticode_pe.docx + fn hash(&self, digest: &mut dyn digest::Update) -> Option<()> { + // Offset within the PE file where the checksum field is located. The + // checksum is skipped while computing the digest. + let checksum_offset = self.dos_stub.len() + + Self::SIZE_OF_PE_SIGNATURE + + Self::SIZE_OF_FILE_HEADER + + 64_usize; + + // Offset of the security entry in the data directory. This entry is skipped + // while computing the digest. + let security_data_offset = self.dos_stub.len() + + Self::SIZE_OF_PE_SIGNATURE + + Self::SIZE_OF_FILE_HEADER + + if self.optional_hdr.magic == Self::IMAGE_NT_OPTIONAL_HDR32_MAGIC + { + Self::SIZE_OF_OPT_HEADER_32 + } else { + Self::SIZE_OF_OPT_HEADER_64 + } + + Self::SIZE_OF_DIR_ENTRY * Self::IMAGE_DIRECTORY_ENTRY_SECURITY; + + let (_, cert_table_size, _) = self + .get_dir_entry_data(Self::IMAGE_DIRECTORY_ENTRY_SECURITY, true)?; + + // Hash from start of the file to the checksum. + digest.update(self.data.get(0..checksum_offset)?); + + // Hash from the end of the checksum to the start of the security entry + // in the data directory. + digest.update(self.data.get( + checksum_offset + mem::size_of::()..security_data_offset, + )?); + + // Hash from the end of the security entry in the data directory to the + // end of the PE header. + digest.update(self.data.get( + security_data_offset + Self::SIZE_OF_DIR_ENTRY + ..self.optional_hdr.size_of_headers as usize, + )?); + + // Sections must be sorted by `raw_data_offset`. + let sections = self + .sections + .iter() + .sorted_unstable_by_key(|section| section.raw_data_offset); + + let mut sum_of_bytes_hashed = + self.optional_hdr.size_of_headers as usize; + + // Hash each section's data. + for section in sections { + let section_start = section.raw_data_offset as usize; + let section_size = section.raw_data_size as usize; + let section_end = section_start.saturating_add(section_size); + let section_bytes = self.data.get(section_start..section_end)?; + + digest.update(section_bytes); + + sum_of_bytes_hashed = + sum_of_bytes_hashed.checked_add(section_size)?; + } + + let extra_hash_len = self + .data + .len() + .checked_sub(cert_table_size as usize)? + .checked_sub(sum_of_bytes_hashed)?; + + digest.update(self.data.get( + sum_of_bytes_hashed + ..sum_of_bytes_hashed.checked_add(extra_hash_len)?, + )?); + + Some(()) + } +} + impl<'a> PE<'a> { /// Given the content of PE file, parses it and returns a [`PE`] object /// representing the file. @@ -405,97 +496,6 @@ impl<'a> PE<'a> { .map(|s| s.as_slice()) .unwrap_or(&[]) } - - /// Compute an Authenticode hash for this PE file. - /// - /// The Authenticode covers all the data in the PE file except: - /// - /// * The checksum in the PE header - /// * The security entry in the data directory (which points to the certificate table) - /// * The certificate table. - /// - /// The algorithm is described in [1] and [2]. - /// - /// [1]: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#process-for-generating-the-authenticode-pe-image-hash - /// [2]: https://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/authenticode_pe.docx - pub fn authenticode_hash( - &self, - digest: &mut dyn digest::Update, - ) -> Option<()> { - // Offset within the PE file where the checksum field is located. The - // checksum is skipped while computing the digest. - let checksum_offset = self.dos_stub.len() - + Self::SIZE_OF_PE_SIGNATURE - + Self::SIZE_OF_FILE_HEADER - + 64_usize; - - // Offset of the security entry in the data directory. This entry is skipped - // while computing the digest. - let security_data_offset = self.dos_stub.len() - + Self::SIZE_OF_PE_SIGNATURE - + Self::SIZE_OF_FILE_HEADER - + if self.optional_hdr.magic == Self::IMAGE_NT_OPTIONAL_HDR32_MAGIC - { - Self::SIZE_OF_OPT_HEADER_32 - } else { - Self::SIZE_OF_OPT_HEADER_64 - } - + Self::SIZE_OF_DIR_ENTRY * Self::IMAGE_DIRECTORY_ENTRY_SECURITY; - - let (_, cert_table_size, _) = self - .get_dir_entry_data(Self::IMAGE_DIRECTORY_ENTRY_SECURITY, true)?; - - // Hash from start of the file to the checksum. - digest.update(self.data.get(0..checksum_offset)?); - - // Hash from the end of the checksum to the start of the security entry - // in the data directory. - digest.update(self.data.get( - checksum_offset + mem::size_of::()..security_data_offset, - )?); - - // Hash from the end of the security entry in the data directory to the - // end of the PE header. - digest.update(self.data.get( - security_data_offset + Self::SIZE_OF_DIR_ENTRY - ..self.optional_hdr.size_of_headers as usize, - )?); - - // Sections must be sorted by `raw_data_offset`. - let sections = self - .sections - .iter() - .sorted_unstable_by_key(|section| section.raw_data_offset); - - let mut sum_of_bytes_hashed = - self.optional_hdr.size_of_headers as usize; - - // Hash each section's data. - for section in sections { - let section_start = section.raw_data_offset as usize; - let section_size = section.raw_data_size as usize; - let section_end = section_start.saturating_add(section_size); - let section_bytes = self.data.get(section_start..section_end)?; - - digest.update(section_bytes); - - sum_of_bytes_hashed = - sum_of_bytes_hashed.checked_add(section_size)?; - } - - let extra_hash_len = self - .data - .len() - .checked_sub(cert_table_size as usize)? - .checked_sub(sum_of_bytes_hashed)?; - - digest.update(self.data.get( - sum_of_bytes_hashed - ..sum_of_bytes_hashed.checked_add(extra_hash_len)?, - )?); - - Some(()) - } } impl<'a> PE<'a> { From 9ed23581793cf77326d6dafab2ae32b63b814998 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Sun, 28 Apr 2024 20:22:39 +0200 Subject: [PATCH 35/38] perf: prevent unnecessary memory allocation. Instead of using `to_der_vec_raw`, which allocates a vector, use `write_der` which writes directly to the hasher. --- lib/src/modules/pe/asn1.rs | 8 ++-- lib/src/modules/pe/authenticode.rs | 73 +++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 25 deletions(-) diff --git a/lib/src/modules/pe/asn1.rs b/lib/src/modules/pe/asn1.rs index 5e9b26c74..659a996cd 100644 --- a/lib/src/modules/pe/asn1.rs +++ b/lib/src/modules/pe/asn1.rs @@ -334,14 +334,14 @@ pub struct SignerInfo<'a> { pub unsigned_attrs: Vec>, /// Signed attributes that contain information about the signer. /// These attributes can't be tampered without invalidating the - /// signature in `signature_value`. + /// signature in `signature`. pub signed_attrs: Vec>, /// The raw bytes of the signed attributes, as they appear in the PE /// files. Used for computing the digest during the validation process. pub raw_signed_attrs: &'a [u8], pub issuer: X509Name<'a>, /// The serial number of the certificate that signed this structure. The - /// produced signature is stored in the `signature_value` field. + /// produced signature is stored in the `signature` field. pub serial_number: BigUint, /// The digest algorithm used during the signing process. This digest /// algorithm is applied to the DER encoding of the signed attributes @@ -352,7 +352,7 @@ pub struct SignerInfo<'a> { pub signature_algorithm: AlgorithmIdentifier<'a>, /// The signature itself. This signature can be validated by using /// the public key stored in the certified identified by `serial_number`. - pub signature_value: &'a [u8], + pub signature: &'a [u8], } impl<'a> SignerInfo<'a> { @@ -403,7 +403,7 @@ impl<'a> SignerInfo<'a> { signed_attrs, raw_signed_attrs, unsigned_attrs: unsigned_attrs.unwrap_or_default(), - signature_value: signature.content.as_slice()?, + signature: signature.content.as_slice()?, issuer, serial_number, digest_algorithm, diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 51930389c..f8c56c30e 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -5,7 +5,7 @@ use array_bytes::bytes2hex; use const_oid::db::{rfc5912, rfc6268}; use const_oid::{AssociatedOid, ObjectIdentifier}; use der_parser::asn1_rs::{Set, Tag, ToDer, UtcTime}; -use digest::Digest; +use digest::{Digest, Output}; use dsa::Components; use ecdsa::signature::hazmat::PrehashVerifier; @@ -331,7 +331,7 @@ impl AuthenticodeParser { countersignature.verified = verify_message_digest( &tst.hash_algorithm, - si.signature_value, + si.signature, tst.hashed_message, ) && verify_signer_info(cs_si, certificates.as_slice()); @@ -355,7 +355,7 @@ impl AuthenticodeParser { countersignature.verified = verify_message_digest( &cs_si.digest_algorithm, - si.signature_value, + si.signature, countersignature.digest, ) && verify_signer_info(&cs_si, certificates.as_slice()); @@ -745,6 +745,13 @@ fn verify_signer_info(si: &SignerInfo, certs: &[Certificate<'_>]) -> bool { None => return false, }; + // Obtain the public key included in the certificate. + let spki = &signing_cert.tbs_certificate.subject_pki; + let key = match PublicKey::try_from(spki) { + Ok(key) => key, + Err(_) => return false, + }; + // We need to compute the hash for the signed attributes. This is a hash of // the DER encoding of the attributes, however, the computation of the hash // is not straightforward. One may think that the hash can be computed over @@ -783,21 +790,37 @@ fn verify_signer_info(si: &SignerInfo, certs: &[Certificate<'_>]) -> bool { // 0x31 [size] [content] // let attrs_set = Set::new(Cow::Borrowed(si.raw_signed_attrs)); - let attrs_set_der = attrs_set.to_der_vec_raw().unwrap(); - - // Obtain the public key included in the certificate. - let spki = &signing_cert.tbs_certificate.subject_pki; - let key = match PublicKey::try_from(spki) { - Ok(key) => key, - Err(_) => return false, - }; // Verify that the signature in `SignerInfo` is correct. - key.verify( - &si.digest_algorithm, - attrs_set_der.as_slice(), - si.signature_value, - ) + match oid_to_object_identifier(si.digest_algorithm.oid()) { + rfc5912::ID_MD_5 => { + let mut md5 = Md5::default(); + attrs_set.write_der(&mut md5).unwrap(); + key.verify_digest::(md5.finalize(), si.signature) + } + rfc5912::ID_SHA_1 => { + let mut sha1 = Sha1::default(); + attrs_set.write_der(&mut sha1).unwrap(); + key.verify_digest::(sha1.finalize(), si.signature) + } + rfc5912::ID_SHA_256 => { + let mut sha256 = Sha256::default(); + attrs_set.write_der(&mut sha256).unwrap(); + key.verify_digest::(sha256.finalize(), si.signature) + } + rfc5912::ID_SHA_384 => { + let mut sha384 = Sha384::default(); + attrs_set.write_der(&mut sha384).unwrap(); + key.verify_digest::(sha384.finalize(), si.signature) + } + rfc5912::ID_SHA_512 => { + let mut sha512 = Sha512::default(); + attrs_set.write_der(&mut sha512).unwrap(); + key.verify_digest::(sha512.finalize(), si.signature) + } + + oid => unimplemented!("{:?}", oid), + } } /// Represents a certificate chain. @@ -1048,31 +1071,39 @@ impl PublicKey { signature: &[u8], ) -> bool { let digest = D::digest(message); + self.verify_digest::(digest, signature) + } + + fn verify_digest( + &self, + hash: Output, + signature: &[u8], + ) -> bool { match self { Self::Rsa(key) => { if Pkcs1v15Sign::new::() - .verify(key, digest.as_slice(), signature) + .verify(key, hash.as_slice(), signature) .is_ok() { return true; } Pkcs1v15Sign::new_unprefixed() - .verify(key, digest.as_slice(), signature) + .verify(key, hash.as_slice(), signature) .is_ok() } Self::Dsa(key) => { use dsa::pkcs8::der::Decode; dsa::Signature::from_der(signature).is_ok_and(|s| { - key.verify_prehash(digest.as_slice(), &s).is_ok() + key.verify_prehash(hash.as_slice(), &s).is_ok() }) } Self::EcdsaP256(key) => ecdsa::Signature::from_der(signature) .is_ok_and(|s| { - key.verify_prehash(digest.as_slice(), &s).is_ok() + key.verify_prehash(hash.as_slice(), &s).is_ok() }), Self::EcdsaP384(key) => ecdsa::Signature::from_der(signature) .is_ok_and(|s| { - key.verify_prehash(digest.as_slice(), &s).is_ok() + key.verify_prehash(hash.as_slice(), &s).is_ok() }), } } From 4af2b724fb8072284f4db6159a6bccc0a49ce716 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Mon, 29 Apr 2024 10:08:17 +0200 Subject: [PATCH 36/38] style: code cleanup --- lib/src/modules/pe/asn1.rs | 107 +++++++---------------------- lib/src/modules/pe/authenticode.rs | 74 ++++++++++---------- 2 files changed, 61 insertions(+), 120 deletions(-) diff --git a/lib/src/modules/pe/asn1.rs b/lib/src/modules/pe/asn1.rs index 659a996cd..bfca55191 100644 --- a/lib/src/modules/pe/asn1.rs +++ b/lib/src/modules/pe/asn1.rs @@ -29,68 +29,7 @@ use x509_parser::x509::X509Name; #[allow(dead_code)] pub mod oid { use const_oid::ObjectIdentifier; - use der_parser::{oid, Oid}; - - pub const MD5: Oid = oid!(1.2.840.113549.2.5); - pub const MD5_B: &[u8] = &oid!(raw 1.2.840.113549.2.5); - - pub const SHA_1: Oid = oid!(1.3.14.3.2.26); - pub const SHA_1_B: &[u8] = &oid!(raw 1.3.14.3.2.26); - - pub const SHA_256: Oid = oid!(2.16.840.1.101.3.4.2.1); - pub const SHA_256_B: &[u8] = &oid!(raw 2.16.840.1.101.3.4.2.1); - - pub const SHA_384: Oid = oid!(2.16.840.1.101.3.4.2.2); - pub const SHA_384_B: &[u8] = &oid!(raw 2.16.840.1.101.3.4.2.2); - - pub const SHA_512: Oid = oid!(2.16.840.1.101.3.4.2.3); - pub const SHA_512_B: &[u8] = &oid!(raw 2.16.840.1.101.3.4.2.3); - - pub const MD5_WITH_RSA_ENCRYPTION: Oid = oid!(1.2.840.113549.1.1.4); - pub const MD5_WITH_RSA_ENCRYPTION_B: &[u8] = &oid!(raw 1.2.840.113549.1.1.4); - - pub const SHA_1_WITH_RSA_ENCRYPTION: Oid = oid!(1.2.840.113549.1.1.5); - pub const SHA_1_WITH_RSA_ENCRYPTION_B: &[u8] = &oid!(raw 1.2.840.113549.1.1.5); - - pub const SHA_256_WITH_RSA_ENCRYPTION: Oid = oid!(1.2.840.113549.1.1.11); - pub const SHA_256_WITH_RSA_ENCRYPTION_B: &[u8] = &oid!(raw 1.2.840.113549.1.1.11); - - pub const SHA_384_WITH_RSA_ENCRYPTION: Oid = oid!(1.2.840.113549.1.1.12); - pub const SHA_384_WITH_RSA_ENCRYPTION_B: &[u8] = &oid!(raw 1.2.840.113549.1.1.12); - - pub const SHA_512_WITH_RSA_ENCRYPTION: Oid = oid!(1.2.840.113549.1.1.13); - pub const SHA_512_WITH_RSA_ENCRYPTION_B: &[u8] = &oid!(raw 1.2.840.113549.1.1.13); - - pub const RSA_ENCRYPTION: Oid = oid!(1.2.840.113549.1.1.1); - pub const RSA_ENCRYPTION_B: &[u8] = &oid!(raw 1.2.840.113549.1.1.1); - pub const SIGNED_DATA: Oid = oid!(1.2.840.113549.1.7.2); - pub const SIGNED_DATA_B: &[u8] = &oid!(raw 1.2.840.113549.1.7.2); - - pub const MESSAGE_DIGEST: Oid = oid!(1.2.840.113549.1.9.4); - pub const MESSAGE_DIGEST_B: &[u8] = &oid!(raw 1.2.840.113549.1.9.4); - - pub const INDIRECT_DATA_OBJID: Oid = oid!(1.3.6.1.4.1.311.2.1.4); - pub const INDIRECT_DATA_OBJID_B: &[u8] = &oid!(raw 1.3.6.1.4.1.311.2.1.4); - - pub const CONTENT_TYPE: Oid = oid!(1.2.840.113549.1.9.3); - pub const CONTENT_TYPE_B: &[u8] = &oid!(raw 1.2.840.113549.1.9.3); - - pub const OPUS_INFO_OBJID: Oid = oid!(1.3.6.1.4.1.311.2.1.12); - pub const OPUS_INFO_OBJID_B: &[u8] = &oid!(raw 1.3.6.1.4.1.311.2.1.12); - - pub const MS_NESTED_SIGNATURE: Oid = oid!(1.3.6.1.4.1.311.2.4.1); - pub const MS_NESTED_SIGNATURE_B: &[u8] = &oid!(raw 1.3.6.1.4.1.311.2.4.1); - - pub const MS_COUNTERSIGN: Oid = oid!(1.3.6.1.4.1.311.3.3.1); - pub const MS_COUNTERSIGN_B: &[u8] = &oid!(raw 1.3.6.1.4.1.311.3.3.1); - - pub const PKCS9_COUNTERSIGN: Oid = oid!(1.2.840.113549.1.9.6); - pub const PKCS9_COUNTERSIGN_B: &[u8] = &oid!(raw 1.2.840.113549.1.9.6); - - pub const COUNTRY: Oid = oid!(2.5.4.6); - pub const COUNTRY_B: &[u8] = &oid!(raw 2.5.4.6); - pub const JURISDICTION_L: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.60.2.1.1"); @@ -99,7 +38,19 @@ pub mod oid { pub const JURISDICTION_C: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.60.2.1.3"); + + pub const MS_SPC_NESTED_SIGNATURE: ObjectIdentifier = + ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.2.4.1"); + + pub const MS_SPC_INDIRECT_DATA_OBJID: ObjectIdentifier = + ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.2.1.4"); + pub const MS_SPC_OPUS_INFO: ObjectIdentifier = + ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.2.1.12"); + + pub const MS_COUNTERSIGN: ObjectIdentifier = + ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.3.3.1"); + /// Similar to 1.2.840.113549.1.1.5. Obsolete, but still present in some files /// like: 111aeddc6a6dbf64b28cb565aa12af9ee3cc0a56ce31e4da0068cf6b474c3288 pub const SHA1_WITH_RSA_ENCRYPTION_OBSOLETE: ObjectIdentifier = @@ -160,7 +111,7 @@ pub fn oid_to_str(oid: &Oid) -> Cow<'static, str> { } pub struct ContentInfo<'a> { - pub content_type: Oid<'a>, + pub content_type: ObjectIdentifier, pub content: Any<'a>, } @@ -184,7 +135,10 @@ impl<'a> ContentInfo<'a> { Ok(( remainder, - Self { content_type: content_type.as_oid_val()?, content }, + Self { + content_type: oid_to_object_identifier(content_type.as_oid()?), + content, + }, )) } } @@ -233,12 +187,6 @@ pub struct SignedData<'a> { } impl<'a> SignedData<'a> { - pub fn parse(input: &'a [u8]) -> BerResult { - parse_ber_sequence_defined_g(|input: &[u8], _| { - Self::parse_inner(input) - })(input) - } - fn parse_inner(input: &'a [u8]) -> BerResult { let (remainder, version) = parse_ber_integer(input)?; @@ -418,7 +366,7 @@ impl<'a> SignerInfo<'a> { /// signatures all the attributes we need to work with have a /// single value. This function retrieves the attribute and its /// first value in a single step. - pub fn get_signed_attr(&self, oid: &Oid) -> Option<&Any<'a>> { + pub fn get_signed_attr(&self, oid: &ObjectIdentifier) -> Option<&Any<'a>> { self.signed_attrs .iter() .find(|attr| attr.attr_type.eq(oid)) @@ -481,7 +429,7 @@ impl<'a> TryFrom<&Any<'a>> for SignerInfo<'a> { /// /// [1]: https://datatracker.ietf.org/doc/html/rfc5652#section-5.3 pub struct Attribute<'a> { - pub attr_type: Oid<'a>, + pub attr_type: ObjectIdentifier, pub attr_values: Vec>, } @@ -494,7 +442,10 @@ impl<'a> Attribute<'a> { Ok(( remainder, - Self { attr_type: attr_type.as_oid_val()?, attr_values }, + Self { + attr_type: oid_to_object_identifier(attr_type.as_oid()?), + attr_values, + }, )) })(input) } @@ -515,12 +466,6 @@ pub struct SpcIndirectDataContent<'a> { } impl<'a> SpcIndirectDataContent<'a> { - pub fn parse(input: &'a [u8]) -> BerResult { - parse_ber_sequence_defined_g(|input: &[u8], _| { - Self::parse_inner(input) - })(input) - } - pub fn parse_inner(input: &'a [u8]) -> BerResult { let (remainder, _data) = parse_ber(input)?; let (remainder, message_digest) = DigestInfo::parse(remainder)?; @@ -579,12 +524,6 @@ pub struct SpcSpOpusInfo { } impl SpcSpOpusInfo { - pub fn parse(input: &[u8]) -> BerResult { - parse_ber_sequence_defined_g(|input: &[u8], _| { - Self::parse_inner(input) - })(input) - } - fn parse_inner(input: &[u8]) -> BerResult { let (remainder, program_name) = OptTaggedParser::from(0) .parse_ber(input, |_, content| Self::parse_spc_string(content))?; diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index f8c56c30e..752a5fc8b 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -2,17 +2,24 @@ use std::borrow::Cow; use std::fmt::Write; use array_bytes::bytes2hex; -use const_oid::db::{rfc5912, rfc6268}; +use const_oid::db::{rfc5911, rfc5912, rfc6268}; use const_oid::{AssociatedOid, ObjectIdentifier}; use der_parser::asn1_rs::{Set, Tag, ToDer, UtcTime}; use digest::{Digest, Output}; use dsa::Components; - use ecdsa::signature::hazmat::PrehashVerifier; use itertools::Itertools; use md5::Md5; use nom::AsBytes; use protobuf::MessageField; +use rsa::traits::SignatureScheme; +use rsa::Pkcs1v15Sign; +use sha1::Sha1; +use sha2::{Sha256, Sha384, Sha512}; +use thiserror::Error; +use x509_parser::certificate::X509Certificate; +use x509_parser::der_parser::num_bigint::BigUint; +use x509_parser::x509::{AlgorithmIdentifier, SubjectPublicKeyInfo, X509Name}; use crate::modules::pe::asn1::{ oid, oid_to_object_identifier, oid_to_str, Attribute, Certificate, @@ -20,14 +27,6 @@ use crate::modules::pe::asn1::{ SpcSpOpusInfo, TstInfo, }; use crate::modules::protos; -use rsa::traits::SignatureScheme; -use rsa::Pkcs1v15Sign; -use sha1::Sha1; -use sha2::{Sha256, Sha384, Sha512}; -use thiserror::Error; -use x509_parser::der_parser::num_bigint::BigUint; -use x509_parser::prelude::{AlgorithmIdentifier, X509Certificate}; -use x509_parser::x509::{SubjectPublicKeyInfo, X509Name}; /// Error returned by [`AuthenticodeParser::parse`]. #[derive(Clone, Debug, Eq, PartialEq)] @@ -100,9 +99,9 @@ impl AuthenticodeParser { content_info: ContentInfo<'a>, authenticode_hasher: &impl AuthenticodeHasher, ) -> Result>, ParseError> { - if content_info.content_type != oid::SIGNED_DATA { + if content_info.content_type != rfc5911::ID_SIGNED_DATA { return Err(ParseError::InvalidContentType( - content_info.content_type.to_id_string(), + content_info.content_type.to_string(), )); } @@ -127,9 +126,11 @@ impl AuthenticodeParser { // The content in `SignedData` must be a `SpcIndirectDataContent` // structure. - if signed_data.content_info.content_type != oid::INDIRECT_DATA_OBJID { + if signed_data.content_info.content_type + != oid::MS_SPC_INDIRECT_DATA_OBJID + { return Err(ParseError::InvalidEncapsulatedContentType( - signed_data.content_info.content_type.to_id_string(), + signed_data.content_info.content_type.to_string(), )); } @@ -149,21 +150,21 @@ impl AuthenticodeParser { // Authenticode digest. This attribute is identified by OID // 1.2.840.113549.1.9.4. let signer_info_digest = match signer_info - .get_signed_attr(&oid::MESSAGE_DIGEST) + .get_signed_attr(&rfc5911::ID_MESSAGE_DIGEST) .map(|value| value.data.as_bytes()) { Some(md) => md, None => return Err(ParseError::MissingAuthenticodeDigest), }; - if signer_info.get_signed_attr(&oid::CONTENT_TYPE).is_none() { + if signer_info.get_signed_attr(&rfc5911::ID_CONTENT_TYPE).is_none() { return Err(ParseError::MissingContentTypeAuthenticatedAttribute); } // `SignerInfo` can have a signed attribute that contains information // about the signed program in a `SpcSpOpusInfo` struct. let opus_info: Option = signer_info - .get_signed_attr(&oid::OPUS_INFO_OBJID) + .get_signed_attr(&oid::MS_SPC_OPUS_INFO) .and_then(|value| value.try_into().ok()); let signed_data_raw = signed_data.content_info.content.data; @@ -186,13 +187,13 @@ impl AuthenticodeParser { let mut countersignatures = Vec::new(); for attr in signer_info.unsigned_attrs.iter() { - match attr.attr_type.as_bytes() { + match attr.attr_type { // SignerInfo can have unsigned attributes containing nested // Authenticode signatures. These attributes are identified by // OID 1.3.6.1.4.1.311.2.4.1 and their values are `ContentInfo` // structures. Find those attributes, parse their values, and // append the resulting signatures to `nested_signatures`. - oid::MS_NESTED_SIGNATURE_B => { + oid::MS_SPC_NESTED_SIGNATURE => { for value in &attr.attr_values { if let Ok(content_info) = value.try_into() { if let Ok(nested) = Self::parse_content_info( @@ -204,7 +205,7 @@ impl AuthenticodeParser { }; } } - oid::MS_COUNTERSIGN_B => { + oid::MS_COUNTERSIGN => { Self::parse_ms_countersignature_attr( &signer_info, attr, @@ -212,7 +213,7 @@ impl AuthenticodeParser { &mut countersignatures, )?; } - oid::PKCS9_COUNTERSIGN_B => { + rfc5911::ID_COUNTERSIGNATURE => { Self::parse_pkcs9_countersignature_attr( &signer_info, attr, @@ -227,28 +228,29 @@ impl AuthenticodeParser { // Compute the Authenticode hash by ourselves. This hash will be // compared later with the one included in the PE file. let computed_authenticode_hash = - match signer_info.digest_algorithm.oid().as_bytes() { - oid::MD5_B => { + match oid_to_object_identifier(signer_info.digest_algorithm.oid()) + { + rfc5912::ID_MD_5 => { let mut md5 = Md5::default(); authenticode_hasher.hash(&mut md5); md5.finalize().to_vec() } - oid::SHA_1_B => { + rfc5912::ID_SHA_1 => { let mut sha1 = Sha1::default(); authenticode_hasher.hash(&mut sha1); sha1.finalize().to_vec() } - oid::SHA_256_B => { + rfc5912::ID_SHA_256 => { let mut sha256 = Sha256::default(); authenticode_hasher.hash(&mut sha256); sha256.finalize().to_vec() } - oid::SHA_384_B => { + rfc5912::ID_SHA_384 => { let mut sha384 = Sha384::default(); authenticode_hasher.hash(&mut sha384); sha384.finalize().to_vec() } - oid::SHA_512_B => { + rfc5912::ID_SHA_512 => { let mut sha512 = Sha512::default(); authenticode_hasher.hash(&mut sha512); sha512.finalize().to_vec() @@ -373,11 +375,11 @@ impl AuthenticodeParser { let mut signing_time = None; for attr in &si.signed_attrs { - match oid_to_object_identifier(&attr.attr_type) { - rfc6268::ID_MESSAGE_DIGEST => { + match &attr.attr_type { + &rfc6268::ID_MESSAGE_DIGEST => { digest = attr.attr_values.first().map(|v| v.data); } - rfc6268::ID_SIGNING_TIME => { + &rfc6268::ID_SIGNING_TIME => { signing_time = attr .attr_values .first() @@ -690,12 +692,12 @@ fn verify_message_digest( message: &[u8], digest: &[u8], ) -> bool { - match algorithm.oid().as_bytes() { - oid::SHA_1_B => Sha1::digest(message).as_slice() == digest, - oid::SHA_256_B => Sha256::digest(message).as_slice() == digest, - oid::SHA_384_B => Sha384::digest(message).as_slice() == digest, - oid::SHA_512_B => Sha512::digest(message).as_slice() == digest, - oid::MD5_B => Md5::digest(message).as_slice() == digest, + match oid_to_object_identifier(algorithm.oid()) { + rfc5912::ID_SHA_1 => Sha1::digest(message).as_slice() == digest, + rfc5912::ID_SHA_256 => Sha256::digest(message).as_slice() == digest, + rfc5912::ID_SHA_384 => Sha384::digest(message).as_slice() == digest, + rfc5912::ID_SHA_512 => Sha512::digest(message).as_slice() == digest, + rfc5912::ID_MD_5 => Md5::digest(message).as_slice() == digest, _ => unimplemented!("{:?}", algorithm.oid()), } } From d28b416f6bd90350a6ec650bfa2aff2172f2dfc4 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Mon, 29 Apr 2024 13:31:58 +0200 Subject: [PATCH 37/38] style: fix Clippy warning --- lib/src/modules/pe/authenticode.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index 752a5fc8b..e8d298426 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -375,11 +375,11 @@ impl AuthenticodeParser { let mut signing_time = None; for attr in &si.signed_attrs { - match &attr.attr_type { - &rfc6268::ID_MESSAGE_DIGEST => { + match attr.attr_type { + rfc6268::ID_MESSAGE_DIGEST => { digest = attr.attr_values.first().map(|v| v.data); } - &rfc6268::ID_SIGNING_TIME => { + rfc6268::ID_SIGNING_TIME => { signing_time = attr .attr_values .first() From eb7b4da474379c9f2bf02f9bb96a8bd1e20deb3c Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" Date: Mon, 29 Apr 2024 13:35:38 +0200 Subject: [PATCH 38/38] chore: `PublicKey::verify` is not used when the `x509-parser-verify` feature is enabled --- lib/src/modules/pe/authenticode.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/modules/pe/authenticode.rs b/lib/src/modules/pe/authenticode.rs index e8d298426..33279ca86 100644 --- a/lib/src/modules/pe/authenticode.rs +++ b/lib/src/modules/pe/authenticode.rs @@ -1031,6 +1031,7 @@ impl TryFrom<&SubjectPublicKeyInfo<'_>> for PublicKey { } impl PublicKey { + #[cfg(not(feature = "x509-parser-verify"))] fn verify( &self, digest_algorithm: &AlgorithmIdentifier, @@ -1067,6 +1068,7 @@ impl PublicKey { } } + #[cfg(not(feature = "x509-parser-verify"))] fn verify_impl( &self, message: &[u8],