I have i binary that can be exploited with a buffer overflow, but it has a stack canary
I can get many addresses and values through a gets() call, but i cant locate the stack canary in pwndbg( version of gdb) so i can find out what of the values i get is the stack canary
I tried looking on the stack but cant find it and looked at a script that can already exploit it and it uses a canary value (by this i mean index of the leaked addresses from the gets() ) that i cant even find in the disassembler
I am missing some key details here, but I'll try to give this a go.
Firstly, the canary is not going to be on the stack, but between stack frames:
https://manybutfinite.com/img/stack/bufferCanary.png
Googling "stack canary location gcc" yields a couple images to help you understand this mechanism more easily.
Secondly, I am not quite sure what do you mean by using gets() to read. gets() reads the stdin and puts it into a buffer. You will not be able to use it to read program memory.
Regarding the script that is already working: I am skeptical.
From the gcc docs (https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html):
The guards are initialized when a function is entered and then checked when the function exits.
It might be possible that the code that manages to exploit it either has stack protector turned off in the binary, or it finds another way to bypass this protection by some other means. You can, for example overflow a local function pointer and not trigger the stack protector at all. The stack protector only protects against overflowing into the stored RBP and RIP (32bit: EBP and EIP), not against overflowing into local variables.
Related
So let's say I have created a thread, on Windows OS, for which I know that the default stack size is much more than what is needed. Can I then run the application and ask the thread about the amount of stack it actually has used so that I know how much I should set its stack size instead of the default stack size?
Windows usually doesn't commit the entire stack, it only reserves it. (Well, unless you ask it to, e.g. by specifying a non-zero stack size argument for CreateThread without also passing the STACK_SIZE_PARAM_IS_A_RESERVATION flag).
You can use this to figure out how much stack your thread has ever needed while running, including any CRT, WinAPI or third-party library calls.
To do that, simply read the StackBase and StackLimit values from the TEB - see answers to this question for how to do that. The difference of the two values should be the amount of stack memory that has been committed, i.e. - the amount of stack memory that the thread has actually used.
Alternatively, if a manual process is sufficient: Simply start the application in WinDBG, set a breakpoint before the thread exits and then dump the TEB with the !teb command. You can also dump the entire memory map with !address and look for committed areas with usage Stack.
This question is to get ideas. So basically we have run into a particular crash, where the backtrace is meaningless above some frame. This is from an ARM based binary. We were unable to reproduce the issue yet, which hardens the analysis. Some observations first:
Nearly all the required libraries' unstripped shared libraries are available so the backtrace should be ok normally
However, the backtrace points on frame 3 to a memory address, which is clearly not in the code segment
That problematic memory address is also visible in some argument parameters
Register info shows unaligned address on R3 register. Disassemble shows that stmia ASM operation on it, which was the root cause - it caused sigbus.
All in all, this is because of a corrupted memory, stack, etc. I have only limited information right now. I want to trace back at least where this call came, but because of the corruption, I am now not really able to find it.
Do you have any ideas, how to proceed which such problems? Any tools, which can help me to analyze the assembly flow and data and registers in a better environment, maybe seeing the stack, etc in a more intuitive way? Much thanks in advance!
EDIT: To be a bit more precise: how would you try to find out what was above frame 2? Is it possible in some scenarios to decode it back, even though the stack was somehow corrupted? Or finding out what corrupted it?
EDIT2: i think i will debug that function and I saw a particular log line before the crash. I will place a breakpoint and check where the calls are coming, albeit it is a very generic méthod, plus the initialization functions' orders are really fuzzy. Have no other clue. Do you have some "intuitive reading ASM level data from core file" tool idea?
Is there a way to monitor the call stack size in Visual Studio ? A call stack window is provided while running but does not show the size of the stack. I am using C++ and facing stack overflow issue. I know something might be wrong about some recursive functions I am using, but before solving these issues I would like to monitor the call stack size to see what is going on.
Using a data breakpoint can be helpful here. Wherever you happen to be in the code, it doesn't matter as long as you are on the right thread, use Debug + New Breakpoint + New Data Breakpoint. In the address box type #esp - 250000. Press F5 to continue running and it will break somewhere inside the recursion when a quarter of the available stack space has been consumed. The exact offset from esp isn't critical.
There are a few ways:
Examine ESP in the watch window. You can do this by watching #esp in the watch window. Compare this to what ESP was at the start of the process.
Similarly, examine the address of stack-allocated variables in first / last stack frames.
Note that the stack is usually allocated backwards, so as the stack grows, ESP gets smaller and smaller.
The "Microsoft Recommended Native Rules" Code Analysis can look at your code and find problems with your code that might overflow your stack. I'm not sure how good it is at finding a recursion problem, but it did find an issue in my code where I used a local instance of a class that was very big (1MB). At runtime, the only error was a stack overflow. It's a bad idea to use large objects on the stack of course; you should only use small objects and objects that store most of their dirty laundry on the heap.
In VS2012, right-click on the project Properties, and select Code Analysis, then click the checkbox to Enable Code Analysis. It takes a few minutes to run.
I'm having problems with stack overflows and would like to see exactly what the contents on the stack are.
How can I examine the stack frame with GDB? is kind of the same question, however info locals looks fine here (few variables, most of them std::vectors and std::maps), so I wouldn't expect the stack to overflow from this. Moreover, I have set the stack limit to 32MB, so this should be plenty and no recursive functions are used.
Is there a tool that can show the complete contents of the stack, maybe ordered by size?
Stack overflows are better caught by special profilers rather than manually looking at variables in gdb. It is more likely that you have buffer overrun rather than stack overflow. In either case, here is a list of some profilers that can help you to point out the problem:
Valgrind
Purify
Insure++
Electric Fence
Good luck!
Even if you have no functions that call themselves, it's possible you've created a situation in which two or more functions are mutually recursive.
A good starting point would be to examine not the current stack frame, but a list of stack frames, using the "backtrace" (or "bt" for short) command. If you see a repeated pattern of two or more functions calling each other, then you have mutual recursion.
You can examine the current stack frame using the backtrace command.
You can also get the current stack pointer in gdb (e.g., by running 'info registers') and then dump the memory around that location using the examine (or 'x') command. Just be aware that the stack pointer points below the stack, so you need to start dumping from stack pointer - N to see the first N bytes on the stack.
I just ran into an issue where a stack overflow in a threaded c++ program on HPUX caused a SEGV_MAPERR when a local object tried to call a very simple procedure. I was puzzled for a while, but luckily I talked to someone who recognized this as a stack size issue and we were able to fix the problem by increasing the stack size available to the threads.
How can I recognize when the stack overflows? Do the symptoms differ on windows/linux/hpux?
Assuming you're not on a platform thats going to stop your app and say "stack overflow" I suspect you'll see the same behavior that you would see from any kind of buffer overflow. The stack is just another preallocated chunk of memory for your program, and if you go outside those bounds... well good luck! Who knows what you'll stomp on!
You could write over the temperature readout from the CPU, it could be the email you're typing to Larry, it could be the bit saying that the kernel is locked, causing a fun deadlock condition! Who knows.
As for C++, there's nothing saying how the stack should be laid out in relation to other things in memory or that this thing even needs to be a stack!
How can I recognize when the stack overflows?
If you know the stack size, where the stack starts and the direction it grows in memory, you can simply check the address of the stack pointer and see if it past the end of the stack. C++ does not allow direct access to the stack pointer. You could easily write a small function in assembly to perform this analysis and link it into you program.
Exception code 0xC00000FD on Windows.
Usually it's easier to diagnose when you realize your SEH stops working.
Perhaps a bit off topic, but the analagous issue in Ada (running out of stack space in tasks) is a rather common "uncommon" error. Many compilers will stop the task (but not the main task) with a PROGRAM_ERROR exception.
In a way, you almost have to be able to sniff out this one. It tends to start with something like, "I moved this big array inside my task, and suddenly it quit working".
Output text to screen became mixed with lines of code from program under test. Also present were previous bash commands and other text of unidentified origin. Added to all that the program text became corrupted.