Лекция 5
.pdfПодмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
./loop_sleep (компиляция и запуск) |
|||
Компиляция |
|
|
|
$ gcc -static loop_sleep.c -o loop_sleep |
|
||
Запуск |
|
|
|
$ ./loop_sleep |
|
$ cat \ |
|
25646: I'm alive and now ... |
|
||
25646: I'm alive and now ... |
/proc/$(pgrep loop_sleep)/maps | \ |
||
25646: I'm alive and now ... |
grep rwx |
|
|
25646: I'm alive and now ... |
|
|
|
signal SIGUSR1 was captured |
$ kill -s SIGUSR1 \ |
|
|
addr: 7f50d0456000 |
|
$(pgrep loop_sleep) |
|
25646: I'm alive and now ... |
$ cat \ |
|
|
25646: I'm alive and now ... |
/proc/$(pgrep loop_sleep)/maps | \ |
||
25646: I'm alive and now ... |
grep rwx |
|
|
25646: I'm alive and now ... |
7f50d0456000-7f50d0457000 rwxp ... |
||
|
|
$ gdb -q |
|
|
|
(gdb) attach 25646 |
|
|
|
(gdb) p strcpy((char *) |
|
|
|
0x7f50d0456000, "Hello world!") |
|
|
|
$1 = -800759808 |
|
|
|
(gdb) quit |
|
signal SIGUSR2 was captured |
$ kill -s SIGUSR2 \ |
|
|
*addr: Hello world! |
|
$(pgrep loop_sleep) |
|
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
14/50 |
Подмена dll Изменение дампа памяти Python-процесса Инъекция кода
./loop_sleep (дизассемблирование)
$ objdump -d -M intel loop_sleep | grep -A 20 'sig_process.*:'
0000000000400f8e <sig_process>: |
|
|||||
... |
|
|
|
|
|
|
400f9f: c7 45 fc 07 00 |
00 00 |
mov DWORD PTR [rbp-0x4],0x7 |
||||
400fa6: c7 45 f8 22 00 |
00 00 |
mov DWORD PTR [rbp-0x8],0x22 |
||||
400fad: |
8b |
55 |
f8 |
|
|
mov edx,DWORD PTR [rbp-0x8] |
400fb0: |
8b |
45 |
fc |
|
|
mov eax,DWORD PTR [rbp-0x4] |
400fb3: 41 b9 00 |
00 00 |
00 |
mov r9d,0x0 |
|||
400fb9: 41 b8 00 |
00 00 |
00 |
mov r8d,0x0 |
|||
400fbf: |
89 |
d1 |
|
|
|
mov ecx,edx |
400fc1: |
89 |
c2 |
|
|
|
mov edx,eax |
400fc3: be 0a 00 |
00 00 |
|
mov esi,0xa |
|||
400fc8: bf 00 00 |
00 00 |
|
mov edi,0x0 |
|||
400fcd: |
e8 |
1e |
11 |
03 00 |
|
call 4320f0 <__mmap> |
...
$ objdump -d -M intel loop_sleep | grep -A 5 '__mmap.*:'
00000000004320f0 <__mmap>: |
|
||||
4320f0: |
49 |
89 |
ca |
|
mov r10,rcx |
4320f3: |
b8 |
09 |
00 |
00 00 |
mov eax,0x9 |
4320f8: |
0f |
05 |
|
|
syscall |
... |
|
|
|
|
|
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
15/50 |
Подмена dll Изменение дампа памяти Python-процесса Инъекция кода
./loop_sleep (дизассемблирование)
$ objdump -d -M intel loop_sleep | grep -A 20 'sig_process.*:'
0000000000400f8e <sig_process>: |
|
|
|||||
... |
|
|
|
|
|
|
|
400f9f: c7 45 fc 07 00 |
00 00 |
mov DWORD PTR [rbp-0x4],0x7 |
|||||
400fa6: c7 45 f8 22 00 |
00 00 |
mov DWORD PTR [rbp-0x8],0x22 |
|||||
400fad: |
8b |
55 |
f8 |
|
|
mov edx,DWORD PTR [rbp-0x8] |
|
400fb0: |
8b |
45 |
fc |
|
|
mov eax,DWORD PTR [rbp-0x4] |
|
400fb3: 41 b9 00 |
00 00 |
00 |
mov r9d,0x0 |
; offset |
|||
400fb9: 41 b8 00 |
00 00 |
00 |
mov r8d,0x0 |
; fd |
|||
400fbf: |
89 |
d1 |
|
|
|
mov ecx,edx |
; flags |
400fc1: |
89 |
c2 |
|
|
|
mov edx,eax |
; prot |
400fc3: be 0a 00 |
00 00 |
|
mov esi,0xa |
; length |
|||
400fc8: bf 00 00 |
00 00 |
|
mov edi,0x0 |
; addr |
|||
400fcd: |
e8 |
1e |
11 |
03 00 |
|
call 4320f0 <__mmap> |
...
$ objdump -d -M intel loop_sleep | grep -A 5 '__mmap.*:'
00000000004320f0 <__mmap>: |
|
||||
4320f0: |
49 |
89 |
ca |
|
mov r10,rcx |
4320f3: |
b8 |
09 |
00 |
00 00 |
mov eax,0x9 ; mmap syscode |
4320f8: |
0f |
05 |
|
|
syscall |
... |
|
|
|
|
|
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
15/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
Передача аргументов в mmap
0x0 ! edi; addr 0xa ! esi; length
0x7 ! [rbp 0x4] ! eax ! edx; prot
0x22 ! [rbp 0x8] ! edx ! ecx ! r10; flags 0x0 ! r8d; fd
0x0 ! r9d; offset
0x9 ! eax; mmap_syscode
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
16/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
Передача аргументов в mmap
0x0 ! edi; addr mov edi; 0x0 0xa ! esi; length mov esi; 0xa
0x7 ! [rbp 0x4] ! eax ! edx; prot mov edx; 0x7
0x22 ! [rbp 0x8] ! edx ! ecx ! r10; flags mov r10; 0x22 0x0 ! r8d; fd mov r8d; 0x0
0x0 ! r9d; offset mov r9d; 0x0
0x9 ! eax; mmap_syscode mov eax; 0x9
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
16/50 |
Подмена dll |
|
|
Изменение дампа памяти Python-процесса |
Инъекция кода |
|||
|
mmap_test.asm |
|
|
||||
1 section |
.text |
|
|
|
|
|
|
2 global |
_start |
|
|
|
|
|
|
3 |
_start : |
|
|
|
|
|
|
4 |
mov |
edi , |
0 x0 |
; |
addr |
|
|
5 |
mov |
esi , |
0 xa |
; |
length |
|
|
6 |
mov |
edx , |
0 x7 |
; |
prot |
|
|
7 |
mov r10 , 0 x22 ; flags |
|
|||||
8 |
mov |
r8d , |
0 x0 |
; |
fd |
|
|
9 |
mov |
r9d , |
0 x0 |
; |
offset |
|
|
10 |
mov |
eax , |
0 x9 |
; |
mmap |
syscode |
|
11 |
syscall |
|
|
|
|
|
|
12 |
mov |
rdi , |
0 |
; |
arg |
of exit syscode |
|
13 |
; look file |
/ usr / include / x86_64 - linux - gnu / asm / unistd_64.h |
|||||
14 |
mov |
rax , |
60 |
; |
exit |
syscode |
|
15 |
syscall |
|
|
|
|
|
Компиляция (для x86_64):
$ nasm -felf64 mmap_test.asm -o mmap_test.o
Компоновка:
$ ld mmap_test.o -o mmap_test
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
17/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
objdump mmap_test (дизассемблирование)
$ objdump -d -M intel mmap_test
mmap_test: file format elf64-x86-64
Disassembly of section .text: |
|
|
|
|||
0000000000400080 <_start>: |
|
|
|
|||
400080: |
bf 00 00 00 00 |
|
mov |
edi,0x0 |
||
400085: |
be 0a 00 00 00 |
|
mov |
esi,0xa |
||
40008a: |
ba 07 00 00 00 |
|
mov |
edx,0x7 |
||
40008f: |
41 |
ba 22 00 00 00 |
mov |
r10d,0x22 |
||
400095: |
41 |
b8 |
00 00 00 |
00 |
mov |
r8d,0x0 |
40009b: |
41 |
b9 |
00 00 00 |
00 |
mov |
r9d,0x0 |
4000a1: |
b8 |
09 |
00 00 00 |
|
mov |
eax,0x9 |
4000a6: |
0f |
05 |
|
|
syscall |
|
4000a8: |
bf 00 00 00 00 |
|
mov |
edi,0x0 |
||
4000ad: |
b8 |
3c |
00 00 00 |
|
mov |
eax,0x3c |
4000b2: |
0f |
05 |
|
|
syscall |
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
18/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
objdump mmap_test (дизассемблирование)
$ objdump -d -M intel mmap_test
mmap_test: file format elf64-x86-64
Disassembly of section .text: Подготовка регистров
0000000000400080 |
<_start>: |
|
|
|
|
||
400080: |
bf 00 00 00 00 |
|
|
mov |
edi,0x0 |
||
400085: |
be 0a 00 00 00 |
|
|
mov |
esi,0xa |
||
40008a: |
ba 07 00 00 00 |
|
|
mov |
edx,0x7 |
||
40008f: |
41 |
ba 22 00 00 00 |
|
mov |
r10d,0x22 |
||
400095: |
41 |
b8 |
00 00 00 |
00 |
|
mov |
r8d,0x0 |
40009b: |
41 |
b9 |
00 00 00 |
00 |
|
mov |
r9d,0x0 |
4000a1: |
b8 |
09 |
00 00 00 |
|
|
mov |
eax,0x9 |
4000a6: |
0f |
05 |
|
|
|
syscall |
|
4000a8: |
bf 00 00 00 00 |
|
|
mov |
edi,0x0 |
||
4000ad: |
b8 |
3c |
00 00 00 |
|
Прерывание mov |
eax,0x3c |
|
4000b2: |
0f |
05 |
|
|
|
syscall |
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
18/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
man ptrace |
|
|
PTRACE(2) |
Linux Programmer's Manual |
|
|
PTRACE(2) |
|
NAME
ptrace - process trace
SYNOPSIS
#include <sys/ptrace.h>
long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
DESCRIPTION
The ptrace() system call provides a means by which one process (the "tracer") may observe and control the execution of another process (the "tracee"), and examine and change the tracee 's memory and registers. It is primarily used to implement breakpoint debugging and system call tracing.
A tracee first needs to be attached to the tracer. Attachment and subsequent commands are per thread: in a multithreaded process, every thread can be individually attached to a (potentially different) tracer, or left not attached and thus not debugged. Therefore, "tracee" always means "(one) thread", never "a (possibly multithreaded) process". Ptrace commands are always sent to a specific tracee using a call of the form
ptrace(PTRACE_foo, pid, ...)
where pid is the thread ID of the corresponding Linux thread.
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
19/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
simple_loop.c
1 |
# include < stdio .h > |
|
2 |
# include < unistd .h > |
|
3 int main ( int argc , |
char * argv []) |
|
4 |
{ |
|
5 |
const int nsec = 5; |
|
6 |
while (1) { |
|
7 |
printf ("%d: I 'm alive and now I want to sleep for %d sec\n", |
|
8 |
getpid (), |
nsec ); |
9 |
sleep ( nsec ); |
|
10 |
} |
|
11 |
return 0; |
|
12 |
} |
|
Компиляция: gcc simple_loop.c -o simple_loop
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
20/50 |