在验证的 fips 中添加重定位信息的后果 libeay32.dll

Consequences for adding relocation information in fips validated libeay32.dll

我们正在使用经过验证的 FIPS libeay32.dll。此 dll 使用 /FIXED 链接器开关,以便 libeay32.dll 将加载到固定基地址。我们项目中的其他模块正在使用 LoadLibrary() 函数以共享模式使用 openssl dll。我们在加载提到的 dll 时观察到间歇性问题。

作为解决方案的一部分,我们在 libeay32.dll 的图像 header 中添加了重定位信息,理解 dll 将加载到某个基地址(如果不是固定基地址)以解决间歇性问题加载问题。我检查了 open ssl 用户指南,其中提到了以下内容。

The standard OpenSSL build with the fips option will use a base address for libeay32.dll of 0xFB00000 by default. This value was chosen because it is unlikely to conflict with other dynamically loaded libraries. In the event of a clash with another dynamically loaded library which will trigger runtime relocation of libeay32.dll, the integrity check will fail with the error

FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED

A base address conflict can be resolved by shuffling the other DLLs or re-compiling OpenSSL with an alternative base address specified with the --with­baseaddr= option.

这是我的问题。

  1. 通过在 libeay32.dll 的图像 header 中引入重定位信息,我是否使 libeay32.dll 易受安全性影响 [fips 140-2]?

  2. 我在使用这些开放 ssl 库的模块中引入了哪些安全漏洞及其副作用?

  3. 有没有解决此类加载问题的更简洁的解决方案?

提前致谢...

By introducing the relocation information in image header of libeay32.dll, am I making the libeay32.dll vulnerable to security

所有 Windows PE 文件 have relocation information. Its not like -fPIC on Unix and Linux. The mechanisms are different because the PE/PE+ executable format is different than the ELF/ELF64 specification. Also Microsoft compilers/linkers do not use PC-relative addressing mode,Unix 和 Linux 通常会使用。

你想要的 Windows 是 /ASLR,但 /ASLR/FIXED 正交。 /FIXED被FIPS模块用来保证模块的完整性。 /ASLR 是关于 Windows 和 Microsoft SDLC 项目的最佳实践。

地址 space 布局随机化使攻击者在某些情况下更难猜测地址。例如,它将有助于 "return to libc" 攻击。


What kind of security vulnerabilities am I introducing with their side effect in the modules which are using those OpenSSL libraries ?

由于/FIXED,攻击者总是知道二进制文件的加载位置,并且他可以使用它构建ROP chain。这假设攻击者掌握了漏洞。

我不喜欢 FIPS 验证库的原因之一是你失去了 /ASLR


Any cleaner solution to such kind of loading issues ?

通常您可以做的是,在使用 FIPS DLL 的可执行文件 (EXE) 中,将 OpenSSL 导入库添加为库列表中的第一项。它大致按照指定的顺序写入 PE header。运行时 link/loader 将尽早而不是延迟地加载库。尽早加载它可以最大限度地减少[不满意]位移的可能性。

我相信你也可以在你的程序(EXE)中做到以下几点。它取自 Crypto++'s dll.h,它也经过验证。将其放入预编译的 header 或程序的 "main header"。

#ifdef NDEBUG
#pragma comment(lib, "msvcrt")
#else
#pragma comment(lib, "msvcrtd")
#endif

#pragma comment(lib, "libeay32")
#pragma comment(lib, "anotherlib")
#pragma comment(lib, "yetanotherlib")

FIPS 与政策和程序密切相关。你必须严格遵守它。如果您通过更改 /FIXED 来修改构建过程,那么您将失去验证。您也可以使用常规库。

正如您正确指出的那样,您可以更改用于模块的基地址。 User Guide for the OpenSSL FIPS Object Module v2.0,第 52/208 页中提供了权限。

对于 64 位版本(假设您正在构建 OpenSSL 的 DLL 版本)只需更改 ms/ntdll.mk 文件以在 libeay32.dll 文件的链接中使用 /dynamic 即可ASLR 支持。标准的 64 位构建过程本身没有 /fixed - 但 /dynamic 的额外步骤很可能是您想要实现的。

$(O_CRYPTO): $(CRYPTOOBJ) $(O_FIPSCANISTER) $(PREMAIN_DSO_EXE)
        SET FIPS_LINK=$(LINK_CMD)
        SET FIPS_CC=$(CC)
        SET FIPS_CC_ARGS=/Fo$(OBJ_D)\fips_premain.obj $(SHLIB_CFLAGS) -c
        SET PREMAIN_DSO_EXE=$(PREMAIN_DSO_EXE)
        SET FIPS_SHA1_EXE=$(FIPS_SHA1_EXE)
        SET FIPS_TARGET=$(O_CRYPTO)
        SET FIPSLIB_D=$(FIPSLIB_D)
        $(FIPSLINK) $(MLFLAGS)  /map  /dynamicbase /out:$(O_CRYPTO) /def:ms/LIBEAY32.def @<<
  $(SHLIB_EX_OBJ) $(CRYPTOOBJ) $(O_FIPSCANISTER) $(EX_LIBS) $(OBJ_D)\fips_premain.obj 
<<
        IF EXIST $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2

之前的回答中关于无法修改支持 FIPS 的 OpenSSL 构建过程的陈述不正确。只有安全策略中记录的 fipscanister 本身的构建具有固定的不可更改的过程。支持 FIPS 的 OpenSSL 构建过程完全可以修改以满足您的要求 - 它只是使用 OpenSSL FIPS 模块。

tjh是正确的;从 FIPS 140-2 的角度来看,OpenSSL 本身(例如 1.0.1、1.0.2)只是应用程序代码,超出了 FIPS 140-2 验证的范围。只有模块——一个独立且不同的软件组件——被验证,并且验证过程根本没有考虑 OpenSSL。

另请注意,在 FIPS 领域,安全性仅次于验证的神圣性。例如,通常不允许 OpenSSL 纠正 FIPS 模块中的安全漏洞(例如“Lucky 13”、CVE-2014-0076、CVE-2016-0701)。