diff --git a/README.md b/README.md index 586b243..db5d2be 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ This is an SSRF testing sheriff written in Go. It was originally created for the ## Features -- Repsond to any HTTP method (`GET`, `POST`, `PUT`, `DELETE`, etc.) +- Respond to any HTTP method (`GET`, `POST`, `PUT`, `DELETE`, etc.) - Configurable secret token (see [base.example.yaml](config/base.example.yaml)) - Content-specific responses - With secret token in response body @@ -14,10 +14,10 @@ This is an SSRF testing sheriff written in Go. It was originally created for the - HTML - CSV - TXT - - Without token in response body - - GIF - PNG - JPEG + - Without token in response body + - GIF - MP3 - MP4 @@ -63,8 +63,6 @@ Content-Length: 81 - Dynamically generate valid responses with the secret token visible for - GIF - - PNG - - JPEG - MP3 - MP4 - Secrets in HTTP response generated/created/signed per-request, instead of returning a single secret for all requests diff --git a/generators/images.go b/generators/images.go new file mode 100644 index 0000000..55af724 --- /dev/null +++ b/generators/images.go @@ -0,0 +1,32 @@ +package generators + +import ( + "github.com/fogleman/gg" + "github.com/golang/freetype/truetype" + "golang.org/x/image/font/gofont/goregular" +) + +// function that generates JPG and PNG images with the provided text +// and save them into "/templates" directory +func GenerateJPGAndPNG(ssrfToken string) { + const W = 1024 + const H = 768 + + dc := gg.NewContext(W, H) + dc.SetRGB(0, 0, 0) + dc.Clear() + dc.SetRGB(1, 1, 1) + font, err := truetype.Parse(goregular.TTF) + if err != nil { + panic("") + } + face := truetype.NewFace(font, &truetype.Options{ + Size: 14, + }) + dc.SetFontFace(face) + dc.DrawStringAnchored(ssrfToken, W/2, H/2, 0.5, 0.5) + + + dc.SaveJPG("./templates/jpeg.jpg", 80) + dc.SavePNG("./templates/png.png") +} \ No newline at end of file diff --git a/generators/init.go b/generators/init.go new file mode 100644 index 0000000..88697df --- /dev/null +++ b/generators/init.go @@ -0,0 +1,6 @@ +package generators + +// function that run all media files generators with the provided text +func InitMediaGenerators(ssrfToken string) { + GenerateJPGAndPNG(ssrfToken) +} diff --git a/handler/handler.go b/handler/handler.go index a886310..e2ff01e 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -11,6 +11,7 @@ import ( "path/filepath" "github.com/gorilla/mux" + "github.com/teknogeek/ssrf-sheriff/generators" "github.com/teknogeek/ssrf-sheriff/httpserver" "go.uber.org/config" "go.uber.org/fx" @@ -52,6 +53,12 @@ func NewSSRFSheriffRouter( } } +// StartFilesGenerator starts the function which is dynamically generating JPG/PNG formats +// with the secret token rendered in the media +func StartFilesGenerator(cfg config.Provider) { + generators.InitMediaGenerators(cfg.Get("ssrf_token").String()) +} + // StartServer starts the HTTP server func StartServer(server *http.Server, lc fx.Lifecycle) { h := httpserver.NewHandle(server) @@ -82,14 +89,13 @@ func (s *SSRFSheriffRouter) PathHandler(w http.ResponseWriter, r *http.Request) response = fmt.Sprintf(tmpl, s.ssrfToken) case ".txt": response = fmt.Sprintf("token=%s", s.ssrfToken) - - // TODO: dynamically generate these formats with the secret token rendered in the media - case ".gif": - response = readTemplateFile("gif.gif") case ".png": response = readTemplateFile("png.png") case ".jpg", ".jpeg": response = readTemplateFile("jpeg.jpg") + // TODO: dynamically generate these formats with the secret token rendered in the media + case ".gif": + response = readTemplateFile("gif.gif") case ".mp3": response = readTemplateFile("mp3.mp3") case ".mp4": diff --git a/main.go b/main.go index f5303dc..32e7853 100644 --- a/main.go +++ b/main.go @@ -18,6 +18,6 @@ func opts() fx.Option { handler.NewServerRouter, handler.NewHTTPServer, ), - fx.Invoke(handler.StartServer), + fx.Invoke(handler.StartFilesGenerator, handler.StartServer), ) }