lib/ronin/exploits/mixins/stack_overflow.rb
# frozen_string_literal: true
#
# ronin-exploits - A Ruby library for ronin-rb that provides exploitation and
# payload crafting functionality.
#
# Copyright (c) 2007-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
#
# ronin-exploits is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ronin-exploits is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ronin-exploits. If not, see <https://www.gnu.org/licenses/>.
#
require 'ronin/exploits/mixins/binary'
require 'ronin/exploits/mixins/nops'
require 'ronin/exploits/mixins/text'
module Ronin
module Exploits
module Mixins
#
# Methods for building Stack Overflow buffers.
#
# ## Example
#
# include Mixins::StackOverflow
#
# def build
# ebp = 0x06eb9090
# eip = 0x1001ae86
#
# buffer = buffer_overflow(length: 1024, nops: 16, payload: payload, bp: ebp, ip: eip)
# # ...
# end
#
# If you want more control over how the buffer is constructed:
#
# include Mixins::StackOverflow
#
# def build
# ebp = 0x06eb9090
# eip = 0x1001ae86
#
# buffer = junk(1024) + nops(16) + payload + stack_frame(ebp,eip)
# # ...
# end
#
# @api public
#
# @since 1.0.0
#
module StackOverflow
include Binary
include NOPS
include Text
#
# Creates a new stack frame.
#
# @param [Integer] bp
# The stack base pointer address.
#
# @param [Integer] ip
# The instruction pointer address.
#
# @return [String]
# The new stack frame.
#
def stack_frame(bp,ip)
pack(:machine_word,bp) + pack(:machine_word,ip)
end
#
# Builds the stack overflow buffer containing the payload, nops, and a
# stack frame.
#
# @param [Integer] length
# The desired total length of the buffer.
#
# @param [Integer, nil] nops
# The amount of NOP padding before the payload.
#
# @param [#to_s] payload
# The payload to add to the buffer.
#
# @param [Integer] bp
# The stack base pointer address.
#
# @param [Integer] ip
# The instruction pointer address.
#
# @return [String]
# The built buffer.
#
# @example
# ebp = 0x06eb9090 # short jump 6 bytes
# eip = 0x1001ae86 # pop pop ret 1001AE86 SSLEAY32.DLL
#
# buffer = buffer_overflow(length: 1024, nops: 16, payload: payload, bp: ebp, ip: eip)
#
def buffer_overflow(length: , nops: nil, payload: , bp: , ip: )
payload = payload.to_s
payload = self.nops(nops) + payload if nops
stack_frame = self.stack_frame(bp,ip)
buffer = String.new(encoding: Encoding::ASCII_8BIT)
buffer << junk(length - payload.bytesize - stack_frame.bytesize)
buffer << payload
buffer << stack_frame
return buffer
end
end
end
end
end