heapinfo 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3afc942b75cd48a72f4d699b68423d2b6e23ff01
4
- data.tar.gz: 69bbf96563700cdf3275b680229f65c6ba20e8e5
3
+ metadata.gz: 38cb3f9332f88d77ee939beeec7ef2e1563e92fb
4
+ data.tar.gz: 897f2130e7167fcae28c678df332b4aa0c8be682
5
5
  SHA512:
6
- metadata.gz: c3cceb98b2e06f7c02a6ce16c9d9322de0a554742a213aeb26e8e7dce945fb35f9e425cf2e316e9317128df0ef061317c57fbcf449842888c9a35886c6549783
7
- data.tar.gz: b1285f36856258f0834707b54252cc2989050fc72f99a9ebead0fadc565ab10e0e090fe03bbd42bb1c3ebd6e52c293ea1ef49e237451dcc81f33d43d9f5f30ac
6
+ metadata.gz: 3fcb02ec66361586e3f5c00466f266dd1c388b0b27651c3ce030f88ab7d084b080cf7296bd71bbc32dc96a1a41e65f4318d73456c2d6126f6b37a9659e72bcb6
7
+ data.tar.gz: 7884b477325650a2baf197a303387f580d4cb6de6100691b9e985842b23b8ea863afce4f07b1385a65cf5ce189aff3b70979b00681d39b6863fdde337375d62f
@@ -73,9 +73,9 @@ module HeapInfo
73
73
 
74
74
  # Class for record fastbin type chunk.
75
75
  class Fastbin < Chunk
76
- # @return [Integer]
76
+ # @return [Integer] fd
77
77
  attr_reader :fd
78
- # @return [Integer]
78
+ # @return [Integer] index
79
79
  attr_accessor :index
80
80
 
81
81
  # Instantiate a <tt>HeapInfo::Fastbin</tt> object.
@@ -6,8 +6,7 @@ module HeapInfo
6
6
  @chunks = []
7
7
  end
8
8
 
9
- # Redirect methods to private records.
10
- def method_missing(method_sym, *arguments, &block)
9
+ def method_missing(method_sym, *arguments, &block) # :nodoc:
11
10
  return super unless @chunks.respond_to? method_sym
12
11
  @chunks.send(method_sym, *arguments, &block)
13
12
  end
@@ -3,7 +3,7 @@
3
3
  module HeapInfo
4
4
  module Glibc
5
5
  # Implmentation of <tt>void __libc_free(void *mem)</tt>.
6
- # [Source](https://code.woboq.org/userspace/glibc/malloc/malloc.c.html#__libc_free)
6
+ # [glibc-2.23](https://github.com/david942j/heapinfo/blob/master/examples/libcdb/libc-2.23/malloc.c#L2934) or [Online Source](https://code.woboq.org/userspace/glibc/malloc/malloc.c.html#__libc_free)
7
7
  # @param [Integer] mem Memory address to be free.
8
8
  def libc_free(mem)
9
9
  # TODO: free_hook
@@ -18,7 +18,7 @@ module HeapInfo
18
18
 
19
19
  private
20
20
  # Implmentation of <tt>void _int_free (mstate av, mchunkptr p, [int have_lock])</tt>.
21
- # [Source](https://code.woboq.org/userspace/glibc/malloc/malloc.c.html#_int_free)
21
+ # [glibc-2.23](https://github.com/david942j/heapinfo/blob/master/examples/libcdb/libc-2.23/malloc.c#L2934) or [Online Source](https://code.woboq.org/userspace/glibc/malloc/malloc.c.html#__libc_free)
22
22
  #
23
23
  # The original method in C is too long, split to multiple methods to match ruby convention.
24
24
  # @param [HeapInfo::Arena] av
@@ -40,10 +40,14 @@ module HeapInfo
40
40
 
41
41
  def int_free_fast(av, ptr, size)
42
42
  invalid_next_size(:fast, av, ptr, size)
43
+ idx = fastbin_index(size)
44
+ old = av.fastbin[idx].fd
45
+ malloc_assert( old != ptr ) { "double free or corruption (fasttop)\ntop of fastbin[0x%x]: 0x%x=0x%x" % [size & -8, ptr, ptr] }
43
46
  true
44
47
  end
45
48
 
46
49
  def int_free_small(av, ptr, size)
50
+ # TODO: unfinished
47
51
  true
48
52
  end
49
53
 
@@ -40,5 +40,9 @@ module HeapInfo
40
40
  main_arena
41
41
  end
42
42
 
43
+ # @return [Integer]
44
+ def fastbin_index(size)
45
+ (size >> (size_t == 8 ? 4 : 3)) - 2
46
+ end
43
47
  end
44
48
  end
@@ -5,7 +5,7 @@ module HeapInfo
5
5
  # The default options of libaries,
6
6
  # use for matching glibc and ld segments in <tt>/proc/[pid]/maps</tt>
7
7
  DEFAULT_LIB = {
8
- libc: /libc[^\w]/,
8
+ libc: /bc.*\.so/,
9
9
  ld: /\/ld-.+\.so/,
10
10
  }
