ooooooo_qの日記

脆弱性の話とか

RubyやRubyのOSSの脆弱性を見つけた話の続き

この記事はRuby Advent Calendar 2019 - Qiitaの24日目です。


去年(RubyやRubyのOSSの脆弱性を見つけた話 - ooooooo_qの日記)と同様にRuby関連で今年見つけた脆弱性の話です。

Ruby

CVE-2019-16255: Shell#[]およびShell#testのコード挿入脆弱性

hackerone.com

脆弱性なのか判断に迷うもの。 引数が.sendにそのまま渡されるので値によってはコードが実行できるものでした。 .sendを使って実際に攻撃できるパターンが有るのか、Rubyのコードの中を調べて見つけた覚えがあります。

CVE-2019-15845: File.fnmatch の NUL 文字挿入脆弱性

hackerone.com

またNul文字。さすがにRubyではもうNul文字の問題はないのではないでしょうか。多分。

Pathnameでのコマンドインジェクション

hackerone.com

Ruby 2.6までのPathnameFileと同様にIOのクラスを継承していたため、.readなどのメソッドに値が渡されるとき、先頭の文字が|の場合にはコマンドが実行できました。 これも脆弱性か仕様なのか微妙なところですが、報奨金をいただけました。

Rubygems

CVE-2019-8320 symlinkを使ったディレクトリの削除

hackerone.com

重複になった報告の修正漏れでした。gemの解凍しようとすると全く関係ないディレクトリの中身が消えます。rubygemsのtarの解凍の仕方はちょっと特殊ですね。

ESCAPE SEQUENCE INJECTION * 4 (CVE-2019-8321,CVE-2019-8322, CVE-2019-8323, CVE-2019-8325)

blog.rubygems.org

