Skip to content

Instantly share code, notes, and snippets.

@benmanns
Forked from kivikakk/ci-key-recover.py
Created February 21, 2016 12:35
Show Gist options
  • Save benmanns/2ba510748286cfd221bc to your computer and use it in GitHub Desktop.
Save benmanns/2ba510748286cfd221bc to your computer and use it in GitHub Desktop.
recover key from CodeIgniter homegrown crypto
#!/usr/bin/env python3
# CodeIgniter pre-2.2 non-mcrypt Encrypt reverser.
# Finds the key by partially-known plaintext attack.
# Written by Yuki Izumi. Placed in the public domain.
import codecs
import re
import sys
import time
def decode(s, key):
r = bytearray()
for i in range(len(s) // 2):
r.append(s[i*2] ^ s[i*2+1] ^ key[(i*2)%40] ^ key[(i*2+1)%40])
return bytes(r)
def find_key(known, encrypted):
key = bytearray(b'0') * 40
confirmed = [False] * 20
hexstr = b'0123456789abcdef'
ix = 0
while not all(confirmed):
if confirmed[ix%20]:
ix += 1
continue
kcompb = known[ix::20]
for k in range(256):
key[(ix*2)%40] = hexstr[k&0xf]
key[(ix*2+1)%40] = hexstr[k>>4]
r = decode(encrypted, key)
kcomp = kcompb
rcomp = r[ix::20][:len(kcomp)]
while True:
try:
j = kcomp.index(b' ')
except ValueError:
break
kcomp = kcomp[:j] + kcomp[j+1:]
rcomp = rcomp[:j] + rcomp[j+1:]
if kcomp[0] == rcomp[0]:
confirmed[ix%20] = True
break
if not confirmed[ix%20]:
return None
ix += 1
return key
with open(sys.argv[1], 'r') as f:
encrypted = f.read().split("\n", 2)[0]
encrypted = codecs.decode(encrypted.encode('ascii'), 'base64')
# Try each of these; space represents an unknown value. Here we account for
# the unknown size of the session array in general. We just need one byte of
# known plaintext for each index of the key, i.e. as long as there's at least
# one value in each 'column'.
knowns = ([
b'a: :{s:10:"session_i' +
b'd";s:32:" '
,
b'a: :{s:10:"session_' +
b'id";s:32:" '
,
b'a: :{s:10:"session' +
b'_id";s:32:" '
])
key = None
for known in knowns:
key = find_key(known, encrypted)
if key:
break
if not key:
print("Could not recover key.")
exit(1)
print(key.decode('ascii'))
print(decode(encrypted, key))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment