Strange memory issue with sscanf - c

Using gcc-arm-none-eabi-5_42016q3-20160926 tool chain in eclipse.
Processor: STM32F030
I have a 3 line program that starts before any hardware initializations to isolate the problem:
int a;
char * num="3";
memset(0x20000970,0XAA, 0x20001f00-0x20000970);
sscanf(num, "%i",&a);
I have set the RAM to 0XAA so I can see what gets clobbered, leaving plenty of room for the stack.
After the memset instruction the stack pointer is at 0X20001F78, the memory is 0XAA up to 0X20001F00 as expected. After I execute the sscanf function the stack pointer is back at 0X20001F78 however memory was clobbered all the way down to 0X20001BB4 which makes me think that either this simple call took almost 1K of stack or there is some other error in the routine. I have stopped using this function but am curious whether this is expected behavior? Also, is there a list of C functions that one should avoid in embedded systems, this was a surprise to me but from searching I see I am not alone.

Related

Two shellcodes in one program result in segfault, how can I pass shellcode as parameter to a function?

I have two questions related to C programming and shellcoding (assembly) following below.
Question 1: Can anyone provide an answer on why putting two shellcodes in one program wouldn't work? I know it's related to the memory region but I need to know the exact reason. Program is compiled using gcc with the -zexecstack and -fno-stack-protector options.
#include <stdio.h>
#include <string.h>
main(int argc, char *argv[])
{
unsigned char shellcode[] = "\x01\x02<SHELLCODE>";
/* if the below line is uncommmented it will result in segault */
/* unsigned char shellcode_[] = "\x01\x02<SHELLCODE>"; */
int (*ret)() = (int(*)())shellcode;
return 0;
}
So how would it be possible to divide multiple shellcodes into different memory regions and call them without them interrupting the execution flow between each other, and decide which one to call? (I mean just STORE two shellcodes, not RUN them simultaneously, if that's possible at all).
Question 2: if the shellcode has to be passed as a parameter to a function, what would be the proper way to do it?
Pseudocode:
unsigned char shellcode[] = "\x01\x02...";
void call_shellcode(unsigned char shellcode[200]);
main()
{
call_shellcode(shellcode);
}
void call_shellcode(unsigned char shellcode[200])
{
... print/call shellcode
}
UPDATE: As there seems to be some misunderstanding to the question, this is not the ACTUAL shellcode. I do know what shellcode is and how it is generated, and how it works. I have not provided an actual shellcode within the C stub to leave it in a readable state. The value "\x01\x01" is a pseudo code to point to the idea of the question and NOT any actual contents.
Your shellcode cannot possibly work for a very simple reason: it begins with \x01\x02:
unsigned char shellcode[] = "\x01\x02<SHELLCODE>";
I'm not sure why your think your shellcode has to begin with those two bytes: it really doesn't!
Those two bytes decode to add DWORD PTR [rdx],eax (or edx if running in 32-bit mode). Since you do not have any control over the value of RDX/EDX at the time your shellcode is called, it will very likely immediately cause a segmentation fault because RDX/EDX does not contain a valid (and writable) memory address.
Changing literally anything around the shellcode, in the function or outside, could cause the compiler to choose a different register allocation that will result in RDX/EDX having a good value at runtime that doesn't result in a crash, but that'd just be a lucky coincidence. Writing and using shellcode like this is inherently undefined behavior, or at least implementation defined (fixed an operating system and compiler) so extra care must be taken.
So how would it be possible to divide multiple shellcodes into different memory regions and call them without them interrupting the execution flow between each other, and decide which one to call?
Well, you're not really dividing anything in "different memory regions"... whether you use one array or two or ten, they are all declared on the stack and they will be close together on the stack.
If you want to jump from one to the other, that's going to be a complex task, because in general you do not know the location of a variable on the stack beforehand, so you will have to do some math calculating your current location and then the offset from one shellcode chunk to the other, ultimately performing a relative call/jump.
If shellcode has to be passed as a parameter to a function what would be the proper way to do this?
The proper way is to mmap a region of memory that is RWX, write the shellcode into it (memcpy, read from stdin, etc.) and then pass a pointer to that memory region to the function you want. You have no guarantee that a piece of global data will be put by the compiler in an executable memory region. In fact, no modern day compiler would do that, and furthermore, no modern day kernel would map such a region as executable even if the ELF is compiled with -z execstack.
In recent kernels -z execstack is only respected for the stack itself, so passing a shellcode as function argument through a variable will only work if the variable was defined on the stack.
You can't have two variables with the same name in the same scope (this part has nothing to do with what the variables are or how they are used). Simply give the second shellcode a different name.
Note I am not going to comment at all on what you are trying to do, other than that I would not think of manually created machine code as "shell code" (which I would usually think of as code intended for a command shell like bash).

Running own code with a buffer overflow exploit

I am trying to understand the buffer overflow exploit and more specifically, how it can be used to run own code - e.g. by starting our own malicious application or anything similar.
While I do understand the idea of the buffer overflow exploit using the gets() function (overwriting the return address with a long enough string and then jumping to the said address), there are a few things I am struggling to understand in real application, those being:
Do I put my own code into the string just behind the return address? If so, how do I know the address to jump to? And if not, where do I jump and where is the actual code located?
Is the actual payload that runs the code my own software that's running and the other program just jumps into it or are all the instructions provided in the payload? Or more specifically, what does the buffer overflow exploit implementation actually look like?
What can I do when the address (or any instruction) contains 0? gets() function stops reading when it reads 0 so how is it possible to get around this problem?
As a homework, I am trying to exploit a very simple program that just asks for an input with gets() (ASLR turned off) and then prints it. While I can find the memory address of the function which calls it and the return, I just can't figure out how to actually implement the exploit.
You understand how changing the return address lets you jump to an arbitrary location.
But as you have correctly identified you don't know where you have loaded the code you want to execute. You just copied it into a local buffer(which was mostly some where on the stack).
But there is something that always points to this stack and it is the stack pointer register. (Lets assume x64 and it would be %rsp).
Assuming your custom code is on the top of the stack. (It could be at an offset but that too can be managed similarly).
Now we need an instruction that
1. Allows us to jump to the esp
2. Is located at a fixed address.
So most binaries use some kind of shared libraries. On windows you have kernel32.dll. In all the programs this library is loaded, it is always mapped at the same address. So you know the exact location of every instruction in this library.
All you have to do is disassemble one such library and find an instruction like
jmp *%rsp // or a sequence of instructions that lets you jump to an offset
Then the address of this instruction is what you will place where the return address is supposed to be.
The function will return then and then jump to the stack (ofcourse you need an executable stack for this). Then it will execute your arbitrary code.
Hope that clears some confusion on how to get the exploit running.
To answer your other questions -
Yes you can place your code in the buffer directly. Or if you can find the exact code you want to execute (again in a shared library), you can simply jump to that.
Yes, gets would stop at \n and 0. But usually you can get away by changing your instructions a bit to write code that doesn't use these bytes at all.
You try different instructions and check the assembled bytes.

Use of keep(int,int) function in TSR programming using dos.h

While studying tsr programming i have seen the use of certain code which i cannot understand..
The example cede part is(in c):
(please explain the bolded sections)
#include "dos.h"
#include"stdio.h"
void interrupt our();
void interrupt (*prev)();
char far *scr=(char far*)0xB8000000L;
int ticks;
unsigned char color;
main()
{
prev=getvect(8); // <<<<<
setvect(8,our); // <<<<<
keep(0,10000); // <<<<<
}
You would partially understand this code if you read the answer i posted to your similar question on TSR
How to write a TSR which changes case of characters
The most important things here are
Far pointer: Since 16 bit DOS used segment offset addressing scheme, your normal near pointer could not access memory beyond 64K of it's allocated segment. You have to read details to understand it.
Video memory address: This B8000000 is the address for which you need far pointer. The special thing about this address is, that starting from this location bytes (equal to the resolution of screen * 2) are copied directly into video memory.
So if you assign a character to a pointer address after indirection it will be printed on screen
Something like
char * far p = 0xB8000000;
*p = 'a'; // this would actually print a on screen at left top
Loop forward to get to the rest of the screen.
There was a c book by yashwant kanetkar which had a good deal of reference for this. I remember using it in my undergrad many years ago.
The rest of them are just indexing api's in dos.h. Why don't you go through their description and get back here if you don't understand any?
This program installs an interrupt handler. It uses interrupt number 8, the system timer interrupt. This was a common practice to use this interrupt to "continuously" do stuff on a machine running DOS.
prev=getvect(8);
This line gets the interrupt vector, that is, a pointer to a function that the system calls 18 times per second.
setvect(8,our);
This line sets the interrupt vector, that is, tells the system to call this function, instead of the old function, 18 times per second. Note that to avoid a crash, the new function must call the old function, in addition to its main purpose (which seems to be changing the case of characters).
keep(0,10000);
This line makes the program with exit code 0 (a conventional value for success) and tells DOS to leave 10000 bytes (or maybe 16-byte units? Unlikely; I don't remember) in RAM. This is unlike normal completion of program (exit(0)), where DOS marks all RAM previously occupied by the program as free.
A common cause of a crash in a TSR program is caused by the absence of keep at the end. DOS releases the memory occupied the by the code of the function our, and in the next 1/18 of a second, a random piece of code is executed.
See Int 21/AH=31h for more information.
Please note also that the parameter to keep should be calculated by manipulating some addresses, so that you don't take too much memory, and on the other hand, take enough memory to contain the code of the function our, which performs the stuff you need. The value 10000 is just an example.

detecting stack overwrite error

I'm developing a software for the Cortex-M3 embedded micro controller (Atmel SAM3S)
I using the IAR EWARM IDE & compiler.
I suspect that for some reason I have a buffer overflow, or a memory leak, which causes the stack to be corrupted, because I suddenly find myself stuck outside of my code space.
The reason I ask this question, is that it's really hard finding out what actually caused this mess-up, and I want to know which techniques are you using when you want to find out the cause of the issue.
Are you using memory debuggers, in-circuit trace debugging hardware, etc.
You should try using canary values. This is how it basically goes - say you have some struct:
struct foo {
unsigned long bar;
void * baz;
};
Modify it so it looks like this:
struct foo {
unsigned long canary1;
unsigned long bar;
void * baz;
unsigned long canary2;
};
When you initialize the struct, put some arbitrary values into canary1 and canary2. Whenever you do some operation on your struct, check if the values stay the same. This way, if you have a buffer overflow or stack smashing, you'll detect it. You can do the same inside functions with automatic variables:
int foo(int bar) {
unsigned long canary1 = 0xDEADBABE;
char baz[20];
unsigned long canary2 = 0xBAD0C0DE;
...
}
And so on. Don't forget to check that the values remain the same before you return. Also, if you can get your code to consistently jump to the same location, try putting some code there (or a breakpoint) and get a stack trace.
GCC knows how to add these canary values by itself, but I don't know if your compiler can do that. But you could still do it manually.
The program counter is a register, and as such it cannot be "overwritten". What might happen is, as you say, that the stack gets overwritten and then you execute a return instruction which reads an invalid return address from the stack, thus causing a jump into la-la-land.
My favourite debugging method is printing things out, which might be difficult on an embedded target, of course. The second-best would be to step through the suspect routine.
You should also investigate things that are known to cause jumps, such as interrupt service routines.
I had a similar issue using IAR EWARM on an STM32. Memory dumps, disassembly, canaries, all turned up nothing. Finally rolled back to an earlier version of EWARM and the problem went away. I sent a message to IAR support but never heard back. I'm sorry I don't remember which version of EWARM this was. It was a few projects ago.
I would keep a memory window open and try the canary test first. If it still randomly jumps out of code space, try installing an older version of EWARM.
One thing I can add is that with ARM chips, it is possible that there was a BL somewhere instead of a BX or BLX causing the chip to go into the wrong Thumb/ARM mode. Not as common with later chips, but still...
When I find jumps to nowhere, I look for bad function pointer tables, overwrites of any interrupt vector tables, and yes, stack overflow which is the easiest to test. Drop known bytes values into your stack area and when the crash occurs, see how much stack you had remaining with a debugger. If none, there you go.
I'd also do the standard see what's changed in the last X days stuff to try and isolate any problems. Finally, just printf the heck out of your code to try and narrow where the bad jump is occurring. If you can get it down to a function or two, you can trace the assembler and see if it's a compiler issue, a memory issue, or an interrupt issue pretty quickly. Good luck!

Example of a buffer overflow leading to a security leak

I read many articles about unsafe functions like strcpy, memcpy, etc. which may lead to security problems when processing external data, like the content of a file or data coming from sockets. This may sound stupid, but I wrote a vulnerable program but I did not manage to "hack" it.
I understand the problem of buffer overflow. Take this example code:
int main() {
char buffer[1];
int var = 0;
scan("%s", &buffer);
printf("var = 0x%x\n", var);
return 0;
}
When I execute the program and type "abcde", the program outputs 0x65646362 which is "edcb" in hexadecimal + little-endian. However I read that you could modify the eip value that was pushed on the stack in order to make the program execute some unwanted code (eg. right before a call to the system() function).
However the function's assembly starts like this:
push %ebp
mov %ebp, %esp
and $0xfffffff0, %esp
sub $0x20, %esp
Since the value of %esp is random at the start of the function and because of this "and", there seems to be no reliable way to write a precise value into the pushed eip value.
Moreover, I read that it was possible to execute the code you wrote in the buffer (here the buffer is only 1 byte long, but in reality it would be large enough to store some code) but what value would you give to eip in order to do so (considering the location of the buffer is random)?
So why are developpers so worried about security problems (except that the program could crash) ? Do you have an example of a vulnerable program and how to "hack" it to execute unwanted code? I tried this on linux, is Windows less safe?
Read the excellent article by Aleph One: Smashing the Stack for Fun and Profit.
Well for one thing, don't under estimate the hazards associated with being able to unreliably place a value inside EIP. If an exploit works one in 16 times, and the service it is attacking automatically restarts, like many web applications, then an attacker that fails when trying to get access can always try, try again.
Also in a lot of cases the value of ESP is less random than you think. For starters on a 32-bit system it is nearly always a multiple of four. That means that the extra padding offered by the and $0xfffffff0, %esp instruction will be either 0, 4, 8 or 12 bytes. That means that it is possible to just repeat the value that is to be written into the return EIP four times to cover all possible offsets to the address of return EIP.
There are actually much more aggressive stack protection / buffer overflow detection mechanisms around. However, there are ways and means around even these.
Also, for an example of where this sort of thing can be dangerous, consider if the value of var was important to you logic as in the following toy example.
int main() {
char buffer[1];
int var = 0;
var = SecurityCheck();
scan("%s", &buffer);
if (var != 0)
GrantAccess();
else
DenyAccess()
}
Further you don't have to overwrite EIP with a pointer to something in your string. For example you could overwrite it with a pointer to system() and overwrite the next word with a pointer to /bin/sh at a fixed location in the program image.
Edit: Note that system uses the PATH (actually it runs the command via a shell), so "sh" would be just as good; thus, any English word ending in "sh" at the end of a string provides the argument you need.
A classic example of an actual exploit based on buffer overruns is the Morris Worm of 1988.
As mentioned in other answers, absolute reliability is not always essential for the attack to succeed. Applications that restart automatically are an example. Locally exploitable buffer overflows on suid programs would be another. And there's the NOP sled technique to increase chances of successful exploitation, put a lot of NOPs before your shellcode so you have a much better chance to correctly guess the "start" of your shellcode.
There are many more techniques for increasing the reliability of attacks. On Windows, back in the day, many exploits overwrote the return address with the address of a "jmp %esp" located somewhere in the program (trampoline).
"Insecure programming by example" had a nice trick for Linux. Clean your environment and put your shellcode in an environment variable. Back in the day, this would lead to a predictable address near the top of the stack.
And there are also variants like return-into-libc and return-oriented programming.
There was even an article on Phrack on how to exploit 1-byte stack overflows (meaning the buffer was overrun by only one byte) (btw, 1-byte heap overflows are also exploitable in the vast majority of cases, barring protections).
To sum up, it's not that developers are paranoid, there are lots of ways to exploit even the strangest cases, and remember:
A program is of good quality when it does what it is supposed to do.
A program is secure when it does what it is supposed to do, and nothing more.
Here's a windows version and tutorial:
http://www.codeproject.com/KB/winsdk/CodeInject.aspx
The general case I was always warned about was:
printf( string );
Because the user can provide a "%n" in there, which allows you to insert anything you want into memory. All you need to do is find the memory offset for a system call, pass a few "%n"'s and junk characters, and thus insert the memory address onto the stack where the return vector would normally be. Voila -- insert any code you like.

Resources