Sindbad~EG File Manager

Current Path : /opt/nginxhttpd_/etc/openresty_config/lua/
Upload File :
Current File : //opt/nginxhttpd_/etc/openresty_config/lua/waf_challenge.lua

--[[
Code responsible for creating/managing the Javascript anti-bot challenge

Contains 3 types of challenge :
  * JS Challenge : send a 503 to the browser with a javascript code that will auto-execute, make an ajax request to
    retrieve the JS Challenge to another endpoint, execute the challenge, send the response, redirect to the
    original page (improved)
  * Captcha : send a 503 to the browser with a javascript code that contains a captcha to solve. Send the response to
    the o2switch endpoint and redirect
  * Cookie challenge : send a 307 response and ask the browser to set a cookie

We must pass a 'challengetype' nginx variable to check what king a challenge we use
--]]

-- Right, we support just 3 types of challenges
-- Early test / exit (probably better performance wise, this code is executed A LOT)
local challengeType = ngx.var.challengetype
if challengeType ~= 'js' and challengeType ~= 'cookie' and challengeType ~= 'captcha' then
    ngx.exit(418)
end

local o2utils = require "lib/o2switch_utils"
local o2debug = require "lib/o2switch_debug"
local ck = require "resty.cookie"
local jsChl = require "lib/o2switch_js_challenge_v2"
local captchaChl = require "lib/o2switch_captcha"
local cookieChl = require "lib/o2switch_cookie_challenge"
local o2counter = require "lib/o2switch_counter"
local ngx = ngx
local clientIp = ngx.var.remote_addr
local ua = ngx.var.http_user_agent or '-'
local cookieName = 'o2s-chl'
local uniqueId = ngx.var.request_id
local type = type
local domain = o2utils.extractDomain(o2utils.extractDomainWww(ngx.var.host))
local cookie, err = ck:new()

--[[
    New, improved, JS Challenge
--]]
if challengeType == 'js' then
    if not cookie then
        jsChl.sendChallengeHtmlPage(
            jsChl.getAntiTamperingHash(clientIp, ua), 
            uniqueId
        )
    end

    local field, err = cookie:get(cookieName)
    if not field or type(field) ~= "string" then
        jsChl.sendChallengeHtmlPage(
            jsChl.getAntiTamperingHash(clientIp, ua), 
            uniqueId
        )
    end

    local expectedCookie = jsChl.getBypassCookieValue(clientIp, ua, domain)
    if field ~= expectedCookie then
        --o2debug.debug('Not bypassed, not the expected cookie. Received = "' .. field .. '" and expected was "'.. expectedCookie ..'"')
        jsChl.sendChallengeHtmlPage(
            jsChl.getAntiTamperingHash(clientIp, ua), 
            uniqueId
        )
    end

    -- The cookie is valid but we ignore it because we have some mitigation in place
    if ngx.var['autoMitigationOverride']  == 1 then
        jsChl.sendChallengeHtmlPage(
            jsChl.getAntiTamperingHash(clientIp, ua), 
            uniqueId
        )
    end

    -- TODO : Also implement the credit system in here

    -- TODO : Should we delete persisted challenge in redis or just dont give a fuck because of the expiration on the key ?

    ngx.exit(418) 
end

--[[
    Captcha challenge
--]]
if challengeType == 'captcha' then
    if not cookie then
        captchaChl.sendChallengeHtmlPage(captchaChl.getAntiTamperingHash(clientIp, ua), uniqueId)
    end

    local field, err = cookie:get(cookieName)
    if not field or type(field) ~= "string" then
        captchaChl.sendChallengeHtmlPage(captchaChl.getAntiTamperingHash(clientIp, ua), uniqueId)
    end

    local expectedCookie = captchaChl.getBypassCookieValue(clientIp, ua, domain)
    if field ~= expectedCookie then
        --o2debug.debug('Not bypassed, not the expected cookie. Received = "' .. field .. '" and expected was "'.. expectedCookie ..'"')
        captchaChl.sendChallengeHtmlPage(captchaChl.getAntiTamperingHash(clientIp, ua), uniqueId)
    end

    -- The cookie is valid but we ignore it because we have some mitigation in place
    if ngx.var['autoMitigationOverride']  == 1 then
        captchaChl.sendChallengeHtmlPage(captchaChl.getAntiTamperingHash(clientIp, ua), uniqueId)
    end

    return ngx.exit(418)
end

--[[
    Cookie challenge
--]]
if challengeType == 'cookie' then
    -- No cookie at all ? Send the challenge
    if not cookie then
        --o2debug.debug("Cookie CHL : No cookie " .. clientIp .. ' on ' .. domain)
        --o2debug.debug("Cookie CHL : Send 307 + cookie challenge for " .. clientIp .. ' on ' .. domain)
        cookieChl.send307WithCookie(domain, cookieName, cookieChl.getChallengeCookieValue(clientIp, ua, domain))
    end

    -- Not cookie name o2s-chl : Send the challenge
    local field, err = cookie:get(cookieName)
    if not field then
        --o2debug.debug("Cookie CHL : No cookie named " .. cookieName .. ' for ' .. clientIp .. ' on ' .. domain)
        --o2debug.debug("Cookie CHL : Send 307 + cookie challenge for " .. clientIp .. ' on ' .. domain)
        cookieChl.send307WithCookie(domain, cookieName, cookieChl.getChallengeCookieValue(clientIp, ua, domain))
    end


    -- A cookie is provided ? Is it valid and does it contains the right value ?
    local expectedValue = cookieChl.getChallengeCookieValue(clientIp, ua, domain)
    if field ~= expectedValue then
        --o2debug.debug("Cookie CHL : Failed for " .. clientIp .. ' on ' .. domain)
        --o2debug.debug("Cookie CHL : RE-Send 307 + cookie challenge for " .. clientIp .. ' on ' .. domain)
        cookieChl.send307WithCookie(domain, cookieName, expectedValue)
    end

    if ngx.var['autoMitigationOverride']  == 1 then
        cookieChl.send307WithCookie(domain, cookieName, expectedValue)
    end

    ngx.exit(418)
end

o2debug.debugErr('Weird, we shouldn\'t be here')
ngx.exit(418) -- Should not happen

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists