Juggling Facts
Target Information
- IP:
139.59.167.169:32273
Exploitation
-
This problem came with
nginx.conf
andfpm.conf
files, whereas the other problems did not. Inspecting these files did not yield any actionable intelligence.My guess is that they were simply included to make the whole Docker image work together, as PHP requires specific configurations to work with
nginx
. -
Navigating to the "Secret Facts" tab tells us "Secrets can only be accessed by admin"
The request to
/api/getfacts
with the payload{"type": "secrets"}
returns the following response:{"message":"Currently this type can be only accessed through localhost!"}
Of note, this endpoint only supports
POST
requests. -
M@k3l@R!d3s$
is in the Entrypoint as the root user's password, so we can try logging in remotely to directly access the database:$ mysql -u root -p'M@k3l@R!d3s$' -h 139.59.167.169 -P 32273 mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 2
This did not work, it hung on the warning message for a while before returning the error. Trying with
-D -D web_juggling_facts
for the specific database did not work either. This is probably because we are trying to access the database outside oflocalhost
, so the same issue as the API endpoint.The
--skip-name-resolve
is set, but thelocalhost
limitation is still enforced, so that doesn't get us anywhere. -
The
getfacts($router)
function inIndexController.php
can return the flag if the$_SERVER['REMOTE_ADDR']
is127.0.0.1
, so we need to trick the server into making an internal request to itself.I did some digging to see if I could spoof my IP address as localhost instead of sending a request from within the server, but the closest I could find is with the
X-Forwarded-For
header, which is not checked in this case. Any other method would result in me not getting the response data.We know now that the vulnerability is either some form of SQL injection or sending an internal request somehow. The SQL calls are made in
FactModel.php
, there doesn't appear to be any way to inject anything due to the nature of how theget_facts($facts_type)
function is called, leading me to believe that sending an internal request is the only viable avenue of approach. -
There is a function
getRouteParameters($route)
with no discernable reason for existing, so that may be open to exploitation.I tried
http://139.59.167.169:32273/?type=secrets
, but as expected, no dice.REMOTE_ADDR=127.0.0.1
didn't do anything either, but this is just grasping at straws.