【问题标题】:bug? in codesign --remove-signature feature漏洞?在 codesign --remove-signature 功能中
【发布时间】:2011-09-21 13:15:15
【问题描述】:

我想从使用 cosign 签名的 Mac 应用程序中删除数字签名。有一个未记录的协同设计选项 --remove-signature,它的名字似乎是我需要的。但是,我无法让它工作。我意识到它没有记录,但我真的可以使用该功能。也许我做错了什么?

 codesign -s MyIdentity foo.app

正常工作,签署应用程序

 codesign --remove-signature foo.app

磁盘活动几秒钟,然后说

 foo.app: invalid format for signature

而 foo.app 已增长到 1.9 GB!!! (具体来说,是 foo.app/Contents/Resources/MacOS 中的可执行文件从 1.1 MB 增长到 1.9 GB。)

当我尝试对二进制支持工具而不是 .app 进行签名/取消签名时,也会发生同样的情况。

有什么想法吗?


背景:这是我自己的应用程序;我并不是要破坏版权保护或类似的东西。

我想分发一个签名的应用程序,以便应用程序的每次更新都不需要用户批准来读取/写入钥匙串中的应用程序条目。但是,有些人需要通过将自己的文件夹添加到 /Resources 来修改应用程序。如果他们这样做,签名将失效,并且应用程序无法使用它自己的钥匙串条目。

该应用可以轻松检测是否发生了这种情况。如果应用程序可以删除它的签名,一切都会好起来的。进行此修改的人需要授予修改后的、现在未签名的应用程序使用钥匙串的权限,但这对我来说很好。

