Nginx Lua Web Application Security

栏目: Lua · 发布时间: 7年前

内容简介:Nginx Lua Web Application Security

前言

我们知道,Nginx Lua经常被用来编写WAF。但随着 lua 语言的广泛,在其他web应用中也会有大量的Lua。

安装配置

可以使用OpenResty或者nginx编译的时候添加 lua-nginx-module 模块。区别在于OpenResty自带了很多第三方Lua库。

所有测试均在以下环境:

Lua 5.1.4
nginx/1.9.15
lua-nginx-module-0.10.5

安装完成后,进行nginx配置。注意该配置只是拿来做漏洞测试。

server块添加一个location

location /sec_ngx_lua {
    content_by_lua_file /opt/lua_module/content.lua;
}

http块添加lua模块

lua_package_path '/opt/lua_module/?.lua;;';
lua_code_cache on;

表示添加/opt/lua_module路径的所有模块。

接下来就只在/opt/lua_module路径中写代码测试了。

vuls.lua(漏洞代码)

local _M = {}

function _M.xss()
    local name = ngx.req.get_uri_args().name or ""
    ngx.header.content_type = "text/html"
    ngx.say(name)
end

return _M

content.lua(调用vuls.lua中的代码)

local vul = require "vuls"
vul.xss();

漏洞类型

XSS

漏洞代码

function _M.xss()
    local name = ngx.req.get_uri_args().name or ""
    ngx.header.content_type = "text/html"
    ngx.say(name)
end

漏洞验证

http://joychou.me/sec_ngx_lua?name=<script>alert(9527)</script>

修复

没有提供方法进行编码,所以编码需要自己实现。

Sql Injection

由于要使用数据库,所以如果未使用OpenResty,需要添加OpenResty提供的 mysql.lua

下载地址:

https://raw.githubusercontent.com/openresty/lua-resty-mysql/master/lib/resty/mysql.lua

将下载的mysql.lua同样放在/opt/lua_module/路径。

漏洞代码

local _M = {}

function close_db(db)  
    if not db then  
        return  
    end  
    db:close()  
end

