package main import ( "crypto/sha1" _ "embed" "encoding/json" "fmt" "log" "math/rand" "net/http" "os" "time" ) //go:embed main.go var source []byte //go:embed Dockerfile var docker []byte var password string var passwordLength = 32 var passwordNumber = 0 var hashes = make(map[string]string) var letters = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") var keyPattern = "%d-%d-%d" type charactersResponse struct { Indices []int `json:"indices"` Hash string `json:"hash"` Number int `json:"number"` } func randStringBytes(n int) string { b := make([]byte, n) for i := range b { b[i] = letters[rand.Intn(len(letters))] } return string(b) } func updatePassword() { password = randStringBytes(passwordLength) log.Printf("Password is %s", password) tempHashes := make(map[string]string) for i := 0; i < passwordLength; i++ { for j := 0; j < passwordLength; j++ { for k := 0; k < passwordLength; k++ { key := fmt.Sprintf(keyPattern, i, j, k) hash := fmt.Sprintf("%x", sha1.Sum([]byte{password[i], password[j], password[k]})) tempHashes[key] = hash } } } hashes = tempHashes passwordNumber += 1 } func indexHandler(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "index.html") } func sourceHandler(w http.ResponseWriter, r *http.Request) { w.Write(source) } func dockerHandler(w http.ResponseWriter, r *http.Request) { w.Write(docker) } func passwordHandler(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("Failed to parse request")) return } if !r.Form.Has("password") { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("No password submitted")) return } if r.Form.Get("password") == password { fmt.Fprintf(w, "Flag: %s", os.Getenv("FLAG")) return } w.WriteHeader(http.StatusForbidden) w.Write([]byte("Incorrect password")) } func charactersHandler(w http.ResponseWriter, r *http.Request) { indicies := []int{rand.Intn(passwordLength), rand.Intn(passwordLength), rand.Intn(passwordLength)} hash := hashes[fmt.Sprintf(keyPattern, indicies[0], indicies[1], indicies[2])] w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(&charactersResponse{Indices: indicies, Hash: hash, Number: passwordNumber}) } func main() { updatePassword() http.HandleFunc("/", indexHandler) http.HandleFunc("/source", sourceHandler) http.HandleFunc("/docker", dockerHandler) http.HandleFunc("/password", passwordHandler) http.HandleFunc("/characters", charactersHandler) reset, _ := time.ParseDuration(os.Getenv("RESET_TIME")) ticker := time.NewTicker(reset) go func() { for range ticker.C { updatePassword() } }() log.Fatal(http.ListenAndServe(":8080", nil)) }