Overflowing Buffer by specific integer - c

So If I had this code:
int main() {
char buff[20];
int x = 0;
gets(buff);
if (x==1337) {
print("Congrats");
}
printf("%d\n", x);
return 0;
}
Knowing that this is written in C (not that it matters too much), how would one go about overflowing this char[] by exactly 1337?
And also, I don't really understand the output I'm getting.. For example, if I run this code and input:
12345678901234567890a
The output is:
0
In fact, I have to overflow my char[] by an additional 8 characters past my array size before the data leaks into the value for X. I have no idea why this is, and would really like some help if somebody understand that.. However, it doesn't stop there.
If my input is:
1234567890123456789012345678aa
My output is:
24929
This throws me for quite a twirl.. Since I would've expected it to either overflow by the char value of a+a or maybe even a*a, alas it is neither. (the char value of a is 97).
So to sum it up, since I now it is probably confusing.. I would like to know how to overflow a buffer (in C) into an int, leaving the int a very specific value (in this case 1337). And in addition, if you could explain how these numbers are coming out, I would greatly appreciate it! By the way, it might help to mention the code is being executed on a Linux shell.

Since this is probably homework, rather than give you a direct answer, what I'm going to do is show you the C program that does what you thought your program would do, and how it behaves when fed over-length input.
#include <stdio.h>
int main(void)
{
struct {
char buff[20];
volatile unsigned int x;
} S;
S.x = 0;
gets(S.buff);
if (S.x == 1337)
puts("Congrats");
else
printf("Wrong: %08x\n", S.x);
return 0;
}
The key difference is that I am forcing the compiler to lay out the stack frame a particular way. I am also printing the value of x in hexadecimal. This makes the output both more predictable, and easier to interpret.
$ printf 'xxxxxxxxxxxxxxxxxxxxABCD' | ./a.out
Wrong: 44434241
$ printf 'xxxxxxxxxxxxxxxxxxxxABC' | ./a.out
Wrong: 00434241
$ printf 'xxxxxxxxxxxxxxxxxxxxAB' | ./a.out
Wrong: 00004241
$ printf 'xxxxxxxxxxxxxxxxxxxxA' | ./a.out
Wrong: 00000041
Everything that confused you is caused by one or more of: the compiler not laying out the stack frame the way you expected, the ordering of bytes within an int not being what you expected, and the conversion from binary to decimal obscuring the data in RAM.
Exercise for you: Compile both my program and your original program in -S mode, which dumps out the generated assembly language. Read them side by side. Figure out what the differences mean. That should tell you what input (if any -- it might not be possible!) will get your program to print 'Congrats'.

Related

Why am I getting this huge numbers in C?

