Keywords
- Change ClientIP() value using http header
X-Forwarded-For
Given info
- baby-simple-gocurl.tar.gz was given
└─dist
│ Dockerfile
│ start.sh
│
└─baby-simple-gocurl
│ go.mod
│ go.sum
│ main.go
│
├─static
│ curl.css
│ curl.js
│ jquery.min.js
│
└─view
index.html
- We can find /flag/ service in main.go file
...
r.GET("/flag/", func(c *gin.Context) {
reqIP := strings.Split(c.Request.RemoteAddr, ":")[0]
log.Println("[+] IP : " + reqIP)
if reqIP == "127.0.0.1" {
c.JSON(http.StatusOK, gin.H{
"message": flag,
})
return
}
c.JSON(http.StatusBadRequest, gin.H{
"message": "You are a Guest, This is only for Host",
})
})
...
- But, the /flag/ service check the
c.Request.RemoteAddr
value is same with 127.0.0.1
or not
- We should bypass this IF code
- May be the Header key and Header Value are hints
Flow
- Modify
c.Request.RemoteAddr
value to 127.0.0.1
Get Flag
- try to /flag/, We can not execute it
reqUrl := strings.ToLower(c.Query("url"))
reqHeaderKey := c.Query("header_key")
reqHeaderValue := c.Query("header_value")
reqIP := strings.Split(c.Request.RemoteAddr, ":")[0]
fmt.Println("[+] " + reqUrl + ", " + reqIP + ", " + reqHeaderKey + ", " + reqHeaderValue)
if c.ClientIP() != "127.0.0.1" && (strings.Contains(reqUrl, "flag") || strings.Contains(reqUrl, "curl") || strings.Contains(reqUrl, "%")) {
c.JSON(http.StatusBadRequest, gin.H{"message": "Something wrong"})
return
}
- Following code, we can see that flag, curl, % were filtered
- However, we can check this code
c.ClientIP() != "127.0.0.1" && (strings.Contains(reqUrl, "flag") || strings.Contains(reqUrl, "curl") || strings.Contains(reqUrl, "%"))
- If we make c.ClietIP() == "127.0.0.1", we can bypass this IF code
- We can use http header
X-Forwarded-For
to change the c.ClientIP()
value
- Now, we can write flag in url parameter and GET FLAG