pwnlib.tubes.process
— Processes¶
-
class
pwnlib.tubes.process.
process
(argv, shell=False, executable=None, cwd=None, env=None, timeout=pwnlib.timeout.Timeout.default, stdin=-1, stdout=<object object>, stderr=-2, level=None, close_fds=True, preexec_fn=<function process.<lambda>>, raw=True, aslr=None, setuid=None)[source]¶ Bases:
pwnlib.tubes.tube.tube
Spawns a new process, and wraps it with a tube for communication.
Parameters: - argv (list) – List of arguments to pass to the spawned process.
- shell (bool) – Set to True to interpret argv as a string to pass to the shell for interpretation instead of as argv.
- executable (str) – Path t`o the binary to execute. If
None
, usesargv[0]
. Cannot be used withshell
. - cwd (str) – Working directory. Uses the current working directory by default.
- env (dict) – Environment variables. By default, inherits from Python’s environment.
- timeout (int) – Timeout to use on
tube
recv
operations. - stdin (int) – File object or file descriptor number to use for
stdin
. By default, a pipe is used. A pty can be used instead by setting this toprocess.PTY
. This will cause programs to behave in an interactive manner (e.g..,python
will show a>>>
prompt). If the application reads from/dev/tty
directly, use a pty. - stdout (int) – File object or file descriptor number to use for
stdout
. By default, a pty is used so that any stdout buffering by libc routines is disabled. May also besubprocess.PIPE
to use a normal pipe. - stderr (int) – File object or file descriptor number to use for
stderr
. By default,stdout
is used. May also besubprocess.PIPE
to use a separate pipe, although thetube
wrapper will not be able to read this data. - close_fds (bool) – Close all open file descriptors except stdin, stdout, stderr.
By default,
True
is used. - preexec_fn (callable) – Callable to invoke immediately before calling
execve
. - raw (bool) – Set the created pty to raw mode (i.e. disable echo and control
characters).
True
by default. If no pty is created, this has no effect. - aslr (bool) –
If set to
False
, disable ASLR viapersonality
(setarch -R
) andsetrlimit
(ulimit -s unlimited
).This disables ASLR for the target process. However, the
setarch
changes are lost if asetuid
binary is executed.The default value is inherited from
context.aslr
. Seesetuid
below for additional options and information. - setuid (bool) –
Used to control setuid status of the target binary, and the corresponding actions taken.
By default, this value is
None
, so no assumptions are made.If
True
, treat the target binary assetuid
. This modifies the mechanisms used to disable ASLR on the process ifaslr=False
. This is useful for debugging locally, when the exploit is asetuid
binary.If
False
, preventsetuid
bits from taking effect on the target binary. This is only supported on Linux, with kernels v3.5 or greater.
Examples
>>> p = process(which('python3')) >>> p.sendline("print('Hello world')") >>> p.sendline("print('Wow, such data')") >>> b'' == p.recv(timeout=0.01) True >>> p.shutdown('send') >>> p.proc.stdin.closed True >>> p.connected('send') False >>> p.recvline() b'Hello world\n' >>> p.recvuntil(',') b'Wow,' >>> p.recvregex('.*data') b' such data' >>> p.recv() b'\n' >>> p.recv() Traceback (most recent call last): ... EOFError
>>> p = process('cat') >>> d = open('/dev/urandom', 'rb').read(4096) >>> p.recv(timeout=0.1) b'' >>> p.write(d) >>> p.recvrepeat(0.1) == d True >>> p.recv(timeout=0.1) b'' >>> p.shutdown('send') >>> p.wait_for_close() >>> p.poll() 0
>>> p = process('cat /dev/zero | head -c8', shell=True, stderr=open('/dev/null', 'w+')) >>> p.recv() b'\x00\x00\x00\x00\x00\x00\x00\x00'
>>> p = process(['python2', '-c', 'import os; print os.read(2, 1024)'], ... preexec_fn=lambda: os.dup2(0, 2)) >>> p.sendline('hello') >>> p.recvline() b'hello\n'
>>> stack_smashing = ['python2', '-c', 'open("/dev/tty", "wb").write("stack smashing detected")'] >>> process(stack_smashing).recvall() b'stack smashing detected' >>> process(stack_smashing, stdout=process.PIPE).recvall() b''
>>> getpass = ['python2', '-c', 'import getpass; print(getpass.getpass("XXX"))'] >>> p = process(getpass, stdin=process.PTY) >>> p.recv() b'XXX' >>> p.sendline('hunter2') >>> p.recvall() b'\nhunter2\n'
>>> process('echo hello 1>&2', shell=True).recvall() b'hello\n'
>>> process('echo hello 1>&2', shell=True, stderr=process.PIPE).recvall() b''
>>> a = process(['cat', '/proc/self/maps']).recvall() >>> b = process(['cat', '/proc/self/maps'], aslr=False).recvall() >>> with context.local(aslr=False): ... c = process(['cat', '/proc/self/maps']).recvall() >>> a == b False >>> b == c True
>>> process(['sh', '-c', 'ulimit -s'], aslr=0).recvline() b'unlimited\n'
-
communicate
(stdin=None) → bytes tuple[source]¶ Calls
subprocess.Popen.communicate()
method on the process.
-
leak
(address, count=0)[source]¶ Leaks memory within the process at the specified address.
Parameters:
-
libc
[source]¶ Returns an ELF for the libc for the current process. If possible, it is adjusted to the correct address automatically.
-
libs
() → dict[source]¶ Return a dictionary mapping the path of each shared library loaded by the process to the address it is loaded at in the process’ address space.
If
/proc/$PID/maps
for the process cannot be accessed, the output ofldd
alone is used. This may give inaccurate results if ASLR is enabled.
-
poll
(block=False) → int[source]¶ Parameters: block (bool) – Wait for the process to exit Poll the exit code of the process. Will return None, if the process has not yet finished and the exit code otherwise.
-
proc
= None[source] subprocess.Popen object