pwntools 0.1.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +96 -15
  3. data/Rakefile +8 -2
  4. data/lib/pwn.rb +10 -7
  5. data/lib/pwnlib/abi.rb +61 -0
  6. data/lib/pwnlib/asm.rb +357 -0
  7. data/lib/pwnlib/constants/constant.rb +19 -3
  8. data/lib/pwnlib/constants/constants.rb +46 -20
  9. data/lib/pwnlib/constants/linux/amd64.rb +32 -1
  10. data/lib/pwnlib/constants/linux/i386.rb +2 -0
  11. data/lib/pwnlib/context.rb +128 -27
  12. data/lib/pwnlib/dynelf.rb +122 -54
  13. data/lib/pwnlib/elf/elf.rb +340 -0
  14. data/lib/pwnlib/errors.rb +31 -0
  15. data/lib/pwnlib/ext/array.rb +2 -1
  16. data/lib/pwnlib/ext/helper.rb +6 -5
  17. data/lib/pwnlib/ext/integer.rb +2 -1
  18. data/lib/pwnlib/ext/string.rb +3 -2
  19. data/lib/pwnlib/logger.rb +245 -0
  20. data/lib/pwnlib/memleak.rb +59 -29
  21. data/lib/pwnlib/pwn.rb +27 -9
  22. data/lib/pwnlib/reg_sort.rb +109 -110
  23. data/lib/pwnlib/runner.rb +53 -0
  24. data/lib/pwnlib/shellcraft/generators/amd64/common/common.rb +16 -0
  25. data/lib/pwnlib/shellcraft/generators/amd64/common/infloop.rb +24 -0
  26. data/lib/pwnlib/shellcraft/generators/amd64/common/memcpy.rb +35 -0
  27. data/lib/pwnlib/shellcraft/generators/amd64/common/mov.rb +131 -0
  28. data/lib/pwnlib/shellcraft/generators/amd64/common/nop.rb +18 -0
  29. data/lib/pwnlib/shellcraft/generators/amd64/common/popad.rb +28 -0
  30. data/lib/pwnlib/shellcraft/generators/amd64/common/pushstr.rb +66 -0
  31. data/lib/pwnlib/shellcraft/generators/amd64/common/pushstr_array.rb +24 -0
  32. data/lib/pwnlib/shellcraft/generators/amd64/common/ret.rb +33 -0
  33. data/lib/pwnlib/shellcraft/generators/amd64/common/setregs.rb +24 -0
  34. data/lib/pwnlib/shellcraft/generators/amd64/linux/cat.rb +24 -0
  35. data/lib/pwnlib/shellcraft/generators/amd64/linux/execve.rb +24 -0
  36. data/lib/pwnlib/shellcraft/generators/amd64/linux/exit.rb +24 -0
  37. data/lib/pwnlib/shellcraft/generators/amd64/linux/linux.rb +16 -0
  38. data/lib/pwnlib/shellcraft/generators/amd64/linux/ls.rb +24 -0
  39. data/lib/pwnlib/shellcraft/generators/amd64/linux/open.rb +24 -0
  40. data/lib/pwnlib/shellcraft/generators/amd64/linux/sh.rb +24 -0
  41. data/lib/pwnlib/shellcraft/generators/amd64/linux/sleep.rb +24 -0
  42. data/lib/pwnlib/shellcraft/generators/amd64/linux/syscall.rb +24 -0
  43. data/lib/pwnlib/shellcraft/generators/helper.rb +115 -0
  44. data/lib/pwnlib/shellcraft/generators/i386/common/common.rb +16 -0
  45. data/lib/pwnlib/shellcraft/generators/i386/common/infloop.rb +24 -0
  46. data/lib/pwnlib/shellcraft/generators/i386/common/memcpy.rb +34 -0
  47. data/lib/pwnlib/shellcraft/generators/i386/common/mov.rb +93 -0
  48. data/lib/pwnlib/shellcraft/generators/i386/common/nop.rb +18 -0
  49. data/lib/pwnlib/shellcraft/generators/i386/common/pushstr.rb +41 -0
  50. data/lib/pwnlib/shellcraft/generators/i386/common/pushstr_array.rb +24 -0
  51. data/lib/pwnlib/shellcraft/generators/i386/common/setregs.rb +24 -0
  52. data/lib/pwnlib/shellcraft/generators/i386/linux/cat.rb +24 -0
  53. data/lib/pwnlib/shellcraft/generators/i386/linux/execve.rb +24 -0
  54. data/lib/pwnlib/shellcraft/generators/i386/linux/exit.rb +24 -0
  55. data/lib/pwnlib/shellcraft/generators/i386/linux/linux.rb +16 -0
  56. data/lib/pwnlib/shellcraft/generators/i386/linux/ls.rb +24 -0
  57. data/lib/pwnlib/shellcraft/generators/i386/linux/open.rb +24 -0
  58. data/lib/pwnlib/shellcraft/generators/i386/linux/sh.rb +24 -0
  59. data/lib/pwnlib/shellcraft/generators/i386/linux/sleep.rb +24 -0
  60. data/lib/pwnlib/shellcraft/generators/i386/linux/syscall.rb +24 -0
  61. data/lib/pwnlib/shellcraft/generators/x86/common/common.rb +29 -0
  62. data/lib/pwnlib/shellcraft/generators/x86/common/infloop.rb +24 -0
  63. data/lib/pwnlib/shellcraft/generators/x86/common/memcpy.rb +17 -0
  64. data/lib/pwnlib/shellcraft/generators/x86/common/mov.rb +17 -0
  65. data/lib/pwnlib/shellcraft/generators/x86/common/pushstr.rb +17 -0
  66. data/lib/pwnlib/shellcraft/generators/x86/common/pushstr_array.rb +86 -0
  67. data/lib/pwnlib/shellcraft/generators/x86/common/setregs.rb +84 -0
  68. data/lib/pwnlib/shellcraft/generators/x86/linux/cat.rb +54 -0
  69. data/lib/pwnlib/shellcraft/generators/x86/linux/execve.rb +72 -0
  70. data/lib/pwnlib/shellcraft/generators/x86/linux/exit.rb +34 -0
  71. data/lib/pwnlib/shellcraft/generators/x86/linux/linux.rb +16 -0
  72. data/lib/pwnlib/shellcraft/generators/x86/linux/ls.rb +67 -0
  73. data/lib/pwnlib/shellcraft/generators/x86/linux/open.rb +47 -0
  74. data/lib/pwnlib/shellcraft/generators/x86/linux/sh.rb +53 -0
  75. data/lib/pwnlib/shellcraft/generators/x86/linux/sleep.rb +52 -0
  76. data/lib/pwnlib/shellcraft/generators/x86/linux/syscall.rb +52 -0
  77. data/lib/pwnlib/shellcraft/registers.rb +148 -0
  78. data/lib/pwnlib/shellcraft/shellcraft.rb +73 -0
  79. data/lib/pwnlib/timer.rb +67 -0
  80. data/lib/pwnlib/tubes/buffer.rb +99 -0
  81. data/lib/pwnlib/tubes/process.rb +155 -0
  82. data/lib/pwnlib/tubes/serialtube.rb +114 -0
  83. data/lib/pwnlib/tubes/sock.rb +101 -0
  84. data/lib/pwnlib/tubes/tube.rb +442 -0
  85. data/lib/pwnlib/ui.rb +21 -0
  86. data/lib/pwnlib/util/cyclic.rb +97 -94
  87. data/lib/pwnlib/util/fiddling.rb +288 -220
  88. data/lib/pwnlib/util/getdents.rb +85 -0
  89. data/lib/pwnlib/util/hexdump.rb +116 -112
  90. data/lib/pwnlib/util/lists.rb +58 -0
  91. data/lib/pwnlib/util/packing.rb +223 -228
  92. data/lib/pwnlib/util/ruby.rb +19 -0
  93. data/lib/pwnlib/version.rb +3 -1
  94. data/test/abi_test.rb +22 -0
  95. data/test/asm_test.rb +177 -0
  96. data/test/constants/constant_test.rb +2 -0
  97. data/test/constants/constants_test.rb +5 -2
  98. data/test/context_test.rb +14 -3
  99. data/test/data/assembly/aarch64.s +19 -0
  100. data/test/data/assembly/amd64.s +21 -0
  101. data/test/data/assembly/arm.s +9 -0
  102. data/test/data/assembly/i386.s +21 -0
  103. data/test/data/assembly/mips.s +16 -0
  104. data/test/data/assembly/mips64.s +6 -0
  105. data/test/data/assembly/powerpc.s +18 -0
  106. data/test/data/assembly/powerpc64.s +36 -0
  107. data/test/data/assembly/sparc.s +33 -0
  108. data/test/data/assembly/sparc64.s +5 -0
  109. data/test/data/assembly/thumb.s +37 -0
  110. data/test/data/echo.rb +16 -0
  111. data/test/data/elfs/Makefile +24 -0
  112. data/test/data/elfs/amd64.frelro.elf +0 -0
  113. data/test/data/elfs/amd64.frelro.pie.elf +0 -0
  114. data/test/data/elfs/amd64.nrelro.elf +0 -0
  115. data/test/data/elfs/amd64.prelro.elf +0 -0
  116. data/test/data/elfs/amd64.static.elf +0 -0
  117. data/test/data/elfs/i386.frelro.pie.elf +0 -0
  118. data/test/data/elfs/i386.prelro.elf +0 -0
  119. data/test/data/elfs/source.cpp +19 -0
  120. data/test/data/flag +1 -0
  121. data/test/data/lib32/ld.so.2 +0 -0
  122. data/test/data/lib32/libc.so.6 +0 -0
  123. data/test/data/lib64/ld.so.2 +0 -0
  124. data/test/data/lib64/libc.so.6 +0 -0
  125. data/test/dynelf_test.rb +62 -25
  126. data/test/elf/elf_test.rb +147 -0
  127. data/test/ext_test.rb +4 -2
  128. data/test/files/use_pwn.rb +3 -6
  129. data/test/files/use_pwnlib.rb +2 -1
  130. data/test/full_file_test.rb +6 -0
  131. data/test/logger_test.rb +120 -0
  132. data/test/memleak_test.rb +5 -33
  133. data/test/reg_sort_test.rb +4 -1
  134. data/test/runner_test.rb +32 -0
  135. data/test/shellcraft/infloop_test.rb +27 -0
  136. data/test/shellcraft/linux/cat_test.rb +87 -0
  137. data/test/shellcraft/linux/ls_test.rb +109 -0
  138. data/test/shellcraft/linux/sh_test.rb +120 -0
  139. data/test/shellcraft/linux/sleep_test.rb +68 -0
  140. data/test/shellcraft/linux/syscalls/execve_test.rb +137 -0
  141. data/test/shellcraft/linux/syscalls/exit_test.rb +57 -0
  142. data/test/shellcraft/linux/syscalls/open_test.rb +87 -0
  143. data/test/shellcraft/linux/syscalls/syscall_test.rb +84 -0
  144. data/test/shellcraft/memcpy_test.rb +50 -0
  145. data/test/shellcraft/mov_test.rb +99 -0
  146. data/test/shellcraft/nop_test.rb +27 -0
  147. data/test/shellcraft/popad_test.rb +30 -0
  148. data/test/shellcraft/pushstr_array_test.rb +92 -0
  149. data/test/shellcraft/pushstr_test.rb +109 -0
  150. data/test/shellcraft/registers_test.rb +33 -0
  151. data/test/shellcraft/ret_test.rb +31 -0
  152. data/test/shellcraft/setregs_test.rb +63 -0
  153. data/test/shellcraft/shellcraft_test.rb +30 -0
  154. data/test/test_helper.rb +61 -2
  155. data/test/timer_test.rb +42 -0
  156. data/test/tubes/buffer_test.rb +46 -0
  157. data/test/tubes/process_test.rb +105 -0
  158. data/test/tubes/serialtube_test.rb +162 -0
  159. data/test/tubes/sock_test.rb +68 -0
  160. data/test/tubes/tube_test.rb +320 -0
  161. data/test/ui_test.rb +18 -0
  162. data/test/util/cyclic_test.rb +3 -1
  163. data/test/util/fiddling_test.rb +12 -3
  164. data/test/util/getdents_test.rb +33 -0
  165. data/test/util/hexdump_test.rb +9 -10
  166. data/test/util/lists_test.rb +22 -0
  167. data/test/util/packing_test.rb +5 -3
  168. metadata +357 -37