実際のところ現在ではescape sequence injectionが影響あるようなターミナルは存在しないのでは、とも思っていたんですがitermでは印刷ダイアログが出せるようです(iTerm2 で `cat /dev/urandom` すると印刷ダイアログが出ることがある - mizdra's blog)。まだ知られていないことがあるかもしれません。

Rails

MarshalからのObject injectionとCVE-2019-5420

hackerone.com

詳細はRailsの上で走る - ooooooo_qの日記の方に書いたのでそちらを。

Discourse

hackerone.com

昨年と同じくDiscourseにも2つほど。どちらもファイルアップロード経由でのXSSでした。*1

github.com

アップロードされたらファイルのダウンロード時に、Content-Dispositionの値をinlineに変更できてしまったので、そのままXSSとなりえたものです。

github.com

SVGのアップロード時にはXSSになりそうなタグが除去されていたんですが、イベントハンドラが使えてしまったもの。

感想

今年はお金が出るところばかり探していたのが反省点です*2。あとRailsの情報をどこまで出していいのか探り探りで疲れましたね…。

少し順位が上がりました。

*1:1/5にコミットへのリンクなど追記。

*2:その割には去年より少ない

RubyやRubyのOSSの脆弱性を見つけた話

この記事はRuby Advent Calendar 2018 - Qiitaの23日目です。

今年はRubyOSS脆弱性をいろいろ探していたので、その感想を。

まずはRubyから

Ruby (Cruby)

techlife.cookpad.com

昨年公開された↑の@mametterさんの記事を見て、ちょっと調べてみようと思い今年のはじめから調査を開始。

はじめに見つけたものがWEBrickのhttp header injectionで、これは影響度低いのでは…?と思いながら報告してみたのですが結果は重複(CVE-2017-17742: WEBrick における HTTP レスポンス偽装の脆弱性について)。逆にこれぐらいでも脆弱性として扱われるかと思い、いろいろ調べてみることにしました。手法としては過去にRubyに報告された脆弱性を確認し、泥臭くドキュメントにあるメソッドをひとつずつ動作を試し続けました。

Tmpでのディレクトリトラバーサル

CVE-2018-6914: Tempfile および Tmpdir でのディレクトリトラバーサルを伴う意図しないファイルまたはディレクトリ作成の脆弱性について hackerone.com これって脆弱性なのと時々突っ込まれるやつです。ですよね、と自分でも思います。 これは同じ問題であったDir.mktmpdirのほうがわかりやすくて

[vagrant@localhost ~]$ ls .
[vagrant@localhost ~]$ irb
irb(main):001:0> require 'tmpdir'
=> true

irb(main):002:0> Dir.mktmpdir(['../../home/vagrant/', 'gold'])
=> "/tmp/../../home/vagrant/20180104-6544-1atequhgold"

irb(main):003:0> Dir.mktmpdir('../../home/vagrant/silver')
=> "/tmp/../../home/vagrant/silver20180104-6544-1822fif"

irb(main):004:0> `ls`
=> "20180104-6544-1atequhgold\nsilver20180104-6544-1822fif\n"

とするとシステムが提供するtmp以外の場所に作られたうえに、Rubyも自動で削除しないのでテンポラリじゃないという問題がありました。PHPのサーバなんかが一緒に動いてるとまずそうですね。

あと、ドキュメント上ではパスではなくprefixとされているのでユーザが安全と思ってしまいそうということで 、Pythonでも似たような話がされていますね。 https://bugs.python.org/issue35278

この辺の話をどこかに書こうと思っていたんでしたが忘れてました。

DirでのNUL文字の扱いの問題

CVE-2018-8780: Dir において NUL 文字挿入により意図しないディレクトリにアクセスされうる脆弱性について hackerone.com 以前FileでNUL文字の問題があったので、一応調べてみたらDirのメソッドの一部に残っていたもの。

TmpfileとDirの問題は書いてしまうことがありそうな気がするのですが、いまだ影響しているところを見たことがないですね…。

UNIX ドメインソケットでのNUL文字

CVE-2018-8779: UNIX ドメインソケットにおいて NUL 文字挿入により意図しないソケットにアクセスされうる脆弱性について hackerone.com NUL文字二つ目。UNIX ドメインソケットは普段使わないので、これが脆弱性として扱われるかよくわからなかったのですがとりあえず報告してみたら通りました。ここに任意の文字列が入る時点ですでに不味そうなので実際の影響は殆どなさそうです。

Ruby 2.6での挙動変更

Dir[]でのNUL文字について

知らない人も結構多そうなんですがDir[]Dir.glob()ではNUL文字が区切り文字になります。

$ irb
irb(main):001:0> Dir["/tmp\0/home"]
=> ["/tmp", "/home"]
irb(main):002:0> Dir["/tmp"]
=> ["/tmp"]
irb(main):003:0> Dir["/tmp/home"]
=> []

このため固定した文字列 + ユーザ入力の文字列の文字列を渡すと全く別の場所が探索される可能性があります。 これはドキュメントに書かれている挙動であり仕様です。*1

singleton method Dir.[] (Ruby 2.6.0)

[PARAM] pattern: パターンを文字列で指定します。 パターンを "\0" で区切って 1 度に複数のパターンを指定することもで きます。 パターンの区切りには "\0" のみ指定できます。 配列を指定することで複数のパターンを指定できます。

しかし、対策しているコードは今のところ見たことがありません。

これはちょっと使う側として辛いので、twitterでusaさんにRuby3で廃止できないか提案してみたところ、チケットを作ってくださって採用されました。Feature #14643: Remove problematic separator '\0' of Dir.glob and Dir.[] - Ruby trunk - Ruby Issue Tracking System

今月リリースのRuby 2.6からNUL文字が渡されると警告が出るようになります。(ruby/NEWS at v2_6_0_rc2 · ruby/ruby · GitHub)

Rubygems

rubygems

2月のリリースのものと似たものを報告していて重複に。

3/28に公開されたRubyの脆弱性情報についてのポエム的解説 - pixiv insideと見解が違うのが、サーバ側だけでなく普通の利用者も危険なはずという点です。gemのinstallとかunpackで問題がでるので。

65534倍効率的なブルートフォース

hackerone.com

rubygems.orgでAPIキーの確認時に渡されるパラメータの型をチェックしておらず、配列を投げてやるとそれがそのままモデルのfindに渡されるため、どれか一つでも正しいものがあれば認証が通ってしまっていました。rubygems.orgではrack-attackが入ってたんですが、これを使うと1つのリクエストで効率的にブルートフォースができるのですり抜けます。型のチェックがゆるい言語で、認証系を独自に実装しているようなところではたまにありそうな問題です。

どれぐらい渡せるか限界を探ると、65534倍まで効率的なブルートフォースが可能でそれ以上の値はエラーとなりました。この場合はAPIキーがSecureRandom.hex(32)で生成されていたので、65534倍効率的な程度ではほぼ影響はなかったと思われます。SecureRandom.hex(8)ぐらいではまずかったかもしれません。

Rails 5.2.2からは渡されるパラメータが多すぎるときにbindしなくなったらしいので、より大きな配列を投げられるかもしれませんがまだ確認していません。

minitarでのKernel.open*2

github.com

input,outputにKernel.openが使われていたのでissueで書いてみたところ意図的なものとのこと。ただ、gemを使う側が気にしてにないと危ないのは確かなのでreamdeに追記されました。

geminabox

Avoid XSS vulnerability on /reindex · geminabox/geminabox@50da77f · GitHub エラーからのXSS。異常系からのXSSはたまに見かけますね。

Discourse

hackerone.com いくつか報告を出して通ったのですが、公開扱いにはなっていないので詳細については省略。 報告に書いた説明がいくつか変だったり調査不足だったところがあったので、もっとちゃんと書けばもっと報奨金もらえたのではというのが反省点。

Heroku

bugcrowd.com 会社で公開しているOSSにも報奨金を設定している企業はいくつかありまして、Herokuもそのうちの一つです。 RubyOSSのものにいくつか出しました。これも公開されていないので詳細は省略。

Rails

pgでのNUL文字

hackerone.com

これはCVEが出てないので知らない人も多そうです。 内容としてはこれもまたNUL文字で、文字列中にNUL文字があるとそこで切られたクエリが送信されていました。

> Article.where("title = :title", {title: "test title\0suffix"})
  Article Load (0.4ms)  SELECT  "articles".* FROM "articles" WHERE (title = 'test title') LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Article id: 1, title: "test title", text: "dummy", created_at: "2018-08-13 13:31:37", updated_at: "2018-08-13 13:31:37">]>

