日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Rails動(dòng)態(tài)模板路徑的風(fēng)險(xiǎn)

[[172440]]

前言

從安全開發(fā)的角度來看,Ruby on Rails是一套很友善的框架。它從框架層避免了很多過去網(wǎng)站長(zhǎng)出現(xiàn)的安全問題。例如使用ORM避免大部分的SQL injection問題,有內(nèi)建的authenticity_token讓開發(fā)者不必特別煩惱CSRF,從機(jī)制面規(guī)定了開發(fā)者使用Strong Parameter來避免Mass Assignment,預(yù)設(shè)轉(zhuǎn)化危險(xiǎn)字符避免XSS等。

就我們從過去的滲透測(cè)試的經(jīng)驗(yàn)來看,Rails網(wǎng)站雖然還是能找到問題,但相對(duì)問題較少,而且很少單純因?yàn)镽ails寫法問題拿到系統(tǒng)權(quán)限。而今天要分享的,是一次滲透測(cè)試中比較特別的例子。因?yàn)殚_發(fā)者使用了動(dòng)態(tài)模板路徑(Dynamic Render Paths)的寫法(注解1),最后造成了嚴(yán)重的結(jié)果。

動(dòng)態(tài)模板路徑,OWASP的介紹是這樣的:

OWASP是這樣說,如果你的模板路徑是動(dòng)態(tài)產(chǎn)生的,而且使用者可以控制那個(gè)模板路徑。那么使用者就可以讀取任意模板,包括管理界面模板。這樣的描述感覺還好,但就我們的發(fā)現(xiàn),這其實(shí)是嚴(yán)重的直接存取物件問題(Insecure Direct Object References),甚至有機(jī)會(huì)造成遠(yuǎn)程代碼執(zhí)行(Remote Code Execution)。怎么說呢?我們直接看下去。

基本細(xì)節(jié)

一個(gè)動(dòng)態(tài)模版路徑的寫法如下:

 
 
 
 
  1. # app/controllers/welcome_controller.rb 
  2. class WelcomeController < ApplicationController 
  3.   def index 
  4.     page = params[:page] || 'index' 
  5.     render page 
  6.   end 
  7. end 

而index的模版內(nèi)容是這樣:

 
 
 
 
  1. #app/views/welcome/index.html.erb 
  2. This is INDEX page. 

另外建一個(gè)demo模版做示意:

 
 
 
 
  1. # app/views/welcome/demo.html.erb 
  2. This is DEMO page. 

實(shí)際測(cè)試,如果我們連到WelcomeController的index action,不帶任何參數(shù)會(huì)讀取index模版。

如果帶參數(shù)page=demo,會(huì)讀取到demo模版。

所以,如果我們知道管理界面的模版路徑,送出路徑參數(shù)就可以讀取到管理界面。這就是OWASP所描述的風(fēng)險(xiǎn),攻擊者得以讀取任意模版。

然而,當(dāng)我們嘗試送出系統(tǒng)絕對(duì)路徑例如/etc/passwd(注解2),網(wǎng)頁竟然顯示/etc/passwd的內(nèi)容!這就是之前所述的直接存取物件問題,可以遍歷目錄瀏覽檔案。

進(jìn)階攻擊

通常在Rails環(huán)境下能夠讀取任意檔案,攻擊者會(huì)優(yōu)先尋找secret_token,目的是變?cè)鞇阂鈙ession cookie利用Marshal serialize的問題做RCE。然而在本案例系統(tǒng)使用了Rails 4.1后的版本,Rails 4.1預(yù)設(shè)使用了JSON-based的serializer防止了之前的RCE問題,所以并沒有辦法輕松利用。

