
plaintext
Copy code
java -XX:ErrorFile=/tmp/java_error%!p(MISSING).log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof -XX:+CrashOnOutOfMemoryError -XX:OnOutOfMemoryError="gcore %!p(MISSING)kill -9 %!p(MISSING)" YourJavaProgram
其中,-XX:ErrorFile用于指定JVM错误日志的保存路径,-XX:+HeapDumpOnOutOfMemoryError用于在发生内存溢出时生成堆转储文件,-XX:HeapDumpPath用于指定堆转储文件的保存路径,-XX:+CrashOnOutOfMemoryError用于在发生内存溢出时直接崩溃,-XX:OnOutOfMemoryError用于在发生内存溢出时执行指定的命令。在这个例子中,我们使用gcore命令生成core文件,并将进程杀掉。
在生成了core文件之后,你可以使用gdb来分析core文件。首先,你需要使用以下命令启动gdb:
plaintext
Copy code
gdb YourJavaProgram core
其中,YourJavaProgram是你的Java程序的可执行文件名,core是你生成的core文件名。启动gdb后,你可以使用gdb命令来分析core文件,例如,可以使用bt命令来查看堆栈信息,使用info命令来查看线程信息等等。
需要注意的是,在使用gdb分析core文件时,你需要了解Java程序的内部实现,例如,你需要知道Java线程是如何映射到 *** 作系统线程的,以及Java对象是如何映射到内存中的。否则,你可能无法正确地分析core文件,或者分析结果可能不准确。
CHECK THE MESSAGE "(core dumped)" and the generation of the 'core' file.
If you do not see the message or the core file on crash,
please run the following command again, and also check the current working
directory.
This command will open a gdb session at the crash point. The coredump file
contains a system's status at the crash point, which includes memory,
register, type of signal on crash (mostly SIGSEGV), etc.
You cannot execute (e.g., using r, ni, si) because the execution was
terminated, but you can still check the memory.
Core was generated by
Program terminated with signal SIGSEGV, Segmentation fault.
This output means that the coredump is generated by './frame-pointer-32',
and the program crashed at 0x8048635 with the signal SIGSEGV.
You can see that the program uses the stack address around 0xffffd5c0,
and the frame pointer (%ebp) has been changed to 0x41414141.
And to check the cause of the crash, let's check what is the current instruction.
x/i means that "examine instruction", and the eip, actually).
Because the value of %ebp is 0x41414141, which is an invalid address,
SIGSEGV was raised on running leave instruction because it will change
%esp = 0x41414141 then run "pop %ebp" (dereferencing 0x41414141).
You already know that this challenge is about changing the frame pointer (%ebp)
to control the execution (return address) at the end.
The important part of launching such attack is to know where the start of my
input buffer is on the stack.
Some of you are suffering the problem that your attack works on the samples
binary but does not work with challenges binarythis is because the stack
layout could be different on each program execution, so the starting address
of your buffer could be different in challenge binary than the sample binary.
To get the exact address in the challenge binary, you can get the 'corefile'
of the challenge binary by running it and generating the crash because
corefile contains the exact content at the crash point. In other words,
if you get the address of your buffer in the corefile, the same address
was being used on its execution!
Let's check how to get that in the corefile.
You can start with the current stack (%esp), however, there are two function
calls (non_main_func() ->input_func()). While your input resides in the
local stack of input_func(), your current execution is on the non_main_func()
(frame-pointer attack returns twice, and crash by invalid %ebp requires
two returns to generate SIGSEGV).
We can presume that stack has moved up little bit, because there is the code for
leaveret, which rolls back the local stack of input_func().
So let's examine the stack values from somewhere below the stack (%esp)
x/100x $esp - 0x200 this command will display upto 100 4-byte integer values
from the address %esp-0x200 (the location 0x200 before the espyou can use +
to see upwards).
While we were injecting the input of "A"*200, which will be lots of 0x41414141,
I cannot see that on the stack. Let's move upwards (pressing the enter again).
Ah, now I can see several 0x41414141s .
It seems the buffer starts at 0xffffd560 (for the samples/frame-pointer-32) binary.
Then, what if I run the program in the challenges directory?
Let's check with the core.
-- GDB --
Core was generated by `../challenges/frame-pointer/frame-pointer-32'.
Program terminated with signal SIGSEGV, Segmentation fault.
Ah, now you can see that the address starts at 0xffffd510 (contains 0x41414141).
Previously, it was 0xffffd560 but now it is 0xffffd510 (changed!).
In a subsequent running of the challenge program, this address value will be
the same if your running command is the same
(i.e., runs ../challenges/frame-pointer/frame-pointer-32,
not in the different path or something).
A shortcut to have a correct address value is that, when you are using
pwntools (writing a python script), the program execution within pwntools
will also generate a corefile to your directory.
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)