【问题讨论】:

    标签: macos digital-signature


    【解决方案1】:

    有点晚了,但我更新了一个名为 unsign 的公共域工具,它可以修改可执行文件以清除签名。

    https://github.com/steakknife/unsign

    【讨论】:

    • 推广您编写(甚至是部分)编写的代码很好,只要您清楚地详细说明 OP 如何使用它来完成他们想要做的事情。否则,将被视为垃圾邮件。
    • 是的,这确实与 OP 的问题无关,这与删除签名和退出 捆绑包有关,而不仅仅是单个可执行文件或二进制文件。
    【解决方案2】:

    我今天遇到了这个问题。我可以确认 Apple 的 codesign--remove-signature 选项是(并且仍然是,在 OP 提出这个问题六年后)严重错误。

    对于一些背景知识,Xcode(和 Apple 的命令行开发人员工具)包含 codesign 实用程序,但不包含用于删除签名的工具。但是,由于在某些情况下需要经常执行此操作,因此包含了一个完全未记录的选项:

    codesign --remove-signature(假设缺乏文档)应该是相当不言自明的,但不幸的是,它很少不费吹灰之力就能按预期工作。所以我最终编写了一个脚本来解决 OP 的问题、我的问题和类似问题。如果有足够多的人在这里找到它并觉得它有用,请告诉我,我会将它放在 GitHub 或其他地方。


    #!/bin/sh # codesign_remove_for_real -- working `codesign --remove-signature`
    # (c) 2018 G. Nixon. BSD 2-clause minus retain/reproduce license requirements.
    
    total_size(){
      # Why its so damn hard to get decent recursive filesize total in the shell?
      # - Darwin `du` doesn't do *bytes* (or anything less than 512B blocks)
      # - `find` size options are completely non-standardized and doesn't recurse
      # - `stat` is not in POSIX at all, and its options are all over the map...
      # - ... etc. 
      # So: here we just use `find` for a recursive list of *files*, then wc -c
      # and total it all up. Which sucks, because we have to read in every bit
      # of every file. But its the only truly portable solution I think.
      find "$@" -type f -print0 | xargs -0n1 cat | wc -c | tr -d '[:space:]'
    }
    
    # Get an accurate byte count before we touch anything. Zero would be bad.
    size_total=$(total_size "$@") && [ $size_total -gt 0 ] || exit 1
    
    recursively_repeat_remove_signature(){
      # `codesign --remove-signature` randomly fails in a few ways.
      # If you're lucky, you'll get an error like:
      # [...]/codesign_allocate: can't write output file: [...] (Invalid argument)
      # [...] the codesign_allocate helper tool cannot be found or used
      # or something to that effect, in which case it will return non-zero.
      # So we'll try it (suppressing stderr), and if it fails we'll just try again.
      codesign --remove-signature --deep "$@" 2>/dev/null ||
        recursively_repeat_remove_signature "$@"
    
      # Unfortunately, the other very common way it fails is to do something? that
      # hugely increases the binary size(s) by a seemingly arbitrary amount and
      # then exits 0. `codesign -v` will tell you that there's no signature, but
      # there are other telltale signs its not completely removed. For example,
      # if you try stripping an executable after this, you'll get something like
      # strip: changes being made to the file will invalidate the code signature
      # So, the solution  (well, my solution) is to do a file size check; once
      # we're finally getting the same result, we've probably been sucessful.
      # We could of course also use checksums, but its much faster this way.
      [ $size_total == $(total_size "$@") ] ||
        recursively_repeat_remove_signature "$@"
    
      # Finally, remove any leftover _CodeSignature directories.
      find "$@" -type d -name _CodeSignature -print0 | xargs -0n1 rm -rf
    } 
    
    signature_info(){
      # Get some info on code signatures. Not really required for anything here.
      for info in "-dr-" "-vv"; do codesign $info "$@";  done # "-dvvvv" 
    }
    
    # If we want to be be "verbose", check signature before. Un/comment out:
    # echo >&2; echo "Current Signature State:" >&2; echo >&2; signature_info "$@"
    
    
    # So we first remove any extended attributes and/or ACLs (which are common,
    # and tend to interfere with the process here) then run our repeat scheme.
    xattr -rc "$@" && chmod -RN "$@" && recursively_repeat_remove_signature "$@"
    
    # Done!
    
    
    # That's it; at this point, the executable or bundle(s) should sucessfully
    # have truly become stripped of any code-signing. To test, one could
    # try re-signing it again with an ad-hoc signature, then removing it again:
    # (un/comment out below, as you see fit)
    
    # echo >&2 && echo "Testing..." >&2; codesign -vvvvs - "$@" &&
      # signature_info "$@" && recursively_repeat_remove_signature "$@"
    
    # And of course, while it sometimes returns false positives, lets at least:
    codesign -dvvvv "$@" || echo "Signature successfully removed!" >&2 && exit 0
    

    【讨论】:

    • 我今天正在尝试您的脚本(macOS 10.15.7)并收到此错误:./codesign_remove_for_real.sh: line 38: [: 503504: unary operator expected。你有解决这个问题吗?它似乎也工作得很好,第二次我在同一个文件上运行它现在说没有找到签名。
    • 还尝试了这个脚本(作为尝试在 12.0 beta 8 上修复 GitKraken 的最后手段):[1] 51813 segmentation fault codesign_remove_for_real.sh
    【解决方案3】:

    Here's the source for codesign 列出了所有选项,包括命令行-h 和手册页未涵盖的选项。

    另外,here is Apple's tech note on recent changes in how code-signing works

    【讨论】:

      【解决方案4】:

      我同意你在--remove-signature 时发生了一些奇怪的事情。

      但是,您应该更改用户在Resources 中放置额外文件的方式,而不是尝试取消代码签名。相反,指定一个特定的路径,通常

      ~/Library/Application Support/Name_Of_Your_App/
      

      或许

      ~/Library/Application Support/Name_Of_Your_App/Resources/
      

      并要求用户将额外的文件放在那里。然后,在您的代码中,当您需要读取文件时,始终检查除Resources 中的文件之外的目录。

      【讨论】:

      • 用户可能有多个带有不同额外文件的应用程序副本,并且可以移动应用程序。如果他们的额外文件在应用程序中,则一切正常。否则,我必须以某种方式根据应用程序的位置跟踪不同的文件,然后如果应用程序移动它就会停止工作。一团糟。
      【解决方案5】:

      在第二次阅读这个问题时,另一个想法是:也许更好的方法来完成问题的最终目标不是删除签名,而是让用户(通过脚本/透明)重新-在修改后使用临时签名对应用程序进行签名。也就是说,codesign -fs - [app],我相信。见https://apple.stackexchange.com/questions/105588/anyone-with-experience-in-hacking-the-codesigning-on-os-x

      【讨论】:

        猜你喜欢
        • 2012-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-27
        • 1970-01-01
        • 1970-01-01
        • 2021-06-05
        • 2017-06-08
        相关资源
        最近更新 更多