Tuesday, April 27, 2021

S4CTF "file-upload": Poison All Things (OR Nginx Cache Poisoning)


 

So, the website is dependent on nginx, node.js with express.

Example of "/report" endpoint

One can observe the following endpoints:

  1. /login - GET

    1. In-Short: You type username - and server generates JwT token for you.

      1. Server will also save your current username connected with your

         cookie aka JwT token.

      2. If we type - “admin” as the username - the server will do 

        nothing and login fails.

    2. Ideas:

      1. Vuln in JwT token generation? - would we will be able to

         generate our own tokens? Somehow? Does it vulnerable?

      2. Vuln in json GET args validation? If we give a JSON in the GET 

        arguments instead of string - as the username - can we generate a token for 

        admin somehow? Maybe kinda due to some inconsistency? 

        Seems not because validating the type as a string.

        1. But it’s seems like its worth noting this scenario 

          where we give weird types in the arguments

          instead of wanted kinda real one.

  2. /upload - POST

    1. In-Short: Upload files to the server side.

    2. Ideas:

      1. HTML Uploading? Upload HTML file and give the link to the admin of course :)

        1. Not working as Content-Type is constant, 

          inside the “/files/” endpoint, they always return “Content-Type” 

          which is one of “.jpg”/”.js”/”.txt”/.. And not “.html”

      2. Upload file and override others? like traversal upload 

        and override some other kinda server files maybe?

        1. Nope - filename is generated by md5’ing 

          of some timestamp and the given filename as well.

  3. /report - GET

    1. In-Short: report links to admin OR show links if you’re the admin. 

      1. For the admin user - it returns list of URL’s for the admin to look over.

      2. For normal user - it returns an endpoint to upload a link 

        for the admin to review.

    2. Ideas:

      1. XSS in URL string? aka put /report " onclick=javascript:something 

         - well it doesn’t works and seems like kinda filtered.

      2. “javascript:” scheme inside reporting URL? starting point -

        yep this can kinda work - didn’t tried that though - as it seem like :)


Path-Traversal Vulnerability:

  • Inside “/files” endpoint - we can get other server files which are accessible.

  • This endpoint calls - “sendFile” function - which can be given “relative-path”.

  • They don’t santize our variables - “file”/”user” or token - so cool cool.

  • They only check that it ends with valid mime type - aka “.jpg” / “.js”

  • Because how the express.js works, 

    we can inject url-encoded strings inside the path after “/files/:file…”

  • We can end it with some 

    • Payload example:

       “/files/%2f..%2f..%2f..%2fa.html/user/token.jpg”


Nginx Configuration:

The nginx caching mechanism added, seemed like the most interesting one in here:

  1. What? They added caching for “.jpg” URL’s…

  2. How? Inside nginx configuration - directive of 

    1. location  ~* ^.(jp[e]g|png)$ { /* ADD_RETURNED_FILE_TO_CACHE } 


They used cache key as “$request_method$request_uri” variable.

So… Ideas? Can we inject into cache something secret… and then maybe kinda read it??


Where is The Flag?:

  • In-Short: shown in "/report" for the admin username only (after JwT validation).

  • So, if we have admin Cookie / JwT token somehow - we will win absolutely!!!

  • Hmmm... And what about the Nginx cache? Yes yes, If we can make the admin

     click /report and the server will cache it we are winning!

  • As node.js express endpoint works whenever the starting substring matches - 

    we can win using the following payload:

    Payload link example: /report/a.jpg


The Full-Attack:

  • Send admin a link to report page & 

    make it seems like jpg so it will be cached by nginx.

    • /report/a.jpg seemed to work

  • Query this page as another user - as nginx already cached this html page before -

    we get the previously shown /report HTML file that have been shown to the admin!!!

     

    Cached flag response :)





No comments:

Hitcon 2021' CTF - Vulpixelize

Vulpixelize Writeup In this challenge – we are given docker webserver with the following files: 1.       Dockerfile 2.       Simple Flask we...