Module: Pwnlib::Shellcraft::Generators::X86::Linux
- Extended by:
- Helper
- Defined in:
- lib/pwnlib/shellcraft/generators/x86/linux/linux.rb,
lib/pwnlib/shellcraft/generators/x86/linux/ls.rb,
lib/pwnlib/shellcraft/generators/x86/linux/sh.rb,
lib/pwnlib/shellcraft/generators/x86/linux/cat.rb,
lib/pwnlib/shellcraft/generators/x86/linux/exit.rb,
lib/pwnlib/shellcraft/generators/x86/linux/open.rb,
lib/pwnlib/shellcraft/generators/x86/linux/sleep.rb,
lib/pwnlib/shellcraft/generators/x86/linux/execve.rb,
lib/pwnlib/shellcraft/generators/x86/linux/syscall.rb
Overview
For os-related methods.
Instance Method Summary collapse
-
#cat(filename, fd: 1) ⇒ Object
Opens a file and writes its contents to the specified file descriptor.
-
#execve(path, argv, envp) ⇒ Object
Execute a different process.
-
#exit(status = 0) ⇒ String
Exit syscall.
-
#ls(dir = '.') ⇒ Object
List files.
-
#open(filename, flags = 'O_RDONLY', mode = 0) ⇒ String
Push filename onto stack and perform open syscall.
-
#sh(argv: false) ⇒ Object
Get shell!.
-
#sleep(seconds) ⇒ Object
Sleep for a specified number of seconds.
-
#syscall(*arguments) ⇒ Object
Assembly of
syscall
.
Methods included from Helper
Instance Method Details
#cat(filename, fd: 1) ⇒ Object
Opens a file and writes its contents to the specified file descriptor.
45 46 47 48 49 |
# File 'lib/pwnlib/shellcraft/generators/x86/linux/cat.rb', line 45 def cat(filename, fd: 1) abi = ::Pwnlib::ABI::ABI.syscall cat Linux.open(filename, 'O_RDONLY') cat Linux.syscall('SYS_sendfile', fd, abi.register_arguments.first, 0, 0x7fffffff) end |
#execve(path, argv, envp) ⇒ Object
Execute a different process.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/pwnlib/shellcraft/generators/x86/linux/execve.rb', line 33 def execve(path, argv, envp) abi = ::Pwnlib::ABI::ABI.syscall argv = case argv when String raise ArgumentError, "#{argv.inspect} is not a valid register name" unless register?(argv) argv when Array cat Common.pushstr_array(abi.register_arguments[2], argv) cat '' abi.register_arguments[2] when Integer, nil argv.to_i end envp = case envp when String raise ArgumentError, "#{envp.inspect} is not a valid register name" unless register?(envp) envp when Hash cat Common.pushstr_array(abi.register_arguments[3], envp.map { |k, v| "#{k}=#{v}" }) cat '' abi.register_arguments[3] when Integer, nil envp.to_i end unless register?(path) cat Common.pushstr(path) cat '' path = abi.stack_pointer end cat Linux.syscall('SYS_execve', path, argv, envp) end |
#exit(status = 0) ⇒ String
Exit syscall.
27 28 29 |
# File 'lib/pwnlib/shellcraft/generators/x86/linux/exit.rb', line 27 def exit(status = 0) cat Linux.syscall('SYS_exit', status) end |
#ls(dir = '.') ⇒ Object
This shellcode will output the binary data returned by syscall getdents
. Use Util::Getdents.parse to parse the output.
List files.
51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/pwnlib/shellcraft/generators/x86/linux/ls.rb', line 51 def ls(dir = '.') abi = ::Pwnlib::ABI::ABI.syscall cat Common.pushstr(dir) cat Linux.syscall('SYS_open', abi.stack_pointer, 0, 0) # In x86, return value register is same as sysnr register. ret = abi.register_arguments.first # XXX(david942j): Will fixed size 0x1000 be an issue? cat Linux.syscall('SYS_getdents', ret, abi.stack_pointer, 0x1000) # getdents(fd, buf, sz) # Just write all the shits out cat Linux.syscall('SYS_write', 1, abi.stack_pointer, ret) end |
#open(filename, flags = 'O_RDONLY', mode = 0) ⇒ String
Push filename onto stack and perform open syscall.
38 39 40 41 42 |
# File 'lib/pwnlib/shellcraft/generators/x86/linux/open.rb', line 38 def open(filename, flags = 'O_RDONLY', mode = 0) abi = ::Pwnlib::ABI::ABI.syscall cat Common.pushstr(filename) cat Linux.syscall('SYS_open', abi.stack_pointer, flags, mode) end |
#sh(argv: false) ⇒ Object
Null pointer is always used as envp
.
Get shell!
41 42 43 44 45 46 47 48 |
# File 'lib/pwnlib/shellcraft/generators/x86/linux/sh.rb', line 41 def sh(argv: false) argv = case argv when true then ['sh'] when false then 0 else argv end cat Linux.execve('/bin///sh', argv, 0) end |
#sleep(seconds) ⇒ Object
Syscall nanosleep
accepts a data pointer as argument, the stack will be used for putting the data needed. The generated assembly will use sizeof(struct timespec) = 16 bytes for putting data.
Sleep for a specified number of seconds.
38 39 40 41 42 43 44 45 46 47 |
# File 'lib/pwnlib/shellcraft/generators/x86/linux/sleep.rb', line 38 def sleep(seconds) # pushes the data onto stack tv_sec = seconds.to_i tv_nsec = ((seconds - tv_sec) * 1e9).to_i data = ::Pwnlib::Util::Packing.p64(tv_sec) + ::Pwnlib::Util::Packing.p64(tv_nsec) cat Common.pushstr(data, append_null: false) sp = ::Pwnlib::ABI::ABI.default.stack_pointer cat Linux.syscall('SYS_nanosleep', sp, 0) cat "add #{sp}, #{data.size} /* recover #{sp} */" end |
#syscall(*arguments) ⇒ Object
Assembly of syscall
.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/pwnlib/shellcraft/generators/x86/linux/syscall.rb', line 26 def syscall(*arguments) abi = ::Pwnlib::ABI::ABI.syscall registers = abi.register_arguments reg_ctx = registers.zip(arguments).to_h syscall = arguments.first if syscall.to_s.start_with?('SYS_') fmt = "#{syscall.to_s[4..-1]}(%s)" args = [] else fmt = 'syscall(%s)' args = [syscall ? syscall.inspect : '?'] end # arg0 to arg5 1.upto(6) do |i| args.push(arguments[i] ? arguments[i].inspect : '?') end args.pop while args.last == '?' cat "/* call #{format(fmt, args.join(', '))} */" cat Common.setregs(reg_ctx) if arguments.any? { |v| !v.nil? } cat abi.syscall_str end |