# MySQL/MariaDB InnoDB pages are 16KB with recognizable structure # Find them directly on the translated device python3 -c " CHUNK_B = 128*512 LV_START = 5120000*512 VIRT_SIZE = 9365766144*512 def read_virt(offset, length): result = bytearray(length) pos = offset remaining = length with open('/dev/md0','rb') as f: while remaining > 0: group = pos // (5*CHUNK_B) in_group = pos % (5*CHUNK_B) chunk_idx = in_group // CHUNK_B intra = in_group % CHUNK_B seg_len = min(CHUNK_B-intra, remaining) dst_off = pos - offset if chunk_idx != 4: phys = LV_START + group*4*CHUNK_B + chunk_idx*CHUNK_B + intra f.seek(phys) data = f.read(seg_len) result[dst_off:dst_off+len(data)] = data pos += seg_len remaining -= seg_len return bytes(result) targets = [ b'pterodactyl', b'wings_token', b'server_id', b'eula.txt', b'server.properties', b'level.dat', b'bukkit.yml', b'spigot.yml', ] print('Scanning for game server / pterodactyl data...') chunk = 64*1024*1024 offset = 0 while offset < VIRT_SIZE: try: data = read_virt(offset, min(chunk, VIRT_SIZE-offset)) except: offset += chunk continue for target in targets: pos = 0 while True: idx = data.find(target, pos) if idx < 0: break abs_byte = offset + idx ctx = data[max(0,idx-80):idx+120] print(f'{target.decode()!r} @ byte {abs_byte} sector {abs_byte//512}') try: print(f' {ctx.decode(\"latin1\",errors=\"replace\")}') except: pass print() pos = idx + 1 offset += chunk if offset % (10*1024*1024*1024) == 0: print(f'--- {offset//1024**3}GB scanned ---', flush=True) " 2>&1 | tee /tmp/ptero_scan.txt