diff --git a/builds_list b/builds_list index bddb6b8..b9a5770 100644 --- a/builds_list +++ b/builds_list @@ -1 +1,2 @@ libc-2.23-60131540dadc6796cab33388349e6e4e68692053 +libc-2.23-926eb99d49cab2e5622af38ab07395f5b32035e9 diff --git a/lib/one_gadget/builds/libc-2.23-926eb99d49cab2e5622af38ab07395f5b32035e9.rb b/lib/one_gadget/builds/libc-2.23-926eb99d49cab2e5622af38ab07395f5b32035e9.rb new file mode 100644 index 0000000..c7ff229 --- /dev/null +++ b/lib/one_gadget/builds/libc-2.23-926eb99d49cab2e5622af38ab07395f5b32035e9.rb @@ -0,0 +1,8 @@ +require 'one_gadget/gadget' +# Ubuntu GLIBC 2.23-0ubuntu5 +# ELF 32-bit LSB shared object, Intel 80386 +build_id = File.basename(__FILE__, '.rb').split('-').last +rw_area_constraint = 'esi is the address of `rw-p` area of libc' +OneGadget::Gadget.add(build_id, 0x3ac69, constraints: [rw_area_constraint, '[esp+0x34] == NULL']) +OneGadget::Gadget.add(build_id, 0x5fbbe, constraints: [rw_area_constraint, 'eax == NULL']) +OneGadget::Gadget.add(build_id, 0x12036c, constraints: [rw_area_constraint, 'eax == NULL']) diff --git a/lib/one_gadget/fetchers/base.rb b/lib/one_gadget/fetchers/base.rb index c1beca9..1683145 100644 --- a/lib/one_gadget/fetchers/base.rb +++ b/lib/one_gadget/fetchers/base.rb @@ -54,7 +54,8 @@ module OneGadget offset = lines.first.scan(/^([\da-f]+):/)[0][0].to_i(16) # fetch those might be constraints lines. important_lines = lines.select(&block).map do |line| - line.split("\t").last.gsub(/\s+/, ' ') + ar = line.split("\t") + "#{ar.first} #{ar.last.gsub(/\s+/, ' ')}" end OneGadget::Gadget::Gadget.new(offset, constraints: important_lines) end diff --git a/lib/one_gadget/fetchers/i386.rb b/lib/one_gadget/fetchers/i386.rb new file mode 100644 index 0000000..8cce057 --- /dev/null +++ b/lib/one_gadget/fetchers/i386.rb @@ -0,0 +1,54 @@ +require 'one_gadget/fetchers/base' +module OneGadget + module Fetcher + # Fetcher for i386. + class I386 < OneGadget::Fetcher::Base + def find + rw_off = rw_offset + bin_sh = str_offset('/bin/sh') + minus_c = str_offset('-c') + rel_sh_hex = (rw_off - bin_sh).to_s(16) + rel_minus_c = (rw_off - minus_c).to_s(16) + cands = candidates do |candidate| + next false unless candidate.include?(rel_sh_hex) + true + end + # remove lines before and with -c appears + cands = slice_prefix(cands) do |line| + line.include?(rel_minus_c) + end + # special handle for execl call + cands.map! do |cand| + lines = cand.lines + next cand unless lines.last.include?('execl') + # Find the last three +push+, or mov [esp+0x8], .* + # Make it call +execl("/bin/sh", "sh", NULL)+. + if cand.include?('esp+0x8') + to_rm = lines.index { |c| c.include?('esp+0x8') } + else + push_cnt = 0 + to_rm = lines.rindex do |c| + push_cnt += 1 if c.include?('push') + push_cnt >= 3 + end + end + lines = lines[to_rm..-1] unless to_rm.nil? + lines.join + end + cands.map do |candidate| + convert_to_gadget(candidate) do |_| + true + end + end + end + + private + + def rw_offset + # How to find this offset correctly..? + line = `readelf -d #{file}|grep PLTGOT` + line.scan(/0x[\da-f]+/).last.to_i(16) & -0x1000 + end + end + end +end diff --git a/spec/data/libc-2.23-926eb99d49cab2e5622af38ab07395f5b32035e9.so b/spec/data/libc-2.23-926eb99d49cab2e5622af38ab07395f5b32035e9.so new file mode 100755 index 0000000..e9f8c79 Binary files /dev/null and b/spec/data/libc-2.23-926eb99d49cab2e5622af38ab07395f5b32035e9.so differ diff --git a/spec/helper_spec.rb b/spec/helper_spec.rb index 28bd7c2..7919cf4 100644 --- a/spec/helper_spec.rb +++ b/spec/helper_spec.rb @@ -17,4 +17,9 @@ describe OneGadget::Helper do it 'colorize' do expect(OneGadget::Helper.colorize('123', sev: :integer)).to eq "\e[38;5;12m123\e[0m" end + + it 'architecture' do + expect(OneGadget::Helper.architecture(@libcpath)).to be :amd64 + expect(OneGadget::Helper.architecture(__FILE__)).to be :unknown + end end diff --git a/spec/one_gadget_spec.rb b/spec/one_gadget_amd64_spec.rb similarity index 100% rename from spec/one_gadget_spec.rb rename to spec/one_gadget_amd64_spec.rb diff --git a/spec/one_gadget_i386_spec.rb b/spec/one_gadget_i386_spec.rb new file mode 100644 index 0000000..106ec19 --- /dev/null +++ b/spec/one_gadget_i386_spec.rb @@ -0,0 +1,24 @@ +require 'one_gadget' + +describe 'one_gadget' do + before(:each) do + @build_id = '926eb99d49cab2e5622af38ab07395f5b32035e9' + @libcpath19 = File.join(File.dirname(__FILE__), 'data', 'libc-2.19-fd51b20e670e9a9f60dc3b06dc9761fb08c9358b.so') + @libcpath23 = File.join(File.dirname(__FILE__), 'data', 'libc-2.23-926eb99d49cab2e5622af38ab07395f5b32035e9.so') + end + + it 'from file libc-2.19' do + expect(OneGadget.gadgets(file: @libcpath19, force_file: true)).to eq [0x3fd27, 0x64c60, 0x1244a6] + end + + it 'from file libc-2.23' do + expect(OneGadget.gadgets(file: @libcpath23, force_file: true)).to eq [0x3ac69, 0x5fbbe, 0x12036c] + end + + describe 'from build id' do + it 'normal' do + # only check not empty because the gadgets might add frequently. + expect(OneGadget.gadgets(build_id: @build_id)).not_to be_empty + end + end +end