BUUCTF-[第二章 web进阶]SSRF Training

步骤

打开网站可以看到存在flag.php,所以是要通过SSRF获取flag.php的内容。在intersting chanllenge中查看源代码。

代码分析

php 复制代码
<?php 
highlight_file(__FILE__);        //显示源码
function check_inner_ip($url) 
{ 
    $match_result=preg_match('/^(http|https)?:\/\/.*(\/)?.*$/',$url); //正则匹配是否含有http,https
    if (!$match_result) 
    { 
        die('url fomat error'); 
    } 
    try 
    { 
        $url_parse=parse_url($url); //解析url,返回一个关联数组,包含了url的各个部分,如协议,主机等
    } 
    catch(Exception $e) 
    { 
        die('url fomat error'); 
        return false; 
    } 
    $hostname=$url_parse['host'];  //获取主机名
    $ip=gethostbyname($hostname);     //通过主机名获取ip地址,即dns解析
    $int_ip=ip2long($ip);             //将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;     //检查ip是否属于内网
} 

function safe_request_url($url) 
{ 
     
    if (check_inner_ip($url))   //调用检查是否是内网ip的函数
    { 
        echo $url.' is inner ip'; 
    } 
    else 
    {
        $ch = curl_init();     //初始化cURL会话
        curl_setopt($ch, CURLOPT_URL, $url);         //设置要请求的url
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //将结果以字符串返回,而不是直接输出
        curl_setopt($ch, CURLOPT_HEADER, 0);         //不包含头部信息
        $output = curl_exec($ch);                     //执行cURL请求
        $result_info = curl_getinfo($ch);             //获取请求的信息
        if ($result_info['redirect_url'])             //如果是重定向,递归调用safe_request_url
        { 
            safe_request_url($result_info['redirect_url']); 
        } 
        curl_close($ch);     //关闭cURL会话
        var_dump($output); 
    } 
     
} 

$url = $_GET['url'];     //接收get参数url
if(!empty($url)){     //判空
    safe_request_url($url); 
} 

?>

漏洞点1

parse_url

此函数会返回一个关联数组,包含url各个组成部分,如果缺少其中的某一项,则不会为这个组成部分创建数组项目。

组成部分:

  • scheme -- 如 http
  • host 域名
  • port 端口
  • pass  
  • path   路径
  • query -- 在问号 ? 之后
  • fragment -- 在散列符号 # 之后

关键点在于此函数并不意味着给定的url是合法的,它只是将url的各个部分分开。即parse_url可以接受不完整的url,并尽量解析正确。

传入的url如果是:http://@127.0.0.1:80@baidu.com/flag.php

返回的数组为:

这里host变为第二个@符号后面的了,所以host可控了,在配合gethostbyname获取域名的ip。

这里第一个@符的作用是让cur_getinfo()函数正确解析,而解析的内容就是第一个@符后面的内容:127.0.0.1:80,这样就成功绕过了。

漏洞点2

gethostbyname

将域名解析为ip,如果是127.0.0.1则会解析为本地所在的公网ip。

payload:

bash 复制代码
http://127.0.0.1:80/flag.php
相关推荐
Sagittarius_A*12 分钟前
【好靶场】PHP反序列化入门练习
安全·php·web·反序列化
山甫aa1 小时前
JavaWeb后端开发学习手册
java·开发语言·数据库·学习·mysql·springboot·web
sbjdhjd2 小时前
CTF 技术复盘:从参数类型绕过到正则回溯 | Merry Christmas PHP CTF(gift.php & gift_plus.php)
安全·网络安全·云计算·php·ctf·红队·网络攻防
Chengbei1111 小时前
DSH渗透测试插件dsh-pentest全新升级!适配DeepSeek Harness,可视化探索链路,一键搭建轻量化AI渗透测试环境。
人工智能·web安全·网络安全·微信·小程序·系统安全·安全架构
里欧跑得慢15 小时前
CSS 模块化架构的演进:BEM、CSS Modules 到 CSS-in-JS 的反思
前端·css·flutter·web·css-in-js
Latticy18 小时前
vulnhub系列靶机-mrRobot
web安全·网络安全·渗透测试
白猫不黑21 小时前
网络安全/信息安全专业学习路线与入行指南:从大学到岗位的完整规划
网络·学习·安全·web安全·网络安全·黑客技术
xierui1231231 天前
AI Agent 隐私架构:本地化重点为什么是登录态与执行权限
java·人工智能·网络安全·架构
Chockmans1 天前
春秋云境CVE-2025-49113
安全·web安全·网络安全·网络攻击模型·安全威胁分析·春秋云境·cve-2025-49113
白猫不黑1 天前
从运维到网络安全:转行优势、路径与薪资前景全解析
运维·网络·web安全·网络安全·信息安全·渗透测试