pwntools 1.1.0 → 1.2.0
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 +6 -3
- data/lib/pwn.rb +1 -0
- data/lib/pwnlib/abi.rb +1 -0
- data/lib/pwnlib/asm.rb +83 -42
- data/lib/pwnlib/constants/constant.rb +4 -1
- data/lib/pwnlib/constants/constants.rb +3 -0
- data/lib/pwnlib/constants/linux/amd64.rb +2 -0
- data/lib/pwnlib/constants/linux/i386.rb +2 -0
- data/lib/pwnlib/context.rb +10 -1
- data/lib/pwnlib/dynelf.rb +7 -2
- data/lib/pwnlib/elf/elf.rb +79 -6
- data/lib/pwnlib/errors.rb +3 -2
- data/lib/pwnlib/ext/array.rb +2 -1
- data/lib/pwnlib/ext/helper.rb +3 -2
- data/lib/pwnlib/ext/integer.rb +2 -1
- data/lib/pwnlib/ext/string.rb +3 -2
- data/lib/pwnlib/logger.rb +21 -1
- data/lib/pwnlib/memleak.rb +1 -0
- data/lib/pwnlib/pwn.rb +5 -1
- data/lib/pwnlib/reg_sort.rb +5 -0
- data/lib/pwnlib/runner.rb +53 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/common.rb +2 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/infloop.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/memcpy.rb +5 -1
- data/lib/pwnlib/shellcraft/generators/amd64/common/mov.rb +4 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/nop.rb +2 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/popad.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/pushstr.rb +3 -1
- data/lib/pwnlib/shellcraft/generators/amd64/common/pushstr_array.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/ret.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/setregs.rb +3 -2
- data/lib/pwnlib/shellcraft/generators/amd64/linux/cat.rb +3 -2
- data/lib/pwnlib/shellcraft/generators/amd64/linux/execve.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/exit.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/linux.rb +2 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/ls.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/open.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/sh.rb +3 -2
- data/lib/pwnlib/shellcraft/generators/amd64/linux/sleep.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/syscall.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/helper.rb +11 -2
- data/lib/pwnlib/shellcraft/generators/i386/common/common.rb +2 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/infloop.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/memcpy.rb +34 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/mov.rb +3 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/nop.rb +2 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/pushstr.rb +2 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/pushstr_array.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/setregs.rb +3 -2
- data/lib/pwnlib/shellcraft/generators/i386/linux/cat.rb +3 -2
- data/lib/pwnlib/shellcraft/generators/i386/linux/execve.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/exit.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/linux.rb +2 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/ls.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/open.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/sh.rb +3 -2
- data/lib/pwnlib/shellcraft/generators/i386/linux/sleep.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/syscall.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/common.rb +5 -3
- data/lib/pwnlib/shellcraft/generators/x86/common/infloop.rb +2 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/memcpy.rb +17 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/mov.rb +2 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/pushstr.rb +2 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/pushstr_array.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/setregs.rb +8 -6
- data/lib/pwnlib/shellcraft/generators/x86/linux/cat.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/execve.rb +3 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/exit.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/linux.rb +2 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/ls.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/open.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/sh.rb +1 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/sleep.rb +52 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/syscall.rb +10 -10
- data/lib/pwnlib/shellcraft/registers.rb +5 -1
- data/lib/pwnlib/shellcraft/shellcraft.rb +8 -3
- data/lib/pwnlib/timer.rb +6 -2
- data/lib/pwnlib/tubes/buffer.rb +4 -1
- data/lib/pwnlib/tubes/process.rb +2 -0
- data/lib/pwnlib/tubes/serialtube.rb +3 -1
- data/lib/pwnlib/tubes/sock.rb +7 -1
- data/lib/pwnlib/tubes/tube.rb +23 -3
- data/lib/pwnlib/ui.rb +21 -0
- data/lib/pwnlib/util/cyclic.rb +2 -0
- data/lib/pwnlib/util/fiddling.rb +37 -5
- data/lib/pwnlib/util/getdents.rb +1 -0
- data/lib/pwnlib/util/hexdump.rb +8 -5
- data/lib/pwnlib/util/lists.rb +3 -0
- data/lib/pwnlib/util/packing.rb +5 -2
- data/lib/pwnlib/util/ruby.rb +1 -0
- data/lib/pwnlib/version.rb +2 -1
- data/test/abi_test.rb +1 -0
- data/test/asm_test.rb +75 -85
- data/test/constants/constant_test.rb +1 -0
- data/test/constants/constants_test.rb +1 -0
- data/test/context_test.rb +1 -0
- data/test/data/assembly/aarch64.s +19 -0
- data/test/data/assembly/amd64.s +21 -0
- data/test/data/assembly/arm.s +9 -0
- data/test/data/assembly/i386.s +21 -0
- data/test/data/assembly/mips.s +16 -0
- data/test/data/assembly/mips64.s +6 -0
- data/test/data/assembly/powerpc.s +18 -0
- data/test/data/assembly/powerpc64.s +36 -0
- data/test/data/assembly/sparc.s +33 -0
- data/test/data/assembly/sparc64.s +5 -0
- data/test/data/assembly/thumb.s +37 -0
- data/test/data/echo.rb +1 -0
- data/test/dynelf_test.rb +3 -1
- data/test/elf/elf_test.rb +18 -0
- data/test/ext_test.rb +1 -0
- data/test/files/use_pwn.rb +1 -0
- data/test/files/use_pwnlib.rb +1 -0
- data/test/full_file_test.rb +6 -0
- data/test/logger_test.rb +24 -3
- data/test/memleak_test.rb +1 -0
- data/test/reg_sort_test.rb +1 -0
- data/test/runner_test.rb +32 -0
- data/test/shellcraft/infloop_test.rb +1 -0
- data/test/shellcraft/linux/cat_test.rb +1 -0
- data/test/shellcraft/linux/ls_test.rb +1 -0
- data/test/shellcraft/linux/sh_test.rb +1 -0
- data/test/shellcraft/linux/sleep_test.rb +68 -0
- data/test/shellcraft/linux/syscalls/execve_test.rb +1 -0
- data/test/shellcraft/linux/syscalls/exit_test.rb +1 -0
- data/test/shellcraft/linux/syscalls/open_test.rb +1 -0
- data/test/shellcraft/linux/syscalls/syscall_test.rb +1 -0
- data/test/shellcraft/memcpy_test.rb +20 -5
- data/test/shellcraft/mov_test.rb +1 -0
- data/test/shellcraft/nop_test.rb +1 -0
- data/test/shellcraft/popad_test.rb +1 -0
- data/test/shellcraft/pushstr_array_test.rb +1 -0
- data/test/shellcraft/pushstr_test.rb +1 -0
- data/test/shellcraft/registers_test.rb +1 -0
- data/test/shellcraft/ret_test.rb +1 -0
- data/test/shellcraft/setregs_test.rb +9 -8
- data/test/shellcraft/shellcraft_test.rb +1 -0
- data/test/test_helper.rb +28 -0
- data/test/timer_test.rb +2 -1
- data/test/tubes/buffer_test.rb +1 -0
- data/test/tubes/process_test.rb +8 -2
- data/test/tubes/serialtube_test.rb +1 -4
- data/test/tubes/sock_test.rb +1 -0
- data/test/tubes/tube_test.rb +10 -1
- data/test/ui_test.rb +18 -0
- data/test/util/cyclic_test.rb +1 -0
- data/test/util/fiddling_test.rb +8 -0
- data/test/util/getdents_test.rb +1 -0
- data/test/util/hexdump_test.rb +2 -1
- data/test/util/lists_test.rb +1 -0
- data/test/util/packing_test.rb +3 -2
- metadata +119 -59
data/lib/pwnlib/errors.rb
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# encoding: ASCII-8BIT
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
module Pwnlib
|
|
4
5
|
# Generic {Pwnlib} exception class.
|
|
5
6
|
class Error < StandardError
|
|
6
7
|
end
|
|
7
8
|
|
|
8
|
-
#
|
|
9
|
+
# {Pwnlib} Errors.
|
|
9
10
|
module Errors
|
|
10
11
|
# Raised by some IO operations in tubes.
|
|
11
12
|
class EndOfTubeError < ::Pwnlib::Error
|
|
@@ -23,7 +24,7 @@ module Pwnlib
|
|
|
23
24
|
class TimeoutError < ::Pwnlib::Error
|
|
24
25
|
end
|
|
25
26
|
|
|
26
|
-
# Raised when method
|
|
27
|
+
# Raised when a method is not supported under current architecture.
|
|
27
28
|
class UnsupportedArchError < ::Pwnlib::Error
|
|
28
29
|
end
|
|
29
30
|
end
|
data/lib/pwnlib/ext/array.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# encoding: ASCII-8BIT
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
require 'pwnlib/ext/helper'
|
|
4
5
|
require 'pwnlib/util/fiddling'
|
|
@@ -18,4 +19,4 @@ module Pwnlib
|
|
|
18
19
|
end
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
::Array.
|
|
22
|
+
::Array.include ::Pwnlib::Ext::Array::InstanceMethods
|
data/lib/pwnlib/ext/helper.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# encoding: ASCII-8BIT
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
module Pwnlib
|
|
4
5
|
module Ext
|
|
@@ -10,8 +11,8 @@ module Pwnlib
|
|
|
10
11
|
.concat(m2.to_a)
|
|
11
12
|
.each do |method, proxy_to|
|
|
12
13
|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
|
13
|
-
def #{method}(*args, &block)
|
|
14
|
-
#{mod}.#{proxy_to}(self, *args, &block)
|
|
14
|
+
def #{method}(*args, **kwargs, &block)
|
|
15
|
+
#{mod}.#{proxy_to}(self, *args, **kwargs, &block)
|
|
15
16
|
end
|
|
16
17
|
EOS
|
|
17
18
|
end
|
data/lib/pwnlib/ext/integer.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# encoding: ASCII-8BIT
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
require 'pwnlib/ext/helper'
|
|
4
5
|
require 'pwnlib/util/packing'
|
|
@@ -18,4 +19,4 @@ module Pwnlib
|
|
|
18
19
|
end
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
::Integer.
|
|
22
|
+
::Integer.include ::Pwnlib::Ext::Integer::InstanceMethods
|
data/lib/pwnlib/ext/string.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# encoding: ASCII-8BIT
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
require 'pwnlib/ext/helper'
|
|
4
5
|
require 'pwnlib/util/fiddling'
|
|
@@ -13,11 +14,11 @@ module Pwnlib
|
|
|
13
14
|
|
|
14
15
|
def_proxy_method ::Pwnlib::Util::Packing, %w(unpack unpack_many u8 u16 u32 u64)
|
|
15
16
|
def_proxy_method ::Pwnlib::Util::Fiddling, %w(
|
|
16
|
-
enhex unhex urlencode urldecode bits bits_str unbits bitswap b64e b64d
|
|
17
|
+
enhex unhex urlencode urldecode bits bits_str unbits bitswap b64e b64d xor
|
|
17
18
|
)
|
|
18
19
|
end
|
|
19
20
|
end
|
|
20
21
|
end
|
|
21
22
|
end
|
|
22
23
|
|
|
23
|
-
::String.
|
|
24
|
+
::String.include ::Pwnlib::Ext::String::InstanceMethods
|
data/lib/pwnlib/logger.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# encoding: ASCII-8BIT
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
require 'logger'
|
|
4
5
|
|
|
@@ -37,6 +38,19 @@ module Pwnlib
|
|
|
37
38
|
@formatter = proc do |severity, _datetime, progname, msg|
|
|
38
39
|
format("[%s] %s\n", Rainbow(progname || severity).color(SEV_COLOR[severity]), msg)
|
|
39
40
|
end
|
|
41
|
+
|
|
42
|
+
# Cache the file content so we can modify the file when it's running.
|
|
43
|
+
# If the source is modified before the first call, parsing source file
|
|
44
|
+
# might still fail.
|
|
45
|
+
@source_of_file_cache = Hash.new do |h, key|
|
|
46
|
+
next if key.nil?
|
|
47
|
+
|
|
48
|
+
h[key] = IO.read(key)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# As a naive heuristic for the most common single file use case, adding
|
|
52
|
+
# the last file from the execution stack.
|
|
53
|
+
@source_of_file_cache[caller_locations.last.absolute_path]
|
|
40
54
|
end
|
|
41
55
|
|
|
42
56
|
# Log the message with indent.
|
|
@@ -47,6 +61,7 @@ module Pwnlib
|
|
|
47
61
|
# The severity of the message.
|
|
48
62
|
def indented(message, level: DEBUG)
|
|
49
63
|
return if @logdev.nil? || level < context.log_level
|
|
64
|
+
|
|
50
65
|
@logdev.write(
|
|
51
66
|
message.lines.map { |s| ' ' + s }.join + "\n"
|
|
52
67
|
)
|
|
@@ -108,6 +123,7 @@ module Pwnlib
|
|
|
108
123
|
severity = INFO
|
|
109
124
|
# Don't invoke the block if it's unnecessary.
|
|
110
125
|
return true if severity < context.log_level
|
|
126
|
+
|
|
111
127
|
caller_ = caller_locations(1, 1).first
|
|
112
128
|
src = source_of(caller_.absolute_path, caller_.lineno)
|
|
113
129
|
results = args.empty? ? [[yield, source_of_block(src)]] : args.zip(source_of_args(src))
|
|
@@ -122,11 +138,12 @@ module Pwnlib
|
|
|
122
138
|
def add(severity, message = nil, progname = nil)
|
|
123
139
|
severity ||= UNKNOWN
|
|
124
140
|
return true if severity < context.log_level
|
|
141
|
+
|
|
125
142
|
super(severity, message, progname)
|
|
126
143
|
end
|
|
127
144
|
|
|
128
145
|
def source_of(path, line_number)
|
|
129
|
-
|
|
146
|
+
LoggerType.expression_at(@source_of_file_cache[path], line_number)
|
|
130
147
|
end
|
|
131
148
|
|
|
132
149
|
# Find the content of block that invoked by log.dump { ... }.
|
|
@@ -168,6 +185,7 @@ module Pwnlib
|
|
|
168
185
|
sexp = ::RubyParser.new.process(source)
|
|
169
186
|
sexp = search_sexp(sexp, target)
|
|
170
187
|
return nil if sexp.nil?
|
|
188
|
+
|
|
171
189
|
yield sexp
|
|
172
190
|
end
|
|
173
191
|
|
|
@@ -175,6 +193,7 @@ module Pwnlib
|
|
|
175
193
|
def search_sexp(sexp, target)
|
|
176
194
|
return nil unless sexp.is_a?(::Sexp)
|
|
177
195
|
return sexp if match_sexp?(sexp, target)
|
|
196
|
+
|
|
178
197
|
sexp.find do |e|
|
|
179
198
|
f = search_sexp(e, target)
|
|
180
199
|
break f if f
|
|
@@ -185,6 +204,7 @@ module Pwnlib
|
|
|
185
204
|
target.zip(sexp.entries).all? do |t, s|
|
|
186
205
|
next true if t.nil?
|
|
187
206
|
next match_sexp?(s, t) if t.is_a?(Array)
|
|
207
|
+
|
|
188
208
|
s == t
|
|
189
209
|
end
|
|
190
210
|
end
|
data/lib/pwnlib/memleak.rb
CHANGED
data/lib/pwnlib/pwn.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# encoding: ASCII-8BIT
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
# require this file would also require all things in pwnlib, but would not pollute anything.
|
|
4
5
|
|
|
@@ -11,11 +12,12 @@ require 'pwnlib/elf/elf'
|
|
|
11
12
|
require 'pwnlib/errors'
|
|
12
13
|
require 'pwnlib/logger'
|
|
13
14
|
require 'pwnlib/reg_sort'
|
|
15
|
+
require 'pwnlib/runner'
|
|
14
16
|
require 'pwnlib/shellcraft/shellcraft'
|
|
15
17
|
require 'pwnlib/tubes/process'
|
|
16
18
|
require 'pwnlib/tubes/serialtube'
|
|
17
19
|
require 'pwnlib/tubes/sock'
|
|
18
|
-
|
|
20
|
+
require 'pwnlib/ui'
|
|
19
21
|
require 'pwnlib/util/cyclic'
|
|
20
22
|
require 'pwnlib/util/fiddling'
|
|
21
23
|
require 'pwnlib/util/getdents'
|
|
@@ -28,6 +30,8 @@ module Pwn
|
|
|
28
30
|
include ::Pwnlib::Asm
|
|
29
31
|
include ::Pwnlib::Context
|
|
30
32
|
include ::Pwnlib::Logger
|
|
33
|
+
include ::Pwnlib::Runner
|
|
34
|
+
include ::Pwnlib::UI
|
|
31
35
|
include ::Pwnlib::Util::Cyclic
|
|
32
36
|
include ::Pwnlib::Util::Fiddling
|
|
33
37
|
include ::Pwnlib::Util::HexDump
|
data/lib/pwnlib/reg_sort.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# encoding: ASCII-8BIT
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
require 'pwnlib/context'
|
|
4
5
|
require 'pwnlib/util/ruby'
|
|
@@ -70,6 +71,7 @@ module Pwnlib
|
|
|
70
71
|
first_reg, val = list.shift
|
|
71
72
|
# Special case for val.zero? because zeroify registers is cheaper than mov.
|
|
72
73
|
next if list.empty? || all_regs.include?(val) || val.zero?
|
|
74
|
+
|
|
73
75
|
list.each do |(reg, _)|
|
|
74
76
|
hash[reg] = first_reg
|
|
75
77
|
in_out.delete(reg)
|
|
@@ -87,11 +89,13 @@ module Pwnlib
|
|
|
87
89
|
until deg.empty?
|
|
88
90
|
min_deg = deg.min_by { |_, v| v }[1]
|
|
89
91
|
break unless min_deg.zero? # remain are all cycles
|
|
92
|
+
|
|
90
93
|
min_pivs = deg.select { |_, v| v == min_deg }
|
|
91
94
|
piv = randomize ? min_pivs.sample : min_pivs.first
|
|
92
95
|
dst = piv.first
|
|
93
96
|
deg.delete(dst)
|
|
94
97
|
next unless graph.key?(dst) # Reach an end node.
|
|
98
|
+
|
|
95
99
|
deg[graph[dst]] -= 1
|
|
96
100
|
result << ['mov', dst, graph[dst]]
|
|
97
101
|
graph.delete(dst)
|
|
@@ -134,6 +138,7 @@ module Pwnlib
|
|
|
134
138
|
return [] unless assignments.key?(target)
|
|
135
139
|
# Found a cycle.
|
|
136
140
|
return target == path.first ? path : [] if path.include?(target)
|
|
141
|
+
|
|
137
142
|
check_cycle_(target, assignments, path)
|
|
138
143
|
end
|
|
139
144
|
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# encoding: ASCII-8BIT
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
|
|
6
|
+
require 'pwnlib/asm'
|
|
7
|
+
require 'pwnlib/tubes/process'
|
|
8
|
+
|
|
9
|
+
module Pwnlib
|
|
10
|
+
# This module collects the methods for executing codes, e.g., assembly code, assembled machine code, etc.
|
|
11
|
+
module Runner
|
|
12
|
+
module_function
|
|
13
|
+
|
|
14
|
+
# Given an assembly listing, assemble and execute it.
|
|
15
|
+
#
|
|
16
|
+
# @param [String] assembly
|
|
17
|
+
# Assembly code.
|
|
18
|
+
#
|
|
19
|
+
# @return [Pwnlib::Tubes::Process]
|
|
20
|
+
# The tube for interacting.
|
|
21
|
+
#
|
|
22
|
+
# @see Runner.run_shellcode
|
|
23
|
+
def run_assembly(assembly)
|
|
24
|
+
run_shellcode(::Pwnlib::Asm.asm(assembly))
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Given assembled machine code bytes, execute them.
|
|
28
|
+
#
|
|
29
|
+
# @param [String] bytes
|
|
30
|
+
# Assembled code.
|
|
31
|
+
#
|
|
32
|
+
# @return [Pwnlib::Tubes::Process]
|
|
33
|
+
# The tube for interacting.
|
|
34
|
+
#
|
|
35
|
+
# @example
|
|
36
|
+
# r = run_shellcode(asm(shellcraft.cat('/etc/passwd')))
|
|
37
|
+
# r.interact
|
|
38
|
+
# # [INFO] Switching to interactive mode
|
|
39
|
+
# # root:x:0:0:root:/root:/bin/bash
|
|
40
|
+
# # daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
|
|
41
|
+
# # bin:x:2:2:bin:/bin:/usr/sbin/nologin
|
|
42
|
+
# # sys:x:3:3:sys:/dev:/usr/sbin/nologin
|
|
43
|
+
# # sync:x:4:65534:sync:/bin:/bin/sync
|
|
44
|
+
# # games:x:5:60:games:/usr/games:/usr/sbin/nologin
|
|
45
|
+
# # [INFO] Got EOF in interactive mode
|
|
46
|
+
# #=> true
|
|
47
|
+
def run_shellcode(bytes)
|
|
48
|
+
file = ::Pwnlib::Asm.make_elf(bytes, to_file: true)
|
|
49
|
+
at_exit { FileUtils.rm_f(file) if File.exist?(file) }
|
|
50
|
+
::Pwnlib::Tubes::Process.new(file)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# encoding: ASCII-8BIT
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
require 'pwnlib/shellcraft/generators/amd64/common/common'
|
|
4
5
|
require 'pwnlib/shellcraft/generators/amd64/common/setregs'
|
|
@@ -18,10 +19,13 @@ module Pwnlib
|
|
|
18
19
|
# Source to be copied.
|
|
19
20
|
# @param [Integer] n
|
|
20
21
|
# The number of bytes to be copied.
|
|
22
|
+
#
|
|
23
|
+
# @example
|
|
24
|
+
# shellcraft.memcpy('rax', 'rbx', 0x1000)
|
|
21
25
|
def memcpy(dst, src, n)
|
|
22
26
|
cat "/* memcpy(#{pretty(dst)}, #{pretty(src)}, #{pretty(n)}) */"
|
|
23
27
|
cat 'cld'
|
|
24
|
-
cat Common.setregs(rdi: dst, rsi: src, rcx: n)
|
|
28
|
+
cat Common.setregs({ rdi: dst, rsi: src, rcx: n })
|
|
25
29
|
cat 'rep movsb'
|
|
26
30
|
end
|
|
27
31
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# encoding: ASCII-8BIT
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
require 'pwnlib/shellcraft/generators/amd64/common/common'
|
|
4
5
|
|
|
@@ -36,18 +37,21 @@ module Pwnlib
|
|
|
36
37
|
# #=> nil
|
|
37
38
|
def mov(dst, src, stack_allowed: true)
|
|
38
39
|
raise ArgumentError, "#{dst} is not a register" unless register?(dst)
|
|
40
|
+
|
|
39
41
|
dst = get_register(dst)
|
|
40
42
|
if register?(src)
|
|
41
43
|
src = get_register(src)
|
|
42
44
|
if dst.size < src.size && !dst.bigger.include?(src.name)
|
|
43
45
|
raise ArgumentError, "cannot mov #{dst}, #{src}: dst is smaller than src"
|
|
44
46
|
end
|
|
47
|
+
|
|
45
48
|
# Downgrade our register choice if possible.
|
|
46
49
|
# Opcodes for operating on 32-bit registers are always (?) shorter.
|
|
47
50
|
dst = get_register(dst.native32) if dst.size == 64 && src.size <= 32
|
|
48
51
|
else
|
|
49
52
|
context.local(arch: 'amd64') { src = evaluate(src) }
|
|
50
53
|
raise ArgumentError, format('cannot mov %s, %d: dst is smaller than src', dst, src) unless dst.fits(src)
|
|
54
|
+
|
|
51
55
|
orig_dst = dst
|
|
52
56
|
dst = get_register(dst.native32) if dst.size == 64 && bits_required(src) <= 32
|
|
53
57
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# encoding: ASCII-8BIT
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
require 'pwnlib/shellcraft/generators/amd64/common/common'
|
|
4
5
|
|
|
@@ -27,6 +28,7 @@ module Pwnlib
|
|
|
27
28
|
# This will not affect callee's +str+.
|
|
28
29
|
str += "\x00" if append_null && !str.end_with?("\x00")
|
|
29
30
|
return if str.empty?
|
|
31
|
+
|
|
30
32
|
padding = str[-1].ord >= 128 ? "\xff" : "\x00"
|
|
31
33
|
cat "/* push #{str.inspect} */"
|
|
32
34
|
group(8, str, underfull_action: :fill, fill_value: padding).reverse_each do |word|
|
|
@@ -43,7 +45,7 @@ module Pwnlib
|
|
|
43
45
|
elsif okay(word)
|
|
44
46
|
cat "mov rax, #{pretty(sign)}"
|
|
45
47
|
cat 'push rax'
|
|
46
|
-
elsif sign32
|
|
48
|
+
elsif sign32.positive? && word[4, 4] == "\x00" * 4
|
|
47
49
|
# The high 4 byte of word are all zeros, so we can use +xor dword ptr [rsp]+.
|
|
48
50
|
a = u32(xor_pair(word[0, 4]).first, endian: 'little', signed: true)
|
|
49
51
|
cat "push #{pretty(a)} ^ #{pretty(sign)}"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# encoding: ASCII-8BIT
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
require 'pwnlib/shellcraft/generators/amd64/common/common'
|
|
4
5
|
require 'pwnlib/shellcraft/generators/x86/common/setregs'
|
|
@@ -11,9 +12,9 @@ module Pwnlib
|
|
|
11
12
|
# @overload setregs(reg_context, stack_allowed: true)
|
|
12
13
|
#
|
|
13
14
|
# @see Generators::X86::Common#setregs
|
|
14
|
-
def setregs(*args)
|
|
15
|
+
def setregs(*args, **kwargs)
|
|
15
16
|
context.local(arch: :amd64) do
|
|
16
|
-
cat X86::Common.setregs(*args)
|
|
17
|
+
cat X86::Common.setregs(*args, **kwargs)
|
|
17
18
|
end
|
|
18
19
|
end
|
|
19
20
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# encoding: ASCII-8BIT
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
require 'pwnlib/shellcraft/generators/amd64/linux/linux'
|
|
4
5
|
require 'pwnlib/shellcraft/generators/x86/linux/cat'
|
|
@@ -11,9 +12,9 @@ module Pwnlib
|
|
|
11
12
|
# @overload cat(filename, fd: 1)
|
|
12
13
|
#
|
|
13
14
|
# @see Generators::X86::Linux#cat
|
|
14
|
-
def cat(*args)
|
|
15
|
+
def cat(*args, **kwargs)
|
|
15
16
|
context.local(arch: :amd64) do
|
|
16
|
-
cat X86::Linux.cat(*args)
|
|
17
|
+
cat X86::Linux.cat(*args, **kwargs)
|
|
17
18
|
end
|
|
18
19
|
end
|
|
19
20
|
end
|