BUUCTF [第二章 web进阶]SSRF Training

我真的是在认真摸鱼啊 2024-09-30 09:33:01 阅读 67

1.什么是SSRF?

SSRF(Server-Side Request Forgery,服务器端请求伪造) 是一种网络攻击,攻击者通过欺骗服务器,使其向本不该访问的内部或外部资源发出 HTTP 请求。这种攻击允许攻击者间接利用服务器发起请求,绕过防火墙、访问内网系统,甚至读取本地资源。

SSRF 攻击的基本概念:

在 SSRF 攻击中,攻击者并不直接访问目标资源,而是通过服务器充当代理来发起请求。通常,服务器会处理来自客户端的 URL、IP 地址或其他资源的请求,而 SSRF 攻击者则通过修改这些请求参数,使服务器访问攻击者指定的内部或外部资源。

SSRF 攻击的典型场景:

文件上传或下载功能:服务器接受文件的 URL 或者文件路径,然后下载或处理该文件。

URL 或 API 调用:服务器接受来自客户端的 URL 并发起相应的请求,如获取远程 API 数据。

图片加载或资源获取:服务器从 URL 获取图片或其他资源并返回给用户。

SSRF 攻击示例:

内网探测: 通过 SSRF,攻击者可以让服务器访问内网中的敏感资源(如内部管理系统、数据库服务等),这通常是外部攻击者无法直接访问的。

示例:

<code>http://example.com/page?url=http://127.0.0.1/admin

攻击者将 URL 参数修改为内部 IP 地址 127.0.0.1,服务器被欺骗去访问本地的管理页面。

获取敏感信息: 攻击者通过 SSRF 访问内部的 API 或者云服务的元数据服务器,可能获取敏感的配置信息。

示例: 在 AWS(亚马逊云服务)中,元数据服务器通常位于 http://169.254.169.254/latest/meta-data/,可以泄露云主机的关键信息,如临时凭证。

http://example.com/page?url=http://169.254.169.254/latest/meta-data/

跨站请求伪造(CSRF)结合 SSRF: SSRF 还可以与 CSRF 攻击结合使用,攻击者可以利用服务器发起对外部或第三方系统的恶意请求。

SSRF 攻击的影响:

访问内部网络资源:攻击者可以通过服务器访问原本受限的内部网络资源,包括数据库、管理界面等。数据泄露:服务器可能被用于访问内部系统或云基础设施的敏感信息,比如配置信息、数据库内容等。执行恶意操作:通过特定的请求,攻击者可以操控服务器发送请求,从而执行某些恶意操作(例如,修改数据、执行远程代码等)。

SSRF 的常见绕过手段:

攻击者通常会使用一些绕过方法来避免服务器的内网 IP 检查,比如:

使用 DNS 解析绕过:攻击者使用一个恶意的域名,它解析为内网 IP 地址,从而绕过直接的 IP 检查。多次重定向:攻击者让服务器跟随 URL 重定向,从外部 URL 重定向到内网地址,绕过简单的 URL 白名单过滤。伪造 IP 地址:通过伪造不同的 IP 格式(如整数形式的 IP 地址),绕过内网 IP 检查。、

2.解题思路

首先我们来看一下源代码:

<?php

highlight_file(__FILE__);

function check_inner_ip($url)

{

$match_result=preg_match('/^(http|https)?:\/\/.*(\/)?.*$/',$url);

if (!$match_result)

{

die('url fomat error');

}

try

{

$url_parse=parse_url($url);

}

catch(Exception $e)

{

die('url fomat error');

return false;

}

$hostname=$url_parse['host'];

$ip=gethostbyname($hostname);

$int_ip=ip2long($ip);

return ip2long('127.0.0.0')>>24 == $int_ip>>24 || ip2long('10.0.0.0')>>24 == $int_ip>>24 || ip2long('172.16.0.0')>>20 == $int_ip>>20 || ip2long('192.168.0.0')>>16 == $int_ip>>16;

}

function safe_request_url($url)

