#!/usr/bin/env python # # XOR, ROL, ROT permuter # Doing the same permutes as http://blog.didierstevens.com/programs/xorsearch/ # but printing all output through a strings filter, allowing for use of # command-line tools to be applied to extend the search (e.g. Gnu GREP) # It also performs a double XOR (2 bytes). # # Author : geir@underworld.no (c) 2012,2013 # # Usage: # $> cat FILETOSEARCH | ./xorrolrot.py | grep -i http # # Copyright (c) 2012,2013 Geir Skjotskift # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # 'ivur;-.rnenqukbi/ldv.|fghp' import sys, re ROL_MIN = 1 ROL_MAX = 26 ROT_MIN = 1 ROT_MAX = 26 XOR_MIN = 0 XOR_MAX = 256 def strings(data): return list(set(re.findall("[\040-\176\s]{4,}", data))) def xor_string(s, v): return "".join([chr(ord(c)^v) for c in s]) def double_xor_string(s, v1, v2): return "".join([chr(ord(c)^(v1,v2)[i % 2]) for i, c in enumerate(s)]) def rol_string(s, v): return "".join([chr((ord(c)-v) % 256) for c in s]) def rot_string(s, v): return "".join([chr((ord(c)+v) % 256) for c in s]) def find_all(d): res = [] for x in range(XOR_MIN, XOR_MAX): if x == 0 or x == 0x20: continue for s in strings(xor_string(d, x)): res.append("XOR \"0x%x\": %s" % (x, s)) for y in range(XOR_MIN, XOR_MAX): if y == 0 or y == 0x20 or x == y: continue for s in strings(double_xor_string(d, x, y)): res.append("XOR \"0x%x 0x%x\": %s" % (x, y, s)) for x in range(ROL_MIN, ROL_MAX): for s in strings(rol_string(d, x)): res.append("ROL \"0x%x\": %s" % (x, s)) for x in range(ROT_MIN, ROT_MAX): for s in strings(rot_string(d, x)): res.append("ROT \"0x%x\": %s" % (x, s)) return reversed(sorted(res, key=len)) if __name__ == '__main__': data = sys.stdin.read() print "\n".join(find_all(data))