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

[SUCTF 2019]Pythonginx

# 定义一个路由,处理/getUrl路径的GET和POST请求
@app.route('/getUrl', methods=['GET', 'POST'])
def getUrl():# 从请求参数中获取名为"url"的参数值url = request.args.get("url")# 使用urlparse解析URL,获取主机名(hostname)host = parse.urlparse(url).hostname# 第一次检查:如果主机名是suctf.cc,返回特定字符串if host == 'suctf.cc':return "我扌 your problem? 111"# 使用urlsplit分割URL为多个部分,并转换为列表parts = list(urlsplit(url))# 从分割后的部分中获取主机部分host = parts[1]# 第二次检查:如果主机是suctf.cc,返回特定字符串和主机名if host == 'suctf.cc':return "我扌 your problem? 222 " + host# 初始化一个列表用于存储处理后的主机部分newhost = []# 遍历主机名按"."分割后的每个部分for h in host.split('.'):# 对每个部分进行IDNA编码后再解码为UTF-8newhost.append(h.encode('idna').decode('utf-8'))# 将处理后的主机部分重新用"."连接parts[1] = '.'.join(newhost)# 重新组合URL并去掉空格finalUrl = urlunsplit(parts).split(' ')[0]# 再次解析处理后的URL,获取主机名host = parse.urlparse(finalUrl).hostname# 第三次检查:如果主机名是suctf.cc,则读取该URL内容并返回if host == 'suctf.cc':return urllib.request.urlopen(finalUrl).read()# 否则返回特定字符串else:return "我扌 your problem? 333"</code><!-- Dont worry about the suctf.cc. Go on! --><!-- Do you know the nginx? -->

这个代码主要功能就是对url进行一个过滤,阻止访问suctf.cc。提示中有nginx,说明采用的是该web服务器。所以这道题的考点应该就是利用python中的相关url处理函数与nginx解析url的机制差异绕过过滤访问suctf.cc。由于对这两者都不太了解,直接看答案吧......

跟我想的不一样,这个python过滤代码本身就存在漏洞。

关键函数示例详解:

  1. urlparse.urlparse()

    • 示例:urlparse("https://www.example.com:8080/path?name=test#top")
    • 返回对象的主要属性:
      • scheme → "https"
      • netloc → "www.example.com:8080"
      • path → "/path"
      • params → ""
      • query → "name=test"
      • fragment → "top"
      • hostname → "www.example.com"(自动提取主机名,忽略端口)
  2. urlsplit()

    • 与 urlparse 类似,但不解析 params 部分
    • 示例:urlsplit("http://user:pass@example.com/path;params?query#fragment")
    • 返回:SplitResult(scheme='http', netloc='user:pass@example.com', path='/path;params', query='query', fragment='fragment')
    • 注意:params 部分被包含在 path 中,而不是单独作为一个部分
  3. str.encode('idna')

    • IDNA 编码用于处理国际化域名
    • 示例 1:" Müller ".encode('idna') → 输出 b'xn--mller-kva'(处理德语变音字符)
    • 示例 2:"例子.中国".encode('idna') → 输出 b'xn--fsq650b.xn--fiqs8s'
    • 解码后:b'xn--fsq650b'.decode('utf-8') → "xn--fsq650b"
  4. urlunsplit()

    • 将分割后的 URL 部分重新组合
    • 示例:urlunsplit(('https', 'example.com', '/path', 'id=1', 'section'))
    • 输出:https://example.com/path?id=1#section
  5. urllib.request.urlopen()

    • 打开 URL 并获取内容
    • 示例:urllib.request.urlopen("https://example.com").read()
    • 会返回该 URL 的 HTML 内容字节流
    • 注意:这是一个阻塞操作,会等待服务器响应

我不清楚清楚第二次检查的必要性是什么。第一次检查是hostname的过滤,第二次检查是netloc的过滤。难道存在某种情况使得hostname不是suctf.cc然而netloc却是。算了不管了。

这道题的漏洞在于

for h in host.split('.'):
        # 对每个部分进行IDNA编码后再解码为UTF-8
        newhost.append(h.encode('idna').decode('utf-8'))

可能存在某个非ASCII码字符经过该种编码后成为一个ASCII码字符

chars = ['s', 'u', 'c', 't', 'f']
for c in chars:for i in range(0x7f, 0x10FFFF):try:char_i = chr(i).encode('idna').decode('utf-8')if char_i == c:print('ASCII: {}   Unicode: {}    Number: {}'.format(c, chr(i), i))except:pass

