1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| package main
import ( "bytes" "crypto/rand" "io" "net/http"
"github.com/gin-gonic/gin" )
type ProxyRequest struct { URL string `json:"url" binding:"required"` Method string `json:"method" binding:"required"` Body string `json:"body"` Headers map[string]string `json:"headers"` FollowRedirects bool `json:"follow_redirects"` }
func main() { key := make([]byte, 64) if _, err := io.ReadFull(rand.Reader, key); err != nil { panic(err.Error()) }
r := gin.Default()
v1 := r.Group("/v1") { v1.POST("/api/flag", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"flag": "hello"}) }) }
v2 := r.Group("/v2") { v2.POST("/api/proxy", func(c *gin.Context) { var proxyRequest ProxyRequest if err := c.ShouldBindJSON(&proxyRequest); err != nil { c.JSON(http.StatusBadRequest, gin.H{"status": "error", "message": "Invalid request"}) return }
client := &http.Client{ CheckRedirect: func(req *http.Request, via []*http.Request) error { if !req.URL.IsAbs() { return http.ErrUseLastResponse }
if !proxyRequest.FollowRedirects { return http.ErrUseLastResponse }
return nil }, }
req, err := http.NewRequest(proxyRequest.Method, proxyRequest.URL, bytes.NewReader([]byte(proxyRequest.Body))) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"}) return }
for key, value := range proxyRequest.Headers { req.Header.Set(key, value) }
resp, err := client.Do(req)
if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"}) return }
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "message": "Internal Server Error"}) return }
if bytes.Contains(body, []byte("flag")) { c.JSON(http.StatusOK, gin.H{"status": "error", "message": "Flag is not allowed in response body"}) return }
for i := 0; i < len(body); i++ { body[i] ^= key[i%len(key)] body[i] += key[(i+1)%len(key)] body[i] -= key[(i+2)%len(key)] body[i] ^= key[(i+3)%len(key)] }
c.JSON(resp.StatusCode, gin.H{"status": "success", "body": body, "headers": resp.Header}) }) }
r.Run("127.0.0.1:8769") }
|