424 lines
12 KiB
Go
424 lines
12 KiB
Go
package main
|
|
|
|
import (
|
|
"compress/gzip"
|
|
"encoding/base64"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/gorilla/websocket"
|
|
)
|
|
|
|
var upgrader = websocket.Upgrader{
|
|
CheckOrigin: func(r *http.Request) bool {
|
|
return true
|
|
},
|
|
}
|
|
|
|
type KeyPress struct {
|
|
Key string `json:"key"`
|
|
}
|
|
|
|
type RateLimiter struct {
|
|
connections map[string]int
|
|
messages map[string]time.Time
|
|
mutex sync.RWMutex
|
|
}
|
|
|
|
var limiter = &RateLimiter{
|
|
connections: make(map[string]int),
|
|
messages: make(map[string]time.Time),
|
|
}
|
|
|
|
var trollingGifBase64 string
|
|
var trollingHTML string
|
|
var trollingHTMLOnce sync.Once
|
|
|
|
var curpingFileBase64 string
|
|
var curpingFileName string
|
|
var curpingFileOnce sync.Once
|
|
|
|
func (rl *RateLimiter) canConnect(ip string) bool {
|
|
rl.mutex.Lock()
|
|
defer rl.mutex.Unlock()
|
|
|
|
if rl.connections[ip] >= 3 {
|
|
return false
|
|
}
|
|
rl.connections[ip]++
|
|
return true
|
|
}
|
|
|
|
func (rl *RateLimiter) canSendMessage(ip string) bool {
|
|
rl.mutex.Lock()
|
|
defer rl.mutex.Unlock()
|
|
|
|
lastMessage, exists := rl.messages[ip]
|
|
if exists && time.Since(lastMessage) < 30*time.Millisecond {
|
|
return false
|
|
}
|
|
rl.messages[ip] = time.Now()
|
|
return true
|
|
}
|
|
|
|
func (rl *RateLimiter) disconnect(ip string) {
|
|
rl.mutex.Lock()
|
|
defer rl.mutex.Unlock()
|
|
|
|
if rl.connections[ip] > 0 {
|
|
rl.connections[ip]--
|
|
}
|
|
}
|
|
|
|
type gzipResponseWriter struct {
|
|
io.Writer
|
|
http.ResponseWriter
|
|
}
|
|
|
|
func (w gzipResponseWriter) Write(b []byte) (int, error) {
|
|
return w.Writer.Write(b)
|
|
}
|
|
|
|
func gzipHandler(next http.HandlerFunc) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
|
|
next(w, r)
|
|
return
|
|
}
|
|
|
|
gz := gzip.NewWriter(w)
|
|
defer gz.Close()
|
|
|
|
w.Header().Set("Content-Encoding", "gzip")
|
|
next(gzipResponseWriter{Writer: gz, ResponseWriter: w}, r)
|
|
}
|
|
}
|
|
|
|
func wsHandler(w http.ResponseWriter, r *http.Request) {
|
|
ip := strings.Split(r.RemoteAddr, ":")[0]
|
|
|
|
if !limiter.canConnect(ip) {
|
|
conn, err := upgrader.Upgrade(w, r, nil)
|
|
if err != nil {
|
|
log.Printf("WebSocket upgrade error: %v", err)
|
|
return
|
|
}
|
|
conn.WriteJSON(map[string]string{"action": "show_message", "message": "You make too many requests, yk..."})
|
|
conn.Close()
|
|
return
|
|
}
|
|
|
|
defer limiter.disconnect(ip)
|
|
|
|
conn, err := upgrader.Upgrade(w, r, nil)
|
|
if err != nil {
|
|
log.Printf("WebSocket upgrade error: %v", err)
|
|
return
|
|
}
|
|
defer conn.Close()
|
|
|
|
var buffer string
|
|
var lastPress time.Time
|
|
|
|
for {
|
|
var keyPress KeyPress
|
|
err := conn.ReadJSON(&keyPress)
|
|
if err != nil {
|
|
break
|
|
}
|
|
|
|
if !limiter.canSendMessage(ip) {
|
|
conn.WriteJSON(map[string]string{"action": "show_message", "message": "You make too many requests, yk..."})
|
|
continue
|
|
}
|
|
|
|
now := time.Now()
|
|
if now.Sub(lastPress) > 5*time.Second {
|
|
buffer = ""
|
|
}
|
|
lastPress = now
|
|
|
|
buffer += keyPress.Key
|
|
|
|
if len(buffer) > 20 {
|
|
buffer = buffer[len(buffer)-20:]
|
|
}
|
|
|
|
if buffer == "lain" {
|
|
conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://fauux.neocities.org"})
|
|
buffer = ""
|
|
} else if buffer == "rabbit" {
|
|
conn.WriteJSON(map[string]string{"action": "show_message", "message": "wake up, Neo"})
|
|
buffer = ""
|
|
} else if buffer == "whoareu" {
|
|
conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://t.me/systemxplore"})
|
|
buffer = ""
|
|
} else if buffer == "whoami" {
|
|
conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://t.me/systemxplore"})
|
|
buffer = ""
|
|
} else if buffer == "whoareyou" {
|
|
conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://t.me/systemxplore"})
|
|
buffer = ""
|
|
} else if buffer == "answer" {
|
|
conn.WriteJSON(map[string]string{"action": "show_message", "message": "it must be easy for you, isn't that right?"})
|
|
buffer = ""
|
|
} else if buffer == "answers" {
|
|
conn.WriteJSON(map[string]string{"action": "show_message", "message": "it must be easy for you, isn't that right?"})
|
|
buffer = ""
|
|
} else if buffer == "noise" {
|
|
conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://noiseprotocol.org/"})
|
|
buffer = ""
|
|
} else if buffer == "openbsd" {
|
|
conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://openbsd.org/"})
|
|
buffer = ""
|
|
} else if buffer == "linux" {
|
|
conn.WriteJSON(map[string]string{"action": "show_message", "message": "Linux sucks"})
|
|
buffer = ""
|
|
} else if buffer == "mac" {
|
|
conn.WriteJSON(map[string]string{"action": "show_message", "message": "Yet another BSD-like OS"})
|
|
buffer = ""
|
|
} else if buffer == "windows" {
|
|
conn.WriteJSON(map[string]string{"action": "show_message", "message": "Windows ALWAYS sucks"})
|
|
buffer = ""
|
|
} else if buffer == "github" {
|
|
conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://codeberg.org/"})
|
|
buffer = ""
|
|
} else if buffer == "status" {
|
|
conn.WriteJSON(map[string]string{"action": "redirect", "url": "/status"})
|
|
buffer = ""
|
|
} else if buffer == "reddit" {
|
|
conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://www.reddit.com/r/openbsd/s/zxEkMj0uaW"})
|
|
buffer = ""
|
|
} else if buffer == "intelme" {
|
|
conn.WriteJSON(map[string]string{"action": "show_message", "message": "Everything must be free, without tracking"})
|
|
buffer = ""
|
|
} else if buffer == "amdpsp" {
|
|
conn.WriteJSON(map[string]string{"action": "show_message", "message": "Everything must be free, without tracking"})
|
|
buffer = ""
|
|
} else if buffer == "uefi" {
|
|
conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://www.techtarget.com/searchsecurity/news/366618102/ESET-details-UEFI-Secure-Boot-bypass-vulnerability"})
|
|
buffer = ""
|
|
} else if buffer == "trolling" {
|
|
conn.WriteJSON(map[string]string{"action": "redirect", "url": "/trolling"})
|
|
buffer = ""
|
|
} else if buffer == "club" {
|
|
conn.WriteJSON(map[string]string{"action": "redirect", "url": "https://t.me/+-eNzwqVM5_U5NDdi"})
|
|
buffer = ""
|
|
} else if buffer == "icmp" {
|
|
conn.WriteJSON(map[string]string{"action": "show_message", "message": "\"Timestamp from icmp data...\" why is there a timestamp in the echo request?"})
|
|
buffer = ""
|
|
} else if buffer == "cursping" {
|
|
conn.WriteJSON(map[string]string{"action": "redirect", "url": "/cursping.zip.tar.gz"})
|
|
buffer = ""
|
|
} else if buffer == "uzbekistan" {
|
|
conn.WriteJSON(map[string]string{"action": "show_message", "message": "\"ping uz\" immediately"})
|
|
buffer = ""
|
|
}
|
|
}
|
|
}
|
|
|
|
func initTrollingHTML() {
|
|
fileContent, err := os.ReadFile("files/trolling.gif")
|
|
if err != nil {
|
|
log.Printf("Error reading file: %v", err)
|
|
fileContent = []byte("File not found")
|
|
}
|
|
|
|
trollingGifBase64 = base64.StdEncoding.EncodeToString(fileContent)
|
|
trollingHTML = fmt.Sprintf(`
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Trolling</title>
|
|
<style>
|
|
body {
|
|
background-color: #000;
|
|
color: #00ff00;
|
|
font-family: 'Courier New', monospace;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
height: 100vh;
|
|
margin: 0;
|
|
}
|
|
img {
|
|
max-width: 100%%;
|
|
max-height: 100%%;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<img src="data:image/gif;base64,%s" alt="мы делаем небольшой троллинг">
|
|
</body>
|
|
</html>`, trollingGifBase64)
|
|
}
|
|
|
|
func initCurpingFile() {
|
|
fileContent, err := os.ReadFile("files/cursping.zip.tar.gz")
|
|
if err != nil {
|
|
log.Printf("Error reading curping file: %v", err)
|
|
fileContent = []byte("File not found")
|
|
}
|
|
|
|
curpingFileBase64 = base64.StdEncoding.EncodeToString(fileContent)
|
|
curpingFileName = "curping"
|
|
}
|
|
|
|
func trollingHandler(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
|
w.Header().Set("Server", "0BSD_FOR_EVERYONE")
|
|
w.Header().Set("Cache-Control", "public, max-age=3600")
|
|
|
|
trollingHTMLOnce.Do(initTrollingHTML)
|
|
fmt.Fprint(w, trollingHTML)
|
|
}
|
|
|
|
func curpingHandler(w http.ResponseWriter, r *http.Request) {
|
|
curpingFileOnce.Do(initCurpingFile)
|
|
|
|
fileData, err := base64.StdEncoding.DecodeString(curpingFileBase64)
|
|
if err != nil {
|
|
http.Error(w, "Error decoding file", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/octet-stream")
|
|
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", curpingFileName))
|
|
w.Header().Set("Server", "0BSD_FOR_EVERYONE")
|
|
w.Header().Set("Cache-Control", "public, max-age=3600")
|
|
|
|
w.Write(fileData)
|
|
}
|
|
|
|
func statusHandler(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
|
w.Header().Set("Server", "0BSD_FOR_EVERYONE")
|
|
|
|
openbsdBirth := time.Date(1995, 10, 1, 0, 0, 0, 0, time.UTC)
|
|
now := time.Now()
|
|
duration := now.Sub(openbsdBirth)
|
|
|
|
years := int(duration.Hours() / 8760)
|
|
months := int((duration.Hours() - float64(years*8760)) / 730)
|
|
weeks := int((duration.Hours() - float64(years*8760) - float64(months*730)) / 168)
|
|
hours := int(duration.Hours() - float64(years*8760) - float64(months*730) - float64(weeks*168))
|
|
minutes := int(duration.Minutes()) % 60
|
|
seconds := int(duration.Seconds()) % 60
|
|
milliseconds := int(duration.Milliseconds()) % 1000
|
|
nanoseconds := int(duration.Nanoseconds()) % 1000000
|
|
|
|
status := fmt.Sprintf("OpenBSD created: %d:%d:%d:%d:%d:%d:%d:%d\nTimestamp: %d",
|
|
years, months, weeks, hours, minutes, seconds, milliseconds, nanoseconds,
|
|
int(duration.Seconds()))
|
|
|
|
fmt.Fprint(w, status)
|
|
}
|
|
|
|
func handler(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
|
w.Header().Set("Server", "0BSD_FOR_EVERYONE")
|
|
w.Header().Set("X-Powered-By", "0BSD_FOR_EVERYONE")
|
|
w.Header().Set("X-Frame-Options", "SAMEORIGIN")
|
|
w.Header().Set("X-Content-Type-Options", "nosniff")
|
|
|
|
html := `
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>0BSD_FOR_EVERYONE</title>
|
|
<style>
|
|
body {
|
|
font-family: 'Courier New', monospace;
|
|
background-color: #000;
|
|
color: #00ff00;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
height: 100vh;
|
|
margin: 0;
|
|
font-size: 3em;
|
|
text-shadow: 0 0 10px #00ff00;
|
|
position: relative;
|
|
}
|
|
#y{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);color:#ff0000;font-size:1.5em;text-shadow:0 0 10px #ff0000;display:none;z-index:1000}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
0BSD_FOR_EVERYONE
|
|
<div id="y"></div>
|
|
|
|
<script>
|
|
(function(){
|
|
var ws=new WebSocket('ws://'+window.location.host+'/ws');
|
|
var buffer='';
|
|
var lastPress=Date.now();
|
|
|
|
ws.onopen=function(){};
|
|
ws.onmessage=function(e){
|
|
var data=JSON.parse(e.data);
|
|
if(data.action==='redirect')window.location.href=data.url;
|
|
if(data.action==='show_message'){
|
|
var msg=document.getElementById('y');
|
|
msg.textContent=data.message;
|
|
msg.style.display='block';
|
|
setTimeout(function(){msg.style.display='none'},3000);
|
|
}
|
|
};
|
|
|
|
document.addEventListener('keydown',function(e){
|
|
var now=Date.now();
|
|
if(now-lastPress>5000)buffer='';
|
|
lastPress=now;
|
|
|
|
buffer+=e.key.toLowerCase();
|
|
if(buffer.length>20)buffer=buffer.slice(-20);
|
|
|
|
ws.send(JSON.stringify({key:e.key.toLowerCase()}));
|
|
});
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>`
|
|
fmt.Fprint(w, html)
|
|
}
|
|
|
|
func main() {
|
|
ports := []string{"1337", "1488", "13373", "33737", "25575", "80", "8080"}
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
for _, port := range ports {
|
|
wg.Add(1)
|
|
go func(p string) {
|
|
defer wg.Done()
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("/", gzipHandler(handler))
|
|
mux.HandleFunc("/ws", wsHandler)
|
|
mux.HandleFunc("/status", gzipHandler(statusHandler))
|
|
mux.HandleFunc("/trolling", gzipHandler(trollingHandler))
|
|
mux.HandleFunc("/cursping.zip.tar.gz", curpingHandler)
|
|
|
|
server := &http.Server{
|
|
Addr: ":" + p,
|
|
Handler: mux,
|
|
ReadTimeout: 30 * time.Second,
|
|
WriteTimeout: 30 * time.Second,
|
|
IdleTimeout: 60 * time.Second,
|
|
}
|
|
|
|
log.Printf("Server started on port %s", p)
|
|
if err := server.ListenAndServe(); err != nil {
|
|
log.Printf("Error on port %s: %v", p, err)
|
|
}
|
|
}(port)
|
|
}
|
|
|
|
wg.Wait()
|
|
}
|