Misc上课讲过就不写了= =好忙最近,如果有不会的再来群上问吧

触手可得

先看代码,首页只有这些,访问一下flag.php会发现没有内容,所以只能想办法利用下面的代码去拿到flag

很明显这里只要满足$key等于后面一大串就能拿到flag了,所以payload就是

你说上面那个什么md5是干嘛用的?你都知道这样问了,那当然是没用啦^ ^

时间管理大师

如果你是24届竞赛组成员,可以先看个代码分析的大概逻辑,不一定需要全看懂。

先看入口

这里的spl_autoload_register搜了一下其实就是注册路由,访问什么就进到什么目录下

下面的route其实就是定义访问根路径时使用的路由,这里直接定位到controllers/TimeController.php里看一下逻辑

传入进来的format被赋值给$format,并被丢到TimeModel里处理了一下,这里跟进一下TimeModel类。

可以看到$format被直接与date '+' 2&1拼接,其中2>&1的意思是将标准错误重定向到标准输出中,意思就是会把这一串指令前的指令执行错误的结果也一并显示回来。然后在刚刚的Timecontroller.php里可以看到后面它被直接丢到exec里作为系统指令执行并接收结果,最后返回输出给我们。所以我们可以通过对$format做手脚从而达到命令执行的效果

这里我们假设传入进来的内容是 ';ls||,则整句代码会变成这样

date '+';ls|| 2>&1

这样执行起来的结果我们可以在自己的linux里尝试一下

会发现执行成功。但一开始我想到用 ';ls;这样的方式没有执行成功,提示权限不足,原因是因为闭合后2>&1在等待你的输入但没有得到,所以会提示权限不足。

还有另一种解法的payload是 ';ls|cat ',这样闭合后的结果如下

date '+';ls|cat '' 2>&1

原理就是将ls的输出用cat显示回来给我们,所以就能达到执行的效果

没有人比我更懂JWT

附件只有一个python文件,先看逻辑

使用flask框架,定义了secret_key,但是是随机值,应该没法爆破

并且只有下面两个路由

先来看一下/login

接收两个变量,username和password,其中username被丢到jwt里进行加密,使用HS256算法。最后将加密完的jwt返回给我们。其中包含了一个比较关键的信息,也就是role后跟着的内容,也就是role的值,我们先记住。

/flag路由里首先会接收请求这个路由的用户所携带的jwt,然后对其进行解码后检验role的值是否是admin,是的话返回flag,不是就告诉我们只有admin才能访问

如果只按照代码的登录逻辑,没有找到可以将role值改成admin的地方。所以我们就要手动改,先随便登录一个账号获取到jwt。因为password后面都没用到所以就不用传。这里注意要把content-type改成json,因为data = request.json

接着丢到jwt.io里,改成admin,然后复制被赋值完的jwt

接着我们回到刚刚的代码,注意到一个地方

这里的options被设置成了不需要验证签名和exp的值,也就是说我们可以将加密算法修改成None,这样就能达到修改了role值还能通过解码的目的。原理如下(原文点击这里查看)

这里我们需要借助一款工具,jwt_tool。下载后,可以在使用文档中查看如何使用None攻击

照着格式填进去就可以生成修改后的jwt了

这里我们选择哪一个都可以。最后我们再根据代码构造一个Authorization就可以啦。不过要注意,根据代码,需要先写上你的用户名,再用一个空格加上jwt。这里我的用户名是1,所以结果就如下