pwntools 0.1.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +96 -15
- data/Rakefile +8 -2
- data/lib/pwn.rb +10 -7
- data/lib/pwnlib/abi.rb +61 -0
- data/lib/pwnlib/asm.rb +357 -0
- data/lib/pwnlib/constants/constant.rb +19 -3
- data/lib/pwnlib/constants/constants.rb +46 -20
- data/lib/pwnlib/constants/linux/amd64.rb +32 -1
- data/lib/pwnlib/constants/linux/i386.rb +2 -0
- data/lib/pwnlib/context.rb +128 -27
- data/lib/pwnlib/dynelf.rb +122 -54
- data/lib/pwnlib/elf/elf.rb +340 -0
- data/lib/pwnlib/errors.rb +31 -0
- data/lib/pwnlib/ext/array.rb +2 -1
- data/lib/pwnlib/ext/helper.rb +6 -5
- data/lib/pwnlib/ext/integer.rb +2 -1
- data/lib/pwnlib/ext/string.rb +3 -2
- data/lib/pwnlib/logger.rb +245 -0
- data/lib/pwnlib/memleak.rb +59 -29
- data/lib/pwnlib/pwn.rb +27 -9
- data/lib/pwnlib/reg_sort.rb +109 -110
- data/lib/pwnlib/runner.rb +53 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/common.rb +16 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/infloop.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/memcpy.rb +35 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/mov.rb +131 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/nop.rb +18 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/popad.rb +28 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/pushstr.rb +66 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/pushstr_array.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/ret.rb +33 -0
- data/lib/pwnlib/shellcraft/generators/amd64/common/setregs.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/cat.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/execve.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/exit.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/linux.rb +16 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/ls.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/open.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/sh.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/sleep.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/syscall.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/helper.rb +115 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/common.rb +16 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/infloop.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/memcpy.rb +34 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/mov.rb +93 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/nop.rb +18 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/pushstr.rb +41 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/pushstr_array.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/i386/common/setregs.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/cat.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/execve.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/exit.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/linux.rb +16 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/ls.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/open.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/sh.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/sleep.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/syscall.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/common.rb +29 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/infloop.rb +24 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/memcpy.rb +17 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/mov.rb +17 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/pushstr.rb +17 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/pushstr_array.rb +86 -0
- data/lib/pwnlib/shellcraft/generators/x86/common/setregs.rb +84 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/cat.rb +54 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/execve.rb +72 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/exit.rb +34 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/linux.rb +16 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/ls.rb +67 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/open.rb +47 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/sh.rb +53 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/sleep.rb +52 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/syscall.rb +52 -0
- data/lib/pwnlib/shellcraft/registers.rb +148 -0
- data/lib/pwnlib/shellcraft/shellcraft.rb +73 -0
- data/lib/pwnlib/timer.rb +67 -0
- data/lib/pwnlib/tubes/buffer.rb +99 -0
- data/lib/pwnlib/tubes/process.rb +155 -0
- data/lib/pwnlib/tubes/serialtube.rb +114 -0
- data/lib/pwnlib/tubes/sock.rb +101 -0
- data/lib/pwnlib/tubes/tube.rb +442 -0
- data/lib/pwnlib/ui.rb +21 -0
- data/lib/pwnlib/util/cyclic.rb +97 -94
- data/lib/pwnlib/util/fiddling.rb +288 -220
- data/lib/pwnlib/util/getdents.rb +85 -0
- data/lib/pwnlib/util/hexdump.rb +116 -112
- data/lib/pwnlib/util/lists.rb +58 -0
- data/lib/pwnlib/util/packing.rb +223 -228
- data/lib/pwnlib/util/ruby.rb +19 -0
- data/lib/pwnlib/version.rb +3 -1
- data/test/abi_test.rb +22 -0
- data/test/asm_test.rb +177 -0
- data/test/constants/constant_test.rb +2 -0
- data/test/constants/constants_test.rb +5 -2
- data/test/context_test.rb +14 -3
- 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 +16 -0
- data/test/data/elfs/Makefile +24 -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/amd64.static.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 +62 -25
- data/test/elf/elf_test.rb +147 -0
- data/test/ext_test.rb +4 -2
- data/test/files/use_pwn.rb +3 -6
- data/test/files/use_pwnlib.rb +2 -1
- data/test/full_file_test.rb +6 -0
- data/test/logger_test.rb +120 -0
- data/test/memleak_test.rb +5 -33
- data/test/reg_sort_test.rb +4 -1
- data/test/runner_test.rb +32 -0
- data/test/shellcraft/infloop_test.rb +27 -0
- data/test/shellcraft/linux/cat_test.rb +87 -0
- data/test/shellcraft/linux/ls_test.rb +109 -0
- data/test/shellcraft/linux/sh_test.rb +120 -0
- data/test/shellcraft/linux/sleep_test.rb +68 -0
- data/test/shellcraft/linux/syscalls/execve_test.rb +137 -0
- data/test/shellcraft/linux/syscalls/exit_test.rb +57 -0
- data/test/shellcraft/linux/syscalls/open_test.rb +87 -0
- data/test/shellcraft/linux/syscalls/syscall_test.rb +84 -0
- data/test/shellcraft/memcpy_test.rb +50 -0
- data/test/shellcraft/mov_test.rb +99 -0
- data/test/shellcraft/nop_test.rb +27 -0
- data/test/shellcraft/popad_test.rb +30 -0
- data/test/shellcraft/pushstr_array_test.rb +92 -0
- data/test/shellcraft/pushstr_test.rb +109 -0
- data/test/shellcraft/registers_test.rb +33 -0
- data/test/shellcraft/ret_test.rb +31 -0
- data/test/shellcraft/setregs_test.rb +63 -0
- data/test/shellcraft/shellcraft_test.rb +30 -0
- data/test/test_helper.rb +61 -2
- data/test/timer_test.rb +42 -0
- data/test/tubes/buffer_test.rb +46 -0
- data/test/tubes/process_test.rb +105 -0
- data/test/tubes/serialtube_test.rb +162 -0
- data/test/tubes/sock_test.rb +68 -0
- data/test/tubes/tube_test.rb +320 -0
- data/test/ui_test.rb +18 -0
- data/test/util/cyclic_test.rb +3 -1
- data/test/util/fiddling_test.rb +12 -3
- data/test/util/getdents_test.rb +33 -0
- data/test/util/hexdump_test.rb +9 -10
- data/test/util/lists_test.rb +22 -0
- data/test/util/packing_test.rb +5 -3
- 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
|