解决 mprotect() 系统调用失败
Solving mprotect() syscall failure
我正在编写一些通过系统调用调用 mprotect 的 ROP 漏洞利用代码,在调用 int 0x80 eax 后设置为 0x0 表示成功。将执行转移到目标地址仍然会导致 SIGSEGV。我希望有人能告诉我哪里出了问题。
一些细节,目标地址是.data部分,这是我将通过shellcode写入的地方:
[20] 0x8146820->0x814c2b8 at 0x000fd820: .data ALLOC LOAD DATA HAS_CONTENTS
我将eax
设置为125
,ebx
设置为页面边界0x8146000
,ecx
设置为0x1000
(4096页面大小)和 edx
到 0x7
(RWX)。
就在系统调用之前,寄存器看起来像这样:
eax 0x7d 125
ecx 0x1000 4096
edx 0x7 7
ebx 0x8146000 135553024
esp 0xbffff2b0 0xbffff2b0
ebp 0x8d0e0f0 0x8d0e0f0
esi 0x804fb85 134544261
edi 0x43434343 1128481603
eip 0x80c0182 0x80c0182 <mprotect+18>
eflags 0x202 [ IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) disas $eip, $eip+20
Dump of assembler code from 0x80c0182 to 0x80c0196:
=> 0x080c0182 <mprotect+18>: int [=10=]x80
0x080c0184 <mprotect+20>: pop %ebx
0x080c0185 <mprotect+21>: cmp [=10=]xfffff001,%eax
0x080c018a <mprotect+26>: jae 0x80c7d80 <__syscall_error>
0x080c0190 <mprotect+32>: ret
在系统调用之后,寄存器是:
(gdb) si
0x080c0184 in mprotect ()
(gdb) i r
eax 0x0 0
ecx 0x1000 4096
edx 0x7 7
ebx 0x8146000 135553024
esp 0xbffff2b0 0xbffff2b0
ebp 0x8d0e0f0 0x8d0e0f0
esi 0x804fb85 134544261
edi 0x43434343 1128481603
eip 0x80c0184 0x80c0184 <mprotect+20>
eflags 0x202 [ IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
但是内存位置没有显示权限的变化,并且尝试在那里执行指令会终止应用程序:
(gdb) x/4x 0x8146820
0x8146820: 0x00000000 0x00000000 0x08146154 0x0000ea60
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x08146820 in data_start ()
欢迎就 how/what 调试或我做错了什么提出任何建议。
编辑
我 运行 它在 strace 下没有附加调试器,似乎 mprotect 调用成功,但执行失败:
stat64("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2197, ...}) = 0
mprotect(0x8146000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0} ---
+++ killed by SIGSEGV (core dumped) +++
从核心确认崩溃地址:
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x08146820 in data_start ()
您的 mprotect 调用有效。程序崩溃,因为 0x8146820
成立
0x0000
,反汇编为 add [eax], al
,eax
为零。但是地址 0
没有被映射。 (这就是段错误位于 si_addr=0
的原因)
我正在编写一些通过系统调用调用 mprotect 的 ROP 漏洞利用代码,在调用 int 0x80 eax 后设置为 0x0 表示成功。将执行转移到目标地址仍然会导致 SIGSEGV。我希望有人能告诉我哪里出了问题。
一些细节,目标地址是.data部分,这是我将通过shellcode写入的地方:
[20] 0x8146820->0x814c2b8 at 0x000fd820: .data ALLOC LOAD DATA HAS_CONTENTS
我将eax
设置为125
,ebx
设置为页面边界0x8146000
,ecx
设置为0x1000
(4096页面大小)和 edx
到 0x7
(RWX)。
就在系统调用之前,寄存器看起来像这样:
eax 0x7d 125
ecx 0x1000 4096
edx 0x7 7
ebx 0x8146000 135553024
esp 0xbffff2b0 0xbffff2b0
ebp 0x8d0e0f0 0x8d0e0f0
esi 0x804fb85 134544261
edi 0x43434343 1128481603
eip 0x80c0182 0x80c0182 <mprotect+18>
eflags 0x202 [ IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) disas $eip, $eip+20
Dump of assembler code from 0x80c0182 to 0x80c0196:
=> 0x080c0182 <mprotect+18>: int [=10=]x80
0x080c0184 <mprotect+20>: pop %ebx
0x080c0185 <mprotect+21>: cmp [=10=]xfffff001,%eax
0x080c018a <mprotect+26>: jae 0x80c7d80 <__syscall_error>
0x080c0190 <mprotect+32>: ret
在系统调用之后,寄存器是:
(gdb) si
0x080c0184 in mprotect ()
(gdb) i r
eax 0x0 0
ecx 0x1000 4096
edx 0x7 7
ebx 0x8146000 135553024
esp 0xbffff2b0 0xbffff2b0
ebp 0x8d0e0f0 0x8d0e0f0
esi 0x804fb85 134544261
edi 0x43434343 1128481603
eip 0x80c0184 0x80c0184 <mprotect+20>
eflags 0x202 [ IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
但是内存位置没有显示权限的变化,并且尝试在那里执行指令会终止应用程序:
(gdb) x/4x 0x8146820
0x8146820: 0x00000000 0x00000000 0x08146154 0x0000ea60
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x08146820 in data_start ()
欢迎就 how/what 调试或我做错了什么提出任何建议。
编辑 我 运行 它在 strace 下没有附加调试器,似乎 mprotect 调用成功,但执行失败:
stat64("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2197, ...}) = 0
mprotect(0x8146000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0} ---
+++ killed by SIGSEGV (core dumped) +++
从核心确认崩溃地址:
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x08146820 in data_start ()
您的 mprotect 调用有效。程序崩溃,因为 0x8146820
成立
0x0000
,反汇编为 add [eax], al
,eax
为零。但是地址 0
没有被映射。 (这就是段错误位于 si_addr=0
的原因)