I'm trying to teach myself C using Kernighan's book and I'm supposed to make a graph that indicates how many letters there are in each word. I haven't got to the "plotting" part as I'm getting really weird and enormous numbers at the output. Right now I'm just trying to have the value of the first and second elements of the array "arreglo" printed.
The code is the following:
#include <stdio.h>
#define ARRAY_SIZE 100
/*#define AUX 0
#define AUX2 0*/
main()
{
int s,j,noletra,i,arreglo[ARRAY_SIZE],otros, nopalabra, c;
int a;
nopalabra=1;
while((c=getchar())!=EOF)
{
if(c==' '||c=='\t'||c=='\n')
++nopalabra;
else
++arreglo[nopalabra];
}
printf("%d",arreglo[1],arreglo[2]);
}
The reason I'm trying to know the value in the second element in the array is that the first element has the correct value. The code is supposed to add 1 to the array index which is the number of words each time a space, tab or \n is typed and to add 1 to the array element whenever something different than the previously mentioned characters is typed (Letters). Right now it´s supposed to print correctly the number of the letters of two words, the first element is correctly printed but the second is a huge number, the output is:
alan amaury
^Z
4 8257542
--------------------------------
Process exited after 7.773 seconds with return value 9
Press any key to continue . . .
The output is supposed to be 4 7. I'm using a compiler in windows so EOF should be Ctrl+Z
Any help that I could get from you will be appreciated :)
At least these problems.
int arreglo[ARRAY_SIZE]; is not initialized before its elements are incremented. This is the mostly likely cause of "Why am I getting this huge numbers" #ikegami
// int arreglo[ARRAY_SIZE];
// replace with
int arreglo[ARRAY_SIZE] = { 0 };
Code can access out of array bounds as nopalabra is not confined to 0 to 99.
#define ARRAY_SIZE 100
int arreglo[ARRAY_SIZE];
++arreglo[nopalabra]; // No access protection
printf("%d",arreglo[1],arreglo[2]); only prints arreglo[1]
Logic flow is incorrect to "make a graph that indicates how many letters there are in each word."
main() return type not coded.
Some pseudo-code as an alternative
int main(void) {
set all arreglo[] to 0
int nopalabra = 0;
part_of_word = false; // Keep track of word state
loop forever {
get a character into c
if c is a separator or EOF
if (part_of_word) {
arreglo[nopalabra]++;
part_of_word = false;
nopalabra = 0;
if (c == EOF) break loop
} else {
nopalabra++;
part_of_word = true;
}
}
print out results
}
First, try the solution answered before, changing the printf() call.
If there is still a problem try:
printf("%d %d \n",arreglo[1],arreglo[2]);
Just before the while loop, to see if the "arreglo" array is initialize to 0's or just random values.
On the side:
Your call to printf() has more parameters than covered by the format string.
So you should clean up your code to something similar to
printf("%d %d\n", arreglo[1], arreglo[2]);
Concerning the strange output:
A way of getting surprising values is using non-initialised variables.
In your case the lack of initialisation affects the array arreglo.
Make sure to initialise it, so that all counting starts on a meaningful value.
Another way of getting seemingly very high values is printing several numbers next to each other, without separating white space in between.
So the " " and the "\n" in the format string I proposed are quite relevant.
the question is: "Why am I getting this huge numbers in C?"
the answer is: you have not assigned anything to arreglo array, and since you have not initialized it, you got some random values that have been there in memory. Trust me on this, I have run your code in debugger, which I also highly recommend a a standard practice while lerning to program.
Also, this is a common mistake where the format specifier is not written:
printf("%d",arreglo[1],arreglo[2]);
See if using printf("%d","%d",arreglo[1],arreglo[2]) solves your problem.
By the way, K&R book is very old, and written at the time where there have been no other C books. There are better ways to learn C.

Why does this float array element print properly, but not this double array element?

I'm learning the basics of C right now.
I am trying to input data into an array. After some trial and error, I've found that I can do what I need to using a float array as opposed to a double array.
#include <stdio.h>
int main()
{
float x[4]={2.2,3.3,4.4,5.5};
scanf("%f",&x[3]);
printf("%f",x[3]);
return 0;
}
The user input 3 would result in 3.000000
However in this version:
#include <stdio.h>
int main()
{
double x[4]={2.2,3.3,4.4,5.5};
scanf("%f",&x[3]);
printf("%f",x[3]);
return 0;
}
The user input 3 would result in 5.500001
Why is this, and how can I properly enter values to/print out the array values?
First, you have memory trampling due to use of incorrect format specifiers. First, the corrected example, with less "noise".
#include <stdio.h>
int main(void)
{
double x = 5.5;
scanf("%lf", &x);
printf("%lf", x);
return 0;
}
Second, you should try and avoid scanf() in general for string parsing, and considering reading on a per-line basis (ie: fgets() or some other mechanism), and then writing a parser. There is a plethora of closed/dupe questions on this site for questions like yours alone. Plus, other things, like newlines being left in the input buffer.
Finally, three good points:
David C. Rankin notes: use gcc -Wall -Wextra to catch all compiler warnings. Append -Werror if you want to force yourself not to allow any warnings to get by).
Look into learning how to to use gdb to debug programs. It's dead simple: compile with debug symbols and debug mode (and zero optimizations) configured via: gcc -O0 -ggdb, and then gdb my_program_name; joy!).
Consider building your programs with stack smash detection enabled (gcc -fstack-protector-strong). It will intentionally "crash" (assert) your programs early if you're doing something very wrong, like what happened in your example. It lets you discover serious memory trampling issues during testing rather than in production. Now isn't a bad time to learn about valgrind, strace, ptrace, helgrind, perf, etc, while you're at it.
Best of luck!

