From 361de8b0a8fefb543b171bc4d580375c210b406b Mon Sep 17 00:00:00 2001 From: CFC4N Date: Mon, 2 Dec 2024 23:10:55 +0800 Subject: [PATCH] Fix #678 the issue where the version number string cannot be found in the dynamic library of boringssl. Signed-off-by: CFC4N --- .github/workflows/release.yml | 2 +- cli/cmd/root.go | 4 +- cli/cmd/tls.go | 2 +- user/module/probe_openssl.go | 71 ++++++++++++++++++-------------- user/module/probe_openssl_lib.go | 13 ++++-- 5 files changed, 54 insertions(+), 38 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8cff5a708..c03023172 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ jobs: build-on-ubuntu2204: runs-on: ubuntu-22.04 - name: build on ubuntu-22.04 x86_64 + name: release Linux/Android Version (amd64/arm64) steps: - uses: actions/setup-go@v5 with: diff --git a/cli/cmd/root.go b/cli/cmd/root.go index f0ddf5a16..861f9c232 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -39,7 +39,7 @@ const ( CliDescription = "Capturing SSL/TLS plaintext without a CA certificate using eBPF. Supported on Linux/Android kernels for amd64/arm64." CliHomepage = "https://ecapture.cc" CliAuthor = "CFC4N " - CliRepo = "https://github.com/gojue/ecapture" + CliGithubRepo = "https://github.com/gojue/ecapture" ) var ( @@ -198,7 +198,7 @@ func runModule(modName string, modConfig config.IConfig) { // init eCapture logger.Info().Str("AppName", fmt.Sprintf("%s(%s)", CliName, CliNameZh)).Send() logger.Info().Str("HomePage", CliHomepage).Send() - logger.Info().Str("Repository", CliRepo).Send() + logger.Info().Str("Repository", CliGithubRepo).Send() logger.Info().Str("Author", CliAuthor).Send() logger.Info().Str("Description", CliDescription).Send() logger.Info().Str("Version", GitVersion).Send() diff --git a/cli/cmd/tls.go b/cli/cmd/tls.go index 35a89ca6f..892c9e899 100644 --- a/cli/cmd/tls.go +++ b/cli/cmd/tls.go @@ -52,7 +52,7 @@ func init() { opensslCmd.PersistentFlags().StringVarP(&oc.KeylogFile, "keylogfile", "k", "ecapture_openssl_key.log", "The file stores SSL/TLS keys, and eCapture captures these keys during encrypted traffic communication and saves them to the file.") opensslCmd.PersistentFlags().StringVarP(&oc.PcapFile, "pcapfile", "w", "save.pcapng", "write the raw packets to file as pcapng format.") opensslCmd.PersistentFlags().StringVarP(&oc.Ifname, "ifname", "i", "", "(TC Classifier) Interface name on which the probe will be attached.") - opensslCmd.PersistentFlags().StringVar(&oc.SslVersion, "ssl_version", "", "openssl/boringssl version, e.g: --ssl_version=\"openssl 1.1.1g\" or --ssl_version=\"boringssl 1.1.1\"") + opensslCmd.PersistentFlags().StringVar(&oc.SslVersion, "ssl_version", "", "openssl/boringssl version, e.g: --ssl_version=\"openssl 1.1.1g\" or --ssl_version=\"boringssl 1.1.1\".") rootCmd.AddCommand(opensslCmd) } diff --git a/user/module/probe_openssl.go b/user/module/probe_openssl.go index db228a330..2bc07dad9 100644 --- a/user/module/probe_openssl.go +++ b/user/module/probe_openssl.go @@ -199,6 +199,12 @@ func (m *MOpenSSLProbe) getSslBpfFile(soPath, sslVersion string) error { } err, verString := m.detectOpenssl(soPath) + + if err != nil && !errors.Is(err, ErrProbeOpensslVerNotFound) { + m.logger.Error().Str("soPath", soPath).Err(err).Msg("OpenSSL/BoringSSL version check failed") + return err + } + if errors.Is(err, ErrProbeOpensslVerNotFound) { // 未找到版本号, try libcrypto.so.x if strings.Contains(soPath, "libssl.so.3") { @@ -222,48 +228,51 @@ func (m *MOpenSSLProbe) getSslBpfFile(soPath, sslVersion string) error { soPath = strings.Replace(soPath, "libssl.so.3", libcryptoName, 1) m.logger.Info().Str("soPath", soPath).Str("imported", libcryptoName).Msg("Try to detect imported libcrypto.so ") err, verString = m.detectOpenssl(soPath) - if err != nil { - if !errors.Is(err, ErrProbeOpensslVerNotFound) { - return err - } else { - m.logger.Warn().Err(err).Str("soPath", soPath).Msg("OpenSSL(libcrypto.so.3) version not found.") - } - } else { + if err != nil && !errors.Is(err, ErrProbeOpensslVerNotFound) { + m.logger.Warn().Err(err).Str("soPath", soPath).Str("imported", libcryptoName).Msgf("OpenSSL(libcrypto.so.3) version not found.%s", fmt.Sprintf(OpensslNoticeUsedDefault, OpensslNoticeVersionGuideLinux)) + return err + } + if errors.Is(err, ErrProbeOpensslVerNotFound) { m.logger.Info().Str("soPath", soPath).Str("imported", libcryptoName).Str("version", verString).Msg("OpenSSL/BoringSSL version found from imported libcrypto.so") } } } - if err != nil { - m.logger.Error().Str("soPath", soPath).Err(err).Msg("OpenSSL/BoringSSL version check failed") - return err - } - - m.conf.(*config.OpensslConfig).SslVersion = verString - m.logger.Info().Str("origin versionKey", verString).Str("versionKeyLower", verString).Send() - // find the sslVersion bpfFile from sslVersionBpfMap - + var bpfFileKey, bpfFile string isAndroid := m.conf.(*config.OpensslConfig).IsAndroid androidVer := m.conf.(*config.OpensslConfig).AndroidVer - bpfFileKey := verString - if isAndroid { - // sometimes,boringssl version always was "boringssl 1.1.1" on android. but offsets are different. - // see kern/boringssl_a_13_kern.c and kern/boringssl_a_14_kern.c - // Perhaps we can utilize the Android Version to choose a specific version of boringssl. - // use the corresponding bpfFile - bpfFileKey = fmt.Sprintf("boringssl_a_%s", androidVer) - } - bpfFile, found := m.sslVersionBpfMap[bpfFileKey] - if found { - m.sslBpfFile = bpfFile - m.logger.Info().Bool("Android", isAndroid).Str("library version", bpfFileKey).Msg("OpenSSL/BoringSSL version found") - return nil + if verString != "" { + m.conf.(*config.OpensslConfig).SslVersion = verString + m.logger.Info().Str("origin versionKey", verString).Str("versionKeyLower", verString).Send() + // find the sslVersion bpfFile from sslVersionBpfMap + var found bool + bpfFileKey = verString + if isAndroid { + // sometimes,boringssl version always was "boringssl 1.1.1" on android. but offsets are different. + // see kern/boringssl_a_13_kern.c and kern/boringssl_a_14_kern.c + // Perhaps we can utilize the Android Version to choose a specific version of boringssl. + // use the corresponding bpfFile + bpfFileKey = fmt.Sprintf("boringssl_a_%s", androidVer) + } + bpfFile, found = m.sslVersionBpfMap[bpfFileKey] + if found { + m.sslBpfFile = bpfFile + m.logger.Info().Bool("Android", isAndroid).Str("library version", bpfFileKey).Msg("OpenSSL/BoringSSL version found") + return nil + } else { + m.logger.Warn().Str("version", bpfFileKey).Err(ErrProbeOpensslVerBytecodeNotFound).Msg("Please send an issue to https://github.com/gojue/ecapture/issues") + } } bpfFile = m.getSoDefaultBytecode(soPath, isAndroid) m.sslBpfFile = bpfFile - m.logger.Error().Str("sslVersion", sslVersion).Str("bpfFile", bpfFile).Msg("OpenSSL/BoringSSL version not found, used default version, if you want to use the specific version, please set the sslVersion parameter with `--ssl_version=\"openssl x.x.x\"`") - return err + if isAndroid { + m.logger.Error().Msgf("OpenSSL/BoringSSL version not found, used default version.%s", fmt.Sprintf(OpensslNoticeUsedDefault, OpensslNoticeVersionGuideAndroid)) + } else { + m.logger.Error().Msgf("OpenSSL/BoringSSL version not found, used default version.%s", fmt.Sprintf(OpensslNoticeUsedDefault, OpensslNoticeVersionGuideLinux)) + } + m.logger.Error().Str("sslVersion", m.conf.(*config.OpensslConfig).SslVersion).Str("bpfFile", bpfFile).Send() + return nil } func (m *MOpenSSLProbe) Start() error { diff --git a/user/module/probe_openssl_lib.go b/user/module/probe_openssl_lib.go index 737506cb5..3b4a72e78 100644 --- a/user/module/probe_openssl_lib.go +++ b/user/module/probe_openssl_lib.go @@ -18,6 +18,7 @@ import ( "debug/elf" "errors" "fmt" + "github.com/gojue/ecapture/user/config" "os" "regexp" "strings" @@ -53,6 +54,9 @@ const ( var ( ErrProbeOpensslVerNotFound = errors.New("OpenSSL/BoringSSL version not found") ErrProbeOpensslVerBytecodeNotFound = errors.New("OpenSSL/BoringSSL version bytecode not found") + OpensslNoticeVersionGuideAndroid = "\"--ssl_version='boringssl_a_13'\" , \"--ssl_version='boringssl_a_14'\"" + OpensslNoticeVersionGuideLinux = "\"--ssl_version='openssl x.x.x'\", support openssl 1.0.x, 1.1.x, 3.x or newer" + OpensslNoticeUsedDefault = "If you want to use the specific version, please set the sslVersion parameter with %s, or use \"ecapture tls --help\" for more help." ) // initOpensslOffset initial BpfMap @@ -252,17 +256,20 @@ func (m *MOpenSSLProbe) getSoDefaultBytecode(soPath string, isAndroid bool) stri // if not found, use default if isAndroid { + m.conf.(*config.OpensslConfig).SslVersion = AndroidDefauleFilename bpfFile, _ = m.sslVersionBpfMap[AndroidDefauleFilename] - m.logger.Warn().Str("BoringSSL Version", AndroidDefauleFilename).Msg("OpenSSL/BoringSSL version not found, used default version") + //m.logger.Warn().Str("BoringSSL Version", AndroidDefauleFilename).Msg("OpenSSL/BoringSSL version not found, used default version") return bpfFile } if strings.Contains(soPath, "libssl.so.3") { + m.conf.(*config.OpensslConfig).SslVersion = Linuxdefaulefilename30 bpfFile, _ = m.sslVersionBpfMap[Linuxdefaulefilename30] - m.logger.Warn().Str("OpenSSL Version", Linuxdefaulefilename30).Msg("OpenSSL/BoringSSL version not found from shared library file, used default version") + //m.logger.Warn().Str("OpenSSL Version", Linuxdefaulefilename30).Msg("OpenSSL/BoringSSL version not found from shared library file, used default version") } else { + m.conf.(*config.OpensslConfig).SslVersion = Linuxdefaulefilename111 bpfFile, _ = m.sslVersionBpfMap[Linuxdefaulefilename111] - m.logger.Warn().Str("OpenSSL Version", Linuxdefaulefilename111).Msg("OpenSSL/BoringSSL version not found from shared library file, used default version") + //m.logger.Warn().Str("OpenSSL Version", Linuxdefaulefilename111).Msg("OpenSSL/BoringSSL version not found from shared library file, used default version") } return bpfFile }