Example #1
0
    def __init__(self, text, **kwargs):
        self.arch = kwargs.get('arch')
        self.os   = kwargs.get('os')
        self.text = text

        if not isinstance(text, str):
            pwn.die('Trying to create an AssemblerText class, but the text does not have type str.\nThe type is ' + str(type(text)) + ' with the value:\n' + repr(text)[:100])
Example #2
0
def u(x, arch = None):
    """Unpacks a string into an integer based on the current context"""
    if arch == 'amd64':
        return u64(x)
    elif arch == 'i386':
        return u32(x)
    pwn.die('Architecture not set in the context while calling u(%s)' % repr(x))
Example #3
0
 def gadget(self, what, avoid=''):
     if what in self._gadget_cache:
         return self._gadget_cache[(what, avoid)]
     gs = []
     err = 'Unknown gadget type: "%s"' % what
     if what == 'ret':
         gs = self._gadgets.get('popret', {}).get(0, [])
     elif what == 'leave':
         gs = self._gadgets.get('leave', [])
     elif what == 'popebp':
         gs = self._gadgets.get('popebp', [])
     elif what.startswith('pop'):
         if what.startswith('popret'):
             offset = what[6:]
         else:
             if what[-3:] == 'ret':
                 what = what[:-3]
             offset = what[3:]
         if offset.isdigit():
             offset = int(offset)
         elif offset == '':
             offset = 1
         else:
             pwn.die(err)
         gs = self._gadgets.get('popret', {}).get(offset, [])
     else:
         pwn.die(err)
     for g in gs:
         gstr = pwn.pint(g)
         if all(c not in gstr for c in avoid):
             self._gadget_cache[(avoid, what)] = g
             return g
Example #4
0
def p(x, arch = None):
    """Packs an integer into a string based on the current context"""
    if arch == 'amd64':
        return p64(x)
    elif arch == 'i386':
        return p32(x)
    pwn.die('Architecture not set in the context while calling p(%d)' % x)
Example #5
0
    def _download_to_cache(self, remote):
        self._initialize_sftp()
        fingerprint = self._get_fingerprint(remote)
        if fingerprint == None:
            import time
            local = os.path.normpath(remote)
            local = os.path.basename(local)
            local += time.strftime('-%Y-%m-d-%H:%M:%S')
            local = os.path.join(self._cachedir, local)

            self._download_raw(remote, local)
            return local

        local = self._get_cachefile(fingerprint)

        if self._verify_local_fingerprint(fingerprint):
            if not self.silent:
                pwn.log.success('Found %s in ssh cache' % remote)
        else:
            self._download_raw(remote, local)

            if not self._verify_local_fingerprint(fingerprint):
                pwn.die('Could not download file "%s"' % remote)

        return local
Example #6
0
def p(x, arch=None):
    """Packs an integer into a string based on the current context"""
    if arch == 'amd64':
        return p64(x)
    elif arch == 'i386':
        return p32(x)
    pwn.die('Architecture not set in the context while calling p(%d)' % x)
Example #7
0
 def call(self, target, args = (), pivot = None):
     '''Irrelevant arguments should be marked by a None'''
     target_addr = self._resolve(target)
     if not target_addr:
         pwn.die('symbol {} not found'.format(target))
     self._chain.append(('call', (target_addr, pivot, pwn.tuplify(args))))
     return self
Example #8
0
 def _resolve(self, x):
     if x is None or isinstance(x, int):
         return x
     for y in [self.plt, self.symbols, self.sections]:
         if x in y:
             return y[x]
     die('Could not resolve `%s\'' % x)
