diff --git a/.gitignore b/.gitignore index 21c659353..9f4ba0ac1 100644 --- a/.gitignore +++ b/.gitignore @@ -195,3 +195,4 @@ plugins/goedge-happy /plugins/tools /plugins/choose-linux-python *.md5 +/bak diff --git a/obf/bak/obf_v1.lua b/obf/bak/obf_v1.lua deleted file mode 100644 index d9a0d3c21..000000000 --- a/obf/bak/obf_v1.lua +++ /dev/null @@ -1,139 +0,0 @@ --- Copyright (C) midoks - -local _M = { _VERSION = '1.0' } -local mt = { __index = _M } -local setmetatable = setmetatable - -local obf_log = require "resty.obf.log" -local tpl = require "resty.obf.tpl" -local log_fmt = obf_log.fmt -local aes = require "resty.aes" -local ffi = require "ffi" -local ffi_str = ffi.string -local sha256 = require "resty.sha256" -local resty_str = require "resty.string" -local random = require "resty.random" - -local find = string.find -local byte = string.byte -local log = ngx.log - - - - - -function _M.new(self) - local self = { - } - return setmetatable(self, mt) -end - - -function _M.to_uint8array(content) - if not content then - content = "" - end - local arr = {} - for i = 1, #content do - arr[#arr + 1] = tostring(byte(content, i)) - end - return "new Uint8Array([" .. table.concat(arr, ",") .. "])" -end - --- 响应处理函数 -function _M.process_response() - local ctx = ngx.ctx - local chunk, eof = ngx.arg[1], ngx.arg[2] - - if not ctx.obf_buffer then - ctx.obf_buffer = {} - end - - if chunk and chunk ~= "" then - ctx.obf_buffer[#ctx.obf_buffer + 1] = chunk - ngx.arg[1] = nil - end - - if eof then - local content = table.concat(ctx.obf_buffer) - local enc, tag, iv_bin - local content_type = ngx.header.content_type or "" - local upstream_ct = ngx.var.upstream_http_content_type or "" - local cl = ngx.header["Content-Length"] or "" - local upstream_cl = ngx.var.upstream_http_content_length or "" - - -- log(ngx.ERR, log_fmt("proxy content-type: %s, upstream_content_type: %s", tostring(content_type), tostring(upstream_ct))) - -- log(ngx.ERR, log_fmt("content-length: %s, upstream_content_length: %s", tostring(cl), tostring(upstream_cl))) - -- log(ngx.ERR, log_fmt("body len=%s", tostring(#content))) - - -- log(ngx.ERR, log_fmt("body: %s", content)) - - local password = random.bytes(8, true) - log(ngx.ERR, log_fmt("enc=aes-256-gcm, pass_b64=%s", ngx.encode_base64(password))) - local cipher = aes.cipher(256, "gcm") - local a, aerr = aes:new(password, nil, cipher, aes.hash.md5, 1, 12, true) - if not a then - log(ngx.ERR, log_fmt("aes init error: %s", tostring(aerr))) - else - local key_bin = ffi_str(a._key, 32) - iv_bin = ffi_str(a._iv, 12) - local sh1 = sha256:new(); sh1:update(key_bin); local key_fpr = resty_str.to_hex(sh1:final()) - local sh2 = sha256:new(); sh2:update(iv_bin); local iv_fpr = resty_str.to_hex(sh2:final()) - log(ngx.ERR, log_fmt("key_len=%d, key_sha256=%s", 32, key_fpr)) - log(ngx.ERR, log_fmt("iv_len=%d, iv_sha256=%s", 12, iv_fpr)) - local res, eerr = a:encrypt(content) - if not res then - log(ngx.ERR, log_fmt("aes encrypt error: %s", tostring(eerr))) - else - if type(res) == "table" then - enc = res[1] - tag = res[2] - else - enc = res - end - - content = enc .. (tag or "") - - local b64_ct = ngx.encode_base64(enc:sub(1, math.min(#enc, 128))) - local b64_tag = tag and ngx.encode_base64(tag) or "" - log(ngx.ERR, log_fmt("ciphertext len=%s, tag_len=%s, b64_ct_preview=%s, b64_tag=%s", tostring(#enc), tostring(tag and #tag or 0), b64_ct, b64_tag)) - end - end - - -- local preview = content - -- if #preview > 2048 then - -- preview = preview:sub(1, 2048) - -- end - -- log(ngx.ERR, log_fmt("body preview: %s", preview)) - - -- 根据内容类型进行混淆 - if find(content_type, "text/html") then - - -- content = obfuscate_html(content) - end - - local data = _M.to_uint8array(enc or content) - local iv_data = _M.to_uint8array(iv_bin or "") - local tag_data = _M.to_uint8array(tag or "") - local key_data = _M.to_uint8array(password or "") - -- content type will be set in header_filter phase - -- ngx.arg[1] = literal - - html_data = tpl.content(data, iv_data, tag_data, key_data) - - html_data = html_data:gsub("", function(attrs, body) - local b = body - b = b:gsub("^%s*//[^\n\r]*", "") - b = b:gsub("\n%s*//[^\n\r]*", "\n") - b = b:gsub("([^:])%s+//[^\n\r]*", "%1") - b = b:gsub("%s+", " ") - b = b:gsub("%s*([%(%),;:%{%}%[%]%+%-%*%/%=<>])%s*", "%1") - return "" - end) - - ngx.arg[1] = html_data:gsub("[\r\n]+", ""):gsub(">%s+<", "><") - ctx.obf_buffer = nil - end -end - -return _M diff --git a/obf/bak/obf_v2.lua b/obf/bak/obf_v2.lua deleted file mode 100644 index 2a85b08d4..000000000 --- a/obf/bak/obf_v2.lua +++ /dev/null @@ -1,292 +0,0 @@ --- Copyright (C) midoks - -local _M = { _VERSION = '1.0' } -local mt = { __index = _M } -local setmetatable = setmetatable - -local obf_log = require "resty.obf.log" -local tpl = require "resty.obf.tpl" -local log_fmt = obf_log.fmt -local aes = require "resty.aes" -local ffi = require "ffi" -local ffi_str = ffi.string -local sha256 = require "resty.sha256" -local resty_str = require "resty.string" -local random = require "resty.random" -local lrucache = require "resty.lrucache" -local obf_cache = lrucache.new(1024) - -local find = string.find -local byte = string.byte -local log = ngx.log - - -function _M.new(self) - local self = { - } - return setmetatable(self, mt) -end - - -function _M.to_uint8array(content) - if not content then - content = "" - end - local arr = {} - for i = 1, #content do - arr[#arr + 1] = tostring(byte(content, i)) - end - return "new Uint8Array([" .. table.concat(arr, ",") .. "])" -end - --- 数据过滤 -function _M.data_filter(content) - content = content:gsub("", function(attrs, body) - local b = body - b = b:gsub("^%s*//[^\n\r]*", "") - b = b:gsub("\n%s*//[^\n\r]*", "\n") - b = b:gsub("([^:])%s+//[^\n\r]*", "%1") - b = b:gsub("%s+", " ") - b = b:gsub("%s*([%(%),;:%{%}%[%]%+%-%*%=<>])%s*", "%1") - return "" - end) - - content = content:gsub("[\r\n]+", ""):gsub(">%s+<", "><") - return content -end - --- 随机变量名 -function _M.obf_rand(content) - local function rand_ident(len) - local head = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_" - local tail = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$" - local seed = random.bytes(16, true) .. (ngx.var.request_id or "") .. tostring(ngx.time()) .. tostring(ngx.now()) - local h = sha256:new(); h:update(seed); local digest = resty_str.to_hex(h:final()) - local r = {} - local hi = (string.byte(digest, 1) or 65) % #head + 1 - r[1] = string.sub(head, hi, hi) - local pos, di = 2, 2 - while pos <= len do - local c = string.byte(digest, di) or 97 - local ti = c % #tail + 1 - r[pos] = string.sub(tail, ti, ti) - pos = pos + 1 - di = di + 1 - if di > #digest then - h = sha256:new(); h:update(digest .. random.bytes(8, true)); digest = resty_str.to_hex(h:final()); di = 1 - end - end - return table.concat(r) - end - local ids = {"encrypted","iv_data","key","tag_data","d","u8ToBytes","evpBytesToKey","startTime","dk","decipher","ok","newDoc","endTime"} - local map = {} - for _, id in ipairs(ids) do - map[id] = rand_ident(8) - end - for k, v in pairs(map) do - local pat = "%f[%w_]" .. k .. "%f[^%w_]" - content = content:gsub(pat, v) - end - return content -end - --- 添加混淆代码 -function _M.obf_add_data(content) - content = content:gsub("", function(attrs, body) - local b = body - local function rand_ident(len) - local head = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_" - local tail = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$" - local seed = random.bytes(16, true) .. (ngx.var.request_id or "") .. tostring(ngx.time()) .. tostring(ngx.now()) - local h = sha256:new(); h:update(seed); local digest = resty_str.to_hex(h:final()) - local r = {} - local hi = (string.byte(digest, 1) or 65) % #head + 1 - r[1] = string.sub(head, hi, hi) - local pos, di = 2, 2 - while pos <= len do - local c = string.byte(digest, di) or 97 - local ti = c % #tail + 1 - r[pos] = string.sub(tail, ti, ti) - pos = pos + 1 - di = di + 1 - if di > #digest then - h = sha256:new(); h:update(digest .. random.bytes(8, true)); digest = resty_str.to_hex(h:final()); di = 1 - end - end - return table.concat(r) - end - local v1 = rand_ident(8) - local v2 = rand_ident(8) - local v3 = rand_ident(8) - local f1 = rand_ident(8) - local f2 = rand_ident(8) - local tmp = rand_ident(8) - local filler = "var "..v1.."=\""..ngx.encode_base64(random.bytes(8, true)).."\";" - .."var "..v2.."=".._M.to_uint8array(random.bytes(8, true))..";" - .."var "..v3.."="..tostring(#ngx.encode_base64(random.bytes(6, true)))..";" - .."function "..f1.."(x){return x}" - .."function "..f2.."(){return "..v3.."}" - .."(function(){var "..tmp.."="..v3.."; for(var i=0;i<1;i++){"..tmp.."="..tmp.."+i}})();" - b = filler..";"..b - b = b:gsub("%s+", " ") - b = b:gsub("%s*([%(%),;:%{%}%[%]%+%-%*%=<>])%s*", "%1") - return "" - end) - content = content:gsub("[\r\n]+", ""):gsub(">%s+<", "><") - return content -end - - --- 编码 -function _M.obf_encode(content) - local enc, tag, iv_bin - local content_type = ngx.header.content_type or "" - local upstream_ct = ngx.var.upstream_http_content_type or "" - local cl = ngx.header["Content-Length"] or "" - local upstream_cl = ngx.var.upstream_http_content_length or "" - - local key = random.bytes(8, true) - -- log(ngx.ERR, log_fmt("enc=aes-256-gcm, pass_b64=%s", ngx.encode_base64(password))) - local cipher = aes.cipher(256, "gcm") - local a, aerr = aes:new(key, nil, cipher, aes.hash.md5, 1, 12, true) - - if not a then - log(ngx.ERR, log_fmt("aes init error: %s", tostring(aerr))) - else - local key_bin = ffi_str(a._key, 32) - iv_bin = ffi_str(a._iv, 12) - local sh1 = sha256:new(); sh1:update(key_bin); local key_fpr = resty_str.to_hex(sh1:final()) - local sh2 = sha256:new(); sh2:update(iv_bin); local iv_fpr = resty_str.to_hex(sh2:final()) - local res, eerr = a:encrypt(content) - if not res then - log(ngx.ERR, log_fmt("aes encrypt error: %s", tostring(eerr))) - else - if type(res) == "table" then - enc = res[1] - tag = res[2] - else - enc = res - end - content = enc .. (tag or "") - end - end - - return enc or content, key, iv_bin, tag -end - -function _M.get_cache_key() - local args = ngx.req.get_uri_args() - local parts = {} - for k, v in pairs(args or {}) do - if k ~= "obf" then - local val = v - if type(val) == "table" then val = val[1] end - parts[#parts + 1] = tostring(k) .. "=" .. tostring(val) - end - end - table.sort(parts) - local q = table.concat(parts, "&") - local cache_key = (ngx.var.scheme or "") .. "://" .. (ngx.var.host or "") .. (ngx.var.uri or "") .. (q ~= "" and ("?" .. q) or "") - return cache_key -end - --- HTML标签混淆 -function _M.obf_html() - local content_type = ngx.header.content_type or "" - local ctx = ngx.ctx - local chunk, eof = ngx.arg[1], ngx.arg[2] - local html_debug = "false" - local cache_timeout = 300 - - local args = ngx.req.get_uri_args() - obf = args and args.obf or nil - if obf == "debug" then - html_debug = "true" - end - - local var_debug = ngx.var.close_debug - if var_debug == "true" then - html_debug = "false" - end - - local var_obf_timeout = ngx.var.obf_timeout - - if var_obf_timeout then - cache_timeout = var_obf_timeout - end - -- log(ngx.ERR, log_fmt("var_obf_timeout: %s", tostring(var_obf_timeout))) - - - if not ctx.obf_buffer then - ctx.obf_buffer = {} - end - - if chunk and chunk ~= "" then - ctx.obf_buffer[#ctx.obf_buffer + 1] = chunk - ngx.arg[1] = nil - end - - if eof then - local content = table.concat(ctx.obf_buffer) - - if find(content_type, "text/html") then - - local cache_key = _M.get_cache_key()..html_debug - local cached = obf_cache and obf_cache:get(cache_key) - if cached then - ngx.arg[1] = cached - ctx.obf_buffer = nil - return - end - - -- local t0 = ngx.now() - local content,key,iv,tag = _M.obf_encode(content) - -- local t1 = ngx.now() - - local content_data = _M.to_uint8array(content or "") - local iv_data = _M.to_uint8array(iv or "") - local tag_data = _M.to_uint8array(tag or "") - local key_data = _M.to_uint8array(key or "") - - local html_data = tpl.content(content_data, iv_data, tag_data, key_data,html_debug) - - html_data = _M.obf_rand(html_data) - html_data = _M.obf_add_data(html_data) - if obf_cache then - obf_cache:set(cache_key, html_data, cache_timeout) - end - ngx.arg[1] = html_data - end - - ctx.obf_buffer = nil - end -end - - -function _M.done() - local content_type = ngx.header.content_type or "" - if find(content_type, "text/html") then - _M.obf_html() - end -end --- 响应处理函数 -function _M.process_response() - - local var_close = ngx.var.close_close - -- log(ngx.ERR, log_fmt("var_close: %s", tostring(var_close))) - if var_close == "true" then - _M.done() - return - else - local args = ngx.req.get_uri_args() - local obf = args and args.obf or nil - if obf == "close" then - return - end - end - - _M.done() - -end - -return _M diff --git a/obf/bak/obf_v3.lua b/obf/bak/obf_v3.lua deleted file mode 100644 index 056c98143..000000000 --- a/obf/bak/obf_v3.lua +++ /dev/null @@ -1,199 +0,0 @@ --- Copyright (C) midoks - -local _M = { _VERSION = '1.0' } -local mt = { __index = _M } -local setmetatable = setmetatable - -local obf_log = require "resty.obf.log" -local tpl = require "resty.obf.tpl" -local log_fmt = obf_log.fmt -local aes = require "resty.aes" -local ffi = require "ffi" -local ffi_str = ffi.string -local sha256 = require "resty.sha256" -local resty_str = require "resty.string" -local random = require "resty.random" -local lrucache = require "resty.lrucache" -local util = require "resty.obf.util" -local obf_cache = lrucache.new(4096) - -local find = string.find -local byte = string.byte -local log = ngx.log - - -function _M.new(self) - local self = { - } - return setmetatable(self, mt) -end - --- 编码 -function _M.obf_encode(content) - local enc, tag, iv_bin - local content_type = ngx.header.content_type or "" - local upstream_ct = ngx.var.upstream_http_content_type or "" - local cl = ngx.header["Content-Length"] or "" - local upstream_cl = ngx.var.upstream_http_content_length or "" - - local key = random.bytes(8, true) - -- log(ngx.ERR, log_fmt("enc=aes-256-gcm, pass_b64=%s", ngx.encode_base64(password))) - local cipher = aes.cipher(256, "gcm") - local a, aerr = aes:new(key, nil, cipher, aes.hash.md5, 1, 12, true) - - if not a then - log(ngx.ERR, log_fmt("aes init error: %s", tostring(aerr))) - else - local key_bin = ffi_str(a._key, 32) - iv_bin = ffi_str(a._iv, 12) - local res, eerr = a:encrypt(content) - if not res then - log(ngx.ERR, log_fmt("aes encrypt error: %s", tostring(eerr))) - else - if type(res) == "table" then - enc = res[1] - tag = res[2] - else - enc = res - end - content = enc .. (tag or "") - end - end - - return enc or content, key, iv_bin, tag -end - -function _M.get_cache_key() - local args = ngx.req.get_uri_args() - local parts = {} - for k, v in pairs(args or {}) do - if k ~= "obf" then - local val = v - if type(val) == "table" then val = val[1] end - parts[#parts + 1] = tostring(k) .. "=" .. tostring(val) - end - end - table.sort(parts) - local q = table.concat(parts, "&") - local cache_key = (ngx.var.scheme or "") .. "://" .. (ngx.var.host or "") .. (ngx.var.uri or "") .. (q ~= "" and ("?" .. q) or "") - return cache_key -end - --- HTML标签混淆 -function _M.obf_html() - local content_type = ngx.header.content_type or "" - local ctx = ngx.ctx - local chunk, eof = ngx.arg[1], ngx.arg[2] - local html_debug = "false" - local cache_timeout = 600 - - local args = ngx.req.get_uri_args() - obf = args and args.obf or nil - if obf == "debug" then - html_debug = "true" - end - - local var_debug = ngx.var.close_debug - if var_debug == "true" then - html_debug = "false" - end - - local var_obf_timeout = ngx.var.obf_timeout - if var_obf_timeout then - cache_timeout = var_obf_timeout - end - -- log(ngx.ERR, log_fmt("var_obf_timeout: %s", tostring(var_obf_timeout))) - - if not ctx.obf_buffer then - ctx.obf_buffer = {} - end - - if chunk and chunk ~= "" then - ctx.obf_buffer[#ctx.obf_buffer + 1] = chunk - ngx.arg[1] = nil - end - - if eof then - local content = table.concat(ctx.obf_buffer) - - if find(content_type, "text/html") then - - local var_rand = ngx.var.obf_rand - local var_b64 = ngx.var.obf_uint8_b64 - local var_skip_large = ngx.var.obf_skip_large or "" - local var_skip_small = ngx.var.obf_skip_small or "" - local cache_key = _M.get_cache_key()..html_debug..tostring(var_rand)..tostring(var_b64)..tostring(var_skip_large)..tostring(var_skip_small) - local cached = obf_cache and obf_cache:get(cache_key) - if cached then - ngx.arg[1] = cached - ctx.obf_buffer = nil - return - end - - local var_skip = ngx.var.obf_skip_large - if var_skip then - local n = tonumber(var_skip) or 0 - if n > 0 and #content > n then - ngx.arg[1] = content - ctx.obf_buffer = nil - return - end - end - local var_skip_s = ngx.var.obf_skip_small - if var_skip_s then - local ns = tonumber(var_skip_s) or 0 - if ns > 0 and #content < ns then - ngx.arg[1] = content - ctx.obf_buffer = nil - return - end - end - - local content,key,iv,tag = _M.obf_encode(content) - - local content_data = util.to_uint8array(content or "") - local iv_data = util.to_uint8array(iv or "") - local tag_data = util.to_uint8array(tag or "") - local key_data = util.to_uint8array(key or "") - - local html_data = tpl.content(content_data, iv_data, tag_data, key_data,html_debug) - html_data = util.obf_add_data(html_data) - - if obf_cache then - obf_cache:set(cache_key, html_data, cache_timeout) - end - ngx.arg[1] = html_data - end - - ctx.obf_buffer = nil - end -end - - -function _M.done() - local content_type = ngx.header.content_type or "" - if find(content_type, "text/html") then - _M.obf_html() - end -end --- 响应处理函数 -function _M.process_response() - local content_type = ngx.header.content_type or "" - local var_close = ngx.var.close_close - -- log(ngx.ERR, log_fmt("var_close: %s", tostring(var_close))) - if var_close == "true" then - _M.done() - return - else - local args = ngx.req.get_uri_args() - local obf = args and args.obf or nil - if obf == "close" then - return - end - end - - _M.done() - -end - -return _M diff --git a/obf/bak/obf_v4.lua b/obf/bak/obf_v4.lua deleted file mode 100644 index 6ed00228b..000000000 --- a/obf/bak/obf_v4.lua +++ /dev/null @@ -1,243 +0,0 @@ --- Copyright (C) midoks - -local _M = { _VERSION = '1.0' } -local mt = { __index = _M } -local setmetatable = setmetatable - -local obf_log = require "resty.obf.log" -local tpl = require "resty.obf.tpl" -local log_fmt = obf_log.fmt -local aes = require "resty.aes" -local ffi = require "ffi" -local ffi_str = ffi.string -local sha256 = require "resty.sha256" -local resty_str = require "resty.string" -local random = require "resty.random" -local lrucache = require "resty.lrucache" -local util = require "resty.obf.util" -local obf_cache = nil - -local find = string.find -local byte = string.byte -local log = ngx.log - - -function _M.new(self) - local self = { - } - return setmetatable(self, mt) -end - --- 编码 -function _M.obf_encode(content) - local enc, tag, iv_bin - local content_type = ngx.header.content_type or "" - local upstream_ct = ngx.var.upstream_http_content_type or "" - local cl = ngx.header["Content-Length"] or "" - local upstream_cl = ngx.var.upstream_http_content_length or "" - - local key = random.bytes(8, true) - -- log(ngx.ERR, log_fmt("enc=aes-256-gcm, pass_b64=%s", ngx.encode_base64(password))) - local cipher = aes.cipher(256, "gcm") - local a, aerr = aes:new(key, nil, cipher, aes.hash.md5, 1, 12, true) - - if not a then - log(ngx.ERR, log_fmt("aes init error: %s", tostring(aerr))) - else - local key_bin = ffi_str(a._key, 32) - iv_bin = ffi_str(a._iv, 12) - local res, eerr = a:encrypt(content) - if not res then - log(ngx.ERR, log_fmt("aes encrypt error: %s", tostring(eerr))) - else - if type(res) == "table" then - enc = res[1] - tag = res[2] - else - enc = res - end - content = enc .. (tag or "") - end - end - - return enc or content, key, iv_bin, tag -end - -function _M.get_cache_key() - local args = ngx.req.get_uri_args() - local parts = {} - for k, v in pairs(args or {}) do - if k ~= "obf" then - local val = v - if type(val) == "table" then val = val[1] end - parts[#parts + 1] = tostring(k) .. "=" .. tostring(val) - end - end - table.sort(parts) - local q = table.concat(parts, "&") - local cache_key = (ngx.var.scheme or "") .. "://" .. (ngx.var.host or "") .. (ngx.var.uri or "") .. (q ~= "" and ("?" .. q) or "") - return cache_key -end - --- HTML标签混淆 -function _M.obf_html() - local content_type = ngx.header.content_type or "" - local ctx = ngx.ctx - local chunk, eof = ngx.arg[1], ngx.arg[2] - local html_debug = "false" - local cache_timeout = 600 - - local args = ngx.req.get_uri_args() - obf = args and args.obf or nil - if obf == "debug" then - html_debug = "true" - end - - local var_debug = ngx.var.close_debug - if var_debug == "true" then - html_debug = "false" - end - - local var_obf_timeout = ngx.var.obf_timeout - if var_obf_timeout then - cache_timeout = var_obf_timeout - end - -- log(ngx.ERR, log_fmt("var_obf_timeout: %s", tostring(var_obf_timeout))) - - if not ctx.obf_buffer then - ctx.obf_buffer = {} - ctx.obf_size = 0 - ctx.obf_passthrough = false - end - - if chunk and chunk ~= "" then - if ctx.obf_passthrough then - ngx.arg[1] = chunk - else - ctx.obf_buffer[#ctx.obf_buffer + 1] = chunk - ctx.obf_size = ctx.obf_size + #chunk - local sl = ngx.var.obf_skip_large - if sl then - local n = tonumber(sl) or 0 - if n > 0 and ctx.obf_size > n then - ctx.obf_passthrough = true - ngx.arg[1] = table.concat(ctx.obf_buffer) - ctx.obf_buffer = nil - return - end - end - ngx.arg[1] = nil - end - end - - if eof then - if ctx.obf_passthrough then - return - end - local prof = ngx.var.obf_prof - local t_all0 = ngx.now() - local content = table.concat(ctx.obf_buffer) - - if find(content_type, "text/html", 1, true) then - - if not obf_cache then - local entries = tonumber(ngx.var.obf_cache_entries) or 1024 - obf_cache = lrucache.new(entries) - end - local var_rand = ngx.var.obf_rand - local var_b64 = ngx.var.obf_uint8_b64 - local var_skip_large = ngx.var.obf_skip_large or "" - local var_skip_small = ngx.var.obf_skip_small or "" - local cache_key = _M.get_cache_key()..html_debug..tostring(var_rand)..tostring(var_b64)..tostring(var_skip_large)..tostring(var_skip_small) - local cached = obf_cache and obf_cache:get(cache_key) - if cached then - if prof == "true" then - log(ngx.ERR, log_fmt("obf_prof cache_hit=1 size=%d total_ms=%.2f", #cached, (ngx.now()-t_all0)*1000)) - end - ngx.arg[1] = cached - ctx.obf_buffer = nil - return - end - - local var_skip = ngx.var.obf_skip_large - if var_skip then - local n = tonumber(var_skip) or 0 - if n > 0 and #content > n then - if prof == "true" then - log(ngx.ERR, log_fmt("obf_prof skip_large=1 size=%d total_ms=%.2f", #content, (ngx.now()-t_all0)*1000)) - end - ngx.arg[1] = content - ctx.obf_buffer = nil - return - end - end - - local t_enc0 = ngx.now() - local content,key,iv,tag = _M.obf_encode(content) - local t_enc1 = ngx.now() - - local t_ser0 = ngx.now() - local content_data = util.to_uint8array(content or "") - local iv_data = util.to_uint8array(iv or "") - local tag_data = util.to_uint8array(tag or "") - local key_data = util.to_uint8array(key or "") - local t_ser1 = ngx.now() - - local t_tpl0 = ngx.now() - local html_data = tpl.content(content_data, iv_data, tag_data, key_data,html_debug) - local t_tpl1 = ngx.now() - if not (ngx.var.obf_rand == "false") then - local t_add0 = ngx.now() - html_data = util.obf_add_data(html_data) - local t_add1 = ngx.now() - if prof == "true" then - log(ngx.ERR, log_fmt("obf_prof add_ms=%.2f", (t_add1-t_add0)*1000)) - end - end - - local max_item = tonumber(ngx.var.obf_cache_item_max) or 0 - if obf_cache then - if max_item <= 0 or #html_data <= max_item then - obf_cache:set(cache_key, html_data, cache_timeout) - end - end - if prof == "true" then - log(ngx.ERR, log_fmt("obf_prof size=%d enc_ms=%.2f ser_ms=%.2f tpl_ms=%.2f total_ms=%.2f", #content, (t_enc1-t_enc0)*1000, (t_ser1-t_ser0)*1000, (t_tpl1-t_tpl0)*1000, (ngx.now()-t_all0)*1000)) - end - ngx.arg[1] = html_data - end - - ctx.obf_buffer = nil - ctx.obf_size = nil - ctx.obf_passthrough = nil - end -end - - -function _M.done() - local content_type = ngx.header.content_type or "" - if find(content_type, "text/html") then - _M.obf_html() - end -end --- 响应处理函数 -function _M.process_response() - local content_type = ngx.header.content_type or "" - local var_close = ngx.var.close_close - -- log(ngx.ERR, log_fmt("var_close: %s", tostring(var_close))) - if var_close == "true" then - _M.done() - return - else - local args = ngx.req.get_uri_args() - local obf = args and args.obf or nil - if obf == "close" then - return - end - end - - _M.done() - -end - -return _M diff --git a/obf/bak/obf_v5.lua b/obf/bak/obf_v5.lua deleted file mode 100644 index 7a1bba295..000000000 --- a/obf/bak/obf_v5.lua +++ /dev/null @@ -1,232 +0,0 @@ --- Copyright (C) midoks - -local _M = { _VERSION = '1.0' } -local mt = { __index = _M } -local setmetatable = setmetatable - -local obf_log = require "resty.obf.log" -local tpl = require "resty.obf.tpl" -local log_fmt = obf_log.fmt -local aes = require "resty.aes" -local ffi = require "ffi" -local ffi_str = ffi.string -local random = require "resty.random" -local util = require "resty.obf.util" -local obf_cache = ngx.shared.obf_cache -local obf_cache_bytes = 0 - -local find = string.find -local log = ngx.log - - -function _M.new(self) - local self = { - } - return setmetatable(self, mt) -end - --- 编码 -function _M.obf_encode(content) - local enc, tag, iv_bin - local content_type = ngx.header.content_type or "" - local upstream_ct = ngx.var.upstream_http_content_type or "" - local cl = ngx.header["Content-Length"] or "" - local upstream_cl = ngx.var.upstream_http_content_length or "" - - local key = random.bytes(8, true) - -- log(ngx.ERR, log_fmt("enc=aes-256-gcm, pass_b64=%s", ngx.encode_base64(password))) - local cipher = aes.cipher(256, "gcm") - local a, aerr = aes:new(key, nil, cipher, aes.hash.md5, 1, 12, true) - - if not a then - log(ngx.ERR, log_fmt("aes init error: %s", tostring(aerr))) - else - iv_bin = ffi_str(a._iv, 12) - local res, eerr = a:encrypt(content) - if not res then - log(ngx.ERR, log_fmt("aes encrypt error: %s", tostring(eerr))) - else - if type(res) == "table" then - enc = res[1] - tag = res[2] - else - enc = res - end - content = enc .. (tag or "") - end - end - - return enc or content, key, iv_bin, tag -end - -function _M.get_cache_key() - local args = ngx.req.get_uri_args() - local parts = {} - for k, v in pairs(args or {}) do - if k ~= "obf" then - local val = v - if type(val) == "table" then val = val[1] end - parts[#parts + 1] = tostring(k) .. "=" .. tostring(val) - end - end - table.sort(parts) - local q = table.concat(parts, "&") - local cache_key = (ngx.var.scheme or "") .. "://" .. (ngx.var.host or "") .. (ngx.var.uri or "") .. (q ~= "" and ("?" .. q) or "") - return cache_key -end - --- HTML标签混淆 -function _M.obf_html() - local content_type = ngx.header.content_type or "" - local ctx = ngx.ctx - - local html_debug = "false" - local cache_timeout = 600 - - local args = ngx.req.get_uri_args() - obf = args and args.obf or nil - if obf == "debug" then - html_debug = "true" - end - - local close_debug = ngx.var.close_debug - if close_debug == "true" then - html_debug = "false" - end - - local var_obf_timeout = ngx.var.obf_timeout - if var_obf_timeout then - cache_timeout = var_obf_timeout - end - -- log(ngx.ERR, log_fmt("var_obf_timeout: %s", tostring(var_obf_timeout))) - - if not ctx.obf_buffer then - ctx.obf_buffer = {} - ctx.obf_passthrough = false - end - - local chunk, eof = ngx.arg[1], ngx.arg[2] - if chunk and chunk ~= "" then - if not ctx.obf_first_t then - ctx.obf_first_t = util.tmark() - end - if ctx.obf_passthrough then - ngx.arg[1] = chunk - else - ctx.obf_buffer[#ctx.obf_buffer + 1] = chunk - ngx.arg[1] = nil - end - end - - - if eof then - if ctx.obf_passthrough then - return - end - local prof = ngx.var.obf_prof - local t_all0 = util.tmark() - local content = table.concat(ctx.obf_buffer) - local obf_cache = ngx.shared.obf_cache - - if find(content_type, "text/html", 1, true) then - - local var_rand_var = ngx.var.obf_rand_var - local var_rand_extra = ngx.var.obf_rand_extra - local var_b64 = ngx.var.obf_uint8_b64 - local js_mode = ngx.var.obf_js_mode - local js_url = ngx.var.obf_js_url - local cache_key = _M.get_cache_key()..tostring(html_debug)..tostring(var_rand_var)..tostring(var_rand_extra)..tostring(var_b64)..tostring(js_mode)..tostring(js_url) - local cached = obf_cache and obf_cache:get(cache_key) - if cached then - if prof == "true" then - log(ngx.ERR, log_fmt("obf_prof cache_hit=1 size=%d total_ms=%.2f wait_ms=%.2f", #cached, util.dt_ms(t_all0), ctx.obf_first_t and util.dt_ms(ctx.obf_first_t) or 0)) - end - ngx.arg[1] = cached - ctx.obf_buffer = nil - return - else - if prof == "true" then - log(ngx.ERR, log_fmt("obf_prof cache_miss=1")) - end - end - - - - local t_enc0 = util.tmark() - local content,key,iv,tag = _M.obf_encode(content) - local enc_ms = util.dt_ms(t_enc0) - - local t_ser0 = util.tmark() - local content_data = util.to_uint8array(content or "") - local iv_data = util.to_uint8array(iv or "") - local tag_data = util.to_uint8array(tag or "") - local key_data = util.to_uint8array(key or "") - local ser_ms = util.dt_ms(t_ser0) - - local t_tpl0 = util.tmark() - local html_data = tpl.content(content_data, iv_data, tag_data, key_data,tostring(html_debug)) - local tpl_ms = util.dt_ms(t_tpl0) - - local max_item = tonumber(ngx.var.obf_cache_item_max) or 0 - local max_bytes = tonumber(ngx.var.obf_cache_max_bytes) or 0 - local exptime = tonumber(cache_timeout) or 600 - if obf_cache then - if max_item <= 0 or #html_data <= max_item then - if max_bytes > 0 then - local free = obf_cache:free_space() - if not free or free >= #html_data then - obf_cache:set(cache_key, html_data, exptime) - end - else - obf_cache:set(cache_key, html_data, exptime) - end - end - end - - if prof == "true" then - log(ngx.ERR, log_fmt("obf_prof size=%d enc_ms=%.2f ser_ms=%.2f tpl_ms=%.2f total_ms=%.2f wait_ms=%.2f", #content, enc_ms, ser_ms, tpl_ms, util.dt_ms(t_all0), ctx.obf_first_t and util.dt_ms(ctx.obf_first_t) or 0)) - end - ngx.arg[1] = html_data - end - - ctx.obf_buffer = nil - ctx.obf_passthrough = nil - end -end - - -function _M.done() - local content_type = ngx.header.content_type or "" - if find(content_type, "text/html") then - local prof = ngx.var.obf_prof - local t_start = util.tmark() - _M.obf_html() - if prof == "true" then - log(ngx.ERR, log_fmt("total_ms=%.2f", util.dt_ms(t_start))) - end - else - if ngx.var.obf_prof == "true" then - log(ngx.ERR, log_fmt("obf_prof skip_ct=1 ct=%s", tostring(content_type))) - end - end -end --- 响应处理函数 -function _M.process_response() - local content_type = ngx.header.content_type or "" - local var_close = ngx.var.close_close - if var_close == "true" then - _M.done() - return - else - local args = ngx.req.get_uri_args() - local obf = args and args.obf or nil - if obf == "close" then - return - end - end - - _M.done() - -end - -return _M diff --git a/obf/bak/tpl_v2.lua b/obf/bak/tpl_v2.lua deleted file mode 100644 index 2bc0d7d1e..000000000 --- a/obf/bak/tpl_v2.lua +++ /dev/null @@ -1,83 +0,0 @@ --- Copyright (C) midoks - -local _M = { _VERSION = '1.0' } -local mt = { __index = _M } -local setmetatable = setmetatable - -local forgejs = require "resty.obf.forgejs" - -function _M.new(self) - local self = { - } - return setmetatable(self, mt) -end - -function _M.content(data, iv, tag, key, debug_data) - local cc = [[ - - -
- - - - - - - - -]] - - local fj_content = forgejs.content() - cc = cc:gsub("{{FORGEJS}}", function() return fj_content end) - cc = cc:gsub("{{SOURCE_DATA}}", function() return data end) - cc = cc:gsub("{{IV_DATA}}", function() return iv end) - cc = cc:gsub("{{TAG_DATA}}", function() return tag end) - cc = cc:gsub("{{KEY_DATA}}", function() return key end) - cc = cc:gsub("{{DEBUG_DATA}}", function() return debug_data end) - - return cc -end - - - -return _M diff --git a/obf/bak/tpl_v3.lua b/obf/bak/tpl_v3.lua deleted file mode 100644 index 3ec05bf6e..000000000 --- a/obf/bak/tpl_v3.lua +++ /dev/null @@ -1,86 +0,0 @@ --- Copyright (C) midoks - -local _M = { _VERSION = '1.0' } -local mt = { __index = _M } -local setmetatable = setmetatable - -local forgejs = require "resty.obf.forgejs" -local util = require "resty.obf.util" -local FJ = forgejs.content() - -function _M.new(self) - local self = { - } - return setmetatable(self, mt) -end - -function _M.content(data, iv, tag, key, debug_data) - local cc = [[ - - - - - - - - - - - -]] - -- 先随机变量名 - cc = util.obf_rand(cc) - - cc = cc:gsub("{{FORGEJS}}", function() return FJ end) - cc = cc:gsub("{{SOURCE_DATA}}", function() return data end) - cc = cc:gsub("{{IV_DATA}}", function() return iv end) - cc = cc:gsub("{{TAG_DATA}}", function() return tag end) - cc = cc:gsub("{{KEY_DATA}}", function() return key end) - cc = cc:gsub("{{DEBUG_DATA}}", function() return debug_data end) - - return cc -end - - - -return _M diff --git a/obf/bak/tpl_v4.lua b/obf/bak/tpl_v4.lua deleted file mode 100644 index 05917e337..000000000 --- a/obf/bak/tpl_v4.lua +++ /dev/null @@ -1,76 +0,0 @@ --- Copyright (C) midoks - -local _M = { _VERSION = '1.0' } -local mt = { __index = _M } -local setmetatable = setmetatable - -local forgejs = require "resty.obf.forgejs" -local util = require "resty.obf.util" -local FJ = forgejs.content() - -function _M.new(self) - local self = { - } - return setmetatable(self, mt) -end - -function _M.content(data, iv, tag, key, debug_data) - local head_html = "\n\n \n \n \n \n \n\n" - local fj_open = "\n" - - local decode_script = "var encrypted="..data.."; var iv_data="..iv.."; var tag_data="..tag.."; var key="..key..";var d="..debug_data..";\n".. - "function u8ToBytes(u8){var s=\"\";for(var i=0;i=0;){var S=r.data[--v]==f?this.DM:Math.floor(r.data[v]*y+(r.data[v-1]+m)*g);if((r.data[v]+=o.am(0,S,r,C,0,p)) 4){var r=e;e=a.util.createBuffer();for(var n=0;n0&&r.rShiftTo(l,r),c<0&&i.ZERO.subTo(r,r)}}},i.prototype.invDigit=function(){if(this.t<1)return 0;var e=this.data[0];if(0==(1&e))return 0;var t=3&e;return(t=(t=(t=(t=t*(2-(15&e)*t)&15)*(2-(255&e)*t)&255)*(2-((65535&e)*t&65535))&65535)*(2-e*t%this.DV)%this.DV)>0?this.DV-t:-t},i.prototype.isEven=function(){return 0==(this.t>0?1&this.data[0]:this.s)},i.prototype.exp=function(e,t){if(e>4294967295||e<1)return i.ONE;var r=s(),a=s(),n=t.convert(this),o=d(e)-1;for(n.copyTo(r);--o>=0;)if(t.sqrTo(r,a),(e&1<0&&s.value.push(i.certificateExtensionsToAsn1(e.extensions)),s},i.getCertificationRequestInfo=function(e){return n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,n.integerToDer(e.version).getBytes()),y(e.subject),i.publicKeyToAsn1(e.publicKey),C(e)])},i.distinguishedNameToAsn1=function(e){return y(e)},i.certificateToAsn1=function(e){var t=e.tbsCertificate||i.getTBSCertificate(e);return n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[t,n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[n.create(n.Class.UNIVERSAL,n.Type.OID,!1,n.oidToDer(e.signatureOid).getBytes()),v(e.signatureOid,e.signatureParameters)]),n.create(n.Class.UNIVERSAL,n.Type.BITSTRING,!1,String.fromCharCode(0)+e.signature)])},i.certificateExtensionsToAsn1=function(e){var t=n.create(n.Class.CONTEXT_SPECIFIC,3,!0,[]),r=n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[]);t.value.push(r);for(var a=0;a