zoukankan      html  css  js  c++  java
  • RACTF-web C0llide?(js弱类型)

    源码:

    const bodyParser = require("body-parser")
    const express = require("express")
    const fs = require("fs")
    const customhash = require("./customhash")
    
    const app = express()
    app.use(bodyParser.json())
    
    const port = 3000
    const flag = "flag"
    const secret_key = "Y0ure_g01nG_t0_h4v3_t0_go_1nto_h4rdc0r3_h4ck1ng_m0d3"
    
    app.get('/', (req, res) => {
        console.log("[-] Source view")
        res.type("text")
        return fs.readFile("index.js", (err,data) => res.send(data.toString().replace(flag, "flag")))
    })
    
    app.post('/getflag', (req, res) => {
        console.log("[-] Getflag post")
        if (!req.body) {return res.send("400")}
        let one = req.body.one
        let two = req.body.two
        console.log(req.body)
        if (!one || !two) {
            return res.send("400")
        }
        if ((one.length !== two.length) || (one === two)) {
            return res.send("Strings are either too different or not different enough")
        }
        one = customhash.hash(secret_key + one)
        two = customhash.hash(secret_key + two)
        if (one == two) {
            console.log("[*] Flag get!")
            return res.send(flag)
        } else {
            return res.send(`${one} did not match ${two}!`)
        }
    })
    
    app.listen(port, () => console.log(`Listening on port ${port}`))

    因为本人对nodejs一无所知。所以很多语法都是临时查的。整个源码浏览一遍之后,我们把重点放在以下几处代码上

    app.post('/getflag', (req, res) => {
        console.log("[-] Getflag post")
        if (!req.body) {return res.send("400")}
        let one = req.body.one
        let two = req.body.two

    大致的意思是用post方式向/getfkag传两个参数,参数名为one和two,如果没有接收到参数则返回400。

    const bodyParser = require("body-parser")
    body-parser是Express的中间件。模块会处理application/x-www-form-urlencoded、application/json两种格式的请求体。
    经过这个中间件后,就能在所有路由处理器的req.body中访问请求参数。
    body-parser默认接受方式是application/x-www-form-urlencoded。
    app.use(bodyParser.json())

    app.use()用于定义路由规则。详情可移步https://blog.csdn.net/u014473112/article/details/51992771

    很明显用的是json格式,这就是问题所在。

    hackbar的传参是x-www-form-urlencoded格式。所以怎么传都是返回400。返回的400是第一个if的结果。因为没有收到正确的参数格式所以req.body为空

     因此需要用bp改一下包,把Content-Type改为application/json,然后再以json格式传参

     那么目前传参格式问题就解决了。接着就要分析参数内容了。

    
    
        if ((one.length !== two.length) || (one === two)) {
            return res.send("Strings are either too different or not different enough")
        }
        one = customhash.hash(secret_key + one)
        two = customhash.hash(secret_key + two)
        if (one == two) {
            console.log("[*] Flag get!")
            return res.send(flag)
        } else {
            return res.send(`${one} did not match ${two}!`)
        }
    })
    
    app.listen(port, () => console.log(`Listening on port ${port}`))
    
    

    第一个if判断两个参数长度,要求长度相同且内容且值不同

    之后分别在secret_key后加上两个参数,再进行hash加密,要求hash值相同

    构造payload:{"one":[{"2":"32"}],"two":[{"1":"c"}]}(数组为空也行)

    和php的弱类型差不多。one和two值都为数组类型。因为payload数组元素相等,相当于one[1]和two[1],所以长度相等。js在拼接的时候会转换参数类型,数组转换后解析为NaN,

    因此hash值相等,提交后成功获得flag






  • 相关阅读:
    JS BOM对象 History对象 Location对象
    JS 字符串对象 数组对象 函数对象 函数作用域
    JS 引入方式 基本数据类型 运算符 控制语句 循环 异常
    Pycharm Html CSS JS 快捷方式创建元素
    CSS 内外边距 float positio属性
    CSS 颜色 字体 背景 文本 边框 列表 display属性
    【Android】RxJava的使用(三)转换——map、flatMap
    【Android】RxJava的使用(二)Action
    【Android】RxJava的使用(一)基本用法
    【Android】Retrofit 2.0 的使用
  • 原文地址:https://www.cnblogs.com/remon535/p/13061755.html
Copyright © 2011-2022 走看看