How can I invoke buffer overflow? - c

I got a homework assignment asking me to invoke a function without explicitly calling it, using buffer overflow. The code is basically this:
#include <stdio.h>
#include <stdlib.h>
void g()
{
printf("now inside g()!\n");
}
void f()
{
printf("now inside f()!\n");
// can only modify this section
// cant call g(), maybe use g (pointer to function)
}
int main (int argc, char *argv[])
{
f();
return 0;
}
Though I'm not sure how to proceed. I thought about changing the return address for the program counter so that it'll proceed directly to the address of g(), but I'm not sure how to access it. Anyway, tips will be great.

The basic idea is to alter the function's return address so that when the function returns is continues to execute at a new hacked address. As done by Nils in one of the answers, you can declare a piece of memory (usually array) and overflow it in such a way that the return address is overwritten as well.
I would suggest you to not blindly take any of the programs given here without actually understanding how they work. This article is very well written and you'll find it very useful:
A step-by-step on the buffer overflow vulnerablity

That is compiler dependent, so no single answer can be given.
The following code will do what you want for gcc 4.4.1. Compile with optimizations disabled (important!)
#include <stdio.h>
#include <stdlib.h>
void g()
{
printf("now inside g()!\n");
}
void f()
{
int i;
void * buffer[1];
printf("now inside f()!\n");
// can only modify this section
// cant call g(), maybe use g (pointer to function)
// place the address of g all over the stack:
for (i=0; i<10; i++)
buffer[i] = (void*) g;
// and goodbye..
}
int main (int argc, char *argv[])
{
f();
return 0;
}
Output:
nils#doofnase:~$ gcc overflow.c
nils#doofnase:~$ ./a.out
now inside f()!
now inside g()!
now inside g()!
now inside g()!
now inside g()!
now inside g()!
now inside g()!
Segmentation fault

Since this is homework, I would like to echo codeaddict's suggestion of understanding how a buffer overflow actually works.
I learned the technique by reading the excellent (if a bit dated) article/tutorial on exploiting buffer overflow vulnerabilities Smashing The Stack For Fun And Profit.

Try this one:
void f()
{
void *x[1];
printf("now inside f()!\n");
// can only modify this section
// cant call g(), maybe use g (pointer to function)
x[-1]=&g;
}
or this one:
void f()
{
void *x[1];
printf("now inside f()!\n");
// can only modify this section
// cant call g(), maybe use g (pointer to function)
x[1]=&g;
}

While this solution doesn't use an overflow technique to overwrite the function's return address on the stack, it still causes g() to get called from f() on its way back to main() by only modifying f() and not calling g() directly.
Function epilogue-like inline assembly is added to f() to modify the value of the return address on the stack so that f() will return through g().
#include <stdio.h>
void g()
{
printf("now inside g()!\n");
}
void f()
{
printf("now inside f()!\n");
// can only modify this section
// cant call g(), maybe use g (pointer to function)
/* x86 function epilogue-like inline assembly */
/* Causes f() to return to g() on its way back to main() */
asm(
"mov %%ebp,%%esp;"
"pop %%ebp;"
"push %0;"
"ret"
: /* no output registers */
: "r" (&g)
: "%ebp", "%esp"
);
}
int main (int argc, char *argv[])
{
f();
return 0;
}
Understanding how this code works can lead to a better understanding of how a function's stack frame is setup for a particular architecture which forms the basis of buffer overflow techniques.

Related

Passing int arguments in mbed::Callback

#include "mbed.h"
#include <Callback.h>
InterruptIn up(p14);
void toggle1(int *player)
{
printf("%d \n", *player);
}
int main()
{
int player = 1;
up.rise(callback(toggle1, &player));
}
In the mbed callback function, why the result is not 1? It is 12784.
You are allowing your main function to return. After it returns, player will be out of scope so it might be overwritten with something else. In general, you never want to return from main in an embedded system, so I recommend adding while (1) {} at the end of your main function.
Also, using callback is a source of unnecessary complication and potential errors. I would just put player in a global variable (and mark it as volatile). Then you can simply do up.read(&toggle1).

