lib/ronin/exploits/mixins/format_string.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'
module Ronin
module Exploits
module Mixins
#
# Adds methods to exploits for generating format strings to be used
# in format string vulnerabilities.
#
# @api public
#
# @since 1.0.0
#
module FormatString
include Binary
#
# Builds a format string.
#
# @param [Integer] overwrite
# The address to overwrite.
#
# @param [Integer] pop_length
#
# @param [Integer] address
# The address to write.
#
# @param [#to_s] payload
# The payload append to the format string.
#
# @return [String]
# The built format string.
#
def build_format_string(overwrite: , pop_length: , address: , payload: )
machine_word = platform[:machine_word]
buffer = String.new(encoding: Encoding::ASCII_8BIT)
buffer << pack(:machine_word,overwrite)
buffer << pack(:machine_word,overwrite + (machine_word.size / 2))
low_mask = 0xff
(machine_word.size / 2).times do
low_mask <<= 8
low_mask |= 0xff
end
high_mask = low_mask << ((machine_word.size * 8) / 2)
high = (address & high_mask) >> (machine_word.size / 2)
low = address & low_mask
if low < high
low -= (machine_word.size * 2)
buffer << format("%%.%ud%%%u$hn%%.%ud%%%u$hn",low,pop_length,high - low,pop_length + 1)
else
high -= (machine_word.size * 2)
buffer << format("%%.%ud%%%u$hn%%.%ud%%%u$hn",high,pop_length + 1,low - high,pop_length)
end
buffer << payload.to_s
return buffer
end
end
end
end
end