本仓库包含 ShellCon 2019 演讲“Rolling Your Own: How to Write Custom, Lightweight Static Analysis Tools”的 PoC 代码(幻灯片)。
简而言之,本仓库演示了几个具体示例,展示如何使用开源工具和少量自定义代码构建一些有趣的静态分析。
本仓库中的代码示例:
before_action。这些示例的工作原理
从高层来看,示例的实现方式如下:
本项目设计为使用 Docker 运行。
为此,你需要先完成一些准备工作。
由于我们的 Dockerfile 基于 semantic Docker 镜像,而该镜像托管在 GitHub 的包注册表上,因此你需要为 GitHub 包注册表配置 Docker。
$ docker login docker.pkg.github.com -u USERNAME -p TOKENdocker build -t lightweight_static_analysis .bash shell,然后运行我们的脚本。# 运行以下命令
# (请确保在本仓库的项目根目录下的终端中运行)
$ docker run -it --rm --entrypoint /bin/bash -v $PWD:/lightweight_static_analysis lightweight_static_analysis
# 在正在运行的容器中
# cd 进入此项目的源代码目录
$ cd /lightweight_static_analysis
# 使用下文所述的不同配置选项运行 main.py
当你在 Docker 容器中进入 bash shell 后(参见上面的 docker run 命令),你可以用以下几种模式之一运行 main.py。
/lightweight_static_analysis> $ python3 src/main.py <options>
你可以通过不带任何选项运行 src/main.py 或查看 main.py 中的 parser.add_argument 部分,来查看所有可用选项。
以下是一些可以帮助你交互式探索 Rails 代码库的命令。
首先,你需要克隆一个或多个 Rails 仓库,并将它们放入 examples/ 中。如果你需要一些示例仓库,可以使用 rubygems.org 的源代码,或 Open Source Rails 上列出的仓库之一。
# 打印所有控制器的类、超类、已定义方法和 before actions
$ python3 src/main.py --rails-summarize-controllers examples/<repo_name>
# 打印所有控制器名称,按超类分组
#
# 这可以发现父类(例如 ApplicationController 或 Api::BaseController)中定义的安全保护
# 未生效的情况,原因是易受攻击的控制器没有继承适当的类。
$ python3 src/main.py --rails-controllers-by-superclass examples/<repo_name>
# 对于任何控制器使用的每个 before_action,列出使用该 before_action 的控制器,
# 以及该 before_action 被应用和未应用的路由
# (例如处理 'except' 和 'only' 关键字)
#
# 这可以:
# * 让你快速了解应用定义的各种 before_action,从而对代码的流程和组织有一些直觉。
# * `verify_with_otp` - 嗯,这听起来很有趣,我可能想要
# 审查这个过滤器是如何实现的。
# * 向你展示某个给定 before_action 在整个代码库中被应用和未应用的位置,
# 从而可能发现因使用不一致而导致的 bug。
#
# 例如
# * 是否存在一个 before_action 被用来保护所有改变状态的 API 路由,
# 但偏偏只有 1 个模型除外?这很奇怪。
# * 是否存在一个身份验证或授权 before_action 被应用于控制器中的每个 action,
# 但唯独一个 action 除外?为什么?
$ python3 src/main.py --rails-controllers-by-before_action examples/<repo_name>
如果你希望在解析完成后进入 ipdb REPL,以便交互式检查解析后的 Ruby 代码,可以在上述命令中额外传入 --repl 标志。
这些示例依赖于 ast_node.py 中定义的各种 AstNode 类,而所有与 Rails 相关的代码都在 ruby.py 中。
exec() 查找命令注入此实现尚未清理和编写文档,但请参阅 main.py 中的 batch_parse_json(),以及 visitor.py 中的 visit() 和它调用的其他方法。
我们很乐意更详细地讨论这项工作,欢迎提出问题,或通过 Twitter 联系我们:@clintgibler、@defreez。
如果你想了解这项工作以及我们开展的其他项目,请查看我们的 tl;dr sec newsletter,我们会在其中发送顶级安全演讲的详细摘要以及最佳安全工具和资源的链接。
这是一份低流量、高信号的 newsletter,旨在让你了解安全领域的最新动态,从而更高效、更有效地完成工作,并让你在信息安全茶歇时也能分享一些有用的小知识。