Uninitialized local variable in C

I am learning C and found a similar question on a website.http://www.careercup.com/question?id=5707884834848768
I tried to understand it by writing my own program
int main()
{
int i;
printf("%d\n", i);
int *ptr = &i;
int**ptr2= &(ptr);
return 0;
}
When the two pointer assignments are commented out, the output of this program is a random garbage value each time it is executed.
If I uncomment the first pointer assignment, the output is always a fixed value (134513705).
If I uncomment the second pointer assignment, the output is always 0.
I tried to understand it by using size command for a.out
text data bss dec
1141 252 8 1405
1157 256 8 1421
1157 256 8 1421
So, even though data values are same in 2nd and 3rd cases, the output is different.
Why is the output having different values in the three cases?
As you can tell from the comments the expected output of this program is undefined. The reason for this is that the variable i was never initialized. Commenting out or adding back the pointer declarations is a bit of a red herring. Your printf statement renders the memory that 'i' is using in whatever state it is found. Running this on ideone.com outputs 0 regardless of what lines I comment in or out. Likely this is because they clear the memory before code execution. You could probably even change the output with different compiler options. The takeaway is that an uninitialized variable is a view on uninitialized memory and doesn't have a defined value.

How is this loop ending and are the results deterministic?

I found some code and I am baffled as to how the loop exits, and how it works. Does the program produce a deterministic output?
The reason I am baffled is:
1. `someArray` is of size 2, but clearly, the loop goes till size 3,
2. The value is deterministic and it always exits `someNumber` reaches 4
Can someone please explain how this is happening?
The code was not printing correctly when I put angle brackets <> around include's library names.
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
int main() {
int someNumber = 97;
int someArray[2] = {0,1};
int findTheValue;
for (findTheValue=0; (someNumber -= someArray[findTheValue]) >0; findTheValue++) {
}
printf("The crazy value is %d", findTheValue);
return EXIT_SUCCESS;
}
Accessing an array element beyond its bounds is undefined behavior. That is, the program is allowed to do anything it pleases, reply 42, eat your hard disk or spend all your money. Said in other words what is happening in such cases is entirely platform dependent. It may look "deterministic" but this is just because you are lucky, and also probably because you are only reading from that place and not writing to it.
This kind of code is just bad. Don't do that.
Depending on your compiler, someArray[2] is a pointer to findTheValue!
Because these variables are declared one-after-another, it's entirely possible that they would be positioned consecutively in memory (I believe on the stack). C doesn't really do any memory management or errorchecking, so someArray[2] just means the memory at someArray[0] + 2 * sizeof(int).
So when findTheValue is 0, we subtract, then when findTheValue is 1, we subtract 1. When findTheValue is 2, we subtract someNumber (which is now 94) and exit.
This behavior is by no means guaranteed. Don't rely on it!
EDIT: It is probably more likely that someArray[2] just points to garbage (unspecified) values in your RAM. These values are likely more than 93 and will cause the loop to exit.
EDIT2: Or maybe someArray[2] and someArray[3] are large negative numbers, and subtracting both causes someNumber to roll over to negative.
The loop exits because (someNumber -= someArray[findTheValue]) doesnt set.
Adding a debug line, you can see
value 0 number 97 array 0
value 1 number 96 array 1
value 2 number 1208148276 array -1208148180
that is printing out findTheValue, someNumber, someArray[findTheValue]
Its not the answer I would have expected at first glance.
Checking addresses:
printf("&someNumber = %p\n", &someNumber);
printf("&someArray[0] = %p\n", &someArray[0]);
printf("&someArray[1] = %p\n", &someArray[1]);
printf("&findTheValue = %p\n", &findTheValue);
gave this output:
&someNumber = 0xbfc78e5c
&someArray[0] = 0xbfc78e50
&someArray[1] = 0xbfc78e54
&findTheValue = 0xbfc78e58
It seems that for some reason the compiler puts the array in the beginning of the stack area, then the variables that are declared below and then those that are above in the order they are declared. So someArray[3] effectively points at someNumber.
I really do not know the reason, but I tried gcc on Ubuntu 32 bit and Visual Studio with and without optimisation and the results were always similar.

