It’s been quite awhile since I’ve made a blog post, not that I haven’t been up to tons of cool things, it’s just that I forget to find time to write about them. I am going to make an attempt to strengthen my writing skills and write posts about what I’m doing more often. With all the projects and learnign I do I feel that if I document them it will be a lot easier for me to keep tabs on how I’m progressing and at the same time maybe my ramblings may assist other people in their journeys. Anyway, as for the topic of this post I figured I’d pick up where I left off with the first and attempt the next IO Level from SmashTheStack.


Getting started

Now this level allows us to read the source code, which is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//a little fun brought to you by bla

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

void catcher(int a)
{
setresuid(geteuid(),geteuid(),geteuid());
printf("WIN!\n");
system("/bin/sh");
exit(0);
}

int main(int argc, char **argv)
{
puts("source code is available in level02.c\n");

if (argc != 3 || !atoi(argv[2]))
return 1;
signal(SIGFPE, catcher);
return abs(atoi(argv[1])) / atoi(argv[2]);
}

Looking at the code we see our target right away. We must get into the “catcher” method in order to set our uid to the next level and get the pass. Inside of the main method there is an if statement that when we do not supply 3 arguments OR if the second supplied argument is false (this means if argv[2] is 0) it will close the program.

So to get to the next lines of code we must supply 2 arguments with the program and the last argument must not be 0. Easy enough.

Continuing along, the next line sets the catcher method as the handler for a SIGFPE signal. So how exactly do we trigger a SIGFPE signal?


The SIGFPE

SIGFPE is the Floating-Point exception signal which is thrown when an error occurs in an arithmetic equation. The name is somewhat misleading but originated from an error when integer data is later used in floating point arithmetic. Since we do not have much control over how the variables are declared and used it is unlikely we will be able to leverage an error like that to reach our desired method.

Another way to trigger an SIGFPE signal is a division by zero. Which seems somewhat unlikely as the program specifically checks if the second argument given is a 0 and exits the program. If we look into the man pages for signal (man signal) we see a little hint that SIGFPE may also be generated when dividing the most negative integer by -1. This happens because of something called an integer overflow. Which is when a number is too large to be represented in the number of bits of the datatype it was declared as. This works for us because the absolute value of the max value is one less than the absolute value of the min value, meaning dividing by negative one causes the min value to become positive, but in doing so exceeds the max value by one.


Making it work!

So first we must discover what the minimum integer value really is. If we move to the /tmp folder on the SmashTheStack server we can create a directory to work in and create a program that will tell us. All the values for the min and max values of each datatype are stored in a header file named “limits.h” we need to include that so we can access each of these constants.

1
2
3
4
5
6
7
#include <stdio.h>
#include <limits.h>

int main()
{
printf("int_max: %d\nint_min: %d\n", INT_MAX, INT_MIN);
}

This spits out the number that we need to divide by -1 to generate the SIGFPE signal. When we plug in out numbers we should be dropped right into our shell and be able to get the password for the next level. HAPPY SMASHING!

2015.05.26

⬆︎TOP