{

if (check_inner_ip($url))

{

echo $url.' is inner ip';

}

else

{

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_HEADER, 0);

$output = curl_exec($ch);

$result_info = curl_getinfo($ch);

if ($result_info['redirect_url'])

{

safe_request_url($result_info['redirect_url']);

}

curl_close($ch);

var_dump($output);

}

}

$url = $_GET['url'];

if(!empty($url)){

safe_request_url($url);

}

?>

check_inner_ip 通过 url_parse 检测是否为内网 ip 。

如果满足不是内网 ip ,通过 curl 请求 url 返回结果。

根据【Blackhat】SSRF的新纪元:在编程语言中利用URL解析器提供的思路,url_parse 与curl的结果出现了差异:

http://foo@evil.com@google.com/

当 php_url_parse 认为 google.com 为目标的同时,curl 认为 evil.com:80 是目标。

在这里插入图片描述

根据网上的资料,parse_url 和 cURL 是 PHP 中的两个不同功能,用于处理 URL,但它们的用途和处理方式有所不同。下面是它们的主要区别:

parse_url

功能:

parse_url 是一个用于解析 URL 字符串的函数。它将一个完整的 URL 拆分为不同的组成部分,如协议、主机、端口、路径、查询参数等。

使用示例:

<code>$url = "http://www.example.com/path?arg=value#anchor";

$parsed = parse_url($url);

var_dump($parsed);

输出:

array(5) {

["scheme"] => string(4) "http"

["host"] => string(11) "www.example.com"

["path"] => string(5) "/path"

["query"] => string(8) "arg=value"

["fragment"] => string(6) "anchor"

}

目的:

主要用于从 URL 中提取和分析信息。它不会发起任何网络请求。

cURL

功能:

cURL 是一个强大的库,用于发送 HTTP 请求和处理响应。它支持多种协议(HTTP、HTTPS、FTP等)和多种选项(如设置请求头、处理重定向、发送数据等)。

使用示例:

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "http://www.example.com");

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);

curl_close($ch);

echo $response;

目的:

主要用于与外部服务进行网络交互,获取数据或发送请求。它能够处理请求和响应,但不会解析 URL。

主要区别

功能性:

parse_url 主要用于解析和分析 URL,而 cURL 用于实际的网络请求。

返回值:

parse_url 返回一个数组,包含 URL 的各个部分;cURL 返回请求的响应数据或状态。

操作对象:

parse_url 不涉及网络交互;cURL 则是与网络进行通信的工具。

用法场景:

使用 parse_url 来获取 URL 的结构信息,例如提取主机或路径;

使用 cURL 来获取或发送数据,处理 HTTP 请求和响应。

理解了后我们构造payload就容易了:

Payload 1:

http://foo@127.0.0.1:80 @www.baidu.com/flag.php

Payload解析:

在 URL 中使用两个 @ 符号实际上是利用了 URL 的标准格式和解析规则,来达到绕过防护机制的目的。让我们详细分析一下这两个 @ 符号的作用及其在 SSRF 攻击中的角色。

URL 标准格式

根据 URL 规范(RFC 3986),URL 的基本结构如下:

scheme://username:password@host:port/path?query#fragment

其中,username:password@ 是可选的,用来提供访问主机的身份认证信息(即在访问时指定用户名和密码)。常见的例子包括:

http://user:pass@host/path

这里的 user:pass 是用于访问 host 的认证信息。

在这种情况下,@ 符号用于分隔用户认证信息和主机名,解析时只使用 user:pass 作为认证,实际访问的仍然是 host。

第一个 @ 的作用

在构造的 payload http://foo@127.0.0.1:80@www.baidu.com/flag.php 中,第一个 @ 符号的作用是:

把 foo作为访问 127.0.0.1:80 的认证信息。

foo 是用户名,URL 的前半部分看起来像 http://foo@127.0.0.1:80,这意味着向 127.0.0.1 的请求是使用 foo 作为认证用户名。

