Add EndGame version 2.5

This commit is contained in:
Onion Limited 2021-07-17 15:54:48 +00:00
parent 4a766ef0ac
commit 4075b99603
No known key found for this signature in database
GPG Key ID: E4B6CAC49B242A44
13 changed files with 478 additions and 448 deletions

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/endgame.iml" filepath="$PROJECT_DIR$/.idea/endgame.iml" />
</modules>
</component>
</project>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -1,39 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="29df5c5c-3c59-4700-af86-2362f0062d00" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/site.conf" beforeDir="false" afterPath="$PROJECT_DIR$/site.conf" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="GOROOT" path="$USER_HOME$/.gvm/gos/go1.14" />
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="ProjectId" id="1l8K8ywGwL2SwuuTElCHEoZyLHy" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="go.import.settings.migrated" value="true" />
<property name="go.sdk.automatically.set" value="true" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/../docker-tor-hidden-service" />
<property name="settings.editor.selected.configurable" value="ide.date.format" />
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="WindowStateProjectService">
<state x="473" y="214" key="FileChooserDialogImpl" timestamp="1607015731915">
<screen x="0" y="0" width="1368" height="768" />
</state>
<state x="473" y="214" key="FileChooserDialogImpl/0.0.1368.768@0.0.1368.768" timestamp="1607015731915" />
<state x="380" y="251" width="616" height="512" key="find.popup" timestamp="1606975273843">
<screen x="0" y="0" width="1368" height="768" />
</state>
<state x="380" y="251" width="616" height="512" key="find.popup/0.0.1368.768@0.0.1368.768" timestamp="1606975273843" />
</component>
</project>

View File

@ -19,6 +19,14 @@ Save the params.py file and go back to the main onionbalance directory. Run
python3 setup.py install python3 setup.py install
and then you can setup the configuration and then you can setup the configuration with your front's URLs.
**When setting up your onionbalance configuration limit the amount of fronts to 18! Setting it higher you can get descriptor or introduction issues which will cause your onion's descriptor to not be correctly pushed.** To run onionbalance cd into the onionbalance directory and run:
nohup onionbalance -v info -c config/config.yaml &
This will start onionbalance detacted from the terminal and then put it in the background. Afterwards you can run
tail -f nohup.out
and see the status of it. You want to see distinct descriptors being pushed.

View File

