pwn 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/lib/pwn/banner/code_cave.rb +997 -997
- data/lib/pwn/plugins/xxd.rb +168 -7
- data/lib/pwn/version.rb +1 -1
- metadata +2 -2
data/lib/pwn/plugins/xxd.rb
CHANGED
@@ -58,15 +58,97 @@ module PWN
|
|
58
58
|
raise e
|
59
59
|
end
|
60
60
|
|
61
|
+
# Supported Method Parameters::
|
62
|
+
# hexdump = PWN::Plugins::XXD.fill_range_w_byte(
|
63
|
+
# hexdump: 'required - hexdump returned from #dump method',
|
64
|
+
# start_addr: 'required - start address to fill with byte',
|
65
|
+
# end_addr: 'required - end address to fill with byte',
|
66
|
+
# byte: 'required - byte to fill range with'
|
67
|
+
# )
|
68
|
+
|
69
|
+
def self.fill_range_w_byte(opts = {})
|
70
|
+
hexdump = opts[:hexdump]
|
71
|
+
start_addr = opts[:start_addr]
|
72
|
+
end_addr = opts[:end_addr]
|
73
|
+
byte = opts[:byte]
|
74
|
+
|
75
|
+
start_int = start_addr.to_i(16)
|
76
|
+
end_int = end_addr.to_i(16)
|
77
|
+
|
78
|
+
hexdump.each do |key, value|
|
79
|
+
key_int = key.to_i(16)
|
80
|
+
value[:hex] = Array.new(16, byte) if key_int >= start_int && key_int <= end_int
|
81
|
+
end
|
82
|
+
|
83
|
+
hexdump
|
84
|
+
end
|
85
|
+
|
86
|
+
# Supported Method Parameters::
|
87
|
+
# hex_offset = PWN::Plugins::XXD.calc_addr_offset(
|
88
|
+
# start_addr: 'required - start address to evaluate',
|
89
|
+
# target_addr: 'required - memory address to set breakpoint'
|
90
|
+
# )
|
91
|
+
# ^^^ Instructions for #{self}.calc_addr_offset:
|
92
|
+
# This is useful for calculating address offsets of known functions in debuggers
|
93
|
+
# to set breakpoints of instructions that are not known at runtime.
|
94
|
+
# 1. Set a breakpoint at main and record its address - this is the start_addr.
|
95
|
+
# For example in r2:
|
96
|
+
# ```
|
97
|
+
# [0x00001050]> db main
|
98
|
+
# [0x00001050]> ood
|
99
|
+
# [0x7fd16122b360]> dc
|
100
|
+
# INFO: hit breakpoint at: 0x562e8547d139
|
101
|
+
# [0x562e8547d139]> db
|
102
|
+
# ```
|
103
|
+
# 2. Populate start_addr w/ address (i.e. '0x562e8547d139') of a known function (e.g. main)
|
104
|
+
# 3. Step down to the instruction you want to set a breakpoint. Record its address...
|
105
|
+
# this is the target_addr.
|
106
|
+
# ```
|
107
|
+
# [0x562e8547d139]> v
|
108
|
+
# <step through to target instruction via F7/F8>
|
109
|
+
# ```
|
110
|
+
# 4. Get the hex offset value by calling this method
|
111
|
+
# 5. Future breakpoints can be calculated by adding the hex offset to the
|
112
|
+
# updated start_addr (which changes every time the binary is executed).
|
113
|
+
# If the offset returned is `0x00000ec2` a breakpoint in r2 can be set via:
|
114
|
+
# ```
|
115
|
+
# [0x00001050]> ood
|
116
|
+
# INFO: hit breakpoint at: 0x55ee0a0e5139
|
117
|
+
# [0x7f1a45bea360]> db main
|
118
|
+
# [0x7f1a45bea360]> db (main)+0x00000ec2
|
119
|
+
# [0x7f1a45bea360]> db
|
120
|
+
# 0x558eebd75139 - 0x558eebd7513a 1 --x sw break enabled valid ...
|
121
|
+
# 0x558eebd75ffb - 0x558eebd75ffc 1 --x sw break enabled valid ...
|
122
|
+
# [0x55ee0a0e5139]> dc
|
123
|
+
# [0x7feddfd2d360]> dc
|
124
|
+
# INFO: hit breakpoint at: 0x558eebd75139
|
125
|
+
# INFO: hit breakpoint at: 0x5558c3101ffb
|
126
|
+
# [0x5558c3101ffb]> v
|
127
|
+
# <step through via F7, F8, F9, etc. to get to desired breakpoint>
|
128
|
+
# ```
|
129
|
+
|
130
|
+
def self.calc_addr_offset(opts = {})
|
131
|
+
start_addr = opts[:start_addr]
|
132
|
+
target_addr = opts[:target_addr]
|
133
|
+
|
134
|
+
format(
|
135
|
+
'0x%<s1>08x',
|
136
|
+
s1: target_addr.to_i(16) - start_addr.to_i(16)
|
137
|
+
)
|
138
|
+
end
|
139
|
+
|
61
140
|
# Supported Method Parameters::
|
62
141
|
# PWN::Plugins::XXD.reverse_dump(
|
63
142
|
# hexdump: 'required - hexdump returned from #dump method',
|
64
|
-
# file: 'required - path to binary file to dump'
|
143
|
+
# file: 'required - path to binary file to dump',
|
144
|
+
# byte_chunks: 'optional - if set, will write n byte chunks of hexdump to multiple files'
|
65
145
|
# )
|
66
146
|
|
67
147
|
def self.reverse_dump(opts = {})
|
68
148
|
hexdump = opts[:hexdump]
|
69
149
|
file = opts[:file]
|
150
|
+
byte_chunks = opts[:byte_chunks].to_i
|
151
|
+
|
70
152
|
raise ArgumentError, 'hexdump is required' if hexdump.nil?
|
71
153
|
|
72
154
|
raise ArgumentError, 'output file is required' if file.nil?
|
@@ -84,13 +166,40 @@ module PWN
|
|
84
166
|
puts hexdump
|
85
167
|
end
|
86
168
|
|
87
|
-
|
88
|
-
|
89
|
-
|
169
|
+
# Useful for testing which chunk(s)
|
170
|
+
# trigger malware detection engines
|
171
|
+
if byte_chunks.to_i.positive?
|
172
|
+
# Raise error if byte_chunks is not divisible by 16
|
173
|
+
raise ArgumentError, 'byte_chunks must be divisible by 16' if (byte_chunks % 16).positive?
|
174
|
+
|
175
|
+
# Raise error if byte_chunks is greater than hexdump size
|
176
|
+
raise ArgumentError, 'byte_chunks must be less than hexdump size' if byte_chunks > hexdump.size
|
177
|
+
|
178
|
+
chunks = byte_chunks / 16
|
179
|
+
hexdump.lines.each_slice(chunks) do |chunk|
|
180
|
+
# File name should append memory address of chunks
|
181
|
+
# to make analysis possible
|
182
|
+
start_chunk_addr = chunk.first[0..7]
|
183
|
+
end_chunk_addr = chunk.last[0..7]
|
184
|
+
chunk_file = "#{file}.#{start_chunk_addr}-#{end_chunk_addr}"
|
185
|
+
|
186
|
+
binary_data = chunk.map do |line|
|
187
|
+
line.split[1..8].map do |hex|
|
188
|
+
[hex].pack('H*')
|
189
|
+
end.join
|
190
|
+
end.join
|
191
|
+
|
192
|
+
File.binwrite(chunk_file, binary_data)
|
193
|
+
end
|
194
|
+
else
|
195
|
+
binary_data = hexdump.lines.map do |line|
|
196
|
+
line.split[1..8].map do |hex|
|
197
|
+
[hex].pack('H*')
|
198
|
+
end.join
|
90
199
|
end.join
|
91
|
-
end.join
|
92
200
|
|
93
|
-
|
201
|
+
File.binwrite(file, binary_data)
|
202
|
+
end
|
94
203
|
rescue StandardError => e
|
95
204
|
raise e
|
96
205
|
end
|
@@ -112,9 +221,61 @@ module PWN
|
|
112
221
|
hashed: 'optional - return hexdump as hash instead of string (default: false)'
|
113
222
|
)
|
114
223
|
|
224
|
+
hexdump = #{self}.fill_range_w_byte(
|
225
|
+
hexdump: 'required - hexdump returned from #dump method',
|
226
|
+
start_addr: 'required - start address to fill with byte',
|
227
|
+
end_addr: 'required - end address to fill with byte',
|
228
|
+
byte: 'required - byte to fill range with'
|
229
|
+
)
|
230
|
+
|
231
|
+
hex_offset = #{self}.calc_addr_offset(
|
232
|
+
start_addr: 'required - start address to evaluate',
|
233
|
+
target_addr: 'required - memory address to set breakpoint'
|
234
|
+
)
|
235
|
+
|
236
|
+
# ^^^ Instructions for #{self}.calc_addr_offset:
|
237
|
+
# This is useful for calculating address offsets of known functions in debuggers
|
238
|
+
# to set breakpoints of instructions that are not known at runtime.
|
239
|
+
# 1. Set a breakpoint at main and record its address - this is the start_addr.
|
240
|
+
# For example in r2:
|
241
|
+
# ```
|
242
|
+
# [0x00001050]> db main
|
243
|
+
# [0x00001050]> ood
|
244
|
+
# [0x7fd16122b360]> dc
|
245
|
+
# INFO: hit breakpoint at: 0x562e8547d139
|
246
|
+
# [0x562e8547d139]> db
|
247
|
+
# ```
|
248
|
+
# 2. Populate start_addr w/ address (i.e. '0x562e8547d139') of a known function (e.g. main)
|
249
|
+
# 3. Step down to the instruction you want to set a breakpoint. Record its address...
|
250
|
+
# this is the target_addr.
|
251
|
+
# ```
|
252
|
+
# [0x562e8547d139]> v
|
253
|
+
# <step through to target instruction via F7/F8>
|
254
|
+
# ```
|
255
|
+
# 4. Get the hex offset value by calling this method
|
256
|
+
# 5. Future breakpoints can be calculated by adding the hex offset to the
|
257
|
+
# updated start_addr (which changes every time the binary is executed).
|
258
|
+
# If the offset returned is `0x00000ec2` a breakpoint in r2 can be set via:
|
259
|
+
# ```
|
260
|
+
# [0x00001050]> ood
|
261
|
+
# INFO: hit breakpoint at: 0x55ee0a0e5139
|
262
|
+
# [0x7f1a45bea360]> db main
|
263
|
+
# [0x7f1a45bea360]> db (main)+0x00000ec2
|
264
|
+
# [0x7f1a45bea360]> db
|
265
|
+
# 0x558eebd75139 - 0x558eebd7513a 1 --x sw break enabled valid ...
|
266
|
+
# 0x558eebd75ffb - 0x558eebd75ffc 1 --x sw break enabled valid ...
|
267
|
+
# [0x55ee0a0e5139]> dc
|
268
|
+
# [0x7feddfd2d360]> dc
|
269
|
+
# INFO: hit breakpoint at: 0x558eebd75139
|
270
|
+
# INFO: hit breakpoint at: 0x5558c3101ffb
|
271
|
+
# [0x5558c3101ffb]> v
|
272
|
+
# <step through via F7, F8, F9, etc. to get to desired breakpoint>
|
273
|
+
# ```
|
274
|
+
|
115
275
|
#{self}.reverse_dump(
|
116
276
|
hexdump: 'required - hexdump returned from #dump method',
|
117
|
-
file: 'required - path to binary file to dump'
|
277
|
+
file: 'required - path to binary file to dump',
|
278
|
+
byte_chunks: 'optional - if set, will write n byte chunks of hexdump to multiple files'
|
118
279
|
)
|
119
280
|
|
120
281
|
#{self}.authors
|
data/lib/pwn/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pwn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 0day Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-01-
|
11
|
+
date: 2024-01-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|