由于 username:password@ 是标准的 URL 格式,这部分通常不会触发异常。

第二个 @ 的作用

第二个 @ 符号的作用是:

在某些情况下,URL 解析器会忽略第二个 @ 后面的部分,将它作为路径或注释的一部分,而不影响请求的目标主机。

根据 URL 标准,第二个 @ 后面的 www.baidu.com/flag.php 实际上会被解析为请求的路径(即 /flag.php),而不会真正改变主机名。

因此,即使你在 URL 中加入 www.baidu.com,它也不会改变实际请求的主机名,主机仍然是 127.0.0.1。

实际请求结果

URL 解析器会将整个 URL http://foo@127.0.0.1:80@www.baidu.com/flag.php 解析为:

主机:127.0.0.1

端口:80

认证:foo

路径:/flag.php

这样,最终发出的请求仍然是访问本地 127.0.0.1 上的 /flag.php,而不是 www.baidu.com。

为什么能获取到 flag?

通过构造双 @ 符号的 URL,攻击者能够:

误导服务器,使其访问 127.0.0.1 而不是外部的 www.baidu.com。

绕过内网访问限制,因为服务器自身访问 127.0.0.1 时可能不会受到防火墙的限制,直接访问内部的 /flag.php 文件。

如果本地存在 /flag.php 并且没有严格的访问控制,服务器就会返回 flag,成功触发 SSRF 攻击。

总结

第一个 @:用于指定用户名(如 foo)和主机(如 127.0.0.1),符合 URL 规范。

第二个 @:利用 URL 解析机制,欺骗服务器忽略 www.baidu.com 并继续访问指定的主机(即 127.0.0.1),从而绕过外部主机的验证。

这种双 @ 技巧在 SSRF 攻击中非常有效,因为它能够混淆 URL 解析器的工作逻辑,导致服务器错误地访问内部资源。

Payload 2:

http://127.0.0.1/flag.php

在一个典型的 SSRF(Server-Side Request Forgery)攻击中,http://127.0.0.1/flag.php 能够成功获取到 flag 通常是因为以下几个原因:

127.0.0.1 是本地回环地址

127.0.0.1 是本地回环地址,表示访问的是服务器自身。通常情况下,应用程序的某些资源或服务可能只在本地服务器上暴露,并且无法通过外部网络访问。

举例:

某些服务(如数据库、管理面板、或调试接口)会绑定在 127.0.0.1 上,因为它们不希望被暴露到外部网络,认为这些内部服务是安全的,只有本地系统可以访问。

然而,在 SSRF 攻击中,攻击者可以通过服务器发起请求,访问这些本地服务,并获取内部资源。例如:

/flag.php 文件可能在服务器的文件系统上可访问,且只有本地请求能访问到它。

内网资源的暴露

在很多应用中,/flag.php 或类似的敏感资源仅对内网或本地访问开放,不会对外网用户公开。例如:

竞赛环境(CTF)中的 Flag 可能被放置在一个本地可访问的路径中,且这些资源通常不会公开对外。

当服务器发出请求访问 127.0.0.1/flag.php 时,由于请求来自服务器自身,它能够绕过防火墙或权限限制,直接获取到敏感信息。

缺乏对本地请求的限制

一些服务器内部没有对本地请求进行足够的访问控制,因此即使 /flag.php 是敏感文件,只要请求是从本地发出的,服务器可能会直接返回文件内容。例如:

本地的 /flag.php 文件可能通过服务器应用返回敏感的 flag 值,原本是给管理员或内部服务使用的。

攻击者通过 SSRF,可以利用服务器来替他们发送请求访问这些文件,从而获得敏感数据。

服务的信任模型

许多系统内部服务、API 或应用依赖于信任模型,即假设来自本地的请求是可信的。例如:

内部系统可能通过 127.0.0.1 或 localhost 来提供管理功能或调试接口,而这些接口默认不会进行强认证,因为假设只有管理员能从本地访问这些接口。

SSRF 攻击绕过了这种信任模型,使得攻击者可以伪装成本地用户,发起对本地资源的请求。

