def recvonce(self, size=4, timeout=None): """Receive raw data at once Receive raw data of `size` bytes length through the socket. Args: size (int): The data size to receive timeout (int): Timeout (in second) Returns: bytes: The received data """ self._settimeout(timeout) data = b'' if size <= 0: log.error("`size` must be larger than 0") return None try: read_byte = 0 recv_size = size while read_byte < size: data += self.sock.recv(recv_size) read_byte = len(data) recv_size = size - read_byte except socket.timeout: log.error("Timeout") return None return data
def recv(self, size=4096, timeout=None): """Receive raw data Receive raw data of maximum `size` bytes length through the pipe. Args: size (int): The data size to receive timeout (int): Timeout (in second) Returns: bytes: The received data """ self._settimeout(timeout) if size <= 0: log.error("`size` must be larger than 0") return None if not self._can_recv(): return b'' data = b'' try: data = self.proc.stdout.read(size) except: raise EOFError return data
def symbol(self, name=None): """ Returns the symbol address """ if name is None: return self.__symbol elif name not in self.__symbol: log.error('ELF : symbol "%s" not found' % name) return None return self.__symbol[name]
def function(self, name=None): """ Returns the function address """ if name is None: return self.__function elif name not in self.__function: log.error('ELF : function "%s" not found' % name) return None return self.__function[name]
def got(self, name=None): """ Returns the GOT address """ if name is None: return self.__got elif name not in self.__got: log.error('ELF : got "%s" not found' % name) return None return self.__got[name]
def plt(self, name=None): """ Returns the PLT address """ if name is None: return self.__plt elif name not in self.__plt: log.error('ELF : plt "%s" not found' % name) return None return self.__plt[name]
def section(self, name=None): """ Returns the section address """ if self._pie and not self.base: log.warn('ELF : Base address not set') if name is None: return self.__section elif name not in self.__section: log.error('ELF : section "%s" not found' % name) return None return self.__section[name]
def disasm(blob, arch, vma=0x0): if arch in cmd: md = cmd[arch]["disasm"] else: raise Exception("Unsupported Architecture: %r" % arch) try: res = "" for i in md.disasm(blob, vma): res += "0x%x:\t%s\t%s\n" %(i.address, i.mnemonic, i.op_str) return res except Exception as E: log.error(E)
def shutdown(self, target): """Kill one connection Close send/recv socket. Args: target (str): Connection to close (`send` or `recv`) """ if target in ['write', 'send', 'stdin']: self.sock.shutdown(socket.SHUT_WR) elif target in ['read', 'recv', 'stdout', 'stderr']: self.sock.shutdown(socket.SHUT_RD) else: log.error("You must specify `send` or `recv` as target.")
def recv(self, size=4096, timeout=None): """Receive raw data Receive raw data of maximum `size` bytes length through the socket. Args: size (int): The data size to receive timeout (int): Timeout (in second) Returns: bytes: The received data """ self._settimeout(timeout) if size <= 0: log.error("`size` must be larger than 0") return None try: data = self.sock.recv(size) except socket.timeout: return None # No data received if len(data) == 0: data = None return data
def assemble(s, arch): """ Assemble a string of opcode of given architecture Example: >>> from roppy import * >>> sc = ''' ... xor eax,eax ... push eax ... push 0x68732f2f ... push 0x6e69622f ... mov ebx,esp ... push eax ... push ebx ... mov ecx, esp ... mov al, 0xb ... int $0x80 ... ''' >>> >>> arch = "i386" >>> assemble(sc, arch) b'1\xc0Ph//shh/bin\x89\xe3PS\x89\xe1\xb0\x0b' >>> CODE = b'1\xc0Ph//shh/bin\x89\xe3PS\x89\xe1\xb0\x0b' >>> print(disasm(CODE, arch, 0x4000)) 0x4000: xor eax, eax 0x4002: push eax 0x4003: push 0x68732f2f 0x4008: push 0x6e69622f 0x400d: mov ebx, esp 0x400f: push eax 0x4010: push ebx 0x4011: mov ecx, esp 0x4013: mov al, 0xb >>> It also supports 64 bit assembly which can be specified by passing `amd64` to arch paramter. Example: >>> arch = "amd64" >>> CODE = ''' ... xor rax, rax ... push rax ... xor rdx, rdx ... xor rsi, rsi ... movabs rbx, 0x68732f2f6e69622f ... push rbx ... push rsp ... pop rdi ... mov al, 0x3b ... syscall ... ''' >>> print(assemble(CODE, arch)) b'H1\xc0PH1\xd2H1\xf6H\xbb/bin//shST_\xb0;\x0f\x05' >>> CODE = b'\x48\x31\xc0\x50\x48\x31\xd2\x48\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x54\x5f\xb0\x3b\x0f\x05' >>> print(disasm(CODE, arch, 0x4000)) 0x4000: xor rax, rax 0x4003: push rax 0x4004: xor rdx, rdx 0x4007: xor rsi, rsi 0x400a: movabs rbx, 0x68732f2f6e69622f 0x4014: push rbx 0x4015: push rsp 0x4016: pop rdi 0x4017: mov al, 0x3b 0x4019: syscall >>> """ if arch in cmd: assembler = cmd[arch]["asm"] else: raise Exception("unsupported architecture: %r" % arch) if isinstance(s, str): s = str2bytes(s) try: encoding, count = assembler.asm(s) except Exception as E: log.error(E) res = b"" for ins in encoding: res += bytes([ins]) return res
def __init__(self, args, env=None, cwd=None, timeout=None, stdin=PIPE, stdout=PTY, stderr=STDOUT, preexec_fn=lambda: None, raw=True, closed_fds=True): """ Create a process instance and pipe it for `Tube` Args: args (list): The arguments to pass env (list) : The environment variables """ super(process, self).__init__() if isinstance(args, list): self.args = args self.fpath = self.args[0] else: self.args = [args] self.fpath = self.args[0] self.env = env self.timeout = timeout self.cwd = cwd self.raw = raw self.reservoir = b'' self.temp_timeout = None self.proc = None self.preexec_fn = preexec_fn if stderr is STDOUT: stderr = stdout handles = (stdin, stdout, stderr) self.pty = handles.index(PTY) if PTY in handles else None stdin, stdout, stderr, master, slave = self._handles(*handles) try: self.proc = subprocess.Popen(self.args, cwd=self.cwd, env=self.env, shell=False, stdout=stdout, stdin=stdin, stderr=stderr, preexec_fn=self.__preexec_fn) except FileNotFoundError: log.error("{} not found.".format(self.fpath)) return if self.pty is not None: if stdin is slave: self.proc.stdin = os.fdopen(os.dup(master), 'r+b', 0) if stdout is slave: self.proc.stdout = os.fdopen(os.dup(master), 'r+b', 0) if stderr is slave: self.proc.stderr = os.fdopen(os.dup(master), 'r+b', 0) os.close(master) os.close(slave) fd = self.proc.stdout.fileno() fl = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) log.info("Successfully started process. PID - {}".format( self.proc.pid))