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.tubeSpawns 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
tuberecvoperations. - 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..,pythonwill show a>>>prompt). If the application reads from/dev/ttydirectly, 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.PIPEto use a normal pipe. - stderr (int) – File object or file descriptor number to use for
stderr. By default,stdoutis used. May also besubprocess.PIPEto use a separate pipe, although thetubewrapper will not be able to read this data. - close_fds (bool) – Close all open file descriptors except stdin, stdout, stderr.
By default,
Trueis 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).
Trueby 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
setarchchanges are lost if asetuidbinary is executed.The default value is inherited from
context.aslr. Seesetuidbelow 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 asetuidbinary.If
False, preventsetuidbits 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/mapsfor the process cannot be accessed, the output oflddalone 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