Skip to content

Latest commit

 

History

History
312 lines (217 loc) · 9.81 KB

pwnlib.tubes.process-Processes.md

File metadata and controls

312 lines (217 loc) · 9.81 KB

pwnlib.tubes.process—Processes

class pwnlib.tubes.process.process(argv=None, shell=False, executable=None, cwd=None, env=None, stdin=-1, stdout=<pwnlib.tubes.process.PTY object>, stderr=-2, close_fds=True, preexec_fn=<function <lambda>>, raw=True, aslr=None, setuid=None, where='local', display=None, alarm=None, *args, **kwargs) 源码

基类:pwnlib.tubes.tube.tube

生成一个新的进程,用通信通道封装。

参数:

  • argv (list) – 传送给生成的进程的参数。

  • shell (bool) – 设置为True时将argv设置为字符串来传递给shell,而不是参数。

  • executable (str) – 要执行的二进制文件路径,如果为None,使用argv[0]。不能和shell一起使用。

  • cwd (str) – 工作目录,默认使用当前目录。

  • env (dict) – 环境变量,默认情况下从Python的环境继承。

  • stdin (int) – 用于stdin的文件或工程的标识符。默认情况下使用通道。 可以使用伪终端而不用将其设置为PTY。这会使程序在交互模式下运行(如python会显示>>>提示符)。如果程序直接从/dev/tty读取,则使用伪终端。

  • stdout (int) – 用于stdout的文件或工程的标识符.默认使用伪终端,所以libc的任意stdout缓冲都会被禁用。也可以使用PIPE来使用普通通道。

  • stderr (int) – 用于stderr的文件或工程的标识符。 默认情况下使用STDOUT。也可以作为PIPE来使用特定的通道,即使pwnlib.tubes.tube.tube封包将会无法读取数据

  • close_fds (bool) – 关闭除stdin,stdout和stderr之外的所有文件. 默认使用True

  • preexec_fn (callable) – 在调用execve之前,立刻调用所有可调用的。

  • raw (bool) – 将生成的伪终端设置为原始模式(即禁用回显字符和控制字符)。默认为True,如果没有生成伪终端,则没有作用。

  • aslr (bool) – 如果设置为False,通过personality(setarch -R)和setrlimit(ulimit -s unlimited)禁用ASLR。 这会禁用目标进程的ASLR,但是如果执行setuid二进制文件,setarch的更改会丢失。 默认参数从context.aslr中继承。查看setuid来得到其他选项和信息。

  • setuid (bool) – 用于控制目标二进制文件的setuid状态并采取相应的行动。 默认该值为None,所以没有相应设定。 如果设为True,将目标二进制文件看作setuid。如果aslr=False,这会修改进程上禁用ASLR的机制。当调用为setuid二进制文件时,对本地调试有用。 如果设为False,阻止setuid的位对目标进程的作用。该设置仅在内核为kernels V3.5或更高版本的Linux上提供。

  • where (str) – 进程运行的位置,用于日志记录。

  • display (list) – 要显示的参数列表,而不是主要的执行文件名称。

  • alarm (int) – 设置SIGALRM警告进程上的超时。