Example #9
0
    def _parse_host(self, host):
        # Split off the optional authentication
        host_ = host.split('@', 1)
        if len(host_) == 1:
            auth, host_ = None, host_[0]
        else:
            auth, host_ = host_

        # Parse the authentication
        if auth:
            auth_ = auth.split(':', 1)
            if len(auth_) == 1:
                self._user = auth_[0]
            else:
                self._user, self._password = auth_

        # Parse the optional port
        host_ = host_.split(':', 1)

        if len(host_) == 1:
            self.host = host_[0]
        else:
            self.host, port = host_

            if not (port and port.isdigit()):
                pwn.die('Port "%s" is not a number' % port)

            self._port = int(port)
Example #10
0
 def _resolve(self, x):
     if x is None or isinstance(x, int):
         return x
     for y in [self.plt, self.symbols, self.sections]:
         if x in y:
             return y[x]
     die('Could not resolve `%s\'' % x)
Example #11
0
    def __init__(self, blob, **kwargs):
        self.arch = kwargs.get('arch')
        self.os   = kwargs.get('os')
        self.blob = blob

        if not isinstance(blob, str):
            pwn.die('Trying to create an AssemblerBlob class, but the blob does not have type str.\nThe type is ' + str(type(blob)) + ' with the value:\n' + repr(blob)[:100])
Example #12
0
def unbits(s, endian='big'):
    out = []

    state = {'cur': ''}
    count = 0

    def flush():
        cur = state['cur'].ljust(8, '0')
        state['cur'] = ''
        if endian == 'little':
            out.append(chr(int(cur[::-1], 2)))
        elif endian == 'big':
            out.append(chr(int(cur, 2)))
        else:
            pwn.die('Wat (endian style)')

    for c in s:
        if c not in ['0', '1', 0, 1, True, False]:
            pwn.die('Unbits called with a funky argument')

        state['cur'] += '1' if c in ['1', 1, True] else '0'
        count += 1

        if count == 8:
            count = 0
            flush()
    if count:
        flush()

    return ''.join(out)
Example #13
0
    def __init__(self, file):
        waitfor('Loading ELF file `%s\'' % os.path.basename(file))
        self.sections = {}
        self.symbols = {}
        self.plt = {}
        self.got = {}
        self.elfclass = None
        self._file_data = None

        if not (os.access(file, os.R_OK) and os.path.isfile(file)):
            die('File %s is not readable or does not exist' % file)

        self._file = file

        def check(f):
            if not (os.access(f, os.X_OK) and os.path.isfile(f)):
                die('Executable %s needed for readelf.py, please install binutils'
                    % f)

        check(_READELF)
        check(_OBJDUMP)

        self._load_elfclass()
        self._load_sections()
        self._load_symbols()
        self._load_plt_got()
        succeeded()
Example #14
0
    def load_library(self, file, addr, relative_to=None):
        '''loads a library at an absolute address or relative to a known symbol'''
        import os
        syms = {}

        if not os.path.exists(file):
            if file in self.elf.libs:
                file = self.elf.libs[file]
            else:
                pwn.die('Could not load library, file %s does not exist.' %
                        file)

        for k, v in pwn.elf.symbols(file).items():
            if '@@' in k:
                k = k[:k.find('@@')]
            syms[k] = v
        offset = addr
        if relative_to:
            if relative_to not in syms:
                pwn.die(
                    'Could not load library relative to "%s" -- no such symbol',
                    relative_to)
            offset -= syms[relative_to]['addr']
        for k, v in syms.items():
            self.symbols[k] = v['addr'] + offset
Example #15
0
 def flush(self, loaded_at = None):
     if loaded_at is not None:
         self._load_addr = loaded_at
     if self.elf.elfclass == 'ELF32':
         return self._generate32()
     else:
         pwn.die('Only 32bit ELF supported')
Example #16
0
 def _set_parent(self, other):
     if self.parent != None:
         pwn.die(
             'Trying to set parent of "%s" to "%s", but parent was already "%s"'
             % (self, other, self.parent))
     self.parent = other
     del Block._roots[self.name]
