private bool Validate32BitImage(BinaryAnalyzerContext context)
        {
            PEBinary    target       = context.PEBinary();
            PEHeader    peHeader     = target.PE.PEHeaders.PEHeader;
            SafePointer sp           = new SafePointer(target.PE.ImageBytes, peHeader.LoadConfigTableDirectory.RelativeVirtualAddress);
            SafePointer loadConfigVA = target.PE.RVA2VA(sp);
            ImageLoadConfigDirectory32 loadConfig = new ImageLoadConfigDirectory32(peHeader, loadConfigVA);

            UInt32 cookieVA    = (UInt32)loadConfig.GetField(ImageLoadConfigDirectory32.Fields.SecurityCookie);
            UInt32 baseAddress = (UInt32)peHeader.ImageBase;

            // we need to find the offset in the file based on the cookie's VA
            UInt32        sectionSize, sectionVA = 0;
            SectionHeader ish = new SectionHeader();
            bool          foundCookieSection = false;

            foreach (SectionHeader t in target.PE.PEHeaders.SectionHeaders)
            {
                sectionVA   = (UInt32)t.VirtualAddress + baseAddress;
                sectionSize = (UInt32)t.VirtualSize;
                if ((cookieVA >= sectionVA) &&
                    (cookieVA < sectionVA + sectionSize))
                {
                    ish = t;
                    foundCookieSection = true;
                    break;
                }
            }

            if (!foundCookieSection)
            {
                LogCouldNotLocateCookie(context);
                return(false);
            }

            UInt64      fileCookieOffset = (cookieVA - baseAddress) - (sectionVA - baseAddress) + (UInt32)ish.PointerToRawData;
            SafePointer fileCookiePtr    = loadConfigVA;

            fileCookiePtr.Address = (int)fileCookieOffset;

            SafePointer boundsCheck = fileCookiePtr + 4;

            if (!CookieOffsetValid(context, boundsCheck))
            {
                return(false);
            }

            UInt32 cookie = BitConverter.ToUInt32(fileCookiePtr.GetBytes(4), 0);

            if (!StackProtectionUtilities.DefaultCookiesX86.Contains(cookie) && target.PE.Machine == Machine.I386)
            {
                LogFailure(context, cookie.ToString("x"));
                return(false);
            }

            return(true);
        }
        private bool Validate64BitImage(BinaryAnalyzerContext context)
        {
            PEHeader    peHeader     = context.PE.PEHeaders.PEHeader;
            SafePointer sp           = new SafePointer(context.PE.ImageBytes, peHeader.LoadConfigTableDirectory.RelativeVirtualAddress);
            SafePointer loadConfigVA = context.PE.RVA2VA(sp);
            ImageLoadConfigDirectory64 loadConfig = new ImageLoadConfigDirectory64(peHeader, loadConfigVA);

            UInt64 cookieVA    = (UInt64)loadConfig.GetField(ImageLoadConfigDirectory64.Fields.SecurityCookie);
            UInt64 baseAddress = peHeader.ImageBase;

            // we need to find the offset in the file based on the cookie's VA
            UInt64        sectionSize, sectionVA = 0;
            SectionHeader ish = new SectionHeader();
            bool          foundCookieSection = false;

            foreach (SectionHeader t in context.PE.PEHeaders.SectionHeaders)
            {
                sectionVA   = (UInt64)(UInt32)t.VirtualAddress + baseAddress;
                sectionSize = (UInt32)t.VirtualSize;
                if ((cookieVA >= sectionVA) &&
                    (cookieVA < sectionVA + sectionSize))
                {
                    ish = t;
                    foundCookieSection = true;
                    break;
                }
            }

            if (!foundCookieSection)
            {
                LogCouldNotLocateCookie(context);
                return(false);
            }

            UInt64      fileCookieOffset = (cookieVA - baseAddress) - (sectionVA - baseAddress) + (UInt32)ish.PointerToRawData;
            SafePointer fileCookiePtr    = loadConfigVA;

            fileCookiePtr.Address = (int)fileCookieOffset;
            UInt64 cookie = BitConverter.ToUInt64(fileCookiePtr.GetBytes(8), 0);

            if (cookie != StackProtectionUtilities.DefaultCookieX64)
            {
                LogFailure(context, cookie.ToString("x"));
                return(false);
            }
            return(true);
        }
