当前位置: 首页 > news >正文

ctfshow靶场SSRF部分——基础绕过到协议攻击解题思路与技巧(一)

本文以ctfshow靶场SSRF专栏为例,探讨PHP环境下基于cURL组件引发的请求伪造漏洞。内容重点分析正则表达式过滤缺陷、数字黑名单绕过、DNS重绑定(DNS Rebinding)技术原理,以及利用IP缩写突破主机名长度限制的底层逻辑。

文章目录

    • SSRF介绍
    • Web351
      • 解题思路
    • Web352
      • 解题思路
    • Web353
      • 解题思路
    • Web354
      • 解题思路
      • 方法三:DNSlog平台绑定127.0.0.1
    • Web355
      • 绕过思路
    • 总结

SSRF介绍

什么是 SSRF
SSRF(Server-Side Request Forgery,服务端请求伪造)是一种由攻击者构造指令,并最终由服务端发起请求的安全漏洞;其核心本质是攻击者利用存在安全缺陷的 Web 应用程序作为跳板或代理,去访问和攻击那些原本对外部网络不可见、攻击者自身无法直接触及的内部网络或本地系统。

原理与作用
它的作用机制在于信任的滥用:当目标 Web 服务提供了从其他服务器获取数据的功能(例如图片远程拉取、网页翻译、Webhook 集成),却未能对用户传入的目标 URL 及其协议进行严格的校验与过滤时,攻击者便可以随意篡改这个 URL,迫使服务端乖乖“听令”,代替攻击者向指定的任意地址发起网络请求。

攻击用途
在实战场景中,攻击者主要将其用作突破边界防御的内网渗透利器,具体用途包括对受保护的内网进行大规模的资产探活与端口扫描、利用伪协议读取目标服务器本地的敏感配置文件(如密码本、数据库连接信息),以及对内网中缺乏身份验证的脆弱服务(如 Redis、MySQL、未授权的 API)发送恶意数据包。


Web351

SSRF开始啦
这里我们打开页面,得到如下结果:


内容如下:

<?phperror_reporting(0);highlight_file(__FILE__);$url=$_POST['url'];$ch=curl_init($url);curl_setopt($ch,CURLOPT_HEADER,0);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);$result=curl_exec($ch);curl_close($ch);echo($result);?

代码解释:

  • 接收输入:$url = $_POST['url']获取用户POST提交的URL参数
  • 漏洞核心:curl_init($url)直接将用户可控URL传入cURL发起请求
  • 执行请求:curl_exec($ch)发送网络请求并获取目标响应

这是一道经典的SSRF (Server-Side Request Forgery,服务端请求伪造) 题目:

常见的SSRF渗透思路通常有以下几步:

  1. 读取本地文件:利用file://协议,直接读取系统配置文件(如/etc/passwd)或目录下的 Flag。
  2. 探测内网资产:借助http://扫描内网存活主机与开放端口(如 6379, 3306),寻找未授权访问目标。
  3. 深度打击内网 (RCE):使用万金油协议gopher://dict://,构造恶意数据流攻击内网的 Redis、MySQL 等组件,获取服务器权限。
  4. 获取后端源码:结合php://filter伪协议,将目标代码(如flag.php)Base64 编码后读出,绕过 PHP 解析引擎。
  5. 云环境窃密(特殊场景):若目标位于公有云,尝试请求http://169.254.169.254窃取云实例的元数据及控制台密钥。

解题思路

根据上述,我们尝试读取一下本地文件file://

url=file:///etc/passwd

得到结果:

随后尝试一下读取flag文件

有时候题目会限制外部网络访问,但允许本地访问(Bypass Localhost Restrictions)。有些 flag 可能藏在只有 127.0.0.1 才能访问的页面里。

  • 尝试本地回环访问:url=http://127.0.0.1/flag.phpurl=http://localhost/flag.php
  • 绕过127.0.0.1过滤(如果被禁了): 可以尝试 url=http://0/、url=http://127.0.0.1.xip.io/、或者转换成十进制/十六进制 IP,例如 url=http://2130706433/

这里比较幸运,通过本地回环得到了flag:

url=http://127.0.0.1/flag.php

成功得到flag:

Web352

来到下一题,还是首先观察一下题目:

<?phperror_reporting(0);highlight_file(__FILE__);$url=$_POST['url'];$x=parse_url($url);if($x['scheme']==='http'||$x['scheme']==='https'){if(!preg_match('/localhost|127.0.0/')){$ch=curl_init($url);curl_setopt($ch,CURLOPT_HEADER,0);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);$result=curl_exec($ch);curl_close($ch);echo($result);}else{die('hacker');}}else{die('hacker');}?>hacker

