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
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'pwnlib/shellcraft/generators/helper'
|
2
|
+
|
3
|
+
module Pwnlib
|
4
|
+
module Shellcraft
|
5
|
+
module Generators
|
6
|
+
module X86
|
7
|
+
# For non os-related methods.
|
8
|
+
module Common
|
9
|
+
class << self
|
10
|
+
def define_arch_dependent_method(method)
|
11
|
+
define_method(method) do |*args|
|
12
|
+
if context.arch == 'amd64'
|
13
|
+
cat Amd64::Common.public_send(method, *args)
|
14
|
+
elsif context.arch == 'i386'
|
15
|
+
cat I386::Common.public_send(method, *args)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
extend ::Pwnlib::Shellcraft::Generators::Helper
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'pwnlib/shellcraft/generators/x86/common/common'
|
2
|
+
|
3
|
+
module Pwnlib
|
4
|
+
module Shellcraft
|
5
|
+
module Generators
|
6
|
+
module X86
|
7
|
+
module Common
|
8
|
+
# Infinite loop.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# shellcraft.infloop
|
12
|
+
# #=> "infloop_1:\n jmp infloop_1"
|
13
|
+
def infloop
|
14
|
+
label = get_label('infloop')
|
15
|
+
cat "#{label}:"
|
16
|
+
cat "jmp #{label}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'pwnlib/shellcraft/generators/amd64/common/mov'
|
2
|
+
require 'pwnlib/shellcraft/generators/i386/common/mov'
|
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
|
+
define_arch_dependent_method :mov
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'pwnlib/shellcraft/generators/amd64/common/pushstr'
|
2
|
+
require 'pwnlib/shellcraft/generators/i386/common/pushstr'
|
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
|
+
define_arch_dependent_method :pushstr
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# encoding: ASCII-8BIT
|
2
|
+
|
3
|
+
require 'pwnlib/shellcraft/generators/x86/common/common'
|
4
|
+
require 'pwnlib/shellcraft/generators/x86/common/mov'
|
5
|
+
require 'pwnlib/shellcraft/generators/x86/common/pushstr'
|
6
|
+
|
7
|
+
module Pwnlib
|
8
|
+
module Shellcraft
|
9
|
+
module Generators
|
10
|
+
module X86
|
11
|
+
module Common
|
12
|
+
# Push an array of pointers onto the stack.
|
13
|
+
#
|
14
|
+
# @param [String] reg
|
15
|
+
# Destination register to hold the result pointer.
|
16
|
+
# @param [Array<String>] array
|
17
|
+
# List of arguments to push.
|
18
|
+
# NULL termination is normalized so that each argument ends with exactly one NULL byte.
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# context.arch = 'i386'
|
22
|
+
# puts shellcraft.pushstr_array('eax', ['push', 'een'])
|
23
|
+
# # /* push argument array ["push\x00", "een\x00"] */
|
24
|
+
# # /* push "push\x00een\x00" */
|
25
|
+
# # push 1
|
26
|
+
# # dec byte ptr [esp]
|
27
|
+
# # push 0x1010101
|
28
|
+
# # xor dword ptr [esp], 0x1010101 ^ 0x6e656500
|
29
|
+
# # push 0x68737570
|
30
|
+
# # xor eax, eax /* 0 */
|
31
|
+
# # push eax /* null terminate */
|
32
|
+
# # push 9
|
33
|
+
# # pop eax
|
34
|
+
# # add eax, esp
|
35
|
+
# # push eax /* "een\x00" */
|
36
|
+
# # push 8
|
37
|
+
# # pop eax
|
38
|
+
# # add eax, esp
|
39
|
+
# # push eax /* "push\x00" */
|
40
|
+
# # mov eax, esp
|
41
|
+
# #=> nil
|
42
|
+
# @example
|
43
|
+
# context.arch = 'amd64'
|
44
|
+
# puts shellcraft.pushstr_array('rax', ['meow', 'oh'])
|
45
|
+
# # /* push argument array ["meow\x00", "oh\x00"] */
|
46
|
+
# # /* push "meow\x00oh\x00" */
|
47
|
+
# # mov rax, 0x101010101010101
|
48
|
+
# # push rax
|
49
|
+
# # mov rax, 0x101010101010101 ^ 0x686f00776f656d
|
50
|
+
# # xor [rsp], rax
|
51
|
+
# # xor eax, eax /* 0 */
|
52
|
+
# # push rax /* null terminate */
|
53
|
+
# # push 0xd
|
54
|
+
# # pop rax
|
55
|
+
# # add rax, rsp
|
56
|
+
# # push rax /* "oh\x00" */
|
57
|
+
# # push 0x10
|
58
|
+
# # pop rax
|
59
|
+
# # add rax, rsp
|
60
|
+
# # push rax /* "meow\x00" */
|
61
|
+
# # mov rax, rsp
|
62
|
+
# #=> nil
|
63
|
+
def pushstr_array(reg, array)
|
64
|
+
abi = ::Pwnlib::ABI::ABI.default
|
65
|
+
array = array.map { |a| a.gsub(/\x00+\Z/, '') + "\x00" }
|
66
|
+
array_str = array.join
|
67
|
+
word_size = abi.arg_alignment
|
68
|
+
offset = array_str.size + word_size
|
69
|
+
cat "/* push argument array #{array.inspect} */"
|
70
|
+
cat Common.pushstr(array_str)
|
71
|
+
cat Common.mov(reg, 0)
|
72
|
+
cat "push #{reg} /* null terminate */"
|
73
|
+
array.reverse.each_with_index do |arg, i|
|
74
|
+
cat Common.mov(reg, offset + word_size * i - arg.size)
|
75
|
+
cat "add #{reg}, #{abi.stack_pointer}"
|
76
|
+
cat "push #{reg} /* #{arg.inspect} */"
|
77
|
+
offset -= arg.size
|
78
|
+
end
|
79
|
+
cat Common.mov(reg, abi.stack_pointer)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# encoding: ASCII-8BIT
|
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
|
+
# Set registers to given values. See example for clearly usage.
|
11
|
+
#
|
12
|
+
# @param [Hash{Symbol => String, Symbol, Numeric}] reg_context
|
13
|
+
# The values of each registers to be set, see examples.
|
14
|
+
# @param [Boolean] stack_allowed
|
15
|
+
# If we can use stack for setting values.
|
16
|
+
# With +stack_allowd+ equals +true+, shellcode would be shorter.
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# context.arch = 'i386'
|
20
|
+
# puts shellcraft.setregs(rax: 'ebx', ebx: 'ecx', ecx: 0x123)
|
21
|
+
# # mov rax, rbx
|
22
|
+
# # mov ebx, ecx
|
23
|
+
# # xor ecx, ecx
|
24
|
+
# # mov cx, 0x123
|
25
|
+
# @example
|
26
|
+
# context.arch = 'amd64'
|
27
|
+
# puts shellcraft.setregs(rdi: 'rsi', rsi: 'rdi')
|
28
|
+
# # xchg rdi, rsi
|
29
|
+
#
|
30
|
+
# puts shellcraft.setregs(rax: -1)
|
31
|
+
# # push -1
|
32
|
+
# # pop rax
|
33
|
+
#
|
34
|
+
# puts shellcraft.setregs({rax: -1}, stack_allowed: false)
|
35
|
+
# # mov rax, -1
|
36
|
+
def setregs(reg_context, stack_allowed: true)
|
37
|
+
abi = ::Pwnlib::ABI::ABI.default
|
38
|
+
reg_context = reg_context.reject { |_, v| v.nil? }
|
39
|
+
# convert all registers to string
|
40
|
+
reg_context = reg_context.map do |k, v|
|
41
|
+
v = register?(v) ? v.to_s : v
|
42
|
+
[k.to_s, v]
|
43
|
+
end
|
44
|
+
reg_context = reg_context.to_h
|
45
|
+
ax_str, dx_str = abi.cdq_pair
|
46
|
+
eax = reg_context[ax_str]
|
47
|
+
edx = reg_context[dx_str]
|
48
|
+
cdq = false
|
49
|
+
ev = lambda do |reg|
|
50
|
+
return reg unless reg.is_a?(String)
|
51
|
+
evaluate(reg)
|
52
|
+
end
|
53
|
+
eax = ev[eax]
|
54
|
+
edx = ev[edx]
|
55
|
+
|
56
|
+
if eax.is_a?(Numeric) && edx.is_a?(Numeric) && edx.zero? && (eax & (1 << 31)).zero?
|
57
|
+
# @diff
|
58
|
+
# The condition is wrong in python-pwntools, and here we don't care the case of edx==0xffffffff.
|
59
|
+
cdq = true
|
60
|
+
reg_context.delete(dx_str)
|
61
|
+
end
|
62
|
+
sorted_regs = regsort(reg_context, registers)
|
63
|
+
if sorted_regs.empty?
|
64
|
+
cat '/* setregs noop */'
|
65
|
+
else
|
66
|
+
sorted_regs.each do |how, src, dst|
|
67
|
+
if how == 'xchg'
|
68
|
+
cat "xchg #{src}, #{dst}"
|
69
|
+
else
|
70
|
+
# Bug in python-pwntools, which is missing `stack_allowed`.
|
71
|
+
# Proof of bug: pwnlib.shellcraft.setregs({'rax': 1}, stack_allowed=False)
|
72
|
+
cat Common.mov(src, dst, stack_allowed: stack_allowed)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
cat "cdq /* #{dx_str}=0 */" if cdq
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# encoding: ASCII-8BIT
|
2
|
+
|
3
|
+
require 'pwnlib/shellcraft/generators/x86/common/pushstr'
|
4
|
+
require 'pwnlib/shellcraft/generators/x86/common/pushstr_array'
|
5
|
+
require 'pwnlib/shellcraft/generators/x86/linux/linux'
|
6
|
+
|
7
|
+
module Pwnlib
|
8
|
+
module Shellcraft
|
9
|
+
module Generators
|
10
|
+
module X86
|
11
|
+
module Linux
|
12
|
+
# Execute a different process.
|
13
|
+
#
|
14
|
+
# @param [String] path
|
15
|
+
# Can be either an absolute path or a register's name.
|
16
|
+
# @param [String, Array<String>, Integer, nil] argv
|
17
|
+
# If +argv+ is a +String+, it would be seen as a register.
|
18
|
+
# If +Array<String>+, works like normal arguments array.
|
19
|
+
# If +Integer+, take it as a pointer adrress. (same as +nil+ if zero is given.)
|
20
|
+
# If +nil+, use NULL pointer.
|
21
|
+
# @param [String, Hash{#to_s => #to_s}, Integer, nil] envp
|
22
|
+
# +String+ for register name.
|
23
|
+
# If +envp+ is a +Hash+, it will be converted into the environ form (i.e. key=value).
|
24
|
+
# If +Integer+, take it as a pointer address (same as +nil+ if zero is given).
|
25
|
+
# If +nil+ is given, use NULL pointer.
|
26
|
+
#
|
27
|
+
# @example
|
28
|
+
# shellcraft.execve('/bin/sh', ['sh'], {PWD: '.'})
|
29
|
+
#
|
30
|
+
# @diff
|
31
|
+
# Parameters have no default values since this is a basic function.
|
32
|
+
def execve(path, argv, envp)
|
33
|
+
abi = ::Pwnlib::ABI::ABI.syscall
|
34
|
+
argv = case argv
|
35
|
+
when String
|
36
|
+
raise ArgumentError, "#{argv.inspect} is not a valid register name" unless register?(argv)
|
37
|
+
argv
|
38
|
+
when Array
|
39
|
+
cat Common.pushstr_array(abi.register_arguments[2], argv)
|
40
|
+
cat ''
|
41
|
+
abi.register_arguments[2]
|
42
|
+
when Integer, nil
|
43
|
+
argv.to_i
|
44
|
+
end
|
45
|
+
|
46
|
+
envp = case envp
|
47
|
+
when String
|
48
|
+
raise ArgumentError, "#{envp.inspect} is not a valid register name" unless register?(envp)
|
49
|
+
envp
|
50
|
+
when Hash
|
51
|
+
cat Common.pushstr_array(abi.register_arguments[3], envp.map { |k, v| "#{k}=#{v}" })
|
52
|
+
cat ''
|
53
|
+
abi.register_arguments[3]
|
54
|
+
when Integer, nil
|
55
|
+
envp.to_i
|
56
|
+
end
|
57
|
+
|
58
|
+
unless register?(path)
|
59
|
+
cat Common.pushstr(path)
|
60
|
+
cat ''
|
61
|
+
path = abi.stack_pointer
|
62
|
+
end
|
63
|
+
cat Linux.syscall('SYS_execve', path, argv, envp)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# encoding: ASCII-8BIT
|
2
|
+
|
3
|
+
require 'pwnlib/shellcraft/generators/x86/common/pushstr'
|
4
|
+
require 'pwnlib/shellcraft/generators/x86/linux/linux'
|
5
|
+
require 'pwnlib/shellcraft/generators/x86/linux/syscall'
|
6
|
+
|
7
|
+
module Pwnlib
|
8
|
+
module Shellcraft
|
9
|
+
module Generators
|
10
|
+
module X86
|
11
|
+
module Linux
|
12
|
+
# List files.
|
13
|
+
#
|
14
|
+
# @param [String] dir
|
15
|
+
# The relative path to be listed.
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
# context.arch = 'amd64'
|
19
|
+
# puts shellcraft.ls
|
20
|
+
# # /* push ".\x00" */
|
21
|
+
# # push 0x2e
|
22
|
+
# # /* call open("rsp", 0, 0) */
|
23
|
+
# # push 2 /* (SYS_open) */
|
24
|
+
# # pop rax
|
25
|
+
# # mov rdi, rsp
|
26
|
+
# # xor esi, esi /* 0 */
|
27
|
+
# # cdq /* rdx=0 */
|
28
|
+
# # syscall
|
29
|
+
# # /* call getdents("rax", "rsp", 4096) */
|
30
|
+
# # mov rdi, rax
|
31
|
+
# # push 0x4e /* (SYS_getdents) */
|
32
|
+
# # pop rax
|
33
|
+
# # mov rsi, rsp
|
34
|
+
# # xor edx, edx
|
35
|
+
# # mov dh, 0x1000 >> 8
|
36
|
+
# # syscall
|
37
|
+
# # /* call write(1, "rsp", "rax") */
|
38
|
+
# # push 1
|
39
|
+
# # pop rdi
|
40
|
+
# # mov rsi, rsp
|
41
|
+
# # mov rdx, rax
|
42
|
+
# # push 1 /* (SYS_write) */
|
43
|
+
# # pop rax
|
44
|
+
# # syscall
|
45
|
+
# #=> nil
|
46
|
+
#
|
47
|
+
# @note
|
48
|
+
# This shellcode will output the binary data returned by syscall +getdents+.
|
49
|
+
# Use {Pwnlib::Util::Getdents.parse} to parse the output.
|
50
|
+
def ls(dir = '.')
|
51
|
+
abi = ::Pwnlib::ABI::ABI.syscall
|
52
|
+
cat Common.pushstr(dir)
|
53
|
+
cat Linux.syscall('SYS_open', abi.stack_pointer, 0, 0)
|
54
|
+
# In x86, return value register is same as sysnr register.
|
55
|
+
ret = abi.register_arguments.first
|
56
|
+
# XXX(david942j): Will fixed size 0x1000 be an issue?
|
57
|
+
cat Linux.syscall('SYS_getdents', ret, abi.stack_pointer, 0x1000) # getdents(fd, buf, sz)
|
58
|
+
|
59
|
+
# Just write all the shits out
|
60
|
+
cat Linux.syscall('SYS_write', 1, abi.stack_pointer, ret)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# encoding: ASCII-8BIT
|
2
|
+
|
3
|
+
require 'pwnlib/shellcraft/generators/x86/linux/execve'
|
4
|
+
require 'pwnlib/shellcraft/generators/x86/linux/linux'
|
5
|
+
|
6
|
+
module Pwnlib
|
7
|
+
module Shellcraft
|
8
|
+
module Generators
|
9
|
+
module X86
|
10
|
+
module Linux
|
11
|
+
# Get shell!
|
12
|
+
#
|
13
|
+
# @param [Boolean, Array<String>] argv
|
14
|
+
# Arguments of +argv+ when calling +execve+.
|
15
|
+
# If +true+ is given, use +['sh']+.
|
16
|
+
# If +Array<String>+ is given, use it as arguments array.
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# context.arch = 'i386'
|
20
|
+
# puts shellcraft.sh
|
21
|
+
# # /* push "/bin///sh\x00" */
|
22
|
+
# # push 0x68
|
23
|
+
# # push 0x732f2f2f
|
24
|
+
# # push 0x6e69622f
|
25
|
+
# #
|
26
|
+
# # /* call execve("esp", 0, 0) */
|
27
|
+
# # push 0xb /* (SYS_execve) */
|
28
|
+
# # pop eax
|
29
|
+
# # mov ebx, esp
|
30
|
+
# # xor ecx, ecx /* 0 */
|
31
|
+
# # cdq /* edx=0 */
|
32
|
+
# # int 0x80
|
33
|
+
# #=> nil
|
34
|
+
#
|
35
|
+
# @note Null pointer is always used as +envp+.
|
36
|
+
#
|
37
|
+
# @diff
|
38
|
+
# By default, this method calls +execve('/bin///sh', 0, 0)+, which is different from pwntools-python:
|
39
|
+
# +execve('/bin///sh', ['sh'], 0)+.
|
40
|
+
def sh(argv: false)
|
41
|
+
argv = case argv
|
42
|
+
when true then ['sh']
|
43
|
+
when false then 0
|
44
|
+
else argv
|
45
|
+
end
|
46
|
+
cat Linux.execve('/bin///sh', argv, 0)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|