http://127.0.0.1/flag.php与:http://foo@127.0.0.1:80 @www.baidu.com/flag.php的区别在哪里?

http://127.0.0.1/flag.php 和 http://foo@127.0.0.1:80@www.baidu.com/flag.php 之间的区别主要体现URL 解析方式、使用 @ 符号的目的,以及可能的攻击手法。让我们分别分析两者的不同点:

直接访问本地资源:http://127.0.0.1/flag.php

这个 URL 是标准的访问方式,目标是服务器自身的本地资源(127.0.0.1)上的 /flag.php 文件。

127.0.0.1 是本地回环地址,表示请求直接发往本地主机(服务器本身)。

服务器会解析这个 URL 并向其本地文件 /flag.php 发起请求,若存在该文件并且可访问,服务器会返回文件的内容。

使用场景:这种 URL 通常在 SSRF(Server-Side Request Forgery)攻击中利用,攻击者诱导服务器访问自身的敏感资源(例如 /flag.php)。

利用双 @ 符号混淆解析:http://foo@127.0.0.1:80@www.baidu.com/flag.php

这个 URL 的构造方式是利用了 URL 解析器对 @ 符号的处理方式,试图混淆实际的请求地址。

foo@127.0.0.1:80:这是用户认证信息 (foo) 和目标地址 (127.0.0.1:80) 的一部分。

在 URL 规范中,foo@ 通常表示用户名,用于认证访问服务器。

这个部分会被 URL 解析器解释为要访问 127.0.0.1,同时使用 foo 作为用户名。

第二个 @ 符号后的 www.baidu.com/flag.php:

URL 中的第二个 @ 符号实际上会被 URL 解析器忽略,主要目的是造成混淆。

根据标准 URL 解析,www.baidu.com/flag.php 只会被当作路径的一部分,而不会被当作真正的主机地址。

实际解析的结果:主机仍然是 127.0.0.1,请求的路径为 /flag.php。

使用场景:这个双 @ 技巧常见于某些 SSRF 攻击中,攻击者利用这种 URL 混淆机制绕过应用的安全防护。例如:

某些安全检查可能只针对 URL 中的主机名部分进行过滤,以为目标是 www.baidu.com,却没有意识到服务器实际仍在请求 127.0.0.1。

区别总结

直接访问 vs 混淆:

http://127.0.0.1/flag.php 直接访问本地资源,没有任何混淆,明确表示请求发送到本地的 127.0.0.1。

http://foo@127.0.0.1:80@www.baidu.com/flag.php 利用了 URL 的结构,通过双 @ 符号混淆,意图让应用程序或防火墙误认为目标是 www.baidu.com,但实际请求仍然指向 127.0.0.1。

绕过安全检查:

http://foo@127.0.0.1:80@www.baidu.com/flag.php 中的第二个 @ 符号,通常是用来绕过安全防护机制(如 URL 过滤器)的。例如,某些安全检查可能只对主机名进行过滤,认为 www.baidu.com 是安全的域名,从而绕过了对本地回环地址 127.0.0.1 的阻止。

攻击手段:

http://127.0.0.1/flag.php 是直接的 SSRF 攻击,目标清晰。

http://foo@127.0.0.1:80@www.baidu.com/flag.php 则是在攻击时添加了 URL 混淆,可能用来绕过一些弱的安全机制或应用层过滤,最终仍然对 127.0.0.1 发起请求。

为什么能获取到 Flag?

在这两种情况下,最终目标都是服务器上的本地资源 /flag.php:

在第一个 URL 中,服务器直接向自身发起请求,读取并返回 /flag.php 的内容。

在第二个 URL 中,通过构造双 @,服务器可能会绕过一些防护机制(如针对外网域名的限制),最终仍然向 127.0.0.1 发起请求,成功读取 /flag.php。

两者最终的结果都是让服务器自身访问了 127.0.0.1 的 flag.php 文件,进而泄露了 flag。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。