首页 > 其他分享 >[SCTF 2021]loginme go语言ssti漏洞

[SCTF 2021]loginme go语言ssti漏洞

时间:2024-05-25 15:44:55浏览次数:25  
标签:string err SCTF html loginme ssti template go gin

今天做个新颖的题,go中的ssti问题。进来点击访问/admin/index?id=1发现空白,只有admin能看,看看源码main.go。

点击查看代码
package main

import (
	"html/template"
	"loginme/middleware"
	"loginme/route"
	"loginme/templates"

	"github.com/gin-gonic/gin"
)

func main() {
	gin.SetMode(gin.ReleaseMode)
	r := gin.Default()
	templ := template.Must(template.New("").ParseFS(templates.Templates, "*.tmpl"))
	r.SetHTMLTemplate(templ)

	r.Use(gin.Logger())
	r.Use(gin.Recovery())
	authorized := r.Group("/admin")
	authorized.Use(middleware.LocalRequired())
	{
		authorized.GET("/index", route.Login)
	}

	r.GET("/", route.Index)
	r.Run(":9999")
}

authorized.Use(middleware.LocalRequired())用到了middleware,去看看middleware.go。
点击查看代码
package middleware

import (
	"github.com/gin-gonic/gin"
)

func LocalRequired() gin.HandlerFunc {
	return func(c *gin.Context) {
		if c.GetHeader("x-forwarded-for") != "" || c.GetHeader("x-client-ip") != "" {
			c.AbortWithStatus(403)
			return
		}
		ip := c.ClientIP()
		if ip == "127.0.0.1" {
			c.Next()
		} else {
			c.AbortWithStatus(401)
		}
	}
}

意思就是构造头部为127.0.0.1本地访问,不能用那个用x-forwarded-for与x-client-ip,那就一个一个试,发现x-real-ip可使用。

看看其他源码route.go,struct.go

点击查看代码
package route

import (
	_ "embed"
	"fmt"
	"html/template"
	"loginme/structs"
	"loginme/templates"
	"strconv"

	"github.com/gin-gonic/gin"
)

func Index(c *gin.Context) {
	c.HTML(200, "index.tmpl", gin.H{
		"title": "Try Loginme",
	})
}

func Login(c *gin.Context) {
	idString, flag := c.GetQuery("id")
	if !flag {
		idString = "1"
	}
	id, err := strconv.Atoi(idString)
	if err != nil {
		id = 1
	}
	TargetUser := structs.Admin
	for _, user := range structs.Users {
		if user.Id == id {
			TargetUser = user
		}
	}

	age := TargetUser.Age
	if age == "" {
		age, flag = c.GetQuery("age")
		if !flag {
			age = "forever 18 (Tell me the age)"
		}
	}

	if err != nil {
		c.AbortWithError(500, err)
	}

	html := fmt.Sprintf(templates.AdminIndexTemplateHtml, age)
	if err != nil {
		c.AbortWithError(500, err)
	}

	tmpl, err := template.New("admin_index").Parse(html)
	if err != nil {
		c.AbortWithError(500, err)
	}

	tmpl.Execute(c.Writer, TargetUser)
}



package structs

type UserInfo struct {
	Id       int
	Username string
	Age      string
	Password string
}

var Users = []UserInfo{
	{
		Id:       1,
		Username: "Grandpa Lu",
		Age:      "22",
		Password: "hack you!",
	},
	{
		Id:       2,
		Username: "Longlone",
		Age:      "??",
		Password: "i don't know",
	},
	{
		Id:       3,
		Username: "Teacher Ma",
		Age:      "20",
		Password: "guess",
	},
}

var Admin = UserInfo{
	Id:       0,
	Username: "Admin",
	Age:      "",
	Password: "flag{}",
}


这里涉及到了go ssti的一些知识,看一个例子:
点击查看代码
package main

import (
    "net/http"
    "text/template"
)

type User struct {
    ID       int
    Name     string
    Email    string
    Password string
}

func StringTpl2Exam(w http.ResponseWriter, r *http.Request) {
    user := &User{1,"John", "[email protected]", "test123"}
    r.ParseForm()
    tpl := `<h1>Hi, {{ .Name }}</h1><br>Your Email is {{ .Email }}`
    data := map[string]string{
        "Name":  user.Name,
        "Email": user.Email,
    }
    html := template.Must(template.New("login").Parse(tpl))
    html.Execute(w, data)
}

func main() {
    server := http.Server{
        Addr: "127.0.0.1:8888",
    }
    http.HandleFunc("/string", StringTpl2Exam)
    server.ListenAndServe()
}