RailsであればNUL文字は保存ができないので影響があるのは検索するときだけなのですが、文字列をブラックリストやsuffixでバリデーションしてるとすり抜けます。これは書いてる場所がたまにあると思います。*3

Rails 4.xではpg1.xに対応してないようなので、まだRails5に上げていない場合は頑張って諸々のバージョンを上げるかパッチでなんとかするかしか……

ちゃんと調べてなかったのでRailsのプログラムに報告してしまったのですが、正確にはpg gemの問題でした。ですが、pgのチームに連絡してもらった上で報奨金ももらえました。

Active StorageでのXSS

Rails5.2で追加されたActive Storageではファイルアップロードを実装するときにおこる問題をいろいろ踏んでいました。結構頑張って調べたんですがこれも重複。

報奨金

  • Ruby
    • $500 × 3
  • discourse
    • $128 × 3
  • Heroku
    • $3000 × 1
    • $900 × 1
    • $300 × 2
  • Rails
    • $1500

RubyOSSでの報奨金は合計で$7,584となりました。

感想

Rubyに詳しくなった

Rubyに限らない話なんですが脆弱性調査をしていると、マニアックな挙動を調べるモチベーションが高くなります。ドキュメントのメソッドの挙動をひたすら確認していったのですが、途中これは一体何の修行なんだろうなどと思っていました。どんな物があるのか去年よりだいぶ詳しくなったと思います。 と言いつつ未だにmapの引数の順番で迷いますが。*4

脆弱性としての判定

普段はweb周りのXSSなどを調べていてそれ以外の用途には疎いため、脆弱性に当たるかどうかの判定に悩む場面が何度かありました。仕様なのかバグなのか微妙だけども影響あるならば報告出しておいたほうがいいか、という思考で迷う場合にはとりあえず報告していました。そのほうがシステムの安全性としては高くなるのでしょうがないかなとも思います。報告を受ける側の負荷は高そうですが……

自分が使うものを安全にする

クリティカルな脆弱性を見つけられないのはバグハンターとしては辛いものですが、利用者としては幸いです。 YAML.safe_yamlをなんとかバイバスできないかひたすら探していたり、rubygems.orgでRCEできないかなど結構調べていたのですが見つけることができず、悔しい一方利用者としては安心感が増します。

hackeroneのrubyランクで1位に

*1:昔は空白文字も区切り文字として扱われていたようです。

*2:12/29追加

*3:この問題を見つけたあと、わかっていたはずなのに1回書いてしまったことがあるので

*4:jQueryやEcmascript5などと混ざって覚えてしまっているため

CakePHPの脆弱性を見つけた話(あるいはCakePHP Advent Calendar 2017 n日目)

bakery.cakephp.org

年末にCakePHP 2.x系のSQL injectionを見つけたので報告してました。

詳細

blog.ichikaway.com

内容としてはこちらの記事で書かれているようなCakePHPでよくあるSQL injectionです。

postConditionを使うとリクエストのbodyの形からCakePHPのfindでconditionsに使う形変換されるのですが、その際にキーの値がエスケープされるかというとそうでもない状態であったということです。

これだけでしたらCakePHPの仕様であって使い方の問題ともとれるのですが、ドキュメントを見ると脆弱性が発生する形で記載されておりそれは不味いだろうということで報告しました。

コントローラ - 2.x

public function index() {
    $conditions = $this->postConditions($this->request->data);
    $orders = $this->Order->find('all', compact('conditions'));
    $this->set('orders', $orders);

CakePHP脆弱性のハンドリングは GitHub - cakephp/cakephp: CakePHP: The Rapid Development Framework for PHP - Official Repositoryで示されていたので、それに沿ってメーリングリストにメールを送って修正の方針などでやり取りしました。12/9に最初のメールを送って、修正がリリースされたのは18日です。*1

Securityコンポーネントが設定されている場合の挙動を確認していなかったのでここ数日確認しているのですが、設定している限りは多分大丈夫そうです。*2 とはいえ修正自体はシンプルなので基本的にはバージョンを上げたほうが早いでしょう。

CakePHP Advent Calendar 2017

この脆弱性[CakePHP3] データ漏洩していませんか?RequestHandlerの危険性 - Qiitaの記事の脆弱性を確認のためCakePHPのコードを確認していたときに見つけものでした。なぜかこのアドベントカレンダーでは脆弱性の話が多かったような気がします。

*1:その間にid:ichikaway さんのピンポイントな記事が公開されたのでドキッとしました

*2:少し怪しいところは見つけたのですが、存在しないテーブルがwhere文に入ってエラーになるのを回避する方法が思い浮かばない……