support of i386, tested on 16.04 and 14.04 lib32
This commit is contained in:
parent
77ed626dc1
commit
022a7c57f0
|
@ -1 +1,2 @@
|
|||
libc-2.23-60131540dadc6796cab33388349e6e4e68692053
|
||||
libc-2.23-926eb99d49cab2e5622af38ab07395f5b32035e9
|
||||
|
|
|
@ -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'])
|
|
@ -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
|
||||
|
|
|
@ -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
|
Binary file not shown.
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue