用户
搜索

[思路/技术] Openresty初级入门实验

  • TA的每日心情
    开心
    2018-3-5 14:08
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    i春秋作家

    Rank: 7Rank: 7Rank: 7

    3

    主题

    78

    帖子

    308

    魔法币
    收听
    0
    粉丝
    0
    注册时间
    2015-11-20

    i春秋签约作者

    发表于 2018-11-8 15:27:30 04703
    本帖最后由 sauren 于 2018-11-8 15:27 编辑

    一、openresty简介
    OpenResty(是一个全功能的 Web 应用服务器。它打包了标准的 Nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项,开发人员可以使用 Lua 编程语言对 Nginx 核心以及现有的各种 Nginx C 模块进行脚本编程,构建出可以处理一万以上并发请求的极端高性能的 Web应用。

    二、实验目标
    1.指定黑名单IP封禁
    2.指定的恶意UA封禁
    3.简单的URL参数匹配关键字符封禁(union,select等)

    三、实验环境
    系统:win10_64位
    环境:下载ngx_openresty-1.9.7.1-win32.ziphttps://openresty.org/download/ngx_openresty-1.9.7.1-win32.zip
    此环境为一键包,解压缩即可上手调试。

    四、简单配置
    (1)nginx与lua的执行顺序和步骤说明

       nginx在处理每一个用户请求时,都是按照若干个不同的阶段依次处理的,例如access阶段与content阶段,实际上content阶段,nginx已经完成了请求转发等操作,所以如果WAF仅在此阶段工作,那么实际攻击已经执行了,所以必须前移到access等阶段执行。具体顺序如下:
       1、post-read      读取请求内容阶段
       2、server-rewrite  server请求地址重写阶段
       3、find-config 配置查找阶段,用来完成当前请求与location配重块之间的配对工作;
       4、rewrite location   请求地址重写阶段,当ngx_rewrite指令用于location中,就是再这个阶段运行的;
       5、post-rewrite 请求地址重写提交阶段,当nginx完成rewrite阶段所要求的内部跳转动作
       6、preaccess      访问权限检查准备阶段
       7、access  权限检查阶段
       8、post-access 访问权限检查提交阶段
       9、try-files   配置项try_files处理阶段;
       10、content内容产生阶段,是所有请求处理阶段中最为重要的阶段,因为这个阶段的指令通常是用来生成HTTP响应内容的;
       11、log 日志模块处理阶段;
       对应的lua文件(命令)加载的阶段指令如下:
       1、init_by_lua、init_by_lua_file
       阶段:loading-config
       2、init_worker_by_lua、init_worker_by_lua_file
       阶段:starting-worker
       3、set_by_lua、set_by_lua_file
       阶段:rewrite
       4、rewrite_by_lua、rewrite_by_lua_file
       阶段:rewrite tail
       5、access_by_lua,access_by_lua_file
       阶段:access tail(主要用于访问控制,能收集到大部分的变量。)
       6、content_by_lua,content_by_lua_file
       阶段:content(为请求者输出响应内容)
       7、header_filter_by_lua,header_filter_by_lua_file
       阶段:output-header-filter(一般用来设置cookie和headers)
       8、body_filter_by_lua,body_filter_by_lua_file
       阶段:output-body-filter
       9、log_by_lua,log_by_lua_file
       阶段:log

    实验为了简单操作演示,选用content_by_lua阶段,但正式执行时,应该将各部分代码移植到各阶段进行执行。

    (2)配置文件添加
       2.1 在解压好的openresty主目录下新建waf文件夹,并在waf文件夹下新建我们的主文件my.lua
       2.2 nginx.conf文件进行如下修改:

    location / {
                       default_type text/html;
                      }

        添加一行
    location / {
                     default_type text/html;

                      content_by_lua_file  waf/my.lua;
                      }

    五、正式编码
    (1)hello world.

       
    [AppleScript] 纯文本查看 复制代码
    ngx.say("hello world")
       启动或重启(nginx -s reload)nginx(请注意CMD需要cd到openresty主目录,否则可能出现文件加载出错问题)后访问如下:
              helloworld.png
       (2)指定的IP封禁
       在my.lua同目录下新建black.list(此文件作为黑名单文件,按行读取IP)
       代码如下:
    [HTML] 纯文本查看 复制代码
    local blacklist={} 
    local remote_addr=ngx.var.remote_addr
    --按行读取黑名单IP到table
    
    local file =io.open("./waf/black.list","r+")  --路径需要根据nginx启动路径来配置,否则会报错
    for i in file: lines() do
          table.insert(blacklist,i)
    end
    file: close()
    
    --循环table对比remote_addr IP是否命中,命中则直接退出
    for c,d in pairs(blacklist) do 
         if remote_addr == d then
              ngx.say("forbidden")
              ngx.exit(200)
    
         end
    end
    ngx.say("hello world")
    

       将127.0.0.1加入balck.list,访问则返回forbidden:
              forbidden.png

      (3)指定的UA进行封禁
    [C] 纯文本查看 复制代码
    local ua    =        ngx.var.http_user_agent
    local find  =   ngx.re.find
    local evilua=        "hydra|.nasl|floodgate|sqlmap|get-minimal|gootkit auto-rooter scanner|grabber|grendel-scan|havij|WPScan"
    
    local st1,sp1,err    = find(ua,evilua,"ijo")
       
       if st1 then 
            -- do action
            ngx.exit(505)
       end
    
    
    
    ngx.say("hello world")
    
    
       使用sqlmap默认的UA进行访问如下:
              ua.png
    (4)简单的union注入检测        
    [C] 纯文本查看 复制代码
    --读取request_uri
    local request_uri        =        ngx.var.request_uri
    
    --读取拼凑post_uri
    ngx.req.read_body()
    local arg = ngx.req.get_post_args()
    post_uri=""
    for k,v in pairs(arg) do
            post_uri=post_uri..k.."="..v.." "
    
    end
    
    --定义一个简单的sql union注入规则
    local sqlrule =        "(?:(union(.*?)select))"
    local find  =   ngx.re.find
    
    --检测uri是否含有恶意参数
    local st1,sp1,err    = find(request_uri,sqlrule,"ijo")
       
    if st1 then 
        -- do action
        ngx.exit(506)
    end
    
    --检测post_args是否含有恶意URI
    local st2,sp2,err2    = find(post_uri,sqlrule,"ijo")
       
    if st2 then 
        -- do action
        ngx.exit(506)
    end
    
    ngx.say("hello world")
    
    
            访问测试如下:

              sql.png

    六、TODO MORE

    (1)WAF代码框架化
    (2)更多更精准的规则定制
    (3)API的集成,易于运营人员的操作







    发新帖
    您需要登录后才可以回帖 登录 | 立即注册