def _load32_popret(self): addesp = '\x83\xc4' popr = map(chr, [0x58, 0x59, 0x5a, 0x5b, 0x5d, 0x5e, 0x5f]) popa = '\x61' ret = '\xc3' poprets = defaultdict(list) for data, addr in self._exec_sections(): i = 0 while True: i = data.find(ret, i) if i == -1: break s = [(i, 0)] while len(s) > 0: off, size = s.pop(0) gaddr = addr + off poprets[size].append(gaddr) if data[off - 1] in popr: s.append((off - 1, size + 1)) if data[off - 1] == popa: s.append((off - 1, size + 7)) if data[off - 3:off - 1] == addesp: x = u8(data[off - 1]) if x % 4 == 0: s.append((off - 3, size + x // 4)) i += 1 self._gadgets['popret'] = dict(poprets)
def _load32_popret(self): from collections import defaultdict leaesp_byte = '\x8d\x64\x24' leaesp_word = '\x8d\xa4\x24' addesp_byte = '\x83\xc4' addesp_word = '\x81\xc4' popr = map(chr, [0x58, 0x59, 0x5a, 0x5b, 0x5d, 0x5e, 0x5f]) popa = '\x61' ret = '\xc3' poprets = defaultdict(list) for data, addr in self.elf.executable_segments(): i = 0 while True: i = data.find(ret, i) if i == -1: break s = [(i, 0)] while len(s) > 0: off, size = s.pop(0) gaddr = addr + off poprets[size].append(gaddr) if data[off - 1] in popr: s.append((off - 1, size + 1)) if data[off - 1] == popa: s.append((off - 1, size + 7)) if data[off - 3:off - 1] == addesp_byte: x = pwn.u8(data[off - 1]) if x % 4 == 0 and x < 128: s.append((off - 3, size + x // 4)) if data[off - 6:off - 1] == addesp_word: x = pwn.u32(data[off - 4]) if x % 4 == 0: s.append((off - 3, size + x // 4)) if data[off - 4:off - 1] == leaesp_byte: x = pwn.u8(data[off - 1]) if x % 4 == 0 and x < 128: s.append((off - 3, size + x // 4)) if data[off - 7:off - 1] == leaesp_word: x = pwn.u32(data[off - 4]) if x % 4 == 0: s.append((off - 3, size + x // 4)) i += 1 self._gadgets['popret'] = dict(poprets)
def send_kernel(serial, kernel_file): print('Kernel :') # transfer kernel binary serial.send('s') kernel_bin = pwn.ELF(kernel_file) for section in kernel_bin.sections: if (section.__class__.__name__ == 'Section' and 'debug' not in section.name): checksum = 0 res_checksum = 1 while checksum != res_checksum: start_time = time.time() print('\nSection :', section.name) serial.send('S') serial.recvuntil('S') print('Address :', hex(section.header.sh_addr)) serial.send(pwn.p64(section.header.sh_addr)) print('Size :', hex(section.data_size)) serial.send(pwn.p64(section.data_size)) checksum = 0 print('Type :', section.header.sh_type) if (section.header.sh_type == 'SHT_NOBITS'): serial.send('A') elif (section.header.sh_type == 'SHT_PROGBITS'): serial.send('D') section_bin = kernel_bin.section(section.name) serial.send(section_bin) checksum = reduce(lambda x, y: x ^ y, section_bin) res_checksum = pwn.u8(serial.recv(1)) print('Checksum :', checksum == res_checksum) print(f'Elapse Time :{time.time() - start_time:.2f}s') serial.send('E') print('\nEntry Point :', hex(kernel_bin.entry)) serial.send(pwn.p64(kernel_bin.entry))
def g_display_char(char): print("Hex: 0x" + str(pwn.u8(char)))
def options(prompt, opts, default=None): try: if default is not None: default = int(default) except: pwn.die('default value must be a number in options') linefmt = ' %' + str(len(str(len(opts)))) + 'd) %s' choice = default pos = 0 if default is None else len(str(default)) max_pos = pos offset = len(prompt) + 6 fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: tty.setraw(sys.stdin.fileno()) while True: width, _ = get_term_size() s = '\x1b[G\x1b[K ' + pwn.text.bold('[?]') + ' %s' % prompt if choice: s += ' %d' % choice sys.stdout.write(s) for i, opt in enumerate(opts): s = linefmt % (i + 1, opt) if i + 1 == choice: s = pwn.text.cyanbg(s.ljust(width)) sys.stdout.write('\r\n\x1b[K' + s) sys.stdout.write('\x1b[%dF\x1b[%dC' % (len(opts), offset + pos)) ch = pwn.u8(sys.stdin.read(1)) if ch == 3: # ^C raise KeyboardInterrupt elif ch == 4: # ^D raise EOFError elif ch == 127: # Backspace if pos > 0: s = str(choice) s = s[:pos - 1] + s[pos:] if s: choice = int(s) pos -= 1 max_pos -= 1 else: choice = None pos = 0 max_pos = 0 elif ch in range(48, 58): # 0 - 9 n = ch - 48 s = str(choice or '') n = int(s[:pos] + str(n) + s[pos:]) if n >= 1 and n <= len(opts): choice = n pos += 1 max_pos += 1 elif ch == 13: # Enter break elif ch == 27: ch = pwn.u8(sys.stdin.read(1)) if ch <> 91: continue ch = pwn.u8(sys.stdin.read(1)) if ch == 68: # Left pos = max(pos - 1, 0) elif ch == 67: # Right pos = min(pos + 1, max_pos) elif ch == 65: # Up if choice is None: choice = 1 pos = 1 max_pos = pos if choice > 1: choice -= 1 pos = len(str(choice)) max_pos = pos elif ch == 66: # Down if choice is None: choice = len(opts) pos = len(str(choice)) max_pos = pos if choice < len(opts): choice += 1 pos = len(str(choice)) max_pos = pos elif ch == 51: # Delete ch = pwn.u8(sys.stdin.read(1)) if ch <> 126: continue if pos < max_pos: s = str(choice) s = s[:pos] + s[pos + 1:] if s: choice = int(s) max_pos -= 1 else: choice = None pos = 0 max_pos = 0 finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) sys.stdout.write('\x1b[%dB\n' % len(opts)) return choice
def loadByte(self, value): val = self.read_memory(value, 1) if val is not None: return u8(val)
def options(prompt, opts, default = None): try: if default is not None: default = int(default) except: pwn.die('default value must be a number in options') linefmt = ' %' + str(len(str(len(opts)))) + 'd) %s' choice = default pos = 0 if default is None else len(str(default)) max_pos = pos offset = len(prompt) + 6 fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: tty.setraw(sys.stdin.fileno()) while True: width, _ = get_term_size() s = '\x1b[G\x1b[K ' + pwn.text.bold('[?]') + ' %s' % prompt if choice: s += ' %d' % choice sys.stdout.write(s) for i, opt in enumerate(opts): s = linefmt % (i + 1, opt) if i + 1 == choice: s = pwn.text.cyanbg(s.ljust(width)) sys.stdout.write('\r\n\x1b[K' + s) sys.stdout.write('\x1b[%dF\x1b[%dC' % (len(opts), offset + pos)) ch = pwn.u8(sys.stdin.read(1)) if ch == 3: # ^C raise KeyboardInterrupt elif ch == 4: # ^D raise EOFError elif ch == 127: # Backspace if pos > 0: s = str(choice) s = s[:pos-1] + s[pos:] if s: choice = int(s) pos -= 1 max_pos -= 1 else: choice = None pos = 0 max_pos = 0 elif ch in range(48, 58): # 0 - 9 n = ch - 48 s = str(choice or '') n = int(s[:pos] + str(n) + s[pos:]) if n >= 1 and n <= len(opts): choice = n pos += 1 max_pos += 1 elif ch == 13: # Enter break elif ch == 27: ch = pwn.u8(sys.stdin.read(1)) if ch <> 91: continue ch = pwn.u8(sys.stdin.read(1)) if ch == 68: # Left pos = max(pos - 1, 0) elif ch == 67: # Right pos = min(pos + 1, max_pos) elif ch == 65: # Up if choice is None: choice = 1 pos = 1 max_pos = pos if choice > 1: choice -= 1 pos = len(str(choice)) max_pos = pos elif ch == 66: # Down if choice is None: choice = len(opts) pos = len(str(choice)) max_pos = pos if choice < len(opts): choice += 1 pos = len(str(choice)) max_pos = pos elif ch == 51: # Delete ch = pwn.u8(sys.stdin.read(1)) if ch <> 126: continue if pos < max_pos: s = str(choice) s = s[:pos] + s[pos+1:] if s: choice = int(s) max_pos -= 1 else: choice = None pos = 0 max_pos = 0 finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) sys.stdout.write('\x1b[%dB\n' % len(opts)) return choice