Web1
是个js。登陆界面。。还有注册。
尝试了下unicode。登陆后发现要admin才能cat flag
对JS不熟悉。。有些源码也不知道
/app.js
/controllers/api.js
得到源码
分析下
注册的用户名不能是admin和空。
然后secret是18位随机的16进制
secretid是secrets的长度
讲secret加入secret
然后根据secretid,username,password,secret用HS256生成签名
登陆的签名从header。或body。或query中取
token=签名
用json解析token。取第2段数据。base64解密。取其中的secretid字段赋值给sid
sid不能==undefined。不能===null。长度不能>secrets并且<=0
乍一看没什么特别的点。
但是当初看过一题。修改JWT头。算法改为None。签名置空。绕过登陆
先抓个包看看jwt
那么我们要将secret置为空。然后sid又要过下面的判断
这里[]
可以过所有判断
那么现在就可以构造
const token = jwt.sign({secretid, username, password}, secret, {algorithm: 'HS256'});
const token = jwt.sign({[],admin,123},null,{algorithm:none})
const jwt=require('jsonwebtoken');
const secretid=[];
const username='admin';
const password='123456';
console.log(jwt.sign({secretid,username,password}, null, {algorithm: 'none'});
nodejs执行下得到jwt
登陆时替换。然后就得到了Flag
Web2
通过run.php的报错和index.php的代码。。eval(code)没$
。
大致可以判断是个nodejs。
后台大致是eval(code)
用
var err = new Error();err.stack;
打印出当前栈中的错误。可以看到vm2
过滤了部分字符。用数组就可以绕过
https://github.com/patriksimek/vm2/issues/225
一把梭
数组可以绕过过滤。也可以通过\x的方式来绕过
js中。可以用[]代替.
TypeError.prototype==TypeError[`\xxx\xxx\xxx\xxx`]
``反引号代替双引号
赵总的payload。是用占位符来拼接字符串
`${`${`prototyp`}e`}`
`${"prototype"}`
Web3
给出了源码
<?php
error_reporting(0);
session_save_path("/var/babyctf/");
session_start();
require_once "/flag";
highlight_file(__FILE__);
if($_SESSION['username'] ==='admin')
{
$filename='/var/babyctf/success.txt';
if(file_exists($filename)){
safe_delete($filename);
die($flag);
}
}
else{
$_SESSION['username'] ='guest';
}
$direction = filter_input(INPUT_POST, 'direction');
$attr = filter_input(INPUT_POST, 'attr');
$dir_path = "/var/babyctf/".$attr;
if($attr==="private"){
$dir_path .= "/".$_SESSION['username'];
}
if($direction === "upload"){
try{
if(!is_uploaded_file($_FILES['up_file']['tmp_name'])){
throw new RuntimeException('invalid upload');
}
$file_path = $dir_path."/".$_FILES['up_file']['name'];
$file_path .= "_".hash_file("sha256",$_FILES['up_file']['tmp_name']);
if(preg_match('/(\.\.\/|\.\.\\\\)/', $file_path)){
throw new RuntimeException('invalid file path');
}
@mkdir($dir_path, 0700, TRUE);
if(move_uploaded_file($_FILES['up_file']['tmp_name'],$file_path)){
$upload_result = "uploaded";
}else{
throw new RuntimeException('error while saving');
}
} catch (RuntimeException $e) {
$upload_result = $e->getMessage();
}
} elseif ($direction === "download") {
try{
$filename = basename(filter_input(INPUT_POST, 'filename'));
$file_path = $dir_path."/".$filename;
if(preg_match('/(\.\.\/|\.\.\\\\)/', $file_path)){
throw new RuntimeException('invalid file path');
}
if(!file_exists($file_path)) {
throw new RuntimeException('file not exist');
}
header('Content-Type: application/force-download');
header('Content-Length: '.filesize($file_path));
header('Content-Disposition: attachment; filename="'.substr($filename, 0, -65).'"');
if(readfile($file_path)){
$download_result = "downloaded";
}else{
throw new RuntimeException('error while saving');
}
} catch (RuntimeException $e) {
$download_result = $e->getMessage();
}
exit;
}
?>
这里就重点讲一下关键代码
首先。拿到Flag。得存在success.txt。并且session['username']=='admin'
我们看看。怎么成为admin。
session实质上是根据session文件来判断的。session会将一些信息。序列化成字符串。然后放入session文件。只要我们写一个session文件。内容是xxxxx:admin。就行了
先看看怎么写文件
session_save_path("/var/babyctf/");
$dir_path = "/var/babyctf/".filter_input(INPUT_POST, 'attr');
$file_path = $dir_path."/".$_FILES['up_file']['name']."_".hash_file("sha256",$_FILES['up_file']['tmp_name']);
这里可以写文件。POST传参direction。拼接到/var/babyctf/。然后继续拼接文件名_文件hash
/var/babyctf/$_POST['attr']/文件名_hash
而我们要构造的是
/var/babyctf/sess_xxxxx
是不是很简单。。
attr置为控。上传的文件名为sess。算出文件hash。
就可以写一个sess_xxxx了
接下来去看文件内容。
这里还有个download。读取的功能
$attr = filter_input(INPUT_POST, 'attr');
$filename = basename(filter_input(INPUT_POST, 'filename'));
$dir_path = "/var/babyctf/".$attr;
$file_path = $dir_path."/".$filename;
readfile($file_path)
拼接如下
/var/babyctf/$_POST['attr']/$_POST['filename']
已知session存放在/var/babyctf/sess_sessionID
那么attr置空。filename为session就行了
复制session内容(有个不可见的字符。。也要复制上去)到文件。函数算一下hash值
第一关。这就过去了。还要搞个success.txt
file_exists
这个函数。用来匹配文件或文件夹是否存在。那么我们可以创建一个file_exists文件夹
根据之前的上传
/var/babyctf/$_POST['attr']/文件名_hash
我们可以控制attr。将其变成success.txt。其他随意
这个题。会自动删除文件。我真是。。。。。。mmp
开BURP一直跑