11
11
  # @return [Fixnum, NilClass] return the pid of process, <tt>nil</tt> if no such process found
@@ -197,7 +197,7 @@ module HeapInfo
197
197
  false
198
198
  end
199
199
 
200
- def load_info!
200
+ def load_info! # :nodoc:
201
201
  @info = ProcessInfo.new(self)
202
202
  ProcessInfo::EXPORT.each do |m|
203
203
  self.class.send(:define_method, m) {@info.send(m)}
@@ -28,6 +28,7 @@ module HeapInfo
28
28
  # @param [Regexp, String] pattern The segment name want to match in maps. If <tt>String</tt> is given, the pattern is matched as a substring.
29
29
  # @return [HeapInfo::Segment, NilClass] The request <tt>Segment</tt> object. If the pattern is not matched, <tt>nil</tt> will be returned.
30
30
  def self.find(maps, pattern)
31
+ return Nil.new if pattern.nil?
31
32
  needs = maps.select{|m| pattern.is_a?(Regexp) ? m[3] =~ pattern : m[3].include?(pattern)}
32
33
  self.new needs.map{|m| m[0]}.min, needs[0][3] unless needs.empty?
33
34
  end
@@ -1,3 +1,3 @@
1
1
  module HeapInfo
2
- VERSION = '0.0.4'.freeze
2
+ VERSION = '0.0.5'.freeze
3
3
  end
@@ -2,7 +2,7 @@
2
2
  #include <cstdio>
3
3
  #include <unistd.h>
4
4
  int main(int argc, char **argv) {
5
- if(argc <=1 ) alarm(10);
5
+ if(argc <= 1) alarm(10);
6
6
  void *v, *u;
7
7
  int *i, *j;
8
8
 
@@ -12,7 +12,7 @@ int main(int argc, char **argv) {
12
12
  v = malloc(24); u = malloc(24);
13
13
  free(v); free(u);
14
14
 
15
- // invalid
15
+ // invalid fd
16
16
  i = (int*)malloc(40);
17
17
  free(i);
18
18
  *i = 0xdeadbeef;
data/spec/libc_spec.rb CHANGED
@@ -49,6 +49,27 @@ describe HeapInfo::Libc do
49
49
  @set_memory.call [0, 0x21, 0, 0, 0, 0x21000].pack("Q*")
50
50
  expect {@h.libc.free(@fake_mem + 16)}.to raise_error "free(): invalid next size (fast)\nnext chunk(#{HeapInfo::Helper.hex(@fake_mem + 32)}) has size(0x21000) >= av.system_mem(0x21000)"
51
51
  end
52
+
53
+ it 'double free (fastop)' do
54
+ expect { @h.libc.free(@h.heap.base + 0x30) }.to raise_error "double free or corruption (fasttop)\ntop of fastbin[0x20]: 0x602020=0x602020"
55
+ end
56
+
57
+ it 'success' do
58
+ expect(@h.libc.free(@h.heap.base + 0x10)).to be true
59
+ end
60
+ end
61
+
62
+ describe 'munmap' do
63
+ it 'success' do
64
+ mmap_addr = HeapInfo::Helper.unpack(8, @h.dump(:heap, 0x190, 8)) # backdoor of victim.cpp
65
+ expect(@h.libc.free(mmap_addr)).to be true
66
+ end
67
+ end
68
+
69
+ describe 'small' do
70
+ it 'success' do
71
+ expect(@h.libc.free(@h.heap.base + 0x280)).to be true
72
+ end
52
73
  end
53
74
  end
54
75
  end
data/spec/process_spec.rb CHANGED
@@ -151,6 +151,32 @@ describe HeapInfo::Process do
151
151
  end
152
152
  end
153
153
 
154
+ describe 'static-link' do
155
+ before(:all) do
156
+ @victim = HeapInfo::TMP_DIR + '/victim'
157
+ %x(g++ -static #{File.expand_path('../files/victim.cpp', __FILE__)} -o #{@victim} 2>&1 > /dev/null)
158
+ pid = fork
159
+ # run without ASLR
160
+ exec "setarch `uname -m` -R /bin/sh -c #{@victim}" if pid.nil?
161
+ loop until `pidof #{@victim}` != ''
162
+ @h = heapinfo(@victim)
163
+ end
164
+
165
+ after(:all) do
166
+ `killall #{@victim}`
167
+ FileUtils.rm(@victim)
168
+ end
169
+
170
+ it 'normal' do
171
+ expect(@h.libc).to be_a HeapInfo::Nil
172
+ expect(@h.ld).to be_a HeapInfo::Nil
173
+ end
174
+
175
+ it 'dump' do
176
+ expect(@h.dump :elf, 4).to eq "\x7fELF"
177
+ end
178
+ end
179
+
154
180
  describe 'no process' do
155
181
  before(:all) do
156
182
  @h = heapinfo('NO_SUCH_PROCESS~~~')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heapinfo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - david942j
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-28 00:00:00.000000000 Z
11
+ date: 2017-01-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: create an interactive memory info interface while pwn / exploiting
14
14
  email: