2021SCTF-Loginme


最近也是刚刚放假,比较忙,就看了看这个SCTF

比赛快到尾声的时候才抽出空来看看题

按照惯例,肯定是要看看分最少的题

这道题被我看中了,我打算研究一下这个题

附件是一份源码,而且是go语言的源码

我们来看一看

题中源码给了middleware.go

此时我们应该理解一下go语言的中间件是起到什么作用的

有时候在执行实际Handler里面的逻辑的时候想要预处理或者后处理一些行为(比如写入log、统计执行时间等等);有时候我们想要在调用一个Handler之前或之后调用另一个Handler。这时我们就需要用到中间件这个中间处理函数,把我们实际使用的Handler放在中间件里面,以实现额外的功能。

所以我们先来看看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)
		}
	}
}

这里导入了一个包github.com/gin-gonic/gin

我们来看一下该包的描述

Gin is a web framework written in Go (Golang). It features a martini-like API with performance that is up to 40 times faster thanks to httprouter. If you need performance and good productivity, you will love Gin.
-------------------------------------------------------------------------------
Gin 是一个用 Go (Golang) 编写的 Web 框架。 它具有类似martini-like的 API,由于 httprouter,性能提高了 40 倍。 如果您需要性能和良好的生产力,您会喜欢 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)
		}
	}
}

这里就是简单的获取数据头的函数

其中

if c.GetHeader("x-forwarded-for") != "" || c.GetHeader("x-client-ip") != "" {
			c.AbortWithStatus(403)
			return
}

这里定义到如果存在x-forwarded-for或者x-client-ip就会返回403

但是还需要ip == "127.0.0.1"

百度一下就知道x-real-ip这个头

中间件看完了,接着往下看route.go

这里就能看到端倪了

go语言模板渲染支持传入一个结构体的实例来渲染它的字段,就有可能造成信息泄露

而在route.go中恰巧传入了一个结构体,我们接着看structs.go

到这里已经真相大白了

1、首先构造ip伪造
2、在age变量中存在ssti信息泄露出flag
3、干他!


文章作者: H3h3QAQ
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 H3h3QAQ !
  目录