代码解释:

  1. 协议限制::
    if($x['scheme'] === 'http' || $x['scheme']==='https')检查 URL 必须以 http:// 或 https:// 开头。这是为了防止攻击者使用 file://(读取本地文件)或 dict:// 等其他危险协议。

  2. 黑名单过滤失效(语法错误)
    if(!preg_match('/localhost|127.0.0/'))这一行中,preg_match函数漏写了第二个参数(应该写成preg_match('...', $url))。这导致该函数执行失败返回false,再经过!取反后永远为true,使得针对localhost和内网 IP 的拦截完全失效。

  3. 任意请求执行
    防御失效后,代码直接通过curl_exec($url)去请求用户完全可控的 URL,并输出结果。

漏洞后果:攻击者可以传入[http://127.0.0.1](http://127.0.0.1)或其他内网地址,利用这台服务器作为跳板,直接读取和探测它的本地或内网敏感服务。

解题思路

既然由于代码本身的逻辑,导致if(!preg_match(‘/localhost|127.0.0/’))限制失败,所以我们还是可以用上一关的相同payload:

url=http://127.0.0.1/flag.php

成功拿到flag;

Web353

我们打开新一关,发现代码发生了变化:

<?phperror_reporting(0);highlight_file(__FILE__);$url=$_POST['url'];$x=parse_url($url);if($x['scheme']==='http'||$x['scheme']==='https'){if(!preg_match('/localhost|127\.0\.|\。/i',$url)){$ch=curl_init($url);curl_setopt($ch,CURLOPT_HEADER,0);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);$result=curl_exec($ch);curl_close($ch);echo($result);}else{die('hacker');}}else{die('hacker');}?>hacker

代码解释:

虽然这次preg_match('/localhost|127\.0\.|\。/i', $url)语法写对了,但仅拦截了localhost127.0.句号。,这种基于表面字符串的防御非常脆弱。

解题思路