示例#3
0
        private bool Validate64BitImage(BinaryAnalyzerContext context)
        {
            PEBinary target = context.PEBinary();

            PEHeader    peHeader     = target.PE.PEHeaders.PEHeader;
            var         sp           = new SafePointer(target.PE.ImageBytes, peHeader.LoadConfigTableDirectory.RelativeVirtualAddress);
            SafePointer loadConfigVA = target.PE.RVA2VA(sp);
            var         loadConfig   = new ImageLoadConfigDirectory64(peHeader, loadConfigVA);

            ulong cookieVA    = (ulong)loadConfig.GetField(ImageLoadConfigDirectory64.Fields.SecurityCookie);
            ulong baseAddress = peHeader.ImageBase;

            // we need to find the offset in the file based on the cookie's VA
            ulong sectionSize, sectionVA = 0;
            var   ish = new SectionHeader();
            bool  foundCookieSection = false;

            foreach (SectionHeader t in target.PE.PEHeaders.SectionHeaders)
            {
                sectionVA   = (uint)t.VirtualAddress + baseAddress;
                sectionSize = (uint)t.VirtualSize;
                if ((cookieVA >= sectionVA) &&
                    (cookieVA < sectionVA + sectionSize))
                {
                    ish = t;
                    foundCookieSection = true;
                    break;
                }
            }

            if (!foundCookieSection)
            {
                this.LogCouldNotLocateCookie(context);
                return(false);
            }

            ulong       fileCookieOffset = (cookieVA - baseAddress) - (sectionVA - baseAddress) + (uint)ish.PointerToRawData;
            SafePointer fileCookiePtr    = loadConfigVA;

            fileCookiePtr.Address = (int)fileCookieOffset;

            SafePointer boundsCheck = fileCookiePtr + 8;

            if (!this.CookieOffsetValid(context, boundsCheck))
            {
                return(false);
            }

            if (!boundsCheck.IsValid && target.PE.IsPacked)
            {
                this.LogInvalidCookieOffsetForKnownPackedFile(context);
                return(false);
            }

            ulong cookie = BitConverter.ToUInt64(fileCookiePtr.GetBytes(8), 0);

            if (cookie != StackProtectionUtilities.DefaultCookieX64)
            {
                this.LogFailure(context, cookie.ToString("x"));
                return(false);
            }
            return(true);
        }
        private bool Validate64BitImage(BinaryAnalyzerContext context)
        {
            PEHeader    peHeader     = context.PE.PEHeaders.PEHeader;
            SafePointer sp           = new SafePointer(context.PE.ImageBytes, peHeader.LoadConfigTableDirectory.RelativeVirtualAddress);
            SafePointer loadConfigVA = context.PE.RVA2VA(sp);
            ImageLoadConfigDirectory64 loadConfig = new ImageLoadConfigDirectory64(peHeader, loadConfigVA);

            UInt64 cookieVA    = (UInt64)loadConfig.GetField(ImageLoadConfigDirectory64.Fields.SecurityCookie);
            UInt64 baseAddress = peHeader.ImageBase;

            // we need to find the offset in the file based on the cookie's VA
            UInt64        sectionSize, sectionVA = 0;
            SectionHeader ish = new SectionHeader();
            bool          foundCookieSection = false;

            foreach (SectionHeader t in context.PE.PEHeaders.SectionHeaders)
            {
                sectionVA   = (UInt64)(UInt32)t.VirtualAddress + baseAddress;
                sectionSize = (UInt32)t.VirtualSize;
                if ((cookieVA >= sectionVA) &&
                    (cookieVA < sectionVA + sectionSize))
                {
                    ish = t;
                    foundCookieSection = true;
                    break;
                }
            }

            if (!foundCookieSection)
            {
                // '{0}' is a C or C++binary that enables the stack protection feature but the security cookie could not be located. The binary may be corrupted.
                context.Logger.Log(MessageKind.Fail, context,
                                   RuleUtilities.BuildMessage(context,
                                                              RulesResources.DoNotModifyStackProtectionCookie_CouldNotLocateCookie_Fail));
                return(false);
            }

            UInt64      fileCookieOffset = (cookieVA - baseAddress) - (sectionVA - baseAddress) + (UInt32)ish.PointerToRawData;
            SafePointer fileCookiePtr    = loadConfigVA;

            fileCookiePtr.Address = (int)fileCookieOffset;
            UInt64 cookie = BitConverter.ToUInt64(fileCookiePtr.GetBytes(8), 0);

            if (cookie != StackProtectionUtilities.DefaultCookieX64)
            {
                // '{0}' is a C or C++ binary that interferes with the stack protector. The
                // stack protector (/GS) is a security feature of the compiler which makes
                // it more difficult to exploit stack buffer overflow memory corruption
                // vulnerabilities. The stack protector relies on a random number, called
                // the "security cookie", to detect these buffer overflows. This 'cookie'
                // is statically linked with your binary from a Visual C++ library in the
                // form of the symbol __security_cookie. On recent Windows versions, the
                // loader looks for the magic statically linked value of this cookie, and
                // initializes the cookie with a far better source of entropy -- the system's
                // secure random number generator -- rather than the limited random number
                // generator available early in the C runtime startup code. When this symbol
                // is not the default value, the additional entropy is not injected by the
                // operating system, reducing the effectiveness of the stack protector. To
                // resolve this issue, ensure that your code does not reference or create a
                // symbol named __security_cookie or __security_cookie_complement. NOTE:
                // the modified cookie value detected was: {1}
                context.Logger.Log(MessageKind.Fail, context,
                                   RuleUtilities.BuildMessage(context,
                                                              RulesResources.DoNotModifyStackProtectionCookie_Fail, cookie.ToString("x")));
                return(false);
            }
            return(true);
        }