扭转乾坤
随便上传一个文件
可以看到返回提示apache拒绝了Content-Type:为multipart/form-data;
这里可以利用RFC标准的差异进行绕过waf
可以使用大写字母任意字母进行waf绕过
添加空格
Node Magical Login
查看controllert.js源代码
首先看一下登录处的代码
function LoginController(req,res) {
try {
const username = req.body.username
const password = req.body.password
if (username !== "admin" || password !== Math.random().toString()) {
res.status(401).type("text/html").send("Login Failed")
} else {
res.cookie("user",SECRET_COOKIE)
res.redirect("/flag1")
}
} catch (__) {}
}
当username=admin,password=Math.random().toString()才能够登录成功,并返回第一部分flag,并设置正确的cookie
但是Math.random().toString()是随机生成的一个字符串,所以基本不可能登录成功
function Flag1Controller(req,res){
try {
if(req.cookies.user === SECRET_COOKIE){
res.setHeader("This_Is_The_Flag1",flag1.toString().trim())
res.setHeader("This_Is_The_Flag2",flag2.toString().trim())
res.status(200).type("text/html").send("Login success. Welcome,admin!")
}
if(req.cookies.user === "admin") {
res.setHeader("This_Is_The_Flag1", flag1.toString().trim())
res.status(200).type("text/html").send("You Got One Part Of Flag! Try To Get Another Part of Flag!")
}else{
res.status(401).type("text/html").send("Unauthorized")
}
}catch (__) {}
}
这部分代码。当我们登录成功后,会设置正确的cookie
if(req.cookies.user === SECRET_COOKIE){
res.setHeader("This_Is_The_Flag1",flag1.toString().trim())
res.setHeader("This_Is_The_Flag2",flag2.toString().trim())
res.status(200).type("text/html").send("Login success. Welcome,admin!")
}
然后会返回两部分的flag,但是在前面我们以及看过了,是不可能登录成分的
if(req.cookies.user === "admin") {
res.setHeader("This_Is_The_Flag1", flag1.toString().trim())
res.status(200).type("text/html").send("You Got One Part Of Flag! Try To Get Another Part of Flag!")
所以我们这里可以伪造cookie为admin,访问路由/flag1获得第一部分的flag
这样我们就得到了第一部分的flag
接下来看一下获得第二部分flag的代码
function CheckController(req,res) {
let checkcode = req.body.checkcode?req.body.checkcode:1234;
console.log(req.body)
if(checkcode.length === 16){
try{
checkcode = checkcode.toLowerCase()
if(checkcode !== "aGr5AtSp55dRacer"){
res.status(403).json({"msg":"Invalid Checkcode1:" + checkcode})
}
}catch (__) {}
res.status(200).type("text/html").json({"msg":"You Got Another Part Of Flag: " + flag2.toString().trim()})
}else{
res.status(403).type("text/html").json({"msg":"Invalid Checkcode2:" + checkcode})
}
}
这里获得flag经历了两个if判断,第一个判断输入的验证码的长度是否为16位
第二个判断验证码是否为aGr5AtSp55dRacer,两个if判断成立进入catch获得第二部分flag
checkcode = checkcode.toLowerCase()
但是toLowerCase()函数回家将输入的验证码强制转为小写,那么我们直接输入aGr5AtSp55dRacer字符串是不能直接获得flag的。
这里可以利用toLowerCase()函数不能处理数组,引起报错从而进入到catch获得flag,
访问/flag2路由
抓包
我们可以吧输入的验证码换为数组进行绕过,但是由于要求长度16
所以我们要让数组里面有16个数据
从而获得第二部分的flag
unusual php
<?php
if($_GET["a"]=="upload"){
move_uploaded_file($_FILES['file']["tmp_name"], "upload/".$_FILES['file']["name"]);
}elseif ($_GET["a"]=="read") {
echo file_get_contents($_GET["file"]);
}elseif ($_GET["a"]=="version") {
phpinfo();
}
当a=upload的时候可以上传文件,但是不解析
a=read读取文件,读取我们刚上传的文件
可以读取
尝试读取源码
可以读取,但是出来是乱码,猜测有加密
读取/etc/passwd
可以读取,而且不是乱码
通过读取 /proc/self/maps 查看当前进程的内存映射关系
发现一个zend_test.so扩展
通过php伪协议进行读取这个扩展文件
解密后保存为so文件
import os
import base64
flag=""
imagedata = base64.b64decode(flag)
file = open('1.so', "wb")
file.write(imagedata)
file.close()
之后的知识就是逆向的知识了
ida64位打开so文件
可以看到有rc4加密函数
但是没有密钥,追踪谁引用了rc4加密函数
可以看到my_compile_file调用这个函数
跟进看一下这个函数
不知道这里为什么是空的,贴一个别的师傅的图
这里可以得到密钥
然后对木马文件进行rc4加密
然后通过进行文件上传
访问
发现成功解析了,蚁剑连接
标签:status,web,checkcode,res,req,flag,toString,复现,论剑 From: https://www.cnblogs.com/GTL-JU/p/17099783.html