>>> p = process('python2')
>>> p.sendline("print 'Hello world'")
>>> p.sendline("print 'Wow, such data'");
>>> '' == p.recv(timeout=0.01)
True
>>> p.shutdown('send')
>>> p.proc.stdin.closed
True
>>> p.connected('send')
False
>>> p.recvline()
'Hello world\n'
>>> p.recvuntil(',')
'Wow,'
>>> p.recvregex('.*data')
' such data'
>>> p.recv()
'\n'
>>> p.recv() 
Traceback (most recent call last):
...
EOFError
>>> p = process('cat')
>>> d = open('/dev/urandom').read(4096)
>>> p.recv(timeout=0.1)
''
>>> p.write(d)
>>> p.recvrepeat(0.1) == d
True
>>> p.recv(timeout=0.1)
''
>>> 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()
'\x00\x00\x00\x00\x00\x00\x00\x00'
>>> p = process(['python','-c','import os; print os.read(2,1024)'],
...             preexec_fn = lambda: os.dup2(0,2))
>>> p.sendline('hello')
>>> p.recvline()
'hello\n'
>>> stack_smashing = ['python','-c','open("/dev/tty","wb").write("stack smashing detected")']
>>> process(stack_smashing).recvall()
'stack smashing detected'
>>> process(stack_smashing, stdout=PIPE).recvall()
''
>>> getpass = ['python','-c','import getpass; print getpass.getpass("XXX")']
>>> p = process(getpass, stdin=PTY)
>>> p.recv()
'XXX'
>>> p.sendline('hunter2')
>>> p.recvall()
'\nhunter2\n'
>>> process('echo hello 1>&2', shell=True).recvall()
'hello\n'
>>> process('echo hello 1>&2', shell=True, stderr=PIPE).recvall()
''
>>> 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()
'unlimited\n'
>>> io = process(['sh','-c','sleep 10; exit 7'], alarm=2)
>>> io.poll(block=True) == -signal.SIGALRM
True
>>> binary = ELF.from_assembly('nop', arch='mips')
>>> p = process(binary.path)

communicate(stdin = None) → str 源码

在进程中调用subprocess.Popem.communicate()的方法。

kill() 源码

中止进程。

leak(address, count=1) 源码

在指定地址的进程中泄露内存。

参数:

  • address (int) – 泄露内存的地址。
  • count (int) – 在地址上泄露内存的字节数。

>>> e = ELF('/bin/sh')
>>> p = process(e.path)

为了确保没有竞争条件阻止进程建立

>>> p.sendline('echo hello')
>>> p.recvuntil('hello')
'hello'

现在我们可以泄露内存了!

>>> p.leak(e.address, 4)
'\x7fELF'

libs() → dict 源码

返回一个映射到进程加载的每个共享库的路径的字典,其加载在进程地址空间中。

如果进程的/proc/$PID/maps无法访问,输出中的的ldd将会被单独使用。如果ASLR被启用,可能会导致不准确的结果。

poll(block = False) → int 源码

参数:block(bool) - 等待进程退出。

轮询进程的退出代码。 如果进程尚未执行完毕,将返回无,否则返回退出代码。

alarm = None 源码

进程的超时警告。

argv = None 源码

参数通过argv传递。

aslr = None 源码

ASLR是否应该打开。

corefile 源码

返回进程的核心文件

如果进程处于活动状态,尝试使用GDB建立一个coredump文件。

如果进程已经关闭,则尝试定位内核创建的coredump文件。

cwd 源码

正在运行进程的目录。

>>> p = process('sh')
>>> p.sendline('cd /tmp; echo AAA')
>>> _ = p.recvuntil('AAA')
>>> p.cwd == '/tmp'
True
>>> p.sendline('cd /proc; echo BBB;')
>>> _ = p.recvuntil('BBB')
>>> p.cwd
'/proc'

elf 源码

为启动该进程的可执行文件返回一个ELF文件。

env = None 源码

传递环境给envp。

executable = None 源码

可执行文件的完整路径。

libc 源码

为当前进程的libc返回ELF,如果可能,会自行调整到正确的地址。

proc = None 源码

支持该进程的subprocess.Popen对象

program 源码

executable的别称,用于向后兼容。

>>> p = process('true')
>>> p.executable == '/bin/true'
True
>>> p.executable == p.program
True

pty = None 源码

用于控制终端的文件标识符。

raw = None 源码

查看正在控制的终端是否运行在原始模式。

stderr 源码

self.proc.stderr的缩写

查看: process.proc

stdin 源码

self.proc.stdin的缩写

查看: process.proc

stdout 源码

self.proc.stdout的缩写

查看: process.proc