JWT
什么是JWT
JWT(JSON Web Token)是一种用于在各方之间作为JSON对象安全地传输信息的开放标准(RFC 7519)。该信息经过数字签名,因此是可验证和可信的。JWT 可以使用HMAC算法或使用RSA的公钥/私钥对进行签名
JWT的组成
[HFCTF2020]EasyLogin
正常进行注册登录,发现有命令框,尝试了各种读取方式都没用,抓包发现存在jwt
再查看一下源码,看有没有什么提示
发现了关于flag的提示
猜测flag应该就在/api/flag里面,提示了koa框架;
koa-static是一个处理静态文件资源的中间件,从大佬哪里借鉴一个koa的框架结构
controllers是项目控制器存放目录,访问来查看源码
结合前面提到的flag所在的目录,访问api目录
/controllers/api.js
发现了返回flag的条件
'GET /api/flag': async (ctx, next) => {
if(ctx.session.username !== 'admin'){
throw new APIError('permission error', 'permission denied');
}
const flag = fs.readFileSync('/flag').toString();
ctx.rest({
flag
});
await next();
},
简单来说就是判断username是否为admin,如果是admin的话就读取'/flag'下的内容以字符串的形式存储在flag中
想要username为admin,就只有通过JWT伪造(因为注册为admin会报错)
那么解题思路也就明确了,通过jwt将username伪造为admin,来读取flag并返回
先解析返回的jwt,签名是HS256
伪造方法,把"alg"值更改为"none",这样就不执行签名验证,将secretid改为[]代表一个空值
修改之后进行base64编码(去掉换行符和编码后的"="),把header和payload拼接,因为签名改为了none所以签名认证就为空
进入/api/flag,抓包,修改一下sses:aok和sses:aok.sig,修改为伪造jwt后返回的对应的值
就完成了jwt的伪造,获取到flag
总结:这个周从复现开始就全是token的题,前面也接触过session,一开始只是草草了解token和session类似,但是现在把两个做了明显的区别对比