@@ -0,0 +1,24 @@
1
+ # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
3
+
4
+ require 'pwnlib/shellcraft/generators/i386/linux/linux'
5
+ require 'pwnlib/shellcraft/generators/x86/linux/sleep'
6
+
7
+ module Pwnlib
8
+ module Shellcraft
9
+ module Generators
10
+ module I386
11
+ module Linux
12
+ # @overload sleep(seconds)
13
+ #
14
+ # @see Generators::X86::Linux#sleep
15
+ def sleep(*args)
16
+ context.local(arch: :i386) do
17
+ cat X86::Linux.sleep(*args)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
3
+
4
+ require 'pwnlib/shellcraft/generators/i386/linux/linux'
5
+ require 'pwnlib/shellcraft/generators/x86/linux/syscall'
6
+
7
+ module Pwnlib
8
+ module Shellcraft
9
+ module Generators
10
+ module I386
11
+ module Linux
12
+ # @overload syscall(*arguments)
13
+ #
14
+ # @see Generators::X86::Linux#syscall
15
+ def syscall(*args)
16
+ context.local(arch: :i386) do
17
+ cat X86::Linux.syscall(*args)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pwnlib/shellcraft/generators/helper'
4
+
5
+ module Pwnlib
6
+ module Shellcraft
7
+ module Generators
8
+ module X86
9
+ # For non os-related methods.
10
+ module Common
11
+ class << self
12
+ def define_arch_dependent_method(method)
13
+ define_method(method) do |*args, **kwargs|
14
+ case context.arch
15
+ when 'amd64'
16
+ cat Amd64::Common.public_send(method, *args, **kwargs)
17
+ when 'i386'
18
+ cat I386::Common.public_send(method, *args, **kwargs)
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ extend ::Pwnlib::Shellcraft::Generators::Helper
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pwnlib/shellcraft/generators/x86/common/common'
4
+
5
+ module Pwnlib
6
+ module Shellcraft
7
+ module Generators
8
+ module X86
9
+ module Common
10
+ # Infinite loop.
11
+ #
12
+ # @example
13
+ # shellcraft.infloop
14
+ # #=> "infloop_1:\n jmp infloop_1"
15
+ def infloop
16
+ label = get_label('infloop')
17
+ cat "#{label}:"
18
+ cat "jmp #{label}"
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pwnlib/shellcraft/generators/amd64/common/memcpy'
4
+ require 'pwnlib/shellcraft/generators/i386/common/memcpy'
5
+ require 'pwnlib/shellcraft/generators/x86/common/common'
6
+
7
+ module Pwnlib
8
+ module Shellcraft
9
+ module Generators
10
+ module X86
11
+ module Common
12
+ define_arch_dependent_method :memcpy
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pwnlib/shellcraft/generators/amd64/common/mov'
4
+ require 'pwnlib/shellcraft/generators/i386/common/mov'
5
+ require 'pwnlib/shellcraft/generators/x86/common/common'
6
+
7
+ module Pwnlib
8
+ module Shellcraft
9
+ module Generators
10
+ module X86
11
+ module Common
12
+ define_arch_dependent_method :mov
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pwnlib/shellcraft/generators/amd64/common/pushstr'
4
+ require 'pwnlib/shellcraft/generators/i386/common/pushstr'
5
+ require 'pwnlib/shellcraft/generators/x86/common/common'
6
+
7
+ module Pwnlib
8
+ module Shellcraft
9
+ module Generators
10
+ module X86
11
+ module Common
12
+ define_arch_dependent_method :pushstr
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,86 @@
1
+ # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
3
+
4
+ require 'pwnlib/shellcraft/generators/x86/common/common'
5
+ require 'pwnlib/shellcraft/generators/x86/common/mov'
6
+ require 'pwnlib/shellcraft/generators/x86/common/pushstr'
7
+
8
+ module Pwnlib
9
+ module Shellcraft
10
+ module Generators
11
+ module X86
12
+ module Common
13
+ # Push an array of pointers onto the stack.
14
+ #
15
+ # @param [String] reg
16
+ # Destination register to hold the result pointer.
17
+ # @param [Array<String>] array
18
+ # List of arguments to push.
19
+ # NULL termination is normalized so that each argument ends with exactly one NULL byte.
20
+ #
21
+ # @example
22
+ # context.arch = 'i386'
23
+ # puts shellcraft.pushstr_array('eax', ['push', 'een'])
24
+ # # /* push argument array ["push\x00", "een\x00"] */
25
+ # # /* push "push\x00een\x00" */
26
+ # # push 1
27
+ # # dec byte ptr [esp]
28
+ # # push 0x1010101
29
+ # # xor dword ptr [esp], 0x1010101 ^ 0x6e656500
30
+ # # push 0x68737570
31
+ # # xor eax, eax /* 0 */
32
+ # # push eax /* null terminate */
33
+ # # push 9
34
+ # # pop eax
35
+ # # add eax, esp
36
+ # # push eax /* "een\x00" */
37
+ # # push 8
38
+ # # pop eax
39
+ # # add eax, esp
40
+ # # push eax /* "push\x00" */
41
+ # # mov eax, esp
42
+ # #=> nil
43
+ # @example
44
+ # context.arch = 'amd64'
45
+ # puts shellcraft.pushstr_array('rax', ['meow', 'oh'])
46
+ # # /* push argument array ["meow\x00", "oh\x00"] */
47
+ # # /* push "meow\x00oh\x00" */
48
+ # # mov rax, 0x101010101010101
49
+ # # push rax
50
+ # # mov rax, 0x101010101010101 ^ 0x686f00776f656d
51
+ # # xor [rsp], rax
52
+ # # xor eax, eax /* 0 */
53
+ # # push rax /* null terminate */
54
+ # # push 0xd
55
+ # # pop rax
56
+ # # add rax, rsp
57
+ # # push rax /* "oh\x00" */
58
+ # # push 0x10
59
+ # # pop rax
60
+ # # add rax, rsp
61
+ # # push rax /* "meow\x00" */
62
+ # # mov rax, rsp
63
+ # #=> nil
64
+ def pushstr_array(reg, array)
65
+ abi = ::Pwnlib::ABI::ABI.default
66
+ array = array.map { |a| "#{a.gsub(/\x00+\Z/, '')}\x00" }
67
+ array_str = array.join
68
+ word_size = abi.arg_alignment
69
+ offset = array_str.size + word_size
70
+ cat "/* push argument array #{array.inspect} */"
71
+ cat Common.pushstr(array_str)
72
+ cat Common.mov(reg, 0)
73
+ cat "push #{reg} /* null terminate */"
74
+ array.reverse.each_with_index do |arg, i|
75
+ cat Common.mov(reg, offset + word_size * i - arg.size)
76
+ cat "add #{reg}, #{abi.stack_pointer}"
77
+ cat "push #{reg} /* #{arg.inspect} */"
78
+ offset -= arg.size
79
+ end
80
+ cat Common.mov(reg, abi.stack_pointer)
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,84 @@
1
+ # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
3
+
4
+ require 'pwnlib/shellcraft/generators/x86/common/common'
5
+
6
+ module Pwnlib
7
+ module Shellcraft
8
+ module Generators
9
+ module X86
10
+ module Common
11
+ # Set registers to given values. See example for clearly usage.
12
+ #
13
+ # @param [Hash{Symbol => String, Symbol, Numeric}] reg_context
14
+ # The values of each registers to be set, see examples.
15
+ # @param [Boolean] stack_allowed
16
+ # If we can use stack for setting values.
17
+ # With +stack_allowed+ equals +true+, shellcode would be shorter.
18
+ #
19
+ # @example
20
+ # context.arch = 'i386'
21
+ # puts shellcraft.setregs({ eax: 'ebx', ebx: 'ecx', ecx: 0x123 })
22
+ # # mov eax, ebx
23
+ # # mov ebx, ecx
24
+ # # xor ecx, ecx
25
+ # # mov cx, 0x123
26
+ # @example
27
+ # context.arch = 'amd64'
28
+ # puts shellcraft.setregs({ rdi: 'rsi', rsi: 'rdi' })
29
+ # # xchg rdi, rsi
30
+ #
31
+ # puts shellcraft.setregs({ rax: -1 })
32
+ # # push -1
33
+ # # pop rax
34
+ #
35
+ # puts shellcraft.setregs({ rax: -1 }, stack_allowed: false)
36
+ # # mov rax, -1
37
+ def setregs(reg_context, stack_allowed: true)
38
+ abi = ::Pwnlib::ABI::ABI.default
39
+ reg_context = reg_context.reject { |_, v| v.nil? }
40
+ # convert all registers to string
41
+ reg_context = reg_context.map do |k, v|
42
+ v = register?(v) ? v.to_s : v
43
+ [k.to_s, v]
44
+ end
45
+ reg_context = reg_context.to_h
46
+ ax_str, dx_str = abi.cdq_pair
47
+ eax = reg_context[ax_str]
48
+ edx = reg_context[dx_str]
49
+ cdq = false
50
+ ev = lambda do |reg|
51
+ return reg unless reg.is_a?(String)
52
+
53
+ evaluate(reg)
54
+ end
55
+ eax = ev[eax]
56
+ edx = ev[edx]
57
+
58
+ if eax.is_a?(Numeric) && edx.is_a?(Numeric) && edx.zero? && (eax & (1 << 31)).zero?
59
+ # @diff
60
+ # The condition is wrong in python-pwntools, and here we don't care the case of edx==0xffffffff.
61
+ cdq = true
62
+ reg_context.delete(dx_str)
63
+ end
64
+ sorted_regs = regsort(reg_context, registers)
65
+ if sorted_regs.empty?
66
+ cat '/* setregs noop */'
67
+ else
68
+ sorted_regs.each do |how, src, dst|
69
+ if how == 'xchg'
70
+ cat "xchg #{src}, #{dst}"
71
+ else
72
+ # Bug in python-pwntools, which is missing `stack_allowed`.
73
+ # Proof of bug: pwnlib.shellcraft.setregs({'rax': 1}, stack_allowed=False)
74
+ cat Common.mov(src, dst, stack_allowed: stack_allowed)
75
+ end
76
+ end
77
+ end
78
+ cat "cdq /* #{dx_str}=0 */" if cdq
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,54 @@
1
+ # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
3
+
4
+ require 'pwnlib/shellcraft/generators/x86/common/pushstr'
5
+ require 'pwnlib/shellcraft/generators/x86/linux/linux'
6
+ require 'pwnlib/shellcraft/generators/x86/linux/syscall'
7
+
8
+ module Pwnlib
9
+ module Shellcraft
10
+ module Generators
11
+ module X86
12
+ module Linux
13
+ # Opens a file and writes its contents to the specified file descriptor.
14
+ #
15
+ # @param [String] filename
16
+ # The filename.
17
+ # @param [Integer] fd
18
+ # The file descriptor to write the file contents.
19
+ #
20
+ # @example
21
+ # context.arch = 'amd64'
22
+ # puts shellcraft.cat('/etc/passwd')
23
+ # # /* push "/etc/passwd\x00" */
24
+ # # push 0x1010101 ^ 0x647773
25
+ # # xor dword ptr [rsp], 0x1010101
26
+ # # mov rax, 0x7361702f6374652f
27
+ # # push rax
28
+ # # /* call open("rsp", 0, "O_RDONLY") */
29
+ # # push 2 /* (SYS_open) */
30
+ # # pop rax
31
+ # # mov rdi, rsp
32
+ # # xor esi, esi /* 0 */
33
+ # # cdq /* rdx=0 */
34
+ # # syscall
35
+ # # /* call sendfile(1, "rax", 0, 2147483647) */
36
+ # # push 1
37
+ # # pop rdi
38
+ # # mov rsi, rax
39
+ # # push 0x28 /* (SYS_sendfile) */
40
+ # # pop rax
41
+ # # mov r10d, 0x7fffffff
42
+ # # cdq /* rdx=0 */
43
+ # # syscall
44
+ # #=> nil
45
+ def cat(filename, fd: 1)
46
+ abi = ::Pwnlib::ABI::ABI.syscall
47
+ cat Linux.open(filename, 'O_RDONLY')
48
+ cat Linux.syscall('SYS_sendfile', fd, abi.register_arguments.first, 0, 0x7fffffff)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,72 @@
1
+ # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
3
+
4
+ require 'pwnlib/shellcraft/generators/x86/common/pushstr'
5
+ require 'pwnlib/shellcraft/generators/x86/common/pushstr_array'
6
+ require 'pwnlib/shellcraft/generators/x86/linux/linux'
7
+
8
+ module Pwnlib
9
+ module Shellcraft
10
+ module Generators
11
+ module X86
12
+ module Linux
13
+ # Execute a different process.
14
+ #
15
+ # @param [String] path
16
+ # Can be either an absolute path or a register's name.
17
+ # @param [String, Array<String>, Integer, nil] argv
18
+ # If +argv+ is a +String+, it would be seen as a register.
19
+ # If +Array<String>+, works like normal arguments array.
20
+ # If +Integer+, take it as a pointer adrress. (same as +nil+ if zero is given.)
21
+ # If +nil+, use NULL pointer.
22
+ # @param [String, Hash{#to_s => #to_s}, Integer, nil] envp
23
+ # +String+ for register name.
24
+ # If +envp+ is a +Hash+, it will be converted into the environ form (i.e. key=value).
25
+ # If +Integer+, take it as a pointer address (same as +nil+ if zero is given).
26
+ # If +nil+ is given, use NULL pointer.
27
+ #
28
+ # @example
29
+ # shellcraft.execve('/bin/sh', ['sh'], {PWD: '.'})
30
+ #
31
+ # @diff
32
+ # Parameters have no default values since this is a basic function.
33
+ def execve(path, argv, envp)
34
+ abi = ::Pwnlib::ABI::ABI.syscall
35
+ argv = case argv
36
+ when String
37
+ raise ArgumentError, "#{argv.inspect} is not a valid register name" unless register?(argv)
38
+
39
+ argv
40
+ when Array
41
+ cat Common.pushstr_array(abi.register_arguments[2], argv)
42
+ cat ''
43
+ abi.register_arguments[2]
44
+ when Integer, nil
45
+ argv.to_i
46
+ end
47
+
48
+ envp = case envp
49
+ when String
50
+ raise ArgumentError, "#{envp.inspect} is not a valid register name" unless register?(envp)
51
+
52
+ envp
53
+ when Hash
54
+ cat Common.pushstr_array(abi.register_arguments[3], envp.map { |k, v| "#{k}=#{v}" })
55
+ cat ''
56
+ abi.register_arguments[3]
57
+ when Integer, nil
58
+ envp.to_i
59
+ end
60
+
61
+ unless register?(path)
62
+ cat Common.pushstr(path)
63
+ cat ''
64
+ path = abi.stack_pointer
65
+ end
66
+ cat Linux.syscall('SYS_execve', path, argv, envp)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end