pwn 0.5.1 → 0.5.2
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 +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
|