40 lines
1.6 KiB
PHP
40 lines
1.6 KiB
PHP
<?php
|
|
// SSRF — fetches an arbitrary url, reflects body to the user.
|
|
// For 169.254.169.254 we serve a canned AWS metadata response so the
|
|
// template detection can fire without needing real cloud infra.
|
|
$url = $_GET['url'] ?? $_GET['u'] ?? $_GET['src'] ?? '';
|
|
|
|
header("Content-Type: text/plain; charset=utf-8");
|
|
|
|
if ($url === '') {
|
|
echo "usage: /fetch.php?url=https://example.com\n";
|
|
exit;
|
|
}
|
|
|
|
// simulate AWS metadata service
|
|
if (stripos($url, '169.254.169.254') !== false || stripos($url, 'metadata.google.internal') !== false) {
|
|
if (stripos($url, 'meta-data/') !== false) {
|
|
echo "ami-id\nami-launch-index\nami-manifest-path\nhostname\ninstance-id\ninstance-type\nlocal-hostname\nlocal-ipv4\nplacement/\npublic-hostname\npublic-ipv4\nsecurity-credentials/\n";
|
|
exit;
|
|
}
|
|
if (stripos($url, 'computeMetadata') !== false || stripos($url, 'project-id') !== false) {
|
|
echo "computeMetadata/v1/\nproject-id: newploit-dev-42\n";
|
|
exit;
|
|
}
|
|
echo "ami-id: ami-0abcdef1234567890\ninstance-id: i-0deadbeefcafe1234\ninstance-type: t3.micro\n";
|
|
echo "security-credentials:\n AccessKeyId: AKIAIOSFODNN7EXAMPLE\n SecretAccessKey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\n";
|
|
exit;
|
|
}
|
|
|
|
// real fetch (no protocol restrictions, no host allowlist)
|
|
$ctx = stream_context_create([
|
|
'http' => ['timeout' => 6, 'ignore_errors' => true, 'follow_location' => 1],
|
|
'ssl' => ['verify_peer' => false, 'verify_peer_name' => false],
|
|
]);
|
|
$body = @file_get_contents($url, false, $ctx);
|
|
if ($body === false) {
|
|
echo "fetch failed: $url\n";
|
|
exit;
|
|
}
|
|
echo substr($body, 0, 65536);
|