@ -82,7 +82,7 @@ The main configuration can be found at the top of the `setup.sh` file. It custom
There are options. Such as: There are options. Such as:
* MASTERONION - Your V3 Master OnionBalance Address **WITHOUT http://** (example: dreadytofatroptsdj6io7l3xptbet6onoyno2yv7jicoxknyazubrad.onion) * MASTERONION - Your V3 Master OnionBalance Address **WITHOUT http://** (example: dreadytofatroptsdj6io7l3xptbet6onoyno2yv7jicoxknyazubrad.onion)
* TORAUTHPASSWORD - Password which is used for your Tor Control Port Authentication with NGINX. Alphanumeric without spaces (example: passwordIcanremembertyping) * TORAUTHPASSWORD - Password which is used for your Tor Control Port Authentication with NGINX. Alphanumeric without spaces (example: passwordIcanremembertyping)
* KEY - Alphanumeric Key for the shared front session key. Random between 64-128 would do fine. (example: isthis64charactorsalreadyicantbelieveitwowsocoolwaitnotyetohdarn) * KEY - Alphanumeric Key for the shared front session key. Random alphanumberic 64 or 128 would do fine. (example: isthis64charactorsalreadyicantbelieveitwowsocoolwaitnotyetohdarn)
* SALT - 8 character salt used with the key. 8 random alphanumeric characters (example: saltsalt) * SALT - 8 character salt used with the key. 8 random alphanumeric characters (example: saltsalt)
* SESSION_LENGTH - In seconds the amount of time until cookie timeout. Set it high as you can. (example: 3600 [aka 1 hour]) * SESSION_LENGTH - In seconds the amount of time until cookie timeout. Set it high as you can. (example: 3600 [aka 1 hour])
* HEXCOLOR - HEX color put into the css file to be not purple but your main site's color. Any CSS hex will work. (example: #9b59b6) * HEXCOLOR - HEX color put into the css file to be not purple but your main site's color. Any CSS hex will work. (example: #9b59b6)

View File

@ -8,10 +8,10 @@ font-family:roboto, helvetica, sans-serif, arial, verdana, tahoma;font-size:16px
.container {width:100%;margin:0 auto;min-height:100%;position:relative;max-height:100vh;overflow:hidden; } .container {width:100%;margin:0 auto;min-height:100%;position:relative;max-height:100vh;overflow:hidden; }
.container>.inner{position:absolute;top:50%;left:0;right:0;margin:0 auto;text-align:center;-webkit-transform:translateY(-50%);-moz-transform:translateY(-50%); transform:translateY(-50%);} .container>.inner{position:absolute;top:50%;left:0;right:0;margin:0 auto;text-align:center;-webkit-transform:translateY(-50%);-moz-transform:translateY(-50%); transform:translateY(-50%);}
.container>.inner>.logo{display:inline-block;vertical-align:middle;text-decoration:none;margin-bottom:10px} .container>.inner>.logo{display:inline-block;vertical-align:middle;text-decoration:none;margin-bottom:10px}
.container>.inner>.logo>.square{display:inline-block;vertical-align:middle;width:40px;height:40px;background-color:#9b59b6;background-size:24px 24px;background-position:center center;background-repeat:no-repeat;margin-right:10px} .container>.inner>.logo>.square{display:inline-block;vertical-align:middle;width:40px;height:40px;background-color:#HEXCOLOR;background-size:24px 24px;background-position:center center;background-repeat:no-repeat;margin-right:10px}
.container>.inner>.logo>.text{display:inline-block;vertical-align:middle;font-size:30px;color:#fff;font-weight:700}.container>.inner>.date{display:block;text-align:center;font-size:42px} .container>.inner>.logo>.text{display:inline-block;vertical-align:middle;font-size:30px;color:#fff;font-weight:700}.container>.inner>.date{display:block;text-align:center;font-size:42px}
.container>.inner>.date>.day{color:#9b59b6;font-weight:bold}.signed{display:block;width:400px;height:150px;margin-top:20px;margin:20px auto 0 auto;} .container>.inner>.date>.day{color:#HEXCOLOR;font-weight:bold}.signed{display:block;width:400px;height:150px;margin-top:20px;margin:20px auto 0 auto;}
.signed>textarea {margin:0 auto;width:400px;height:150px;min-width:400px;max-width:400px;display:block;padding:15px;background:#fff;border:1px solid #9b59b6;min-height:150px;max-height:150px;}p{margin:0 auto 20px auto;max-width:300px;}form.ddos_form .captcha-input{margin:0 auto 20px auto;display: block;width:300px;font-size:0;}form.ddos_form .captcha-input input{display:inline-block;vertical-align:top;height:50px;width:calc(100% - 150px);outline:0;border:none;font-size:16px;color:#000;padding:0 15px;line-height:50px;}form.ddos_form .captcha-input img{display:inline-block;vertical-align:top;}form.ddos_form button{border-radius:3px;display:block;width:300px;margin:0 auto;background:#9b59b6;cursor:pointer;color:#fff;font-size:16px;text-transform:uppercase;text-align:center;height:40px;line-height:40px;outline:0;border:none;} .signed>textarea {margin:0 auto;width:400px;height:150px;min-width:400px;max-width:400px;display:block;padding:15px;background:#fff;border:1px solid #HEXCOLOR;min-height:150px;max-height:150px;}p{margin:0 auto 20px auto;max-width:300px;}form.ddos_form .captcha-input{margin:0 auto 20px auto;display: block;width:300px;font-size:0;}form.ddos_form .captcha-input input{display:inline-block;vertical-align:top;height:50px;width:calc(100% - 150px);outline:0;border:none;font-size:16px;color:#000;padding:0 15px;line-height:50px;}form.ddos_form .captcha-input img{display:inline-block;vertical-align:top;}form.ddos_form button{border-radius:3px;display:block;width:300px;margin:0 auto;background:#HEXCOLOR;cursor:pointer;color:#fff;font-size:16px;text-transform:uppercase;text-align:center;height:40px;line-height:40px;outline:0;border:none;}
.captchav2 {text-align: center;width: 100%;} .captchav2 {text-align: center;width: 100%;}

View File

@ -1,15 +1,15 @@
-- encryption key and salt must be shared across fronts. salt must be 8 chars -- encryption key and salt must be shared across fronts. salt must be 8 chars
local key = "encryption_key" local key = "encryption_key"
local salt = "1saltkey" local salt = "salt1234"
-- for how long the captcha is valid. 120 sec is for testing, 3600 1 hour should be production. -- for how long the captcha is valid. 120 sec is for testing, 3600 1 hour should be production.
local session_timeout = 3600 local session_timeout = sessionconfigvalue
aes = require "resty.aes" aes = require "resty.aes"
str = require "resty.string" str = require "resty.string"
cook = require "resty.cookie" cook = require "resty.cookie"
random = require "resty.random" random = require "resty.random"
aes_128_cbc_sha512x1 = aes:new(key, salt, aes.cipher(128,"cbc"), aes.hash.sha512, 1) aes_128_cbc_sha512x1 = aes:new(key, salt, aes.cipher(128, "cbc"), aes.hash.sha512, 1)
local cookie, err = cook:new() local cookie, err = cook:new()
if not cookie then if not cookie then
@ -18,15 +18,21 @@ if not cookie then
end end
function fromhex(str) function fromhex(str)
return (str:gsub('..', function (cc) return (str:gsub(
return string.char(tonumber(cc, 16)) "..",
end)) function(cc)
return string.char(tonumber(cc, 16))
end
))
end end
function tohex(str) function tohex(str)
return (str:gsub('.', function (c) return (str:gsub(
return string.format('%02X', string.byte(c)) ".",
end)) function(c)
return string.format("%02X", string.byte(c))
end
))
end end
caperror = nil caperror = nil
@ -43,21 +49,21 @@ if in_array(allowed_hosts, ngx.var.http_host) == nil then
if pa ~= "no_proxy" then if pa ~= "no_proxy" then
local ok, err = ngx.timer.at(0, kill_circuit, ngx.var.remote_addr, ngx.var.proxy_protocol_addr) local ok, err = ngx.timer.at(0, kill_circuit, ngx.var.remote_addr, ngx.var.proxy_protocol_addr)
if not ok then if not ok then
ngx.log(ngx.ERR, "failed to create timer: ", err) ngx.log(ngx.ERR, "failed to create timer: ", err)
return return
end end
end end
ngx.exit(444) ngx.exit(444)
end end
-- only GET and POST requests are allowed the others are not used. HEAD for recon checker -- only GET and POST requests are allowed the others are not used.
if ngx.var.request_method ~= "POST" and ngx.var.request_method ~= "GET" and ngx.var.request_method ~= "HEAD" then if ngx.var.request_method ~= "POST" and ngx.var.request_method ~= "GET" then
ngx.log(ngx.ERR, "Wrong request (" .. ngx.var.request_method .. ") " .. ngx.var.remote_addr .. "|" .. pa) ngx.log(ngx.ERR, "Wrong request (" .. ngx.var.request_method .. ") " .. ngx.var.remote_addr .. "|" .. pa)
if pa ~= "no_proxy" then if pa ~= "no_proxy" then
local ok, err = ngx.timer.at(0, kill_circuit, ngx.var.remote_addr, ngx.var.proxy_protocol_addr) local ok, err = ngx.timer.at(0, kill_circuit, ngx.var.remote_addr, ngx.var.proxy_protocol_addr)
if not ok then if not ok then
ngx.log(ngx.ERR, "failed to create timer: ", err) ngx.log(ngx.ERR, "failed to create timer: ", err)
return return
end end
end end
ngx.exit(444) ngx.exit(444)
@ -69,8 +75,8 @@ if ngx.var.http_user_agent == nil then
if pa ~= "no_proxy" then if pa ~= "no_proxy" then
local ok, err = ngx.timer.at(0, kill_circuit, ngx.var.remote_addr, ngx.var.proxy_protocol_addr) local ok, err = ngx.timer.at(0, kill_circuit, ngx.var.remote_addr, ngx.var.proxy_protocol_addr)
if not ok then if not ok then
ngx.log(ngx.ERR, "failed to create timer: ", err) ngx.log(ngx.ERR, "failed to create timer: ", err)
return return
end end
end end
ngx.exit(444) ngx.exit(444)
@ -82,8 +88,8 @@ if ngx.var.request_method == "POST" and ngx.var.http_referer == nil then
if pa ~= "no_proxy" then if pa ~= "no_proxy" then
local ok, err = ngx.timer.at(0, kill_circuit, ngx.var.remote_addr, ngx.var.proxy_protocol_addr) local ok, err = ngx.timer.at(0, kill_circuit, ngx.var.remote_addr, ngx.var.proxy_protocol_addr)
if not ok then if not ok then
ngx.log(ngx.ERR, "failed to create timer: ", err) ngx.log(ngx.ERR, "failed to create timer: ", err)
return return
end end
end end
ngx.exit(444) ngx.exit(444)
@ -94,32 +100,40 @@ local field, err = cookie:get("dcap")
local blocked_cookies = ngx.shared.blocked_cookies local blocked_cookies = ngx.shared.blocked_cookies
local bct, btcflags = blocked_cookies:get(field) local bct, btcflags = blocked_cookies:get(field)
if bct then if bct then
ngx.header.content_type = 'text/plain' ngx.header.content_type = "text/plain"
ngx.say("403 DDOS fliter killed your path. (You probably sent too many requests at once). Not calling you a bot, bot, but grab a new identity and try again.") ngx.say("403 DDOS fliter killed your path. (You probably sent too many requests at once). Not calling you a bot, bot, but grab a new identity and try again.")
ngx.flush() ngx.flush()
ngx.exit(200) ngx.exit(200)
end end
-- check cookie support similar to testcookie -- check cookie support similar to testcookie
if ngx.var.request_method == "GET" then if ngx.var.request_method == "GET" then
local field, err = cookie:get("dcap") local field, err = cookie:get("dcap")
if err then if err or not field then
--local tstamp = ngx.now() + slidingscalefunction local tstamp = ngx.now() + 5
local tstamp = ngx.now() + 10 local plaintext = "queue|" .. tstamp .. "|1|" .. random.token(random.number(10, 20))
local plaintext = "queue|" .. tstamp .. "|1|" .. random.token(random.number(10,20))
local ciphertext = tohex(aes_128_cbc_sha512x1:encrypt(plaintext)) local ciphertext = tohex(aes_128_cbc_sha512x1:encrypt(plaintext))
local ok, err = cookie:set({ local ok, err =
key = "dcap", value = ciphertext, path = "/", cookie:set(
domain = ngx.var.host, httponly = true, {
max_age = session_timeout, key = "dcap",
samesite = "Lax" value = ciphertext,
}) path = "/",
domain = ngx.var.host,
httponly = true,
max_age = 120,
samesite = "Lax"
}
)
if not ok then if not ok then
ngx.log(ngx.ERR, err) ngx.log(ngx.ERR, err)
return return
end end
ngx.header.content_type = 'text/html' ngx.header.content_type = "text/html"
local file = io.open("/etc/nginx/queue.html") local file = io.open("/etc/nginx/queue.html")
if not file then
ngx.exit(500)
end
local queue, err = file:read("*a") local queue, err = file:read("*a")
file:close() file:close()
ngx.say(queue) ngx.say(queue)
@ -128,16 +142,15 @@ if ngx.var.request_method == "GET" then
else else
plaintext = aes_128_cbc_sha512x1:decrypt(fromhex(field)) plaintext = aes_128_cbc_sha512x1:decrypt(fromhex(field))
if not plaintext then if not plaintext then
ngx.header.content_type = 'text/plain' ngx.header.content_type = "text/plain"
ngx.say("403 DDOS fliter killed your path. (You probably sent too many requests at once). Not calling you a bot, bot, but grab a new identity and try again.") ngx.say("403 DDOS fliter killed your path. (You probably sent too many requests at once). Not calling you a bot, bot, but grab a new identity and try again.")
ngx.flush() ngx.flush()
ngx.exit(200) ngx.exit(200)
end end
cookdata = split(plaintext,"|") cookdata = split(plaintext, "|")
local expired = nil local expired = nil
if (cookdata[1] == "queue") then if (cookdata[1] == "queue") then
--if (tonumber(cookdata[2])) > ngx.now() or (tonumber(cookdata[2])) > tonumber(cookdata[2]) + slidingscalefunction then if (tonumber(cookdata[2])) > ngx.now() or (tonumber(cookdata[2])) > ngx.now() + 15 then
if (tonumber(cookdata[2])) > ngx.now() or (tonumber(cookdata[2])) > ngx.now() + 40 then
if pa ~= "no_proxy" then if pa ~= "no_proxy" then
local ok, err = ngx.timer.at(0, kill_circuit, ngx.var.remote_addr, ngx.var.proxy_protocol_addr) local ok, err = ngx.timer.at(0, kill_circuit, ngx.var.remote_addr, ngx.var.proxy_protocol_addr)
if not ok then if not ok then
@ -150,6 +163,7 @@ if ngx.var.request_method == "GET" then
ngx.exit(444) ngx.exit(444)
end end
-- captcha generator functions
require "caphtml_d" require "caphtml_d"
local expired = nil local expired = nil
@ -157,7 +171,6 @@ if ngx.var.request_method == "GET" then
displaycap(session_timeout) displaycap(session_timeout)
ngx.flush() ngx.flush()
ngx.exit(200) ngx.exit(200)
elseif (cookdata[1] == "cap_not_solved") then elseif (cookdata[1] == "cap_not_solved") then
if (tonumber(cookdata[2]) + 60) > ngx.now() then if (tonumber(cookdata[2]) + 60) > ngx.now() then
if pa ~= "no_proxy" then if pa ~= "no_proxy" then
@ -167,29 +180,39 @@ if ngx.var.request_method == "GET" then
return return
end end
end end
ngx.header.content_type = 'text/html' ngx.header.content_type = "text/html"
ngx.say("<h1>THINK OF WHAT YOU HAVE DONE!</h1>") ngx.say("<h1>THINK OF WHAT YOU HAVE DONE!</h1>")
ngx.say("<p>That captcha was generated just for you. And look at what you did. Ignoring the captcha... not even giving an incorrect answer to his meaningless existence. You couldn't even give him false hope. Shame on you.</p>") ngx.say("<p>That captcha was generated just for you. And look at what you did. Ignoring the captcha... not even giving an incorrect answer to his meaningless existence. You couldn't even give him false hope. Shame on you.</p>")
ngx.say("<p>Don't immedately refresh for a new captcha! Try and fail. You must now wait about a minute for a new captcha to load.</p>") ngx.say("<p>Don't immedately refresh for a new captcha! Try and fail. You must now wait about a minute for a new captcha to load.</p>")
ngx.flush() ngx.flush()
ngx.exit(200) ngx.exit(200)
end end
-- captcha generator functions
require "caphtml_d"
local expired = nil local expired = nil
require "caphtml_d"
displaycap(session_timeout)
ngx.flush()
ngx.exit(200)
elseif (cookdata[1] == "captcha_solved") then
if (tonumber(cookdata[2]) + session_timeout) < ngx.now() then if (tonumber(cookdata[2]) + session_timeout) < ngx.now() then
expired = true require "caphtml_d"
caperror = "Session expired" local expired = true
end caperror = "Session expired"
if cookdata[1] ~= "captcha_solved" or expired then
displaycap(session_timeout) displaycap(session_timeout)
ngx.flush() ngx.flush()
ngx.exit(200) ngx.exit(200)
end end
else
local ok, err = ngx.timer.at(0, kill_circuit, ngx.var.remote_addr, ngx.var.proxy_protocol_addr)
if not ok then
ngx.log(ngx.ERR, "failed to create timer: ", err)
return
end
local blocked_cookies = ngx.shared.blocked_cookies
blocked_cookies:set(field, 1, 3600)
ngx.header.content_type = "text/plain"
ngx.say("That isn't going to work here")
ngx.flush()
ngx.exit(200)
end end
end end
end end
@ -197,18 +220,18 @@ end
if ngx.var.request_method == "POST" then if ngx.var.request_method == "POST" then
local field, err = cookie:get("dcap") local field, err = cookie:get("dcap")
if err then if err then
ngx.exit(403) ngx.exit(403)
end end
if field then if field then
plaintext = aes_128_cbc_sha512x1:decrypt(fromhex(field)) plaintext = aes_128_cbc_sha512x1:decrypt(fromhex(field))
if not plaintext then if not plaintext then
ngx.header.content_type = 'text/plain' ngx.header.content_type = "text/plain"
ngx.say("403 DDOS fliter killed your path. (You probably sent too many requests at once). Not calling you a bot, bot, but grab a new identity and try again.") ngx.say("403 DDOS fliter killed your path. (You probably sent too many requests at once). Not calling you a bot, bot, but grab a new identity and try again.")
ngx.flush() ngx.flush()
ngx.exit(200) ngx.exit(200)
end end
cookdata = split(plaintext,"|") cookdata = split(plaintext, "|")
local expired = nil local expired = nil
if (cookdata[1] == "cap_not_solved") then if (cookdata[1] == "cap_not_solved") then
if (tonumber(cookdata[2]) + session_timeout) < ngx.now() then if (tonumber(cookdata[2]) + session_timeout) < ngx.now() then
@ -219,14 +242,14 @@ if ngx.var.request_method == "POST" then
ngx.flush() ngx.flush()
ngx.exit(200) ngx.exit(200)
end end
elseif (cookdata[1] == "captcha_solved") then elseif (cookdata[1] == "captcha_solved") then
return return
end end
end end
require "caphtml_d" require "caphtml_d"
-- resty has a library for parsing POST data but it's not really needed -- resty has a library for parsing POST data but it's not really needed
ngx.req.read_body() ngx.req.read_body()
local dataraw = ngx.req.get_body_data() local dataraw = ngx.req.get_body_data()
if dataraw == nil then if dataraw == nil then
@ -240,18 +263,18 @@ if ngx.var.request_method == "POST" then
data = split(data, "&") data = split(data, "&")
local sentcap = "" local sentcap = ""
for index, value in ipairs(data) do for index, value in ipairs(data) do
sentcap = sentcap .. split(value,"=")[2] sentcap = sentcap .. split(value, "=")[2]
end end
if field then if field then
plaintext = aes_128_cbc_sha512x1:decrypt(fromhex(field)) plaintext = aes_128_cbc_sha512x1:decrypt(fromhex(field))
if not plaintext then if not plaintext then
ngx.header.content_type = 'text/plain' ngx.header.content_type = "text/plain"
ngx.say("403 DDOS fliter killed your path. (You probably sent too many requests at once). Not calling you a bot, bot, but grab a new identity and try again.") ngx.say("403 DDOS fliter killed your path. (You probably sent too many requests at once). Not calling you a bot, bot, but grab a new identity and try again.")
ngx.flush() ngx.flush()
ngx.exit(200) ngx.exit(200)
end end
cookdata = split(plaintext,"|") cookdata = split(plaintext, "|")
if (tonumber(cookdata[2]) + 60) < ngx.now() then if (tonumber(cookdata[2]) + 60) < ngx.now() then
caperror = "Captcha expired" caperror = "Captcha expired"
@ -263,23 +286,29 @@ if ngx.var.request_method == "POST" then
if string.lower(sentcap) == string.lower(cookdata[3]) then if string.lower(sentcap) == string.lower(cookdata[3]) then
local newcookdata = "" local newcookdata = ""
cookdata[1] = "captcha_solved" cookdata[1] = "captcha_solved"
for k,v in pairs(cookdata) do cookdata[2] = ngx.now()
for k, v in pairs(cookdata) do
newcookdata = newcookdata .. "|" .. v newcookdata = newcookdata .. "|" .. v
end end
newcookdata = newcookdata .. "|" .. random.token(random.number(10,20)) newcookdata = newcookdata .. "|" .. random.token(random.number(10, 20))
local tstamp = ngx.now()
local ciphertext = tohex(aes_128_cbc_sha512x1:encrypt(newcookdata)) local ciphertext = tohex(aes_128_cbc_sha512x1:encrypt(newcookdata))
local ok, err = cookie:set({ local ok, err =
key = "dcap", value = ciphertext, path = "/", cookie:set(
domain = ngx.var.host, httponly = true, {
max_age = session_timeout, key = "dcap",
samesite = "Lax" value = ciphertext,
}) path = "/",
domain = ngx.var.host,
httponly = true,
max_age = session_timeout,
samesite = "Lax"
}
)
if not ok then if not ok then
ngx.say("cookie error") ngx.say("cookie error")
return return
end end
local redirect_to = ngx.var.uri local redirect_to = ngx.var.uri
if ngx.var.query_string ~= nil then if ngx.var.query_string ~= nil then
redirect_to = redirect_to .. "?" .. ngx.var.query_string redirect_to = redirect_to .. "?" .. ngx.var.query_string
end end
@ -289,6 +318,6 @@ if ngx.var.request_method == "POST" then
end end
displaycap(session_timeout) displaycap(session_timeout)
ngx.flush() ngx.flush()
ngx.exit(200) ngx.exit(200)
end end
end end

View File

@ -1,85 +1,40 @@
#!/bin/bash #!/bin/bash
apt-get update apt-get update
apt-get -y upgrade apt-get -y upgrade
command="nginx -v" command="nginx -v"
nginxv=$( ${command} 2>&1 ) nginxv=$( ${command} 2>&1 )
NGINXVERSION=$(echo $nginxv | grep -o '[0-9.]*$') NGINXVERSION=$(echo $nginxv | grep -o '[0-9.]*$')
NGINXOPENSSL="1.1.1d"
NGINXOPENSSL="1.1.1d"
wget https://nginx.org/download/nginx-$NGINXVERSION.tar.gz
tar -xzvf nginx-$NGINXVERSION.tar.gz wget https://nginx.org/download/nginx-$NGINXVERSION.tar.gz
cd nginx-$NGINXVERSION tar -xzvf nginx-$NGINXVERSION.tar.gz
apt-get install -y build-essential zlib1g-dev libpcre3 libpcre3-dev unzip uuid-dev gcc git wget curl libgd3 libgd-dev cp -R dependencies/* nginx-$NGINXVERSION/
wget https://github.com/apache/incubator-pagespeed-ngx/archive/latest-beta.tar.gz cd nginx-$NGINXVERSION
tar -xzvf latest-beta.tar.gz
cd incubator-pagespeed-ngx-latest-beta wget https://www.openssl.org/source/openssl-$NGINXOPENSSL.tar.gz
wget https://dl.google.com/dl/page-speed/psol/1.13.35.2-x64.tar.gz tar -xzvf openssl-$NGINXOPENSSL.tar.gz
tar -xzvf 1.13.35.2-x64.tar.gz
cd .. export LUAJIT_LIB=/usr/local/lib
export LUAJIT_INC=/usr/local/include/luajit-2.1
git clone https://github.com/yorkane/socks-nginx-module ./configure --with-cc-opt='-Wno-stringop-overflow -Wno-stringop-truncation -Wno-cast-function-type' \
git clone https://github.com/nbs-system/naxsi.git --with-ld-opt="-Wl,-rpath,/usr/local/lib" \
git clone https://github.com/kyprizel/testcookie-nginx-module.git --with-compat --with-openssl=openssl-$NGINXOPENSSL \
wget https://www.openssl.org/source/openssl-$NGINXOPENSSL.tar.gz --with-http_ssl_module \
tar -xzvf openssl-$NGINXOPENSSL.tar.gz --add-dynamic-module=naxsi/naxsi_src \
git clone https://github.com/openresty/headers-more-nginx-module.git --add-dynamic-module=headers-more-nginx-module \
git clone https://github.com/openresty/echo-nginx-module.git --add-dynamic-module=socks-nginx-module \
--add-dynamic-module=echo-nginx-module \
#some required stuff for lua/luajit. obviously versions should be ckecked with every install/update --add-dynamic-module=ngx_devel_kit \
git clone https://github.com/openresty/lua-nginx-module --add-dynamic-module=lua-nginx-module
cd lua-nginx-module
git checkout v0.10.16 make -j16 modules
cd ..
git clone https://github.com/openresty/luajit2 cp -r objs modules
cd luajit2 rm -R /etc/nginx/modules
git checkout v2.1-20200102 mkdir /etc/nginx/modules
cd ..
git clone https://github.com/vision5/ngx_devel_kit
cd luajit2
make -j8 && make install
cd ..
export LUAJIT_LIB=/usr/local/lib
export LUAJIT_INC=/usr/local/include/luajit-2.1
./configure --with-cc-opt='-Wno-stringop-overflow -Wno-stringop-truncation -Wno-cast-function-type' \
--with-ld-opt="-Wl,-rpath,/usr/local/lib" \
--with-compat --with-openssl=openssl-$NGINXOPENSSL \
--with-http_ssl_module \
--add-dynamic-module=incubator-pagespeed-ngx-latest-beta \
--add-dynamic-module=naxsi/naxsi_src --add-dynamic-module=testcookie-nginx-module \
--add-dynamic-module=headers-more-nginx-module \
--add-dynamic-module=socks-nginx-module \
--add-dynamic-module=echo-nginx-module \
--add-dynamic-module=ngx_devel_kit \
--add-dynamic-module=lua-nginx-module
git clone https://github.com/openresty/lua-resty-string
cd lua-resty-string
make install
cd ..
git clone https://github.com/cloudflare/lua-resty-cookie
cd lua-resty-cookie
make install
cd ..
git clone https://github.com/bungle/lua-resty-session
cp -a lua-resty-session/lib/resty/session* /usr/local/lib/lua/resty/
wget -O /usr/local/lib/lua/resty/aes_functions.lua https://github.com/c64bob/lua-resty-aes/raw/master/lib/resty/aes_functions.lua
#include seems to be a bit mssed up with luajit
mkdir /etc/nginx/resty
ln -s /usr/local/lib/lua/resty/ /etc/nginx/resty/
wget -O /usr/local/lib/lua/resty/random.lua https://raw.githubusercontent.com/bungle/lua-resty-random/master/lib/resty/random.lua
make -j16 modules
cp -r objs modules
rm -R /etc/nginx/modules/modules
mv modules /etc/nginx/modules mv modules /etc/nginx/modules

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' local b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
local function base64_encode(data) local function base64_encode(data)
return ((data:gsub('.', function(x) return ((data:gsub('.', function(x)
@ -29,105 +29,7 @@ local function base64_decode(data)
end end
function displaycap() function displaycap()
ngx.header.content_type = "text/html"
hour = random.number(0,11)
minute = random.number(0,59)
shour = tostring(hour)
sminute = tostring(minute)
if string.len(shour) < 2 then shour = "0" .. shour end
if string.len(sminute) < 2 then sminute = "0" .. sminute end
local gd = require("gd")
local pickedtime = shour .. ":" .. sminute
local radios = {}
local ctimeindex = random.number(1,10)
radios[ctimeindex] = {}
radios[ctimeindex][1] = pickedtime
radios[ctimeindex][2] = shour .. sminute
for i = 1,ctimeindex-1,1 do
fshour = tostring(random.number(0,11))
fsminute = tostring(random.number(0,59))
if string.len(fshour) < 2 then fshour = "0" .. fshour end
if string.len(fsminute) < 2 then fsminute = "0" .. fsminute end
local fpickedtime = fshour .. ":" .. fsminute
radios[i] = {}
radios[i][1] = fpickedtime
radios[i][2] = fshour .. fsminute
end
for i = ctimeindex+1,10,1 do
fshour = tostring(random.number(0,11))
fsminute = tostring(random.number(0,59))
if string.len(fshour) < 2 then fshour = "0" .. fshour end
if string.len(fsminute) < 2 then fsminute = "0" .. fsminute end
local fpickedtime = fshour .. ":" .. fsminute
radios[i] = {}
radios[i][1] = fpickedtime
radios[i][2] = fshour .. fsminute
end
local function createClock(size, hours, minutes)
local im = gd.createTrueColor(size, size)
local white = im:colorAllocate(random.number(200,255), random.number(200,255), random.number(200,255))
local gray = im:colorAllocate(random.number(100,150), random.number(100,150), random.number(100,150))
local black = im:colorAllocate(random.number(0,10), random.number(0,10), random.number(0,10))
local hrhand = im:colorAllocate(random.number(0,350), random.number(0,150), random.number(0,148))
local minhand = im:colorAllocate(random.number(0,350), random.number(0,150), random.number(0,148))
local cxy = size/2
im:filledRectangle(0, 0, size, size, white)
im:setThickness(2)
im:arc(cxy, cxy, size, size, 0, 360, black)
local ang = 0
local rang, gsize
while ang < 360 do
rang = math.rad(ang)
if (ang % 90) == 0 then
gsize = 0.75
elseif (ang % 5) == 0 then
gsize = 0.85
else
gsize = 0.90
end
im:line(
cxy + gsize * cxy * math.sin(rang),
size - (cxy + gsize * cxy * math.cos(rang)),
cxy + cxy * 0.9 * math.sin(rang),
size - (cxy + cxy * 0.9 * math.cos(rang)),
gray)
ang = ang + 6
end
im:setThickness(math.max(1, size/50))
im:line(cxy, cxy,
cxy + 0.45 * size * math.sin(math.rad(6*minutes)),
size - (cxy + 0.45 * size * math.cos(math.rad(6*minutes))),
hrhand)
im:setThickness(math.max(1, size/25))
rang = math.rad(30*hours + minutes/2)
im:line(cxy, cxy,
cxy + 0.25 * size * math.sin(rang),
size - (cxy + 0.25 * size * math.cos(rang)),
minhand)
im:setThickness(1)
local sp = math.max(1, size/20)
im:filledArc(cxy, cxy, sp, sp, 0, 360, black, gd.ARC)
return im
end
local im = createClock(190, hour, minute)
local imageraw = im:jpegStr(90)
local imageb64 = base64_encode(imageraw)
local cookie, err = cook:new() local cookie, err = cook:new()
if not cookie then if not cookie then
ngx.log(ngx.ERR, err) ngx.log(ngx.ERR, err)
@ -135,150 +37,341 @@ local imageb64 = base64_encode(imageraw)
ngx.exit(200) ngx.exit(200)
end end
local tstamp = ngx.now() local field, err = cookie:get("dcap")
local newcookdata = "cap_not_solved|" .. tstamp .. "|" .. shour .. sminute plaintext = aes_128_cbc_sha512x1:decrypt(fromhex(field))
local blocked_cookies = ngx.shared.blocked_cookies
newcookdata = newcookdata .. "|" .. random.token(random.number(10,20)) blocked_cookies:set(field, 1, 3600)
cookdata = split(plaintext, "|")
local ciphertext = tohex(aes_128_cbc_sha512x1:encrypt(newcookdata)) if (cookdata[1] == "cap_not_solved") then
local ok, err = cookie:set({ if (cookdata[5] == "3") then
key = "dcap", value = ciphertext, path = "/", ngx.say("You failed the captcha too many times. Get a new identity and try again.")
domain = ngx.var.host, httponly = true, ngx.exit(200)
max_age = 21600, end
samesite = "Lax"
})
if not ok then
ngx.say("cookie error")
ngx.exit(200)
end end
hour = random.number(0, 11)
minute = random.number(0, 59)
shour = tostring(hour)
sminute = tostring(minute)
if string.len(shour) < 2 then
shour = "0" .. shour
end
if string.len(sminute) < 2 then
sminute = "0" .. sminute
end
ngx.header.content_type = 'text/html'; local gd = require("gd")
ngx.say("<!DOCTYPE html> \
local pickedtime = shour .. ":" .. sminute
local radios = {}
local ctimeindex = random.number(1, 10)
radios[ctimeindex] = {}
radios[ctimeindex][1] = pickedtime
radios[ctimeindex][2] = shour .. sminute
for i = 1, ctimeindex - 1, 1 do
fshour = tostring(random.number(0, 11))
fsminute = tostring(random.number(0, 59))
if string.len(fshour) < 2 then
fshour = "0" .. fshour
end
if string.len(fsminute) < 2 then
fsminute = "0" .. fsminute
end
local fpickedtime = fshour .. ":" .. fsminute
radios[i] = {}
radios[i][1] = fpickedtime
radios[i][2] = fshour .. fsminute
end
for i = ctimeindex + 1, 10, 1 do
fshour = tostring(random.number(0, 11))
fsminute = tostring(random.number(0, 59))
if string.len(fshour) < 2 then
fshour = "0" .. fshour
end
if string.len(fsminute) < 2 then
fsminute = "0" .. fsminute
end
local fpickedtime = fshour .. ":" .. fsminute
radios[i] = {}
radios[i][1] = fpickedtime
radios[i][2] = fshour .. fsminute
end
local function createClock(size, hours, minutes)
local im = gd.createTrueColor(size, size)
local white = im:colorAllocate(random.number(200, 255), random.number(200, 255), random.number(200, 255))
local gray = im:colorAllocate(random.number(100, 150), random.number(100, 150), random.number(100, 150))
local black = im:colorAllocate(random.number(0, 10), random.number(0, 10), random.number(0, 10))
local hrhand = im:colorAllocate(random.number(0, 350), random.number(0, 150), random.number(0, 148))
local minhand = im:colorAllocate(random.number(0, 350), random.number(0, 150), random.number(0, 148))
local cxy = size / 2
im:filledRectangle(0, 0, size, size, white)
im:setThickness(2)
im:arc(cxy, cxy, size, size, 0, 360, black)
local ang = 0
local rang, gsize
while ang < 360 do
rang = math.rad(ang)
if (ang % 90) == 0 then
gsize = 0.75
elseif (ang % 5) == 0 then
gsize = 0.85
else
gsize = 0.90
end
im:line(
cxy + gsize * cxy * math.sin(rang),
size - (cxy + gsize * cxy * math.cos(rang)),
cxy + cxy * 0.9 * math.sin(rang),
size - (cxy + cxy * 0.9 * math.cos(rang)),
gray
)
ang = ang + 6
end
im:setThickness(math.max(1, size / 50))
im:line(
cxy,
cxy,
cxy + 0.45 * size * math.sin(math.rad(6 * minutes)),
size - (cxy + 0.45 * size * math.cos(math.rad(6 * minutes))),
hrhand
)
im:setThickness(math.max(1, size / 25))
rang = math.rad(30 * hours + minutes / 2)
im:line(cxy, cxy, cxy + 0.25 * size * math.sin(rang), size - (cxy + 0.25 * size * math.cos(rang)), minhand)
im:setThickness(1)
local sp = math.max(1, size / 20)
im:filledArc(cxy, cxy, sp, sp, 0, 360, black, gd.ARC)
im:setThickness(random.number(2, 3))
fillcolor = im:colorAllocate(random.number(5, 255), random.number(5, 255), random.number(5, 255))
x = random.number(40, 120)
y = random.number(40, 120)
im:arc(x, y, random.number(30, 90), random.number(30, 90), 0, 360, fillcolor)
fillcolor = im:colorAllocate(random.number(5, 255), random.number(5, 255), random.number(5, 255))
x = random.number(40, 120)
y = random.number(40, 120)
im:rectangle(x, y, x + random.number(30, 90), y + random.number(30, 90), fillcolor)
x = random.number(40, 100)
y = random.number(x + 40, 180)
fillcolor = im:colorAllocate(random.number(5, 255), random.number(5, 255), random.number(5, 255))
im:polygon(
{
{cxy, cxy},
{random.number(10, 150), random.number(10, 150)},
{random.number(10, 150), random.number(10, 150)}
},
fillcolor
)
return im
end
local im = createClock(190, hour, minute)
local imageraw = im:jpegStr(80)
local imageb64 = base64_encode(imageraw)
hour = tostring(hour)
minute = tostring(minute)
if string.len(hour) < 2 then
hour = "0" .. hour
end
if string.len(minute) < 2 then
minute = "0" .. minute
end
if (cookdata[1] == "queue") then
local tstamp = ngx.now()
local newcookdata = "cap_not_solved|" .. tstamp .. "|" .. hour .. minute
newcookdata = newcookdata .. "|" .. random.token(random.number(10, 20)) .. "|1"
local ciphertext = tohex(aes_128_cbc_sha512x1:encrypt(newcookdata))
local ok, err =
cookie:set(
{
key = "dcap",
value = ciphertext,
path = "/",
domain = ngx.var.host,
httponly = true,
max_age = 120,
samesite = "Lax"
}
)
if not ok then
ngx.say("cookie error")
ngx.exit(200)
end
else
local tstamp = ngx.now()
local tries = tonumber(cookdata[5] + 1)
local newcookdata = "cap_not_solved|" .. tstamp .. "|" .. hour .. minute
newcookdata = newcookdata .. "|" .. random.token(random.number(10, 20)) .. "|" .. tries
local ciphertext = tohex(aes_128_cbc_sha512x1:encrypt(newcookdata))
local ok, err =
cookie:set(
{
key = "dcap",
value = ciphertext,
path = "/",
domain = ngx.var.host,
httponly = true,
max_age = 120,
samesite = "Lax"
}
)
if not ok then
ngx.say("cookie error")
ngx.exit(200)
end
end
ngx.say('<!DOCTYPE html> \
<html lang=en> \ <html lang=en> \
<head> \ <head> \
<title>DDOS Protection</title> \ <title>DDOS Protection</title> \
<meta charset=\"UTF-8\"> \ <meta charset="UTF-8"> \
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"> \ <meta name="viewport" content="width=device-width, initial-scale=1.0"> \
<link id=\"favicon\" rel=\"shortcut icon\" href=\"data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABMLAAATCwAAAAAAAAAAAACtRI7/rUSO/61Ejv+tRI7/rUSO/61Fjv+qPor/pzaG/6k7if+sQo3/qDiH/6g4h/+sQ43/rUSO/61Ejv+tRI7/rUSO/61Ejv+tRI7/rUSO/61Fjv+sQo3/uV6e/8iBs/+9aaT/sEyT/8V7r//Feq//sEqS/6xDjf+tRI7/rUSO/61Ejv+tRI7/rUSO/65Fj/+vR5D/rEGM/+fI3v///////fv8/+/a6f/+/f7/+vT4/7Zam/+rP4v/rkWP/61Ejv+tRI7/rUSO/61Fjv+sQYz/qTqI/6g4h//hudX/5sXc/+7Z6P////////7///ft9P+2WZr/q0CL/61Fj/+tRI7/rUSO/61Fj/+rQIv/uFyd/82Ou//Njrv/uWGf/6g6iP+uR5D/5sbc///////47vX/tlma/6s/i/+tRY//rUSO/61Ejv+uRo//qDqI/9aix///////69Hj/61Ejv+vSJD/qTqI/8BvqP//////+O/1/7ZZmv+rP4v/rUWP/61Ejv+tRI7/rkaP/6k8if/fttP//////9ekyP+oOIf/sEuS/6tAi/+7ZKH//vv9//nw9v+2WJr/qz+L/61Fj/+tRI7/rUSO/65Gj/+oOoj/1qHG///////pzeH/qj6K/6o8if+lMoP/0pjB///////47vX/tlma/6s/i/+tRY//rUSO/61Ejv+uRo//qj2K/7xmo//8+Pv//////+G61f+8ZqP/zpC8//v2+v//////+O/1/7ZZmv+rP4v/rUWP/61Ejv+tRI7/rUSO/65Gj/+pPIn/zo+7//79/v///////////////////v////////jw9v+2WZr/qz+L/61Fj/+tRI7/rUSO/61Ejv+tRI7/rUWP/6o9iv/Ab6j/37bT/+vR4//kwdr/16XI//36/P/58ff/tlma/6s/i/+tRY//rUSO/61Ejv+tRI7/rUSO/61Ejv+uRo//qj2K/6o9if+tRY7/qDmH/7VYmv/9+fv/+fH3/7ZYmv+rP4v/rUWP/61Ejv+tRI7/rUSO/61Ejv+tRI7/rUSO/65Gj/+uRo//rkaP/6s/i/+6Y6H//Pf6//ju9f+1WJr/q0CL/61Fj/+tRI7/rUSO/61Ejv+tRI7/rUSO/61Ejv+tRI7/rUSO/65Gj/+qPor/umOh//79/v/69Pj/tlqb/6s/i/+uRY//rUSO/61Ejv+tRI7/rUSO/61Ejv+tRI7/rUSO/61Ejv+tRI7/rEKN/7FNk//GfLD/xHmu/7BKkv+sQ43/rUSO/61Ejv+tRI7/rUSO/61Ejv+tRI7/rUSO/61Ejv+tRI7/rUSO/61Ejv+sQo3/qDiH/6g4h/+sQ43/rUSO/61Ejv+tRI7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"> \ <link id="favicon" rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABMLAAATCwAAAAAAAAAAAACtRI7/rUSO/61Ejv+tRI7/rUSO/61Fjv+qPor/pzaG/6k7if+sQo3/qDiH/6g4h/+sQ43/rUSO/61Ejv+tRI7/rUSO/61Ejv+tRI7/rUSO/61Fjv+sQo3/uV6e/8iBs/+9aaT/sEyT/8V7r//Feq//sEqS/6xDjf+tRI7/rUSO/61Ejv+tRI7/rUSO/65Fj/+vR5D/rEGM/+fI3v///////fv8/+/a6f/+/f7/+vT4/7Zam/+rP4v/rkWP/61Ejv+tRI7/rUSO/61Fjv+sQYz/qTqI/6g4h//hudX/5sXc/+7Z6P////////7///ft9P+2WZr/q0CL/61Fj/+tRI7/rUSO/61Fj/+rQIv/uFyd/82Ou//Njrv/uWGf/6g6iP+uR5D/5sbc///////47vX/tlma/6s/i/+tRY//rUSO/61Ejv+uRo//qDqI/9aix///////69Hj/61Ejv+vSJD/qTqI/8BvqP//////+O/1/7ZZmv+rP4v/rUWP/61Ejv+tRI7/rkaP/6k8if/fttP//////9ekyP+oOIf/sEuS/6tAi/+7ZKH//vv9//nw9v+2WJr/qz+L/61Fj/+tRI7/rUSO/65Gj/+oOoj/1qHG///////pzeH/qj6K/6o8if+lMoP/0pjB///////47vX/tlma/6s/i/+tRY//rUSO/61Ejv+uRo//qj2K/7xmo//8+Pv//////+G61f+8ZqP/zpC8//v2+v//////+O/1/7ZZmv+rP4v/rUWP/61Ejv+tRI7/rUSO/65Gj/+pPIn/zo+7//79/v///////////////////v////////jw9v+2WZr/qz+L/61Fj/+tRI7/rUSO/61Ejv+tRI7/rUWP/6o9iv/Ab6j/37bT/+vR4//kwdr/16XI//36/P/58ff/tlma/6s/i/+tRY//rUSO/61Ejv+tRI7/rUSO/61Ejv+uRo//qj2K/6o9if+tRY7/qDmH/7VYmv/9+fv/+fH3/7ZYmv+rP4v/rUWP/61Ejv+tRI7/rUSO/61Ejv+tRI7/rUSO/65Gj/+uRo//rkaP/6s/i/+6Y6H//Pf6//ju9f+1WJr/q0CL/61Fj/+tRI7/rUSO/61Ejv+tRI7/rUSO/61Ejv+tRI7/rUSO/65Gj/+qPor/umOh//79/v/69Pj/tlqb/6s/i/+uRY//rUSO/61Ejv+tRI7/rUSO/61Ejv+tRI7/rUSO/61Ejv+tRI7/rEKN/7FNk//GfLD/xHmu/7BKkv+sQ43/rUSO/61Ejv+tRI7/rUSO/61Ejv+tRI7/rUSO/61Ejv+tRI7/rUSO/61Ejv+sQo3/qDiH/6g4h/+sQ43/rUSO/61Ejv+tRI7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="> \
</head><body><style>") </head><body><style>')
local file = io.open("/etc/nginx/cap_d.css") local file = io.open("/etc/nginx/cap_d.css")
if not file then if not file then
ngx.exit(500) ngx.exit(500)
end end
local css, err = file:read("*a") local css, err = file:read("*a")
file:close() file:close()
ngx.say(css) ngx.say(css)
ngx.say("</style> \ ngx.say('</style> \
<div class=\"container\"> \ <div class="container"> \
<div class=\"inner\"> \ <div class="inner"> \
<div class=\"logo\"> \ <div class="logo"> \
<div class=\"square\" style=\"background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAA4VBMVEX///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9pPP/NAAAASnRSTlMABAcJCwwQFBYdHyIjKTQ2Oj5ESkxOUVZXWGBkZWlqb3Bzd3+Ag5GZnJ6io6Sxt7q+wMbHyMnNztXW2dvh5ejp6uvw8/T2+fr7/f+3i2wAAADLSURBVCjPzdPXDoJAEAVQ7NgL9q7YG/Zesc//f5DuJG4YBBLfvG93T2CyuyAIXwkAy0AwiR95Zs3Tf2SfIYs5uV57p9Iw4OAQaAiXASxYBitOghU79rjwaEvRRPf5xVXsaw8Wz0rH9gmrR/dngyrlGNYif1mWcgEHi5y9lPGUNppt7gi3WFtqeEsYz+Ro4+o6E07jrAjnMJ0dPLGqcO7ojiWUkqR45vN4CQzvuz92ssFNMOYe3OfK4gambP45/Mz6nyh/UK8XHhjh4gvTGmQQRyXgEgAAAABJRU5ErkJggg==)\"></div> \ <div class="square" style="background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAA4VBMVEX///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9pPP/NAAAASnRSTlMABAcJCwwQFBYdHyIjKTQ2Oj5ESkxOUVZXWGBkZWlqb3Bzd3+Ag5GZnJ6io6Sxt7q+wMbHyMnNztXW2dvh5ejp6uvw8/T2+fr7/f+3i2wAAADLSURBVCjPzdPXDoJAEAVQ7NgL9q7YG/Zesc//f5DuJG4YBBLfvG93T2CyuyAIXwkAy0AwiR95Zs3Tf2SfIYs5uV57p9Iw4OAQaAiXASxYBitOghU79rjwaEvRRPf5xVXsaw8Wz0rH9gmrR/dngyrlGNYif1mWcgEHi5y9lPGUNppt7gi3WFtqeEsYz+Ro4+o6E07jrAjnMJ0dPLGqcO7ojiWUkqR45vN4CQzvuz92ssFNMOYe3OfK4gambP45/Mz6nyh/UK8XHhjh4gvTGmQQRyXgEgAAAABJRU5ErkJggg==)"></div> \
<div class=\"text\">dread</div> \ <div class="text">SITENAME</div> \
</div>") </div>')
if caperror ~= nil
then if caperror ~= nil then
ngx.say("<p class=\"alert alert-danger text-center\"><strong>Error: </strong>" .. caperror .. "</p>") ngx.say('<p class="alert alert-danger text-center"><strong>Error: </strong>' .. caperror .. "</p>")
else else
ngx.say("<p>Prove that you are human. Select the time shown on the clock image.</p>") ngx.say("<p>Prove that you are human. Select the time shown on the clock image.</p>")
end end
ngx.say("<form class=\"ddos_form\" method=\"post\"> \ ngx.say('<form class="ddos_form" method="post"> \
<div class=\"captchav2\" style=\"margin-bottom:15px;\"> \ <div class="captchav2" style="margin-bottom:15px;"> \
<div class=\"imgWrap\" style=\"border:2px solid #fff; max-width: 100%; border-radius: 50%; background-image:url(data:image/png;base64," .. imageb64 .. "\"></div>") <div class="imgWrap" style="border:2px solid #fff; max-width: 100%; border-radius: 50%; background-image:url(data:image/png;base64,' .. imageb64 .. ');"></div>')
ngx.say("</div>"); ngx.say("</div>")
ngx.say("<div style=\"margin-bottom: 15px;\">") ngx.say('<div style="margin-bottom: 15px;">')
ngx.say("<select class=\"center\" name=\"cap\" required>") ngx.say('<select class="center" name="cap" required>')
for i = 0,11,1 do for i = 0, 11, 1 do
if i < 10 then si = "0" .. tostring(i) else si = i end if i < 10 then
ngx.say("<option value=\"" .. si .. "\">" .. si .. "</option>\n") si = "0" .. tostring(i)
end else
ngx.say("</select> : ") si = i
ngx.say("<select name=\"cap\" required>") end
for i = 0,59,1 do ngx.say('<option value="' .. si .. '">' .. si .. "</option>\n")
if i < 10 then si = "0" .. tostring(i) else si = i end end
ngx.say("<option value=\"" .. si .. "\">" .. si .. "</option>\n") ngx.say("</select> : ")
end ngx.say('<select name="cap" required>')
ngx.say("</select>") for i = 0, 59, 1 do
--ngx.say("<input type=\"text\" required name=\"cap\" maxlength=\"2\" size=\"2\" placeholder=\"hh\"> : ") if i < 10 then
--ngx.say("<input type=\"text\" required name=\"cap\" maxlength=\"2\" size=\"2\" placeholder=\"mm\">") si = "0" .. tostring(i)
ngx.say("</div>"); else
ngx.say("<div class=\"expire\"> \ si = i
<div class=\"timer\"> \ end
<div class=\"time-part-wrapper\"> \ ngx.say('<option value="' .. si .. '">' .. si .. "</option>\n")
<div class=\"time-part seconds tens\"> \ end
<div class=\"digit-wrapper\"> \ ngx.say("</select>")
<span class=\"digit\">0</span> \ --ngx.say("<input type=\"text\" required name=\"cap\" maxlength=\"2\" size=\"2\" placeholder=\"hh\"> : ")
<span class=\"digit\">5</span> \ --ngx.say("<input type=\"text\" required name=\"cap\" maxlength=\"2\" size=\"2\" placeholder=\"mm\">")
<span class=\"digit\">4</span> \ ngx.say("</div>")
<span class=\"digit\">3</span> \ ngx.say(
<span class=\"digit\">2</span> \ '<div class="expire"> \
<span class=\"digit\">1</span> \ <div class="timer"> \
<span class=\"digit\">0</span> \ <div class="time-part-wrapper"> \
<div class="time-part seconds tens"> \
<div class="digit-wrapper"> \
<span class="digit">0</span> \
<span class="digit">5</span> \
<span class="digit">4</span> \
<span class="digit">3</span> \
<span class="digit">2</span> \
<span class="digit">1</span> \
<span class="digit">0</span> \
</div> \ </div> \
</div> \ </div> \
<div class=\"time-part seconds ones\"> \ <div class="time-part seconds ones"> \
<div class=\"digit-wrapper\"> \ <div class="digit-wrapper"> \
<span class=\"digit\">0</span> \ <span class="digit">0</span> \
<span class=\"digit\">9</span> \ <span class="digit">9</span> \
<span class=\"digit\">8</span> \ <span class="digit">8</span> \
<span class=\"digit\">7</span> \ <span class="digit">7</span> \
<span class=\"digit\">6</span> \ <span class="digit">6</span> \
<span class=\"digit\">5</span> \ <span class="digit">5</span> \
<span class=\"digit\">4</span> \ <span class="digit">4</span> \
<span class=\"digit\">3</span> \ <span class="digit">3</span> \
<span class=\"digit\">2</span> \ <span class="digit">2</span> \
<span class=\"digit\">1</span> \ <span class="digit">1</span> \
<span class=\"digit\">0</span> \ <span class="digit">0</span> \
</div> \ </div> \
</div> \ </div> \
</div> \ </div> \
<div class=\"time-part-wrapper\"> \ <div class="time-part-wrapper"> \
<div class=\"time-part hundredths tens\"> \ <div class="time-part hundredths tens"> \
<div class=\"digit-wrapper\"> \ <div class="digit-wrapper"> \
<span class=\"digit\">0</span> \ <span class="digit">0</span> \
<span class=\"digit\">9</span> \ <span class="digit">9</span> \
<span class=\"digit\">8</span> \ <span class="digit">8</span> \
<span class=\"digit\">7</span> \ <span class="digit">7</span> \
<span class=\"digit\">6</span> \ <span class="digit">6</span> \
<span class=\"digit\">5</span> \ <span class="digit">5</span> \
<span class=\"digit\">4</span> \ <span class="digit">4</span> \
<span class=\"digit\">3</span> \ <span class="digit">3</span> \
<span class=\"digit\">2</span> \ <span class="digit">2</span> \
<span class=\"digit\">1</span> \ <span class="digit">1</span> \
<span class=\"digit\">0</span> \ <span class="digit">0</span> \
</div> \ </div> \
</div> \ </div> \
<div class=\"time-part hundredths ones\"> \ <div class="time-part hundredths ones"> \
<div class=\"digit-wrapper\"> \ <div class="digit-wrapper"> \
<span class=\"digit\">0</span> \ <span class="digit">0</span> \
<span class=\"digit\">9</span> \ <span class="digit">9</span> \
<span class=\"digit\">8</span> \ <span class="digit">8</span> \
<span class=\"digit\">7</span> \ <span class="digit">7</span> \
<span class=\"digit\">6</span> \ <span class="digit">6</span> \
<span class=\"digit\">5</span> \ <span class="digit">5</span> \
<span class=\"digit\">4</span> \ <span class="digit">4</span> \
<span class=\"digit\">3</span> \ <span class="digit">3</span> \
<span class=\"digit\">2</span> \ <span class="digit">2</span> \
<span class=\"digit\">1</span> \ <span class="digit">1</span> \
<span class=\"digit\">0</span> \ <span class="digit">0</span> \
</div> \ </div> \
</div> \ </div> \
</div> \ </div> \
</div> \ </div> \
</div>") </div>')
ngx.say("<button class=\"before\" type=\"submit\">Verify</button> \ ngx.say('<button class="before" type="submit">Verify</button> \
<button class=\"expired\" type=\"submit\"> Refresh (expired)</button> \ <button class="expired" type="submit"> Refresh (expired)</button> \
</form> \ </form> \
</div> \ </div> \
</div> \ </div> \
</body> \ </body> \
</html>") </html>')
end end

View File

@ -17,7 +17,8 @@ SESSION_LENGTH=3600
#CSS Branding #CSS Branding
HEXCOLOR="#9b59b6" HEXCOLOR="9b59b6"
HEXCOLORDARK="6d3d82"
SITENAME="dread" SITENAME="dread"
#There is more branding you need to do in the resty/caphtml_d.lua file near the end. #There is more branding you need to do in the resty/caphtml_d.lua file near the end.
@ -32,7 +33,7 @@ NC='\033[0m' # No Color
printf "\r\nProvided by your lovely ${BLUE}/u/Paris${NC} from dread. \r\n" printf "\r\nProvided by your lovely ${BLUE}/u/Paris${NC} from dread. \r\n"
printf "with help from ${BLUE}/u/mr_white${NC} from whitehousemarket.\n" printf "with help from ${BLUE}/u/mr_white${NC} from whitehousemarket.\n"
echo "For the full effects of the DDOS prevention you will need to make sure to setup v3 onionbalance." echo "For the full effects of the DDOS prevention you will need to make sure to setup v3 onionbalance."
echo "Onionbalance v3 does have distinct descriptors in a forked version. Read the README.MD in the onionbalance folder for more information. " echo "Onionbalance v3 does have distinct descriptors in a forked version. Read the README.MD in the onionbalance folder for more information."
if [ ${#MASTERONION} -lt 62 ]; then if [ ${#MASTERONION} -lt 62 ]; then
echo "MASTEWRONION doesn't have the correct length. The url needs to include the .onion at the end." echo "MASTEWRONION doesn't have the correct length. The url needs to include the .onion at the end."
@ -104,6 +105,11 @@ string+="$HEXCOLOR"
string+="/g" string+="/g"
sed -i $string queue.html sed -i $string queue.html
string="s/HEXCOLORDARK/"
string+="$HEXCOLORDARK"
string+="/g"
sed -i $string queue.html
string="s/SITENAME/" string="s/SITENAME/"
string+="$SITENAME" string+="$SITENAME"
string+="/g" string+="/g"

View File

@ -15,7 +15,7 @@ lua_package_path "/etc/nginx/resty/?.lua;;";
init_by_lua_block { init_by_lua_block {
allowed_hosts = { "mainonion", allowed_hosts = { "mainonion",
"dreadytofatroptsdj6io7l3xptbet6onoyno2yv7jicoxknyazubrad.onion" "masterbalanceonion"
} }
function in_array(tab, val) function in_array(tab, val)
@ -77,7 +77,7 @@ init_by_lua_block {
end end
ngx.log(ngx.ERR, "connected to tor") ngx.log(ngx.ERR, "connected to tor")
local bytes, err = sock:send("authenticate \"changethispassowrd\"\n") local bytes, err = sock:send("authenticate \"torauthpassword\"\n")
if not bytes then if not bytes then
ngx.log(ngx.ERR, "failed authenticate to tor: " .. err) ngx.log(ngx.ERR, "failed authenticate to tor: " .. err)
return return
@ -286,12 +286,12 @@ server {
error_log /etc/nginx/naxsi.log; error_log /etc/nginx/naxsi.log;
proxy_set_header Host $host; proxy_set_header Host $host;
socks_pass socks5://tor; socks_pass socks5://tor;
socks_set_host biblemeowimkh3utujmhm6oh2oeb3ubjw2lpgeq3lahrfr2l6ev6zgyd.onion; socks_set_host backendurl;
socks_set_header Host $host; socks_set_header Host $host;
socks_redirect off; socks_redirect off;
socks_http_version 1.1; socks_http_version 1.1;
socks_next_upstream error timeout invalid_header http_500 http_502 http_503; socks_next_upstream error timeout invalid_header http_500 http_502 http_503;
#proxy_pass http://10.10.10.10:80; #proxy_pass http://proxypassurl;
header_filter_by_lua_block { header_filter_by_lua_block {
local cookie, err = cook:new() local cookie, err = cook:new()
@ -328,4 +328,4 @@ server {
end end
} }
} }
} }