漏洞?在 codesign --remove-signature 功能中

发布于 2024-12-05 20:59:37 字数 807 浏览 3 评论 0原文

我想从已使用 codesign 签名的 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 来修改应用程序。如果他们这样做,签名就会无效,并且应用程序无法使用它自己的钥匙串条目。

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

I would like to remove the digital signature from a Mac app that has been signed with codesign. There is an undocumented option to codesign, --remove-signature, which by it's name seems to be what I need. However, I can't get it to work. I realize it is undocumented, but I could really use the functionality. Maybe I'm doing something wrong?

 codesign -s MyIdentity foo.app

works normally, signing the app

 codesign --remove-signature foo.app

does disk activity for several seconds, then says

 foo.app: invalid format for signature

and foo.app has grown to 1.9 GB!!! (Specifically, it is the executable in foo.app/Contents/Resources/MacOS that grows, from 1.1 MB to 1.9 GB.)

The same thing happens when I try to sign/unsign a binary support tool instead of a .app.

Any ideas?


Background: This is my own app; I'm not trying to defeat copy protection or anything like that.

I would like to distribute a signed app so that each update to the app won't need user approval to read/write the app's entries in the Keychain. However, some people need to modify the app by adding their own folder to /Resources. If they do that, the signature becomes invalid, and the app can't use it's own Keychain entries.

The app can easily detect if this situation has happened. If the app could then remove it's signature, everything would be fine. Those people who make this modification would need to give the modified, now-unsigned app permission to use the Keychain, but that's fine with me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

寂寞花火° 2024-12-12 20:59:37

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

https://github.com/steakknife/unsign

A bit late, but I've updated a public-domain tool called unsign which modifies executables to clear out signatures.

https://github.com/steakknife/unsign

你在看孤独的风景 2024-12-12 20:59:37

我今天遇到了这个问题。我可以确认苹果的codesign--remove-signature选项是(并且在OP提出这个问题六年后仍然如此)认真越野车。

简单介绍一下背景知识,Xcode(以及 Apple 的命令行开发工具)包含 code>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

I ran into this issue today. I can confirm that the --remove-signature option to Apple's codesign is (and remains, six years after the OP asked this question) seriously buggy.

For a little background, Xcode (and Apple's command line developer tools) include the codesign utility, but there is not included a tool for removing signatures. However, as this is something that needs to be done in certain situations pretty frequently, there is included a completely undocumented option:

codesign --remove-signature which (one assumes, given lack of documentation) should, well, be fairly self-explanatory but unfortunately, it rarely works as intended without some effort. So I ended up writing a script that should take care of the OP's problem, mine, and similar. If enough people find it here and find it useful, let me know and I'll put it on GitHub or something.


#!/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
豆芽 2024-12-12 20:59:37

这是 codesign< 的源代码/code> 列出了所有选项,包括命令行 -h 和手册页中未涵盖的选项。

另外,这里是 Apple 关于代码签名工作方式最近变化的技术说明< /a>

Here's the source for codesign which lists all options, including those not covered by the command-line -h and man page.

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

新一帅帅 2024-12-12 20:59:37

我同意,当您执行 --remove-signature 时,会发生一些奇怪的事情。

但是,您不应该尝试取消代码签名,而应该更改用户在资源中放置额外文件的方式。 指定某个路径,

~/Library/Application Support/Name_Of_Your_App/

相反,通常或可能

~/Library/Application Support/Name_Of_Your_App/Resources/

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

I agree that there's something strange going on when you did --remove-signature.

However, instead of trying to un-code-sign, you should change the way your user put extra files in the Resources. Instead, designate a certain path, usually

~/Library/Application Support/Name_Of_Your_App/

or maybe

~/Library/Application Support/Name_Of_Your_App/Resources/

and ask the user to put extra files there. Then, in your code, always check for the directory in addition to the files in the Resources when you need to read a file.

你没皮卡萌 2024-12-12 20:59:37

在第二次阅读这个问题时,另一个想法:也许实现问题最终目标的更好方法不是删除签名,而是让用户(通过脚本/透明地) ) 使用临时签名重新签名修改后的应用程序。我相信,那就是codesign -fs - [app]。请参阅 https://apple.stackexchange.com /questions/105588/任何有在 os-x 上进行黑客攻击经验的人

On a second reading of this question, another thought: perhaps a better approach to accomplish what the ultimate goal of the question is would be not to remove the signatures, but to have users (via a script/transparently) re-sign the app after modification, using an ad-hoc signature. That is, codesign -fs - [app], I believe. See https://apple.stackexchange.com/questions/105588/anyone-with-experience-in-hacking-the-codesigning-on-os-x

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文