用ˢuct.cc绕过就好。

在 Python 的 urllib.request.urlopen() 函数中,如果要访问本地文件,需要传入带有 file:// 协议前缀的本地文件路径作为参数。

具体格式如下:

  • 对于绝对路径:file:///绝对路径(注意协议后有三个斜杠)
  • 对于相对路径:file://相对路径 或 file://./相对路径

nginx重要文件的位置:
配置文件存放目录:/etc/nginx

主配置文件:/etc/nginx/conf/nginx.conf

管理脚本:/usr/lib64/systemd/system/nginx.service

模块:/usr/lisb64/nginx/modules

应用程序:/usr/sbin/nginx

程序默认存放位置:/usr/share/nginx/html

日志默认存放位置:/var/log/nginx

配置文件目录为:/usr/local/nginx/conf/nginx.conf

总结一下:h.encode('idna').decode('utf-8')该种编码方式能将部分非ASCII字符转换成ASCII字符从而绕过一些过滤。

Web 题目中,flag 通常与网站配置、服务器文件系统或应用逻辑相关,常见位置包括:

  1. 网站根目录或子目录

    • 如 flag.txt flag.php flag.html 直接存放在网站根目录(/var/www/html//var/www/ 等)或子目录(/static//admin/ 等)。
    • 示例:/var/www/html/flag.txt/var/www/secret/flag.php
  2. 服务器配置文件相关目录

    • 如 /etc/apache2//etc/nginx/ 下的配置文件(可能包含 flag 注释或路径)。
    • 示例:/etc/nginx/conf/nginx.conf。
  3. 用户目录

    • 网站运行用户(如 www-dataapache)的家目录,如 /home/www-data/flag.txt/root/flag.txt(若权限泄露可访问)。
  4. 临时文件目录

    • Linux 临时目录 /tmp/ 或 /var/tmp/,可能存在临时生成的含 flag 文件,如 /tmp/flag_123.tmp
  5. 环境变量或配置文件

    • 网站框架的配置文件(如 config.phpsettings.py)中直接硬编码 flag,或引用环境变量(如 FLAG=xxx)。
    • 示例:/var/www/config.php 中 $flag = "flag{xxx}"
  6. 数据库中

    • 部分题目会将 flag 存放在数据库表中(如 flag 表、users 表的某个字段)。
http://www.dtcms.com/a/324882.html

相关文章:

  • JS中typeof与instanceof的区别
  • 【精彩回顾·成都】成都 User Group×柴火创客空间:开源硬件驱动 AI 与云的创新实践!
  • JS 注释类型
  • ADK[3]历史对话信息保存机制与构建多轮对话机器人
  • scanpy单细胞转录组python教程(四):单样本数据分析之降维聚类及细胞注释
  • 【Canvas与戳记】黑底金Z字
  • 正确使用SQL Server中的Hint(10)— 常用Hint(2)
  • Spring WebSocket安全认证与权限控制解析
  • 研究揭示 Apple Intelligence 数据处理中可能存在隐私漏洞
  • 【redis初阶】------List 列表类型
  • 通过脚本修改MATLAB的数据字典
  • 【15】OpenCV C++实战篇——fitEllipse椭圆拟合、 Ellipse()画椭圆
  • 【人工智能99问】BERT的原理什么?(23/99)
  • Elasticsearch 保姆级入门篇
  • SpringBoot查询方式全解析
  • 在Mac上搭建本地AI工作流:Dify与DeepSeek的完美结合
  • 数字图像处理2——图像增强
  • AI(1)-神经网络(正向传播与反向传播)
  • 【RL第七篇】PPO训练策略,如何使PPO训练稳定?
  • unity中如何让原人物动画兼容新人物的动画
  • 异步问题的概念和消除问题技巧
  • Graph-R1:一种用于结构化多轮推理的智能图谱检索框架,并结合端到端强化学习
  • 【面板数据】全国及各省份技术市场成交额数据-dta+xlsx格式(2001-2023年)
  • nginx+lua+redis案例
  • 《Webpack与Vite热模块替换机制深度剖析与策略抉择》
  • 消息生态系统全景解析:技术架构、核心组件与应用场景
  • 【Python练习】085. 编写一个函数,实现简单的DNS服务器功能
  • LeeCode 46. 全排列
  • 【树\思维】P1395 会议
  • 33.搜索旋转排序数组