GHCTF 2025 WP(未完)

qiutou 发布于 16 天前 70 次阅读


MISC

[MISC] mybrave

下载附件之后发现是一个压缩包,我先跑了一遍伪加密,发现不是,然后打开010观察发现是一个ZIPcrypto加密的zip文件,而且可以发现里面含有一个名为“mybrave.png”的png文件,可以猜想知道,这是一个明文加密,所以我们使用了bkcrack,利用png文件的头文件破解

#使用语言如下
./bkcrack -C mybrave.zip -c mybrave.png -x 0 89504e470d0a1a0a0000000d49484452
image-20250314021058849

成功得到密钥key:97d30dcc 173b15a8 6e0e7455

然后再进行解密

./bkcrack -c mybrave.png -k 97d30dcc 173b15a8 6e0e7455 -D 123.zip
#格式如:bkcrack -c cipherfile -k 12345678 23456789 34567890 -d decipheredfile

我所借鉴的bkcrack帮助:CTF压缩包破解神器bkcrack教程和详细使用过程-CSDN博客

我也会写一篇讲述我的bkcrack使用方法介绍

解密之后成功从123.zip中得到一个png图片,然后再将其拖入010中

image-20250314021529225

在最后一段很突兀的出现一串数字,我们将无关的00去掉,即可用base64,得到flag

此处我们可以使用CyberChef直接去除00(不像我,手动去除的/_ \

image-20250314021738313

知识补充:需要单独写一篇bkcrack和CyberChef的使用方法教程

WEB

[WEB] UPLOAD?SSTI!

ps:因为这篇wp对于我而言,缺陷的知识较多而且复杂,所以在解出flag之后又花了一些时间去理解运用,所以写的比较慢。

此处感谢”夜雨、浅秋“ ”My4n“等等文章:GHCTF2025-WEB新手向详解-UPLOAD?SSTI! (内含SSTI模板注入关键字绕过方式)-CSDN博客

首先题目中就可以明显地看到SSTI,然后我就去网上查到了ssti的相关知识,超详细SSTI模板注入漏洞原理讲解_ssti注入-CSDN博客

SSTI是什么:

以我自己的思路来说,当访问我们网站的访客,需要阅读一部分独特的内容的时候,我们的网站需要为其”定制“一个独特的页面,但是更改的时候就会很麻烦,所以我们采取了一个模板,就像写信的时候,我们只需要将“寄信人、名称、关键内容、寄信人、日期”打上空白,然后根据用户提供的内容数据,把这些空白填上,就完成了定制页面。这就是模板注入,而SSTI 服务器端模板注入(Server-Side Template Injection)就是模板注入的一类,当前使用的框架,比如python的flask,php的tp,java的spring等一般都采用这种模式。

SSTI的漏洞成因:

SSTI的漏洞成因就是服务端接收了用户的恶意输入以后,未经处理就将其作为 Web 应用模板内容的一部分,模板引擎在进行目标编译渲染的过程中,执行了用户插入的可以破坏模板的语句,因而可能导致了敏感信息泄露、代码执行、GetShell 等问题。

解题思路:

对于SSTI的题目,大概的步骤是确认题目,注入点测试,构造payload(中文 ' 有效载荷 ',指成功exploit之后,真正在目标系统执行的代码或指令)

打开靶机之后,可见是一个文件上传,我刚才还试了试一句话代码什么的,发现没用,才去研究题目中的SSTI 尝试无果之后,我随即打开了网站源码,开始审计源码。

tmp_str = """<!DOCTYPE html>
      <html lang="zh">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>查看文件内容</title>
      </head>
      <body>
          <h1>文件内容:{name}</h1> <!-- 显示文件名 -->
          <pre>{data}</pre> <!-- 显示文件内容 -->

          <footer>
              <p>&copy; 2025 文件查看器</p>
          </footer>
      </body>
      </html>
      """.format(name=safe_filename, data=file_data)

       return render_template_string(tmp_str)

此处可见“render_template_string”函数,这算是一个SSTI的标志性函数。

成因:在flask中,其渲染方法有两种:render_templaterender_template_string。对于render_template函数的作用就是渲染一个指定的模版文件,并且“{{ 变量 }} “会被模板所代替为相应的变量值以及进行计算,而render_template_string与其类似,不同的是,其接收的是字符串,特点是在渲染模板的时候使用了“%s”来动态的替换字符串,在渲染的时候会把 {undefined{}} 包裹的内容当做变量解析替换,根据这个方式,我们把字符串换成反馈出关键信息的指令,那随机得到了flag

确定题目之后,发现有有waf(防火墙)

def contains_dangerous_keywords(file_path):
   dangerous_keywords = ['_', 'os', 'subclasses', '__builtins__', '__globals__','flag',]

   with open(file_path, 'rb') as f:
       file_content = str(f.read())


       for keyword in dangerous_keywords:
           if keyword in file_content:
               return True  # 找到危险关键字,返回 True
         
if contains_dangerous_keywords(file_path):
           # 删除不安全的文件
           os.remove(file_path)
           return jsonify({"error": "Waf!!!!"}), 400

可知该waf的作用是如果包含黑名单中的字符就会删除该文件并报错,所以在我们构建payload的时候就不能使用黑名单中的字符,我们得想办法绕过,例如编码或者request。

首先我们需要确定注入点,在网站上传一个123.txt文件之后,通过yakit抓包,在上传中文件构建一个“{{9*9}}”

注意!填写的时候,需要空格一行再构建文本(我也不知道为什么,求解)

image-20250321032913759

访问url/file/123.txt,即可观察文{{9*9}}是否被解析,如图,文件已经被解析(由于环境关闭,我就直接用的截图)

接下来我们就要构造payload,由于waf,所以我们采用两种方法:

编码绕过:

1.将下划线、os、flag字符进行编码、2.尝试下划线替换为\x5f ,用cat /f*的通配符方式来访问/flag:、3.用join拼接敏感字符+dir(0)0替代下划线

原始SSTI绕过payload模板:

{{ lipsum.__globals__.__builtins__.open('/flag').read() }}

通过 lipsum 的 globals 获取全局变量字典,再从中提取 builtins 模块,调用 open 函数读取 /flag 文件内容。

使用十六进制绕过敏感字符(如flag中的字母g、下划线),得到:

{{ lipsum.\x5f\x5fglobals\x5f\x5f.\x5f\x5fbuiltins\x5f\x5f.open('/flag').read() }}

方括号 [] 替换 . :Python允许通过obj["key"]的方式访问属性或字典的键,这种方式的属性名被包裹在字符串中,可以动态构造,从而绕过waf对固定模式的过滤

{{ lipsum["\x5f\x5fglobals\x5f\x5f"]["\x5f\x5fbuiltins\x5f\x5f"]["open"]("/fla\x67").read() }}

request绕过:(后面再写吧)

知识补充:我们可以使用fenjing,这个专门用于检测SSTI的工具实现。

关于SSTI的绕过模板构成方式见:SSTI模板注入及绕过姿势(基于Python-Jinja2)_exploit ssti bypass filter-CSDN博客

此作者没有提供个人介绍
最后更新于 2025-03-21