我们只需换种写法,不触发这些关键字,依然能让服务器请求本地或内网:

  1. IP 进制转换:将127.0.0.1转换为十进制形式(如http://2130706433)或十六进制形式(如http://0x7f000001)。
  2. 缺省 IP 写法:在很多系统上,使用http://0.0.0.0甚至直接简写为http://0都能直接访问本地服务。
  3. 域名解析(DNS 欺骗):攻击者可以用一个指向127.0.0.1的公网域名(例如http://localtest.me或攻击者自己配置的域名),直接绕过所有 IP 字符限制。
# payloadurl=http://2130706433/flag.phpurl=http://0x7f000001/flag.phpurl=http://0.0.0.0/flag.php

使用以上payload都可以得到flag:

Web354

同理,我们还是先看代码:

<?phperror_reporting(0);highlight_file(__FILE__);$url=$_POST['url'];$x=parse_url($url);if($x['scheme']==='http'||$x['scheme']==='https'){if(!preg_match('/localhost|1|0|。/i',$url)){$ch=curl_init($url);curl_setopt($ch,CURLOPT_HEADER,0);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);$result=curl_exec($ch);curl_close($ch);echo($result);}else{die('hacker');}}else{die('hacker');}?>hacker

与上一关相比,唯一的区别在于黑名单正则表达式变得极其严格

  • 上一关过滤规则'/localhost|127\.0\.|\。/i'(主要防普通的 127.0 开头的 IP)
  • 本关过滤规则'/localhost|1|0|。/i'(直接拉黑了数字10

区别与脆弱性影响
直接过滤掉10,使得上一关常用的 IP 变形手法(如127.10.0.0.0、十进制2130706433、十六进制0x7f000001等)全部失效

解题思路

依然存在 SSRF 漏洞,因为拦截的只是字符串表面。攻击者可以注册一个完全不包含数字 1 和 0 的域名(例如[http://my-domain.net](http://my-domain.net)),并在自己的 DNS 服务器上将该域名解析到127.0.0.1,即可完美绕过这层过滤。

方法一:将域名A类指向127.0.0.1 http(s)://sudo.cc/指向127.0.0.1url=http://sudo.cc/flag.php 方法二:<?php header("Location: http://127.0.0.1/flag.php");# POST: url=http://your-domain/ssrf.php

方法三:DNSlog平台绑定127.0.0.1

这里我们也可以自己去找个DNSlog平台(注意域名里不能有1):

随后绑定DNS为:127.0.0.1,当你需要让域名解析到你刚才绑定的 127.0.0.1 时,需要在你的专属标识符(Identifier)前加上r.

url=http://r.xxx.ceye.io/flag.php

成功返回结果:

成功拿到结果;

Web355

我们还是先看代码:

<?phperror_reporting(0);highlight_file(__FILE__);$url=$_POST['url'];$x=parse_url($url);if($x['scheme']==='http'||$x['scheme']==='https'){$host=$x['host'];if((strlen($host)<=5)){$ch=curl_init($url);curl_setopt($ch,CURLOPT_HEADER,0);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);$result=curl_exec($ch);curl_close($ch);echo($result);}else{die('hacker');}}else{die('hacker');}?>hacker

与上一关相比,最大的区别在于防御机制由“关键字黑名单”变成了“主机名长度限制”

  • 上一关:通过正则过滤字符(不能有 1、0 等),你用自定义的 CEYE 域名绕过了。
  • 本关(区别):去掉了正则过滤,改为提取 URL 中的host(主机名/IP部分),并严格限制它的长度必须小于或等于 5(strlen($host) <= 5)。

区别与脆弱性影响
由于长度被限制在 5 以内,你上一关用的 CEYE 域名(如r.gojo4j.ceye.io,长度为 16)在这里就行不通了,会被直接拦截。

绕过思路

但漏洞依然存在,因为攻击者可以使用极其简短的IP 缩写形式来绕过长度限制访问本地服务,例如:

  1. http://127.1127.1长度刚好是 5,在网络请求中会自动补全等效于127.0.0.1)。
  2. http://00长度只有 1,在多数 Linux 服务器环境下,http://0会直接解析为访问本地127.0.0.10.0.0.0)。

这里我们直接执行payload:

url=http://127.1/flag.phpurl=http://0/flag.php

成功得到结果:

总结

本文以ctfshow靶场SSRF专栏为例,探讨PHP环境下基于cURL组件引发的请求伪造漏洞。内容重点分析正则表达式过滤缺陷、数字黑名单绕过、DNS重绑定(DNS Rebinding)技术原理,以及利用IP缩写突破主机名长度限制的底层逻辑。

期待下次再见;

http://www.jsqmd.com/news/810541/

相关文章:

  • 极域电子教室终极破解指南:如何简单快速解除课堂控制限制
  • 百度网盘SVIP破解终极指南:3步解锁macOS极速下载体验
  • 2026年高性价比插座品牌推荐与选购参考 - 品牌排行榜
  • 2026年正规实名认证脱单App行业选型指南:核心标准与主流平台分析 - 产业观察网
  • yolo瑞芯微rk4588部署 YOLOv8分割模型转换rknn工具使用指南(ONNX-_RKNN)
  • 对话一多就失忆?用LangGraph打造有状态Agent,状态持久化与人机协作全搞定
  • SMUDebugTool:AMD Ryzen处理器底层调试工具的技术实现与应用
  • 2026年财报投研分析助手哪个好?五大金融AI工具深度横评 - 品牌种草官
  • 2026年接口测试工具对比评测与选型指南
  • 深入探讨Node.js中的Buffer池机制
  • 136.YOLOv8 工程化落地实战|训练 + 评估 + TensorRT/ONNX 导出,完整代码可直接部署
  • 告别模拟器!在Windows上轻松安装安卓应用的秘密武器
  • 2026白墨烫画打印机品牌排行及行业应用解析 - 品牌排行榜
  • 2026年开关插座哪个品牌性价比高?真实测评推荐 - 品牌排行榜
  • ctf show web 入门80
  • 5.4 分布分析
  • 预算有限的中小企业,品牌传播如何花小钱办大事发软文?亲测有效的实战方法 - 代码非世界
  • 如何在移动端项目中快速集成jQuery WeUI框架:完整指南
  • 2026五月天津闲置首饰怎么规划?大牌珠宝回收内行干货分享 - 奢侈品回收测评
  • 硕士研究生文献综述写作指南:检索技巧+阅读方法+AI工具Scholaread实战教程(2026年最新版)
  • 为AI Agent打造精简NixOS网关:OpenClaw部署优化实战
  • 河道水质监测站:给江河湖海装上“电子感官”
  • 14 从中序和后序遍历构造二叉树
  • FalcoClaw:为AI Agent与Linux工作负载构建自动化运行时安全响应引擎
  • 手把手教你为STM32F429的LTDC或大数组配置SDRAM:从硬件选型(W9825G6KH)到CubeMX参数详解
  • 基于比特币与IPFS构建去中心化身份锚点:原理、实现与应用
  • 北京手表回收哪家靠谱?2026 主流渠道实测对比,新手不踩坑 - 奢侈品回收测评
  • 多线程与并发编程
  • 在Windows上优雅处理PDF:Poppler工具包让你的文档工作更轻松
  • 嵌入式开发云端化:架构模式、实战评估与核心挑战解析