為了取得系統(tǒng)操作權(quán),我們嘗試尋找其他可利用的地方。在這邊我們發(fā)現(xiàn)了該站系統(tǒng)production.log中存在AWS的上傳紀(jì)錄。如下:

 
 
 
 
  1. # log/production.log 
  2. INFO -- : [AWS S3 200 0.041347 0 retries] put_object(:acl=>:public_read,:bucket_name=>"xxx 

于是我們可以利用上傳檔案的Content-Type內(nèi)容,將Embedded Ruby語句<%

 
 
 
 
  1. #{params[:devcore]} 

%>添加到production.log檔案里面。于是log的內(nèi)容變成了下面這樣:

 
 
 
 
  1. # log/production.log 
  2. INFO -- : [AWS S3 200 0.041347 0 retries] put_object(:acl=>:public_read,:bucket_name=>"xxxx",:content_length=>12405,:content_type=>"image/png",:data=>#<File:/Users/shaolin/project/playground/rails/render/public/uploads/tmp/test_upload.png (12405 bytes)>,:key=>"upload_001") 
  3.  
  4. INFO -- : [AWS S3 200 0.040211 0 retries] put_object(:acl=>:public_read,:bucket_name=>"xxx 

接著,我們就可以利用前面的弱點(diǎn)讀取production.log檔案,再帶一個(gè)devcore參數(shù)作為指令,如圖,成功取得系統(tǒng)權(quán)限:

風(fēng)險(xiǎn)原因

一般來說Rails開發(fā)并不太會(huì)這樣寫,但稍微搜尋一下Github還是能發(fā)現(xiàn)這種寫法存在一些項(xiàng)目中。我想主要原因多半是開發(fā)者想要偷懶,然后也可能想說動(dòng)態(tài)模板路徑頂多就被看到面板的html,無傷大雅。誰知道就因?yàn)檫@樣導(dǎo)致整個(gè)代碼內(nèi)容被讀取。

若有一個(gè)action要?jiǎng)討B(tài)顯示不同模版的需求,為了避免上述的問題,就辛苦點(diǎn)先用case…when去判斷吧。這跟不要用字串組SQL語句避免SQL injection一樣,這種外面?zhèn)鬟M(jìn)來的參數(shù)都要謹(jǐn)慎處理的觀念要內(nèi)化在開發(fā)中。

除了開發(fā)者基本上不應(yīng)該這樣開發(fā)外,Rails本身也有一點(diǎn)點(diǎn)問題,當(dāng)render路徑?jīng)]有擴(kuò)展名,無法判斷什么格式時(shí),就會(huì)直接采用預(yù)設(shè)的template handler。

 
 
 
 
  1. # lib/action_view/template/resolver.rb 
  2. def extract_handler_and_format_and_variant(path, default_formats) 
  3.   pieces = File.basename(path).split(".") 
  4.   pieces.shift 
  5.  
  6.   extension = pieces.pop 
  7.   unless extension 
  8.     message = "The file #{path} did not specify a template handler. The default is currently ERB, " \ 
  9.               "but will change to RAW in the future." 
  10.     ActiveSupport::Deprecation.warn message 
  11.   end 
  12.  
  13.   handler = Template.handler_for_extension(extension) 
  14.   format, variant = pieces.last.split(EXTENSIONS[:variants], 2) if pieces.last 
  15.   format  &&= Template::Types[format] 
  16.  
  17.   [handler, format, variant] 
  18. end 

而這里預(yù)設(shè)的handler是ERB(見register_default_template_handler),所以有本篇后面提到的進(jìn)階攻擊,可以被利用來RCE。

 
 
 
 
  1. # lib/action_view/template/handlers.rb 
  2. def self.extended(base) 
  3.   base.register_default_template_handler :erb, ERB.new 
  4.   base.register_template_handler :builder, Builder.new 
  5.   base.register_template_handler :raw, Raw.new 
  6.   base.register_template_handler :ruby, :source.to_proc 
  7. end 

慶幸的是,目前Rails已經(jīng)把預(yù)設(shè)的template handler從ERB改成RAW,不會(huì)輕易把要render的檔案當(dāng)成ERB執(zhí)行了。詳細(xì)的內(nèi)容請(qǐng)參考這個(gè)commit。

結(jié)論

Ruby on Rails能讓開發(fā)者較輕松的開發(fā)出安全的應(yīng)用程序,然而,若開發(fā)者不注意,還是有可能寫出嚴(yán)重的漏洞。本文的動(dòng)態(tài)樣板路徑就是這樣一個(gè)例子,它不只是OWASP所描述的可以存取任意模版而已,它可以遍歷檔案,甚至因?yàn)閞ails預(yù)設(shè)的template handler是ERB,造成遠(yuǎn)程代碼執(zhí)行讓攻擊者取得服務(wù)器操作權(quán)。

這個(gè)例子又再次驗(yàn)證,框架可以幫助大家快速開發(fā),增加安全度。但唯有良好的安全意識(shí),才是應(yīng)用程序安全的基石。


標(biāo)題名稱:Rails動(dòng)態(tài)模板路徑的風(fēng)險(xiǎn)
當(dāng)前鏈接:http://www.dlmjj.cn/article/cohicpe.html