function _M.sqli()
    local mysql = require("mysql")
    local db, err = mysql: new()

    ngx.header.content_type = "text/html"

    if not db then
        ngx.say("new mysql error :", err)
        return
    end

    db:set_timeout(1000)

    local props = {  
        host = "127.0.0.1",  
        port = 3306,  
        database = "lua",  
        user = "root",  
        password = "joychouisgood"  
    }

    
    local res, err, errno, sqlstate = db:connect(props)
    if not res then  
        ngx.say("connect to mysql error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate)
        return close_db(db)
    end

    
    local uid = ngx.req.get_uri_args().uid
    local select_sql = "select id, name from info where id =" .. uid
    res, err, errno, sqlstate = db:query(select_sql)
    if not res then  
        ngx.say("select error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate)  
        return close_db(db)
    end

   
    for i, row in ipairs(res) do  
        for id, name in pairs(row) do  
        ngx.say("row ", i, " : ", id, " = ", name, "<br/>")  
        end  
    end 

end

return _M

lua.info表数据

mysql> select * from info;
+----+---------+
| id | name    |
+----+---------+
|  1 | joychou |
|  2 | smilent |
+----+---------+
2 rows in set (0.00 sec)

漏洞证明

http://joychou.me/sec_ngx_lua?uid=2 UNION ALL SELECT CONCAT(0x7162766271,0x744a75536365647154756a6d51436a746b656b6e4f796c4e6461565153537254727851564f6a4c61,0x716a787871),NULL-- cils

返回

id = qbvbqtJuScedqTujmQCjtkeknOylNdaVQSSrTrxQVOjLaqjxxq

漏洞修复

使用 ngx.quote_sql_str 对参数进行编码

CRLF Injection

参数外部可控的情况下,可使用%0d%0a进行CRLR注入。

漏洞代码

function _M.crlf_injection()
    local user = ngx.req.get_uri_args().user or ""
    ngx.header.content_type = "text/html"
    ngx.header['X-Test'] = user
    ngx.say('crlf inject sec test')
end

漏洞验证

➜  ~ curl -v 'http://joychou.me/sec_ngx_lua?user=demo%0d%0aSet-cookie:JSPSESSID%3Djoychou'
*   Trying 35.185.163.135...
* Connected to joychou.me (35.185.163.135) port 80 (#0)
> GET /sec_ngx_lua?user=demo%0d%0aSet-cookie:JSPSESSID%3Djoychou HTTP/1.1
> Host: joychou.me
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.9.15
< Date: Tue, 13 Jun 2017 09:34:12 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Test: demo
< Set-cookie:JSPSESSID=joychou
<
crlf inject sec test

漏洞修复

过滤外部传参。

Command Injection

Lua可执行命令的方法

  • io.popen
  • os.execute (执行操作系统 shell 命令)

os.execute不能拿到回显,但io.popen可以。

漏洞代码

使用io.popen执行命令时,命令外部可控,导致任意命令执行。

function _M.cmd_injection()
    ngx.header.content_type = "text/plain"
    local user = ngx.req.get_uri_args().user or ""
    local handle = io.popen("ls -l /home/"..user)
    local result = handle:read("*a")
    handle:close()
    ngx.say(result)
end

漏洞验证

➜  ~ curl 'http://joychou.me/sec_ngx_lua?user=root;cat%20/etc/passwd'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync

漏洞修复

过滤外部传参。

任意文件读取

使用io.open进行文件读取时,文件名外部可控导致任意文件读取。

function _M.file_read()
    local file = ngx.req.get_uri_args().file or ""
    ngx.header.content_type = "text/html"
    local f = io.open(file..".txt")
    local ret = f:read("*a")
    f.close()
    ngx.say(ret)
end

漏洞验证

使用%00截断后面的 .txt 字符串

http://joychou.me/sec_ngx_lua?file=/etc/hosts%00

漏洞修复

过滤外部传参。

代码注入

先来看下loadstring造成的代码注入的实例

> x="os.execute('echo 111 > /tmp/xx')"
> assert(loadstring(x))()
[root@sectest]# cat /tmp/xx
111

如果loadstring的字符串里可外部控制,就可以导致代码注入,和 phppythoneval 一样。

lua中和loadstring类似的方法还有

require,dofile,loadfile,dostring,loadstring,loadlib,load

漏洞代码

function _M.code_injection()
    local name = ngx.req.get_uri_args().name or ""
    ngx.header.content_type = "text/html"
    local html = string.format([[
        ngx.say("Hello, %s")
        ngx.say("Today is "..os.date())
    ]], name)
    loadstring(html)()
end

漏洞证明

http://joychou.me/sec_ngx_lua?name=joychou") os.execute("echo 2333 > /tmp/xxx
[root@sectest]# cat /tmp/xxx
2333

漏洞修复

过滤外部传参。

参考链接

Lua Web Application Security Vulnerabilities


以上所述就是小编给大家介绍的《Nginx Lua Web Application Security》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

绝对价值

绝对价值

[美] 伊塔马尔·西蒙森 艾曼纽·罗森 / 钱峰 / 中国友谊出版公司 / 2014-7 / 45.00元

绝对价值指的是经用户体验的产品质量,即使用某件产品或者享受某项服务的切实感受。 过去,消费就像是押宝。一件商品好不好,一家餐馆的环境如何,没有亲身体验过消费者无从得知,只能根据营销人员提供的有限信息去猜测。品牌、原产地、价位、广告,这些重要的质量线索左右着消费者的选择。 然而,互联网和新兴科技以一种前所未有的速度改变了商业环境。当消费者可以在购买前查看到交易记录和消费者评价,通过便捷的......一起来看看 《绝对价值》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具