package plg_security_scanner

import (
	"bytes"
	"encoding/base64"
	"github.com/gorilla/mux"
	. "github.com/mickael-kerjean/filestash/server/common"
	"io"
	"math/rand"
	"net/http"
	"strings"
)

var (
	gzipBomb      *bytes.Buffer
	billionsOfLol *bytes.Buffer
)

func init() {
	if plugin_enable := Config.Get("features.protection.enable").Schema(func(f *FormElement) *FormElement {
		if f == nil {
			f = &FormElement{}
		}
		f.Default = true
		f.Name = "enable"
		f.Type = "boolean"
		f.Target = []string{}
		f.Description = "Enable/Disable active protection against scanners"
		f.Placeholder = "Default: true"
		return f
	}).Bool(); plugin_enable == false {
		return
	}
	b, err := base64.StdEncoding.DecodeString("[encoded data, 35368 characters]")
	if err != nil {
		return
	}
	gzipBomb = bytes.NewBuffer(b)
	b, err = base64.StdEncoding.DecodeString("PD94bWwgdmVyc2lvbj0iMS4wIj8+CjwhRE9DVFlQRSBsb2x6IFsKIDwhRU5USVRZIGxvbCAibG9sIj4KIDwhRUxFTUVOVCBsb2x6ICgjUENEQVRBKT4KIDwhRU5USVRZIGxvbDEgIiZsb2w7JmxvbDsmbG9sOyZsb2w7JmxvbDsmbG9sOyZsb2w7JmxvbDsmbG9sOyZsb2w7Ij4KIDwhRU5USVRZIGxvbDIgIiZsb2wxOyZsb2wxOyZsb2wxOyZsb2wxOyZsb2wxOyZsb2wxOyZsb2wxOyZsb2wxOyZsb2wxOyZsb2wxOyI+CiA8IUVOVElUWSBsb2wzICImbG9sMjsmbG9sMjsmbG9sMjsmbG9sMjsmbG9sMjsmbG9sMjsmbG9sMjsmbG9sMjsmbG9sMjsmbG9sMjsiPgogPCFFTlRJVFkgbG9sNCAiJmxvbDM7JmxvbDM7JmxvbDM7JmxvbDM7JmxvbDM7JmxvbDM7JmxvbDM7JmxvbDM7JmxvbDM7JmxvbDM7Ij4KIDwhRU5USVRZIGxvbDUgIiZsb2w0OyZsb2w0OyZsb2w0OyZsb2w0OyZsb2w0OyZsb2w0OyZsb2w0OyZsb2w0OyZsb2w0OyZsb2w0OyI+CiA8IUVOVElUWSBsb2w2ICImbG9sNTsmbG9sNTsmbG9sNTsmbG9sNTsmbG9sNTsmbG9sNTsmbG9sNTsmbG9sNTsmbG9sNTsmbG9sNTsiPgogPCFFTlRJVFkgbG9sNyAiJmxvbDY7JmxvbDY7JmxvbDY7JmxvbDY7JmxvbDY7JmxvbDY7JmxvbDY7JmxvbDY7JmxvbDY7JmxvbDY7Ij4KIDwhRU5USVRZIGxvbDggIiZsb2w3OyZsb2w3OyZsb2w3OyZsb2w3OyZsb2w3OyZsb2w3OyZsb2w3OyZsb2w3OyZsb2w3OyZsb2w3OyI+CiA8IUVOVElUWSBsb2w5ICImbG9sODsmbG9sODsmbG9sODsmbG9sODsmbG9sODsmbG9sODsmbG9sODsmbG9sODsmbG9sODsmbG9sODsiPgpdPgo8bG9sej4mbG9sOTs8L2xvbHo+")
	if err != nil {
		return
	}
	billionsOfLol = bytes.NewBuffer(b)

	Hooks.Register.HttpEndpoint(func(r *mux.Router, _ *App) error {
		// DEFAULT
		r.HandleFunc("/index.php", WelcomePackHandle)
		r.PathPrefix("/html/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/public/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/webdav/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/www/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/MAMP/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/xampp/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/web/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/scripts/").Handler(http.HandlerFunc(WelcomePackHandle))

		// CMS
		r.PathPrefix("/blog/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/cms/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/wordpress/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/wp/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/wp-admin/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/wp-content/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.HandleFunc("/wp-config.php", WelcomePackHandle)
		r.HandleFunc("/wp-login.php", WelcomePackHandle)
		r.PathPrefix("/wp1/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/wp2/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/wp3/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/wp4/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/wp5/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/wp6/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/wp7/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/wp8/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/images/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/joomla/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/libraries/joomla/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/administrator/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/components/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/templates/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/includes/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/modules/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/plugins/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.HandleFunc("/drupal/", WelcomePackHandle)
		r.HandleFunc("/Drupal.php", WelcomePackHandle)
		r.PathPrefix("/core/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.HandleFunc("/web.config", WelcomePackHandle)
		r.HandleFunc("/server.php", WelcomePackHandle)
		r.HandleFunc("/composer.json", WelcomePackHandle)
		r.PathPrefix("/cacti/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/thinkphp/").Handler(http.HandlerFunc(WelcomePackHandle))

		// SQL
		r.PathPrefix("/phpmyadmin/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/pma/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/phpMyAdmin/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/mysqladmin/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/sql/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/myadmin/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/mysql/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/db/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/phpmy/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/phppma/").Handler(http.HandlerFunc(WelcomePackHandle))

		// OTHER
		r.HandleFunc("/echo.php", WelcomePackHandle)
		r.HandleFunc("/composer.php", WelcomePackHandle)
		r.HandleFunc("/uploader.php", WelcomePackHandle)
		r.HandleFunc("/shell.php", WelcomePackHandle)
		r.HandleFunc("/freenode-proxy-checker.txt", WelcomePackHandle)
		r.HandleFunc("/cmd.php", WelcomePackHandle)
		r.HandleFunc("/muhstiks.php", WelcomePackHandle)
		r.HandleFunc("/muhstik.php", WelcomePackHandle)
		r.HandleFunc("/jmx-console", WelcomePackHandle)
		r.HandleFunc("/status.php", WelcomePackHandle)
		r.PathPrefix("/TP/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/HNAP1/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/manager/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/program/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/shopdb/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/programs/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/jenkins/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.HandleFunc("/w00tw00t.at.blackhats.romanian.anti-sec:)", WelcomePackHandle)
		r.HandleFunc("/judge.php", WelcomePackHandle)
		r.HandleFunc("/muieblackcat", WelcomePackHandle)
		r.HandleFunc("/.env", WelcomePackHandle)
		r.HandleFunc("/log", WelcomePackHandle)
		r.HandleFunc("/configs", WelcomePackHandle)
		r.HandleFunc("/config", WelcomePackHandle)
		r.HandleFunc("/cfg", WelcomePackHandle)
		r.HandleFunc("/gs", WelcomePackHandle)
		r.HandleFunc("/gsProvision", WelcomePackHandle)
		r.HandleFunc("/overrides", WelcomePackHandle)
		r.HandleFunc("/polycom", WelcomePackHandle)
		r.HandleFunc("/spa.xml", WelcomePackHandle)
		r.HandleFunc("/yealink", WelcomePackHandle)
		r.HandleFunc("/help.php", WelcomePackHandle)
		r.HandleFunc("/java.php", WelcomePackHandle)
		r.HandleFunc("/_query.php", WelcomePackHandle)
		r.HandleFunc("/test.php", WelcomePackHandle)
		r.HandleFunc("/db_cts.php", WelcomePackHandle)
		r.HandleFunc("/db_pma.php", WelcomePackHandle)
		r.HandleFunc("/logon.php", WelcomePackHandle)
		r.HandleFunc("/help-e.php", WelcomePackHandle)
		r.HandleFunc("/license.php", WelcomePackHandle)
		r.HandleFunc("/log.php", WelcomePackHandle)
		r.HandleFunc("/hell.php", WelcomePackHandle)
		r.HandleFunc("/pmd_online.php", WelcomePackHandle)
		r.HandleFunc("/x.php", WelcomePackHandle)
		r.HandleFunc("/htdocs.php", WelcomePackHandle)
		r.HandleFunc("/b.php", WelcomePackHandle)
		r.HandleFunc("/desktop.ini.php", WelcomePackHandle)
		r.HandleFunc("/z.php", WelcomePackHandle)
		r.HandleFunc("/lala.php", WelcomePackHandle)
		r.HandleFunc("/lala-dpr.php", WelcomePackHandle)
		r.HandleFunc("/wpc.php", WelcomePackHandle)
		r.HandleFunc("/wpo.php", WelcomePackHandle)
		r.HandleFunc("/t6nv.php", WelcomePackHandle)
		r.HandleFunc("/text.php", WelcomePackHandle)
		r.HandleFunc("/muhstik2.php", WelcomePackHandle)
		r.HandleFunc("/muhstik-dpr.php", WelcomePackHandle)
		r.HandleFunc("/lol.php", WelcomePackHandle)
		r.HandleFunc("/cmv.php", WelcomePackHandle)
		r.HandleFunc("/cmdd.php", WelcomePackHandle)
		r.HandleFunc("/knal.php", WelcomePackHandle)
		r.HandleFunc("/appserv.php", WelcomePackHandle)
		r.HandleFunc("/d7.php", WelcomePackHandle)
		r.HandleFunc("/rxr.php", WelcomePackHandle)
		r.HandleFunc("/1x.php", WelcomePackHandle)
		r.HandleFunc("/home.php", WelcomePackHandle)
		r.HandleFunc("/undx.php", WelcomePackHandle)
		r.HandleFunc("/spider.php", WelcomePackHandle)
		r.HandleFunc("/payload.php", WelcomePackHandle)
		r.HandleFunc("/composers.php", WelcomePackHandle)
		r.HandleFunc("/izom.php", WelcomePackHandle)
		r.HandleFunc("/hue2.php", WelcomePackHandle)
		r.HandleFunc("/new_license.php", WelcomePackHandle)
		r.HandleFunc("/up.php", WelcomePackHandle)
		r.PathPrefix("/pmd/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/PMA/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/PMA2/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/pmamy/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/pmamy2/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/dbadmin/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/tools/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/phpma/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/php-my-admin/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/websql/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.PathPrefix("/dbadmin/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.HandleFunc("/xmlrpc.php", WelcomePackHandle)
		r.PathPrefix("/user/").Handler(http.HandlerFunc(WelcomePackHandle))
		r.HandleFunc("/vuln.htm", WelcomePackHandle)
		r.HandleFunc("/webconfig.txt.php", WelcomePackHandle)
		return nil
	})
}

func WelcomePackHandle(res http.ResponseWriter, req *http.Request) {
	Log.Info("Attack attempt %s %s %s", req.RemoteAddr, req.URL.String(), req.Header.Get("User-Agent"))
	r := rand.Intn(100)

	if r < 5 {
		res.Header().Set("Content-Length", "1000")
		res.Write([]byte(""))
	} else if r < 10 {
		res.Header().Set("Content-Length", "10000000000000")
		io.Copy(res, billionsOfLol)
	} else if r < 15 {
		res.Header().Set("Content-Encoding", "gzip")
		res.Header().Set("Content-Type", "text/html")
		res.Write([]byte("WAZAAAA"))
	} else if r < 20 {
		res.Header().Set("Content-Encoding", "gzip")
		res.Header().Set("Content-Type", "text/html")
		io.Copy(res, billionsOfLol)
	} else if r < 25 {
		res.Header().Set("Content-Language", "en-US\u000bContent‑Encoding: gzip")
		io.Copy(res, gzipBomb)
	} else if r < 30 {
		res.Header().Set("Content‑Encoding", "gzip")
		io.Copy(res, gzipBomb)
	} else if r < 35 {
		res.Header().Set("Content-Type", "application/json")
		res.Write([]byte(strings.Repeat("[", 10000) + `"WAZAAAAA"` + strings.Repeat("]", 10000)))
	} else if r < 40 {
		res.Header().Set("Content-Type", "application/json")
		res.Write([]byte(`{"response"꞉ "success"}`)) // not an ASCII colon -> not valid json
	} else if r < 45 {
		req.URL.Host = "127.0.0.1"
		if req.URL.Scheme == "" {
			req.URL.Scheme = "http"
		}
		http.Redirect(res, req, req.URL.String(), 301)
	} else if r < 50 {
		req.URL.Host = req.RemoteAddr
		if req.URL.Scheme == "" {
			req.URL.Scheme = "http"
		}
		http.Redirect(res, req, req.URL.String(), 301)
	} else if r < 55 {
		http.Redirect(res, req, "geo:37.786971,-122.399677", 301)
	} else if r < 60 {
		res.Header().Set("Content-Type", "text/html")
		res.Write([]byte(`<html><sript>alert("WAZAAAA");</script></html>`))
	} else if r < 65 {
		res.Header().Set("Content-Type", "text/html")
		res.Write([]byte(`<html><head><script>do { console.log("WAZAAAA"); } while(true);</script></head><body></body></html>`))
	} else if r < 85 { // xml bomb
		// https://en.wikipedia.org/wiki/Billion_laughs_attack
		if rand.Intn(100) < 50 {
			res.Header().Set("Content-Type", "text/xml")
		} else {
			res.Header().Set("Content-Type", "application/xml")
		}
		io.Copy(res, billionsOfLol)
	} else {
		res.Header().Set("Content-Encoding", "gzip")
		res.Header().Set("Content-Type", "text/html")
		io.Copy(res, gzipBomb)
	}
}