Stack Overflow Exploit in C

The question is actually about stack overflows in C.
I have an assigment that I can not get done for the life of me, I've looked at everything in the gdb and I just cant figure it.
The question is the following:
int i,n;
void confused()
{
printf("who called me");
exit(0);
}
void shell_call(char *c)
{
printf(" ***Now calling \"%s\" shell command *** \n",c);
system(c);
exit(0);
}
void victim_func()
{
int a[4];
printf("[8]:%x\n", &a[8]);
printf("Enter n: "); scanf("%d",&n);
printf("Enter %d HEX Values \n",n);
for(i=0;i<n;i++) scanf("%x",&a[i]);
printf("Done reading junk numbers\n");
}
int main()
{
printf("ls=736c --- ps = 7370 --- cal = 6c6163\n");
printf("location of confused %x \n", confused);
printf("location of shell_call %x \n", shell_call);
victim_func();
printf("Done, thank you\n");
}
Ok, so I managed to get the first question correctly, which is to arbitrarily call one of the two functions not explicitly called in the main path. By the way, this has to be done while running the program without any modifications.
I did this by running the program, setting N to 7, which gets me to the Function Pointer of the victim_func frame, I write a[7] with the memory address of confused or shell_call, and it works. (I have a 64 bit machine, thats why I have to get it to 7, since the EBI pointer is 2 ints wide, instead of 1)
My question is the following, how could I control which argument gets passed to the shell_code funcion? ie. how do I write a string to char* c.
The whole point is executing unix commands like ps etc, by running only the program.
I figured writing the EBI pointer with the hex representation of ps and setting the arg list of shell_call to that, but that didn't work. I also tried inputing argsv arguments and setting the arg list of shell_call to the arg_list of main, but didn't work either.
I think the second version should work, but I believe I'm not setting the arg list of the new stack frame correctly ( I did it by writing a[8] to 0, since its the first part of the function pointer, and writing a[9]=736c and a[10]=0000, but its probably not right since those are the parameters of victim_func. So how do I access the parameters of shell_call?
I probably shouldn't do your homework for you. But the basically:
You need to get a character buffer somewhere in memory to store the string you want to execute. Obviously, you can do this the same way you are getting the other functions called (i.e. you put the text on the stack as well). After you have that written, you need to write a pointer to it on to the stack in the location that the shell_code function expects to find its arguments.
The best way to figure this out without me doing all of the work for you is to write down your stack/memory contents on a piece of paper/whiteboard. Write down how it would look if you called shell_code normally from inside the program. Then write down what the stack looks like inside victum_func and figure out which things to change to get it to look like it would look "naturally" (of course keeping in mind some things are "don't cares" like the return address).
That's all the charity you're gonna get from me today! :-P
SoapBox already did a great job of leading you in the right direction.
For more information;
http://www.skullsecurity.org/wiki/index.php/Example_4
You need to manipulate the stack-frame of the caller (main()), and arrange it in such a way that returning to shell_call() from the epilog of the overflowed victim_func() the latter could find a settled stack as it was been called by the main.
In doing so you probably have to mangle the frame-pointer in the stackframe of the victim, that will be restored in %ebp by means of leave.

Resources