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

How large can our shellcode theoretically become if we count NOPS and the shellcode size together? (Format: 00 Bytes)

Last updated