Example #17
0
    def _download_to_cache(self, remote):
        self._initialize_sftp()
        fingerprint = self._get_fingerprint(remote)
        if fingerprint == None:
            import time
            local = os.path.normpath(remote)
            local = os.path.basename(local)
            local += time.strftime('-%Y-%m-d-%H:%M:%S')
            local = os.path.join(self._cachedir, local)

            self._download_raw(remote, local)
            return local

        local = self._get_cachefile(fingerprint)

        if self._verify_local_fingerprint(fingerprint):
            if not self.silent:
                pwn.log.success('Found %s in ssh cache' % remote)
        else:
            self._download_raw(remote, local)

            if not self._verify_local_fingerprint(fingerprint):
                pwn.die('Could not download file "%s"' % remote)

        return local
Example #18
0
    def _parse_host(self, host):
        # Split off the optional authentication
        host_ = host.split('@', 1)
        if len(host_) == 1:
            auth, host_ = None, host_[0]
        else:
            auth, host_ = host_

        # Parse the authentication
        if auth:
            auth_ = auth.split(':', 1)
            if len(auth_) == 1:
                self._user = auth_[0]
            else:
                self._user, self._password = auth_

        # Parse the optional port
        host_ = host_.split(':', 1)

        if len(host_) == 1:
            self.host = host_[0]
        else:
            self.host, port = host_

            if not (port and port.isdigit()):
                pwn.die('Port "%s" is not a number' % port)

            self._port = int(port)
Example #19
0
 def gadget(self, what, avoid = ''):
     if what in self._gadget_cache:
         return self._gadget_cache[(what, avoid)]
     gs = []
     err = 'Unknown gadget type: "%s"' % what
     if   what == 'ret':
         gs = self._gadgets.get('popret', {}).get(0, [])
     elif what == 'leave':
         gs = self._gadgets.get('leave', [])
     elif what == 'popebp':
         gs = self._gadgets.get('popebp', [])
     elif what.startswith('pop'):
         if what.startswith('popret'):
             offset = what[6:]
         else:
             if what[-3:] == 'ret':
                 what = what[:-3]
             offset = what[3:]
         if offset.isdigit():
             offset = int(offset)
         elif offset == '':
             offset = 1
         else:
             pwn.die(err)
         gs = self._gadgets.get('popret', {}).get(offset, [])
     else:
         pwn.die(err)
     for g in gs:
         gstr = pwn.pint(g)
         if all(c not in gstr for c in avoid):
             self._gadget_cache[(avoid, what)] = g
             return g
Example #20
0
def unbits(s, endian = 'big'):
    out = []

    state = {'cur': ''}
    count = 0

    def flush():
        cur = state['cur'].ljust(8, '0')
        state['cur'] = ''
        if endian == 'little':
            out.append(chr(int(cur[::-1], 2)))
        elif endian == 'big':
            out.append(chr(int(cur, 2)))
        else:
            pwn.die('Wat (endian style)')

    for c in s:
        if c not in ['0', '1', 0, 1, True, False]:
            pwn.die('Unbits called with a funky argument')

        state['cur'] += '1' if c in ['1', 1, True] else '0'
        count += 1

        if count == 8:
            count = 0
            flush()
    if count:
        flush()

    return ''.join(out)
