🔨Fuzzing

doing some multi-threading

lotus is focusing to make the fuzzing or multi-threading process easy and simple by providing two class to help in common fuzzing cases

the first one is for parameter scanning that doesn't means this the can be used for Param Scanner this but the idea is this class has been created for that reason

ParamScan

this class takes one string with List, for the target parameter to scan and the payloads list, after that the ParamScan class will send the target parameter with every item in the payloads list to the target function

target function is just lua function you create to so simple thing like sending http requests and return the response

after sending it to the target function it will take the output of this function and then send it to the callback function

Callback function is list the target function but for parsing

in you callback function parse the target function output and see if this able is valid to save it in the report or not

FUZZ_WORKERS is lua varaible the value of --fuzz-workers option

SCAN_TYPE = 2

local function send_report(url,parameter,payload,matching_error)
    VulnReport:setName("Template Injection")
    VulnReport:setDescription("https://owasp.org/www-project-web-security-testing-guide/v41/4-Web_Application_Security_Testing/07-Input_Validation_Testing/18-Testing_for_Server_Side_Template_Injection")
    VulnReport:setRisk("high")
    VulnReport:setUrl(url)
    VulnReport:setParam(parameter)
    VulnReport:setAttack(payload)
    VulnReport:setEvidence(matching_error)
    print_vuln_report(VulnReport)
end

SSTI_PAYLOADS = {
    "lot{{2*2}}us",
    "lot<%= 2*2 %>us"
}

function scan_ssti(param_name,payload)
    local new_url = HttpMessage:setParam(param_name,payload)
    local resp_status,resp = pcall(function ()
        return http:send("GET",new_url) -- Sending a http request to the new url with GET Method
    end)
        if resp_status == true then
            local out = {}
            local body = resp.body -- Get the response body as string
            out["body"] = body
            out["url"] = resp.url
            out["param_name"] = param_name
            out["payload"] = payload
            return out
        end
end

function ssti_callback(data)
    if data == nil then
        return -- avoid nil cases
    end
    url = data["url"]
    body = data["body"]
    payload = data["payload"]
    param_name = data["param_name"]
    local match_status, match = pcall(function () 
        -- Matching with the response and the targeted regex
        -- we're using pcall here to avoid regex errors (and panic the code)
        return str_contains(body, "lot4us")
    end)
    if match_status == true then
        if match == true then
            send_report(url,param_name,payload,"lot4us")
            Reports:addVulnReport(VulnReport)
        end
    end
end

function main()
    for _,param in ipairs(HttpMessage:Params()) do
        ParamScan:start_scan()
        ParamScan:add_scan(param,SSTI_PAYLOADS, scan_ssti,ssti_callback, FUZZ_WORKERS)
    end
end

Basically, we are doing a for loop on all url parameters in the code above and then creating a scanning thread with the target parameter, the SSTI_PAYLOAD List, scan_ssti as the target function and ssti_callback as the callback function, and FUZZ_WORKERS is a lua variable that gets its value from the --fuzz-workers parameter (you can replace it with real number of you want)

As part of the ssti_scan function, we change the parameter value to the SSTI payload, and then send an HTTP request to it, and return a list with the following components: body, url, payload, parameter name.

ParamScan will then take the output of this function and pass it to the function callback (ssti_callback).

in the call callback function first lines it checks if the function parameter value is nil (Null) or not because doing any match

You may set this option to prevent ParamScan from sending Nil to the call_back functions

ParamScan:accept_nil(false) -- Dont pass any nil values
ParamScan:is_accept_nil() -- check if ParamScan is passing nil values or not

If you are scanning parameters, you do not need to call any of these functions since the default option is not to pass any null values to them

From anywhere in your script, you may call the ParamScan:stop_scan() function to stop the scanner and clear all futures

You can disable this option by using the ParamScan:start_scan() function

and if you want to check first if ParamScan is stopped or not you can use ParamScan:is_stop()

LuaThreader

this a simple class to do multi-threading, it only takes iterator and function to run

SCAN_TYPE = 2

PAYLOADS = {
    "hello",
    'world'
}
function SCANNER(data)
    -- DO YOUR SCANNING LOGIC
end

function main()
    LuaThreader:run_scan(PAYLOADS,SCANNER,10) -- 10 = Number of workers
    -- LuaThreader:stop_scan() = stop the scan and dont accept any new futures
    -- LuaThreader:is_stop() = Check if LuaThreader is stopped or not
end

The LuaThreader class will open two threads in this example, one for the hello word and one for the world word

It is really as simple as that

Last updated