Stack manipulation in C without using inline assembly [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I've been preparing for a coding contest, and came across this question on the Internet:
#include <stdio.h>
void a();
void b();
void c();
int main() { a(); printf("\n"); return 0; }
void a() { b(); printf("hi "); }
void b() { c(); printf("there "); }
void c()
{
int x;
// code here and nowhere else
}
The solution is to write code that would print out "hi there" instead of "there hi" (no additional printing functions may be used and code only goes in the comment block).
Since I've done some basic assembly coding, I realized that this could be done with stack manipulation using the integer x as the base.
I tried using gdb to find the return address of the functions and then swapped the return addresses of a and b. The compiler throws a segmentation fault, and thus I assume that I haven't used the proper return address.
How do I properly calculate the offset to find the return address? Info frame command on gdb wasn't helpful, as using the stack address value given there didn't work.
I'm running this on Linux using gcc.
I am not sure if the following will count. It's portable on POSIX. Basically you change the buffer of printf before its first call and manipulate that before before it's flushed to terminal
void c()
{
static int first = 1;
if (first) {
first = 0;
char buf0[BUFSIZ];
char buf1[BUFSIZ];
setvbuf(stdout, buf0, _IOFBF, BUFSIZ);
a();
memcpy(buf1, buf0 + 6, 3);
memcpy(buf1 + 3, buf0, 6);
memcpy(buf0, buf1, 9);
buf0[8] = '\n';
fflush(stdout);
exit(0);
}
}
You will get warnings on implicitly declaring library functions memcpy and exit. It's legal on C89 though discouraged. But in your case, no trick is too dirty, I guess. You can avoid the memcpy by copy the characters manually. You can avoid exit by instead redirect stdout through freopen. You can change BUFSIZ to a large constants if the system has a strangely small buffer size (smaller than 9). There are variants of this solution that don't require you to manually insert that \n and instead let the program exit normally from main and has the printf("\n") to put that end of line
This problem cannot be solved unless you smash the stack in the same way as an attacker smashes the stack of some process.
And to smesh the stack can be done only if you know each detail of implementation of the compiler, the problem is unsolvable otherwise.
If you know the details of the compilation (the stack structure in particular) you can use the address of the local x variable in order to obtain the addres of the current frame from the stack (of FRAME_C); in each frame is the base pointer of the previous frame and modify it.
The stack looks like that:
FRAME_MAIN = RET_OS some-data
FRAME_A = RET_MAIN some-data
FRAME_B = RET_A some-data
FRAME_C = RET_B some-data(including the variable `x`)
Using the &x we can detect the position of the FRAME_C.
One solution is
to print "Hi" in function c()
Modify FRAME_B such that RET_A to become RET_MAIN
return from function c() with return
The tricky operation is 2. but if each frame has a size that is known, then we can modify the return pointer RET_A of the frame B and detect RET_MAIN something like that:
*(&x+FRAME_C_SIZE+some-small-offset1) = /* *&RET_A = */
*(&x+(FRAME_C_SIZE+FRAME_B_SIZE)+some-small-offset2). /* *&RET_MAIN */
As you can see, you need to know a lot of details about the implementation of the compiler , so this is not at all a portable solution.
Other solution would be to print "hi, there" and redirect the stdout to /dev/null. I suppose that exit() or other compiler-depedent tricks are not allowed, otherwise the problem has no meaning for a contest.
my solution is for x86/x64 and for CL compiler, but think for gcc also exist.
question only - are exist equivalent for function :
void ** _AddressOfReturnAddress();
and are equivalent for __declspec(noinline) - for tell compiler to never inline a particular function
let
void* pb - is address in void b() just after c();
and
void* pa is address in void a() just after b();
because a and b almost the same - we can assume that
(ULONG_PTR)pa - (ULONG_PTR)&a == (ULONG_PTR)pb - (ULONG_PTR)&b;
and of course stack layout in a and b must be the same. based on this and solution.
next code tested/worked with CL compiler - on both x86/x64 (windows) and with /Ox (Full Optimization) and with /Od (Disable (Debug)) - all worked.
extern "C" void ** _AddressOfReturnAddress();
void a();
void b();
void c();
int main() { a(); printf("\n"); return 0; }
__declspec(noinline) void a() { b(); printf("hi "); }
__declspec(noinline) void b() { c(); printf("there "); }
__declspec(noinline) void c()
{
void** pp = _AddressOfReturnAddress();
void* pb = *pp;
void* pa = (void*)((ULONG_PTR)&a + ((ULONG_PTR)pb - (ULONG_PTR)&b));
for (;;)
{
if (*++pp == pa)
{
*pp = pb;
*_AddressOfReturnAddress() = pa;
return;
}
}
}

Bad memory access while calling function

Actually i developing using unit test.
But i break down my code in other form to ask for the error that i faced.
I have these declaration in my header file
typedef struct
{
void *topOfStack;
}Stack;
typedef enum {NUMBER,OPERATOR,IDENTIFIER}Token;
int operatorEvaluate(Stack *numberStack , Stack *operatorStack);
void * pop(Stack *stack);
The following is the respective source file
#include "try.h"
void *pop(Stack *numberStack)
{
Token *newToken = NUMBER;
return newToken;
}
int operatorEvaluate(Stack *numberStack , Stack *operatorStack)
{
Token *first = (Token*)pop (numberStack);
if(numberStack != operatorStack)
{
if(*first == NUMBER)
return 1;
}
return 0;
}
This is the source file that i call the functions which is main
#include "try.h"
#include <stdio.h>
int main ()
{
Stack numberStack;
Stack operatorStack;
int num;
num = operatorEvaluate(&numberStack , &operatorStack);
printf("This is the returned value: %d",num);
return 0;
}
When i tried to compile, the unit test tell me that bad memory access.
So i try to use eclipse to compile these, and windows tells that the .exe had stop working.
Hope someone can help me, i stuck for a long time...
Enable compiler warnings.
In particular, this makes zero sense:
Token *newToken = NUMBER;
That's a pointer, and you're assigning a value.
I cannot propose a fix, as I have no idea what you're doing.
That pop() function isn't touching the stack, and is returning an enum converted to a pointer. If you try to access anything through that pointer, it's going to provoke undefined behavior.
Your pop function is wrong in a few ways. You probably want it to actually pop your stack, rather than return a constant (which it isn't doing either, by the way!)...something like this:
void *pop(Stack *numberStack)
{
return numberStack->topOfStack;
}
but if you do that it'll still crash, because you never initialize your stack OR fill the topOfStack pointer.

Is it possible to exchange a C function implementation at run time?

I have implemented a facade pattern that uses C functions underneath and I would like to test it properly.
I do not really have control over these C functions. They are implemented in a header. Right now I #ifdef to use the real headers in production and my mock headers in tests. Is there a way in C to exchange the C functions at runtime by overwriting the C function address or something? I would like to get rid of the #ifdef in my code.
To expand on Bart's answer, consider the following trivial example.
#include <stdio.h>
#include <stdlib.h>
int (*functionPtr)(const char *format, ...);
int myPrintf(const char *fmt, ...)
{
char *tmpFmt = strdup(fmt);
int i;
for (i=0; i<strlen(tmpFmt); i++)
tmpFmt[i] = toupper(tmpFmt[i]);
// notice - we only print an upper case version of the format
// we totally disregard all but the first parameter to the function
printf(tmpFmt);
free(tmpFmt);
}
int main()
{
functionPtr = printf;
functionPtr("Hello world! - %d\n", 2013);
functionPtr = myPrintf;
functionPtr("Hello world! - %d\n", 2013);
return 0;
}
Output
Hello World! - 2013
HELLO WORLD! - %D
It is strange that you even need an ifdef-selected header. The code-to-test and your mocks should have the exact same function signatures in order to be a correct mock of the module-to-test. The only thing that then changes between a production-compilation and a test-compilation would be which .o files you give to the linker.
It is possible With Typemock Isolator++ without creating unnecessary new levels of indirection. It can be done inside the test without altering your production code. Consider the following example:
You have the Sum function in your code:
int Sum(int a, int b)
{
return a+b;
}
And you want to replace it with Sigma for your test:
int Sigma(int a, int b)
{
int sum = 0;
for( ; 0<a ; a--)
{
sum += b;
}
return sum;
}
In your test, mock Sum before using it:
WHEN_CALLED: call the method you want to fake.
ANY_VAL: specify the args values for which the mock will apply. in this case any 2 integers.
*DoStaticOrGlobalInstead: The alternative behavior you want for Sum.
In this example we call Sigma instead.
TEST_CLASS(C_Function_Tests)
{
public:
TEST_METHOD(Exchange_a_C_function_implementation_at_run_time_is_Possible)
{
void* context = NULL; //since Sum global it has no context
WHEN_CALLED(Sum (ANY_VAL(int), ANY_VAL(int))).DoStaticOrGlobalInstead(Sigma, context);
Assert::AreEqual(2, Sum(1,2));
}
};
*DoStaticOrGlobalInstead
It is possible to set other types of behaviors instead of calling an alternative method. You can throw an exception, return a value, ignore the method etc...
For instance:
TEST_METHOD(Alter_C_Function_Return_Value)
{
WHEN_CALLED(Sum (ANY_VAL(int), ANY_VAL(int))).Return(10);
Assert::AreEqual(10, Sum(1,2));
}
I don't think it's a good idea to overwrite functions at runtime. For one thing, the executable segment may be set as read-only and even if it wasn't you could end up stepping on another function's code if your assembly is too large.
I think you should create something like a function pointer collection for the one and the other set of implementations you want to use. Every time you want to call a function, you'll be calling from the selected function pointer collection. Having done that, you may also have proxy functions (that simply call from the selected set) to hide the function pointer syntax.

How to call a function just before returning in C?

I'm trying to execute something at the end of a function just before it returns to the caller.
To Do so, I would like to override return in a certain context. The behavior should be the same as __cyg_profile_func_exit, but I would like to activate it only for some functions.
I don't know if it's possible using gcc builtins or this kind of thing.
Thanks.
GCC has an attribute for this, which calls a function when an automatic variable goes out of scope, passing it the address of that variable
void cleanup_fn(int *p) {
puts("cleanup called...");
}
void f(void) {
int p __attribute__((cleanup(cleanup_fn)));
puts("in f...");
}
int main(void) {
puts("calling f...");
f();
puts("out of it...");
return 0;
}
Output:
calling f...
in f...
cleanup called...
out of it...
Nope, not in C per se.
What you could do is write a #define macro RETURN:
#define RETURN(func) if(_DEBUG_) func; return ;
#define RETURNV(func, val) if(_DEBUG_) func; return val ;
(Warning, you probably want to think a little more about guarding special cases than I have.)
Otherwise, you would need to write something that mangled the code behind the scenes, which is what profilers do.

Resources