模板内容 <h1>Hi, {{ .Name }}</h1><br>Your Email is {{ .Email }}
期待输出 <h1>Hi, John</h1><br>Your Email is [email protected]
go的模版渲染使用的是{{}},可以看到当传入参数可控时,就会经过动态内容生成不同的内容。 Go 提供了两个模板包。一个是 text/template,另一个是html/template。text/template对 XSS 或任何类型的 HTML 编码都没有保护,因此该模板并不适合构建 Web 应用程序,而html/template与text/template基本相同,但增加了HTML编码等安全保护,更加适用于构建web应用程序。但是两个包都能够构造正常的payload来进行ssti,只是在heml/template中传入的script和js都会被转义,很好地防范了xss,但text/template也提供了内置函数html来转义特殊字符,除此之外还有js,也存在template.HTMLEscapeString等转义函数。 列出几个常用的ssti payload:
点击查看代码
{{.}} 表示当前对象,如user对象

{{.FieldName}} 表示对象的某个字段 如{{.Name}}user对象的Name字段

{{range …}}{{end}} go中for…range语法类似,循环

{{with …}}{{end}} 当前对象的值,上下文

{{if …}}{{else}}{{end}} go中的if-else语法类似,条件选择

{{xxx | xxx}} 左边的输出作为右边的输入

{{template "navbar"}} 引入子模版
知道相关知识后看这道题,在结构体中表明了admin的Password字段是flag,那么将其输出即可。

总结:

  1. go语言中的ssti
  2. text/template与html/template

标签:string,err,SCTF,html,loginme,ssti,template,go,gin
From: https://www.cnblogs.com/jocker-love-you/p/18212499

相关文章

  • CMake Professtional-2 Variables
    set(varNamevalue...[PARENT_SCOPE])cmake中所有的值都是string,如果同时添加多个值,会自动添加;set(myVarabc)#myVar="a;b;c"set(myVara;b;c)#myVar="a;b;c"set(myVar"abc")#myVar="abc"set(myVarab;c)#myVar=&q......
  • CMake Professtional-1 Introduction
    thestageofcmakeGeneratingProjectFileschooseaprojectgenerator:Ninja,UnixMakefiles,MSYSMakefilesmkdirbuildcdbuildcmake-G"UnixMakefiles"../source#use--helpcandisplaythevariablecmake-G-hbuildingtoolcmake--bui......
  • NSSCTF Round#23 Misc个人专项赛
    画师flag为有意义单词flag<mxfilehost="app.diagrams.net"modified="2024-04-22T09:08:59.622Z"agent="Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/124.0.0.0Safari/537.36Edg/124.0.0.0"......
  • NSSCTF round#22逆向
    NSSCTFround#22逆向1.wp要及时写不然忘光光2.赛题分文件夹放ezcrypt下载下来是python打包的exe,解包出pyc用pycdc反编译看一下嗯不认识BEFORE_WITH命令。丢到gpt4o里看看还蛮准确的,和作者提供的源码一样。不过对填充的处理不对,原程序是填充'\x00'。不过比自己硬看好太多......
  • 【 攻防实操系列+漏洞复现 】-- Jinja2 SSTI模板注入
    框架:python---Flask描述:Flask是一个使用Python编写的轻量级Web应用框架。其WSGI工具箱采用Werkzeug,模板引擎则使用Jinja2漏洞复现:Jinja2SSTI模板注入使用vulhub靶场,启动环境先进入容器看一下web服务的代码,得出参数值为name,且可控判断是否存在ssti漏洞,输入:?name={{1*9}},......
  • dasctf2024 week1复现
    复现题目.web1234开局源码泄露www.zipindex.php<?phperror_reporting(0);include"class.php";$Config=unserialize(file_get_contents("/tmp/Config"));foreach($_POSTas$key=>$value){if(!is_array($value)){$param[$key]=ad......
  • NSSCTF流量分析
    1.[BSidesSF-CTF2019]Zippync-l-p4445>flag.zipunzip-Psupercomplexpasswordflag.zipArchive:flag.zipinflating:flag.txtPK.... ...NdbN..,.%...........flag.txtUT ....z\..z\ux...............(.y..z....F.......:...#Bz..:......
  • DASCTFxGFCTF ezvm&unwind&prese
    ezvm输入第一串字符串,生成新的check.dll,然后用新的check.dll的check函数来验证flag。这个vm的流程大概是:#include<stdio.h>intmain(){ staticintstack[]={162,0,132,163,8,0,163,8,1,176,8,316,178,163,9,1,163,9,2,163,9,3,176,9,158,178,......
  • [2022DASCTF Apr X FATE 防疫挑战赛] warmup-java
    没错,还是java。我就跟java杠上了。分析先看依赖:没有啥特别的。审一下源码:IndexController.java:warmup路由下传参data,下面把十六进制转为字节直接反序列化了。看下动态代理MyInvocationHandler.java:看一下Utils的hexStringToBytes方法: 下面分析来自Java专题-简......
  • SSTI.
    SSTI晚上学长讲了ssti我好像要长脑子了..源于一道ssti的签到题sstissti:服务器端模板注入漏洞{为什么利用{{}}来执行ssti语句a=''.__class__.__base__.__subclasses__()‘’一个实例例如print('i')//打印字符串__class__类的内置属性,返回该实例的类型__base__......