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.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +88 -11
  3. data/Rakefile +5 -1
  4. data/lib/pwn.rb +9 -7
  5. data/lib/pwnlib/abi.rb +60 -0
  6. data/lib/pwnlib/asm.rb +146 -0
  7. data/lib/pwnlib/constants/constant.rb +16 -2
  8. data/lib/pwnlib/constants/constants.rb +35 -19
  9. data/lib/pwnlib/constants/linux/amd64.rb +30 -1
  10. data/lib/pwnlib/context.rb +25 -17
  11. data/lib/pwnlib/dynelf.rb +117 -54
  12. data/lib/pwnlib/elf/elf.rb +267 -0
  13. data/lib/pwnlib/ext/helper.rb +4 -4
  14. data/lib/pwnlib/logger.rb +87 -0
  15. data/lib/pwnlib/memleak.rb +58 -29
  16. data/lib/pwnlib/pwn.rb +19 -8
  17. data/lib/pwnlib/reg_sort.rb +102 -108
  18. data/lib/pwnlib/shellcraft/generators/amd64/common/common.rb +14 -0
  19. data/lib/pwnlib/shellcraft/generators/amd64/common/infloop.rb +17 -0
  20. data/lib/pwnlib/shellcraft/generators/amd64/common/memcpy.rb +31 -0
  21. data/lib/pwnlib/shellcraft/generators/amd64/common/mov.rb +127 -0
  22. data/lib/pwnlib/shellcraft/generators/amd64/common/nop.rb +16 -0
  23. data/lib/pwnlib/shellcraft/generators/amd64/common/popad.rb +27 -0
  24. data/lib/pwnlib/shellcraft/generators/amd64/common/pushstr.rb +64 -0
  25. data/lib/pwnlib/shellcraft/generators/amd64/common/pushstr_array.rb +19 -0
  26. data/lib/pwnlib/shellcraft/generators/amd64/common/ret.rb +32 -0
  27. data/lib/pwnlib/shellcraft/generators/amd64/common/setregs.rb +19 -0
  28. data/lib/pwnlib/shellcraft/generators/amd64/linux/execve.rb +21 -0
  29. data/lib/pwnlib/shellcraft/generators/amd64/linux/linux.rb +14 -0
  30. data/lib/pwnlib/shellcraft/generators/amd64/linux/ls.rb +19 -0
  31. data/lib/pwnlib/shellcraft/generators/amd64/linux/sh.rb +19 -0
  32. data/lib/pwnlib/shellcraft/generators/amd64/linux/syscall.rb +21 -0
  33. data/lib/pwnlib/shellcraft/generators/helper.rb +106 -0
  34. data/lib/pwnlib/shellcraft/generators/i386/common/common.rb +14 -0
  35. data/lib/pwnlib/shellcraft/generators/i386/common/infloop.rb +17 -0
  36. data/lib/pwnlib/shellcraft/generators/i386/common/mov.rb +90 -0
  37. data/lib/pwnlib/shellcraft/generators/i386/common/nop.rb +16 -0
  38. data/lib/pwnlib/shellcraft/generators/i386/common/pushstr.rb +39 -0
  39. data/lib/pwnlib/shellcraft/generators/i386/common/pushstr_array.rb +19 -0
  40. data/lib/pwnlib/shellcraft/generators/i386/common/setregs.rb +19 -0
  41. data/lib/pwnlib/shellcraft/generators/i386/linux/execve.rb +19 -0
  42. data/lib/pwnlib/shellcraft/generators/i386/linux/linux.rb +14 -0
  43. data/lib/pwnlib/shellcraft/generators/i386/linux/ls.rb +19 -0
  44. data/lib/pwnlib/shellcraft/generators/i386/linux/sh.rb +19 -0
  45. data/lib/pwnlib/shellcraft/generators/i386/linux/syscall.rb +19 -0
  46. data/lib/pwnlib/shellcraft/generators/x86/common/common.rb +26 -0
  47. data/lib/pwnlib/shellcraft/generators/x86/common/infloop.rb +22 -0
  48. data/lib/pwnlib/shellcraft/generators/x86/common/mov.rb +15 -0
  49. data/lib/pwnlib/shellcraft/generators/x86/common/pushstr.rb +15 -0
  50. data/lib/pwnlib/shellcraft/generators/x86/common/pushstr_array.rb +85 -0
  51. data/lib/pwnlib/shellcraft/generators/x86/common/setregs.rb +82 -0
  52. data/lib/pwnlib/shellcraft/generators/x86/linux/execve.rb +69 -0
  53. data/lib/pwnlib/shellcraft/generators/x86/linux/linux.rb +14 -0
  54. data/lib/pwnlib/shellcraft/generators/x86/linux/ls.rb +66 -0
  55. data/lib/pwnlib/shellcraft/generators/x86/linux/sh.rb +52 -0
  56. data/lib/pwnlib/shellcraft/generators/x86/linux/syscall.rb +52 -0
  57. data/lib/pwnlib/shellcraft/registers.rb +145 -0
  58. data/lib/pwnlib/shellcraft/shellcraft.rb +67 -0
  59. data/lib/pwnlib/timer.rb +60 -0
  60. data/lib/pwnlib/tubes/buffer.rb +96 -0
  61. data/lib/pwnlib/tubes/sock.rb +95 -0
  62. data/lib/pwnlib/tubes/tube.rb +270 -0
  63. data/lib/pwnlib/util/cyclic.rb +95 -94
  64. data/lib/pwnlib/util/fiddling.rb +256 -220
  65. data/lib/pwnlib/util/getdents.rb +83 -0
  66. data/lib/pwnlib/util/hexdump.rb +109 -108
  67. data/lib/pwnlib/util/lists.rb +55 -0
  68. data/lib/pwnlib/util/packing.rb +226 -228
  69. data/lib/pwnlib/util/ruby.rb +18 -0
  70. data/lib/pwnlib/version.rb +2 -1
  71. data/test/abi_test.rb +21 -0
  72. data/test/asm_test.rb +104 -0
  73. data/test/constants/constant_test.rb +1 -0
  74. data/test/constants/constants_test.rb +4 -2
  75. data/test/context_test.rb +1 -0
  76. data/test/data/echo.rb +20 -0
  77. data/test/data/elfs/Makefile +22 -0
  78. data/test/data/elfs/amd64.frelro.elf +0 -0
  79. data/test/data/elfs/amd64.frelro.pie.elf +0 -0
  80. data/test/data/elfs/amd64.nrelro.elf +0 -0
  81. data/test/data/elfs/amd64.prelro.elf +0 -0
  82. data/test/data/elfs/i386.frelro.pie.elf +0 -0
  83. data/test/data/elfs/i386.prelro.elf +0 -0
  84. data/test/data/elfs/source.cpp +19 -0
  85. data/test/data/flag +1 -0
  86. data/test/data/lib32/ld.so.2 +0 -0
  87. data/test/data/lib32/libc.so.6 +0 -0
  88. data/test/data/lib64/ld.so.2 +0 -0
  89. data/test/data/lib64/libc.so.6 +0 -0
  90. data/test/dynelf_test.rb +59 -24
  91. data/test/elf/elf_test.rb +120 -0
  92. data/test/ext_test.rb +3 -2
  93. data/test/files/use_pwnlib.rb +1 -1
  94. data/test/logger_test.rb +61 -0
  95. data/test/memleak_test.rb +4 -33
  96. data/test/reg_sort_test.rb +3 -1
  97. data/test/shellcraft/infloop_test.rb +26 -0
  98. data/test/shellcraft/linux/ls_test.rb +108 -0
  99. data/test/shellcraft/linux/sh_test.rb +119 -0
  100. data/test/shellcraft/linux/syscalls/execve_test.rb +136 -0
  101. data/test/shellcraft/linux/syscalls/syscall_test.rb +83 -0
  102. data/test/shellcraft/memcpy_test.rb +35 -0
  103. data/test/shellcraft/mov_test.rb +98 -0
  104. data/test/shellcraft/nop_test.rb +26 -0
  105. data/test/shellcraft/popad_test.rb +29 -0
  106. data/test/shellcraft/pushstr_array_test.rb +91 -0
  107. data/test/shellcraft/pushstr_test.rb +108 -0
  108. data/test/shellcraft/registers_test.rb +32 -0
  109. data/test/shellcraft/ret_test.rb +30 -0
  110. data/test/shellcraft/setregs_test.rb +62 -0
  111. data/test/shellcraft/shellcraft_test.rb +28 -0
  112. data/test/test_helper.rb +12 -1
  113. data/test/timer_test.rb +23 -0
  114. data/test/tubes/buffer_test.rb +45 -0
  115. data/test/tubes/sock_test.rb +68 -0
  116. data/test/tubes/tube_test.rb +241 -0
  117. data/test/util/cyclic_test.rb +2 -1
  118. data/test/util/fiddling_test.rb +2 -1
  119. data/test/util/getdents_test.rb +32 -0
  120. data/test/util/hexdump_test.rb +7 -9
  121. data/test/util/lists_test.rb +21 -0
  122. data/test/util/packing_test.rb +4 -3
  123. metadata +215 -25
@@ -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
- # stupid (and meaningless) to copy the list of proxied functions to here...
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)
@@ -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::ClassMethods
11
+ include ::Pwnlib::Util::Packing
12
12
  raise 'include module and call fail' unless p8(0x61) == 'a'
13
13
 
14
14
  begin
@@ -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
@@ -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('../data/victim32', __FILE__))
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
@@ -1,9 +1,11 @@
1
1
  # encoding: ASCII-8BIT
2
+
2
3
  require 'test_helper'
4
+
3
5
  require 'pwnlib/reg_sort'
4
6
 
5
7
  class RegSortTest < MiniTest::Test
6
- include ::Pwnlib::RegSort::ClassMethods
8
+ include ::Pwnlib::RegSort
7
9
 
8
10
  def setup
9
11
  @regs = %w(a b c d x y z)
@@ -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