Example #21
0
def nasm_raw(code, checked=True, return_none=False, optimize='x'):

    with tempfile.NamedTemporaryFile(prefix='pwn', suffix='.asm') as tmp:
        tmp.write(code)
        tmp.flush()

        try:
            p = subprocess.Popen(_cmd(tmp.name, optimize),
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
        except OSError, e:
            if e.errno == errno.ENOENT:
                pwn.die('nasm is not installed')
            else:
                raise

        ret = p.wait()
        if ret != 0:
            err = p.stderr.read()
            if return_none:
                return None
            elif checked:
                pwn.die('nasm could not compile file:\n' + err)
            else:
                raise Exception('nasm could not compile file:\n' + err)
        return p.stdout.read()
Example #22
0
 def __coerce__(self, other):
     if pwn.isint(other) and self._load_addr:
         return (self._load_addr, other)
     elif isinstance(other, str):
         return (self.flush(), other)
     else:
         pwn.die('Could not coerce ROP.  Other value was: %r' % other)
Example #23
0
def u(x, arch = None):
    """Unpacks a string into an integer based on the current context"""
    if arch == 'amd64':
        return u64(x)
    elif arch == 'i386':
        return u32(x)
    pwn.die('Architecture not set in the context while calling u(%s)' % repr(x))
Example #24
0
 def flush(self, loaded_at=None):
     if loaded_at is not None:
         self._load_addr = loaded_at
     if self.elf.elfclass == 'ELF32':
         return self._generate32()
     else:
         pwn.die('Only 32bit ELF supported')
Example #25
0
 def __coerce__ (self, other):
     if pwn.isint(other) and self._load_addr:
         return (self._load_addr, other)
     elif isinstance(other, str):
         return (self.flush(), other)
     else:
         pwn.die('Could not coerce ROP.  Other value was: %r' % other)
Example #26
0
    def __init__(self, file):
        waitfor('Loading ELF file `%s\'' % os.path.basename(file))
        self.sections = {}
        self.symbols = {}
        self.plt = {}
        self.got = {}
        self.elfclass = None
        self._file_data = None

        if not (os.access(file, os.R_OK) and os.path.isfile(file)):
            die('File %s is not readable or does not exist' % file)

        self._file = file

        def check(f):
            if not (os.access(f, os.X_OK) and os.path.isfile(f)):
                die('Executable %s needed for readelf.py, please install binutils' % f)

        check(_READELF)
        check(_OBJDUMP)

        self._load_elfclass()
        self._load_sections()
        self._load_symbols()
        self._load_plt_got()
        succeeded()
Example #27
0
 def flush():
     cur = state['cur'].ljust(8, '0')
     state['cur'] = ''
     if endian == 'little':
         out.append(chr(int(cur[::-1], 2)))
     elif endian == 'big':
         out.append(chr(int(cur, 2)))
     else:
         pwn.die('Wat (endian style)')
Example #28
0
 def section(self, name):
     if name in self.sections:
         self._load_data()
         sec = self.sections[name]
         offset = sec['offset']
         size = sec['size']
         return ''.join(self._data[offset:offset + size])
     else:
         pwn.die('No section named %s' % name)
Example #29
0
 def section(self, name):
     if name in self.sections:
         self._load_data()
         sec = self.sections[name]
         offset = sec['offset']
         size = sec['size']
         return self._file_data[offset:offset + size]
     else:
         die('No section named %s' % name)
Example #30
0
 def flush():
     cur = state['cur'].ljust(8, '0')
     state['cur'] = ''
     if endian == 'little':
         out.append(chr(int(cur[::-1], 2)))
     elif endian == 'big':
         out.append(chr(int(cur, 2)))
     else:
         pwn.die('Wat (endian style)')
Example #31
0
 def section(self, name):
     if name in self.sections:
         self._load_data()
         sec = self.sections[name]
         offset = sec['offset']
         size = sec['size']
         return ''.join(self._data[offset:offset + size])
     else:
         pwn.die('No section named %s' % name)
Example #32
0
 def section(self, name):
     if name in self.sections:
         self._load_data()
         sec = self.sections[name]
         offset = sec['offset']
         size = sec['size']
         return self._file_data[offset:offset + size]
     else:
         die('No section named %s' % name)
Example #33
0
    def set_name(self, name):
        if name == self.name:
            return

        if self.name in Block._roots:
            if name in Block._roots:
                pwn.die('A root block with the name "%s" already exicsts' % self.name)
            del Block._roots[self.name]
            Block._roots[name] = self
        self.name = name
Example #34
0
    def set_name(self, name):
        if name == self.name:
            return

        if self.name in Block._roots:
            if name in Block._roots:
                pwn.die('A root block with the name "%s" already exicsts' %
                        self.name)
            del Block._roots[self.name]
            Block._roots[name] = self
        self.name = name
Example #35
0
 def read(self, addr, numb):
     out = []
     while numb > 0:
         data = self._read(addr, numb)
         if data is None:
             die('Offset %x does not live in any section' % addr)
         out.append(data)
         size = len(data)
         numb -= size
         addr += size
     return ''.join(out)
Example #36
0
 def read(self, addr, numb):
     out = []
     while numb > 0:
         data = self._read(addr, numb)
         if data is None:
             die('Offset %x does not live in any section' % addr)
         out.append(data)
         size = len(data)
         numb -= size
         addr += size
     return ''.join(out)
Example #37
0
def _run(cmd):
    import subprocess, errno
    try:
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr = p.communicate()
        exitcode = p.wait()
    except OSError, e:
        if e.errno == errno.ENOENT:
            pwn.die('%s is not installed' % cmd[0])
        else:
            raise
Example #38
0
 def symbol(self, name):
     if name in self.symbols:
         sym = self.symbols[name]
         addr = sym['addr']
         size = sym['size']
         data = self._read(addr, size)
         if data is None:
             die('Symbol %s does not live in any section' % name)
         else:
             return data
     else:
         die('No symbol named %s' % name)
Example #39
0
 def fix(s):
     s_list = set([s])
     for n in range(100):
         s = s.subs(Block.symbols)
         if s.is_integer:
             break
         if s in s_list:
             break
         if repr(s) > 200:
             pwn.die('The expression "%s" is misbehaving' % repr(s))
         s_list.add(s)
     return s
Example #40
0
 def read_symbol(self, name):
     if name in self.symbols:
         sym = self.symbols[name]
         addr = sym['addr']
         size = sym['size']
         data = self.read(addr, size)
         if data is None:
             pwn.die('Symbol %s does not live in any section' % name)
         else:
             return data
     else:
         pwn.die('No symbol named %s' % name)
Example #41
0
 def fix(s):
     s_list = set([s])
     for n in range(100):
         s = s.subs(Block.symbols)
         if s.is_integer:
             break
         if s in s_list:
             break
         if repr(s) > 200:
             pwn.die('The expression "%s" is misbehaving' % repr(s))
         s_list.add(s)
     return s
Example #42
0
def attach_gdb(prog, execute = None, execute_file = None):
    pids = pwn.pidof(prog)
    if isinstance(prog, pwn.remote):
        pid = pids[0]
        if pid is None:
            pwn.die('Could not find remote process (%s:%d) on this machine' % prog.sock.getpeername())
    elif isinstance(prog, str):
        if pids == []:
            pwn.die('No such process')
        pid = max(pids, key = pwn.proc_starttime)
        if len(pids) > 1:
            pwn.log.info('Attaching to youngest process (PID: %d) of %d' % (pid, len(pids)))
    attach_gdb_to_pid(pid, execute = execute, execute_file = execute_file)
Example #43
0
def _run(cmd):
    import subprocess, errno
    try:
        p = subprocess.Popen(cmd,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        stdout, stderr = p.communicate()
        exitcode = p.wait()
    except OSError, e:
        if e.errno == errno.ENOENT:
            pwn.die('%s is not installed' % cmd[0])
        else:
            raise
Example #44
0
    def _initialize_sftp(self):
        import tempfile
        if self._supports_sftp:
            if self._sftp == None:
                self._sftp = self._client.open_sftp()

        self._cachedir = os.path.join(tempfile.gettempdir(), 'pwn-ssh-cache')

        if not os.path.isdir(self._cachedir):
            try:
                os.mkdir(self._cachedir)
            except:
                pwn.die('Could not create ssh cache dir: %s' % self._cachedir)
Example #45
0
    def _initialize_sftp(self):
        import tempfile
        if self._supports_sftp:
            if self._sftp == None:
                self._sftp = self._client.open_sftp()

        self._cachedir = os.path.join(tempfile.gettempdir(), 'pwn-ssh-cache')

        if not os.path.isdir(self._cachedir):
            try:
                os.mkdir(self._cachedir)
            except:
                pwn.die('Could not create ssh cache dir: %s' % self._cachedir)
Example #46
0
def attach_gdb_to_pid(pid, execute=None, execute_file=None):
    import os, tempfile
    if execute is not None and execute_file is not None:
        pwn.die('Both execute and execute_file can\'t be set')
    try:
        prog = pwn.proc_exe(pid)
    except OSError as e:
        pwn.die(e.strerror + ': ' + e.filename)
    if pwn.proc_tracer(pid) is not None:
        pwn.die('Program (pid: %d) is already being debugged' % pid)
    term = pwn.which('x-terminal-emulator')
    if term is None:
        term = os.getenv('COLORTERM') or os.getenv('TERM')
        if term is None:
            pwn.die('No environment variable named (COLOR)TERM')
        term = pwn.which(term)
    termpid = os.fork()
    if termpid == 0:
        argv = [term, '-e', 'gdb "%s" %d' % (prog, pid)]
        if execute:
            with tempfile.NamedTemporaryFile(prefix='pwn',
                                             suffix='.gdb') as tmp:
                tmp.write(execute)
                tmp.flush()
                argv[-1] += ' -x "%s"' % tmp.name
                os.execv(argv[0], argv)
        elif execute_file:
            argv[-1] += ' -x "%s"' % execute_file
            os.execv(argv[0], argv)
        else:
            os.execv(argv[0], argv)
    else:
        pwn.wait_for_debugger(pid)
Example #47
0
    def _generate32(self):
        out = []
        chain = self._chain
        self._chain = []
        p = p32
        def garbage():
            return self._garbage(4)
        def pargs(args):
            args = map(lambda a: garbage() if a is None else p(a), args)
            return args

        for i in range(len(chain)):
            type, link = chain[i]
            islast = i == len(chain) - 1
            issndlast = i == len(chain) - 2
            if type == 'raw':
                out += pargs(link)
            elif type == 'call':
                target, pivot, args = link
                out.append(p(target))
                if len(args) > 0:
                    if islast:
                        out.append(garbage())
                        out += pargs(args)
                    elif issndlast and chain[i + 1][0] == 'call' and \
                      len(chain[i + 1][1][2]) == 0:
                        # the last target has no arguments, so go straight to it
                        out.append(p(chain[i + 1][1][0]))
                        out += pargs(args)
                        break
                    else:
                        if pivot is None:
                            # find suitable popret
                            res = self._pivot(args)
                            if res is None:
                                die('Could not find gadget for pivoting %d arguments' % len(args))
                            pivot, size = res
                            args = pargs(args)
                            for _ in range(size - len(args)):
                                args.append(garbage())
                        out.append(p(pivot))
                        out += args
            elif type == 'migrate':
                if not islast:
                    die('Migrate must be last link in chain')
                esp, ebp = link
                gp = self._gadgets['popebp']
                gl = self._gadgets['leave']
                if len(gp) == 0 and len(gl) == 0:
                    die('Could not find set-EBP and leave gadgets needed to migrate')
                gp = gp[0]
                gl = gl[0]
                if ebp is None:
                    out += [p(gp), p(esp-4), p(gl)]
                else:
                    out += [p(gp), p(esp), p(gl)]
                    self.raw(p(ebp))
            else:
                die('Unknown ROP-link type')
        return ''.join(out)
Example #48
0
 def __init__(self, content = None, wordsize = 4, name = None):
     self._content = []
     self.wordsize = wordsize
     self.parent = None
     if name:
         self.name = name
     else:
         self.name = "block%d" % Block._block_count
         Block._block_count += 1
     if self.name in Block._roots:
         pwn.die('A root block with the name "%s" already exicsts' % self.name)
     Block._roots[self.name] = self
     for o in pwn.concat_all([content]) if content != None else []:
         self._add(o)
Example #49
0
def attach_gdb_to_pid(pid, execute = None, execute_file = None):
    if execute is not None and execute_file is not None:
        pwn.die('Both execute and execute_file can\'t be set')
    try:
        prog = pwn.proc_exe(pid)
    except OSError as e:
        pwn.die(e.strerror + ': ' + e.filename)
    if pwn.proc_tracer(pid) is not None:
        pwn.die('Program (pid: %d) is already being debugged' % pid)
    try:
        term = subprocess.check_output(['/usr/bin/which', 'x-terminal-emulator']).strip()
    except subprocess.CalledProcessError:
        term = ''
    if term == '':
        term = os.getenv('COLORTERM') or os.getenv('TERM')
        if term is None:
            pwn.die('No environment variable named (COLOR)TERM')
        term = subprocess.check_output(['/usr/bin/which', term]).strip()
    termpid = os.fork()
    if termpid == 0:
        argv = [term, '-e', 'gdb "%s" %d' % (prog, pid)]
        if execute:
            with tempfile.NamedTemporaryFile(prefix='pwn', suffix='.gdb') as tmp:
                tmp.write(execute)
                tmp.flush()
                argv[-1] += ' -x "%s"' % tmp.name
                os.execv(argv[0], argv)
        elif execute_file:
            argv[-1] += ' -x "%s"' % execute_file
            os.execv(argv[0], argv)
        else:
            os.execv(argv[0], argv)
    else:
        pwn.wait_for_debugger(pid)
Example #50
0
def which(name, flags = os.X_OK, find_all = False):
    out = []
    try:
        path = os.environ['PATH']
    except KeyError:
        pwn.die('No PATH environment variable')
    for p in path.split(os.pathsep):
        p = os.path.join(p, name)
        if os.access(p, flags):
            out.append(p)
    if find_all:
        return out
    else:
        return out[0] if out else None
Example #51
0
    def __init__(self, *blocks, **kwargs):
        self.arch   = kwargs.get('arch')
        self.os     = kwargs.get('os')
        self.blocks = []

        for b in pwn.concat_all(list(blocks)):
            if isinstance(b, AssemblerBlock):
                if self.os   == None: self.os   = b.os
                if self.arch == None: self.arch = b.arch

                if self.os != b.os and b.os != None:
                    pwn.die('Trying to combine assembler blocks with different os: ' + self.os + ' and ' + b.os)

                if self.arch != b.arch and b.arch != None:
                    pwn.die('Trying to combine assembler blocks with different archs: ' + self.arch + ' and ' + b.arch)

            if isinstance(b, AssemblerContainer):
                self.blocks.extend(b.blocks)
            elif isinstance(b, AssemblerBlock):
                self.blocks.append(b)
            elif isinstance(b, str):
                cast = kwargs.get('cast', 'blob')
                if cast == 'text':
                    self.blocks.append(AssemblerText(b, **kwargs))
                elif cast == 'blob':
                    self.blocks.append(AssemblerBlob(b, **kwargs))
                else:
                    pwn.die('Invalid cast for AssemblerContainer')
            else:
                pwn.die('Trying to force something of type ' + str(type(b)) + ' into an assembler block. Its value is:\n' + repr(b)[:100])
Example #52
0
    def libs(self, remote, dir=None, rop=None):
        '''Downloads the libraries referred to by a file.

        This is done by running ldd on the remote server, parsing the output
        and downloading the relevant files.

        The dir argument specified where to download the files. This defaults
        to './$HOSTNAME' where $HOSTNAME is the hostname of the remote server.

        Set rop to a rop-object to update it's list of known libraries.'''

        libs = self._libs_remote(remote)

        if dir == None:
            dir = self.host

        dir = os.path.realpath(dir)

        res = {}

        seen = set([])

        for lib, remote in libs.items():
            if not remote or lib == 'linux':
                continue

            local = os.path.realpath(
                os.path.join(dir, '.' + os.path.sep + remote))
            if not local.startswith(dir):
                pwn.warning('This seems fishy: %s' % remote)
                continue

            dir2 = os.path.dirname(local)

            if not os.path.exists(dir2):
                try:
                    os.makedirs(dir2)
                except:
                    pwn.die('Could not create dir: %s' % dir2)

            if remote not in seen:
                self.download(remote, local)
                seen.add(remote)
            res[lib] = local

        if rop:
            rop.extra_libs(res)

        return res
Example #53
0
 def __init__(self, content=None, wordsize=4, name=None):
     self._content = []
     self.wordsize = wordsize
     self.parent = None
     if name:
         self.name = name
     else:
         self.name = "block%d" % Block._block_count
         Block._block_count += 1
     if self.name in Block._roots:
         pwn.die('A root block with the name "%s" already exicsts' %
                 self.name)
     Block._roots[self.name] = self
     for o in pwn.concat_all([content]) if content != None else []:
         self._add(o)
Example #54
0
def attach_gdb(prog, execute=None, execute_file=None):
    pids = pwn.pidof(prog)
    if isinstance(prog, pwn.remote):
        pid = pids[0]
        if pid is None:
            pwn.die('Could not find remote process (%s:%d) on this machine' %
                    prog.sock.getpeername())
    elif isinstance(prog, str):
        if pids == []:
            pwn.die('No such process')
        pid = max(pids, key=pwn.proc_starttime)
        if len(pids) > 1:
            pwn.log.info('Attaching to youngest process (PID: %d) of %d' %
                         (pid, len(pids)))
    attach_gdb_to_pid(pid, execute=execute, execute_file=execute_file)
Example #55
0
    def libs(self, remote, dir = None, rop = None):
        '''Downloads the libraries referred to by a file.

        This is done by running ldd on the remote server, parsing the output
        and downloading the relevant files.

        The dir argument specified where to download the files. This defaults
        to './$HOSTNAME' where $HOSTNAME is the hostname of the remote server.

        Set rop to a rop-object to update it's list of known libraries.'''

        libs = self._libs_remote(remote)

        if dir == None:
            dir = self.host

        dir = os.path.realpath(dir)

        res = {}

        seen = set([])

        for lib, remote in libs.items():
            if not remote or lib == 'linux':
                continue

            local = os.path.realpath(os.path.join(dir, '.' + os.path.sep + remote))
            if not local.startswith(dir):
                pwn.warning('This seems fishy: %s' % remote)
                continue

            dir2 = os.path.dirname(local)

            if not os.path.exists(dir2):
                try:
                    os.makedirs(dir2)
                except:
                    pwn.die('Could not create dir: %s' % dir2)

            if remote not in seen:
                self.download(remote, local)
                seen.add(remote)
            res[lib] = local

        if rop:
            rop.extra_libs(res)

        return res
Example #56
0
 def wrapper(*args, **kwargs):
     with pwn.ExtraContext(kwargs) as kwargs:
         for k, vs in supported_context.items():
             if kwargs[k] not in vs:
                 pwn.die('Invalid context for ' + f.func_name + ': ' + k + '=' + str(kwargs[k]) + ' is not supported')
         r = shellcode_wrapper(f, args, kwargs, avoider)
         if kwargs.get('raw'):
             return r
         elif isinstance(r, AssemblerBlock):
             return r
         elif isinstance(r, (tuple, list)):
             kwargs['cast'] = 'blob' if blob else 'text'
             return AssemblerContainer(*r, **kwargs)
         elif not blob:
             return AssemblerText(r, **kwargs)
         else:
             return AssemblerBlob(r, **kwargs)