Skip to content

Commit

Permalink
Public release
Browse files Browse the repository at this point in the history
  • Loading branch information
p0dalirius committed Jul 1, 2022
1 parent 9674cc8 commit a5b18c5
Show file tree
Hide file tree
Showing 7 changed files with 150,096 additions and 20 deletions.
1 change: 1 addition & 0 deletions .github/banner.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2022-06-30T19:42:38.663Z" agent="5.0 (X11)" etag="bwqtTWnJdg6Q0cPReM3U" version="20.0.4"><diagram id="nb3tS5KzVcpROlKnmKRc" name="Page-1">1VVRb5swEP41PKYyELK8JmnZtK3TtGyq1JfKwQa8Gs4zJpD9+p3BhJCk0lrtZU82353vO393Z7xwU7TvNVX5PTAuvYCw1gtvvSDw5/4SF4sceuTd0u+BTAvmnEZgK35zBxKH1oLxauJoAKQRagomUJY8MROMag3N1C0FOWVVNOMXwDah8hJ9EMzkPbqMyIh/4CLLB2afOEtBB2cHVDll0JxA4Z0XbjSA6XdFu+HSijfo0p+LX7AeE9O8NH9z4Juie/794/2XR//p0/Yhf/yZ65mLsqeydhd2yZrDoADmrexWFJ1U6z3XRqBAn+mOy69QCSOgRPsOjIECHaQ1rGnynGmoS7YBCRrtjKe0luYkwkqKzJ40oBClleoLmIqWY87rjnA1oGRAcJ8bY8u/spcNYlryVtCbBMmDeCchw6VRM+wIY6UJ4lpJoKzCXUD8CBeC144T7FXkF4brJzwEN6rMkMMJginy9kWl/WP9sPE5FNzoA7q00949TD+bsX+ioSny09459q3r2ewYeSwrblxlX1Hl4EqVF10pmNhPqr34Vdt+XKco3qzqphFVJnOi2k6bwW6zdNUbQclTc+qyyNzaUYlzwHK8kbwPtOVVZXvPxUNp+pBTGoQvqBHrbj5F/2sxfpSVTcGF2+krV36rOmcPAg6GxXNTYBPe+ritjIZnPgx6CaV9J1Ih5Rk0qNRpc/kOFIIxS7JucpzKraKJZWzwx4JY95bYd6F7CexVti4l330PZF4QxvGSEPJvpjmKpuM8vxzn4No4L8lN9Op5xs/xj9DZTv6r4d0f</diagram></mxfile>
Binary file added .github/banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/codeigniter_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 50 additions & 16 deletions CodeIgniter-session-unsign.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@

import argparse
import binascii
import datetime
import hashlib
import os
import time
import urllib.parse
import requests
import sys
Expand All @@ -34,27 +36,57 @@ def parseArgs():
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 worker(ci_cookie_value, hash, password, monitor_data):
if not monitor_data["found"]:
try:
monitor_data["tries"] += 1
testhash = hashlib.md5(bytes(ci_cookie_value + password, 'UTF-8')).hexdigest()
# print(testhash, hash, (hash == testhash))
if hash == testhash:
monitor_data["found"] = True
monitor_data["candidate"] = password
return True
else:
return False
except Exception as e:
print(e)


def monitor_thread(monitor_data):
last_check, monitoring = 0, True
while monitoring and not monitor_data["found"]:
new_check = monitor_data["tries"]
rate = (new_check - last_check)
print("\r[%s] Status (%d/%d) %5.2f %% | Rate %d H/s " % (
datetime.datetime.now().strftime("%Y/%m/%d %Hh%Mm%Ss"),
new_check, monitor_data["total"], (new_check/monitor_data["total"])*100,
rate
), end="")
last_check = new_check
time.sleep(1)
if rate == 0 and new_check != 0:
monitoring = False

if monitor_data["found"]:
print("\n[>] Found password '%s'" % monitor_data["candidate"])
else:
print("")


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()

monitor_data = {"found": False, "tries": 0, "candidate": "", "total": len(wordlist)}

# Waits for all the threads to be completed
with ThreadPoolExecutor(max_workers=min(threads, len(wordlist))) as tp:
tp.submit(monitor_thread, monitor_data)
for password in wordlist:
tp.submit(worker, ci_cookie_value, hash, password)
tp.submit(worker, ci_cookie_value, hash, password, monitor_data)
if not monitor_data["found"]:
print("[!] Hash could not be cracked from this wordlist.")


if __name__ == '__main__':
Expand All @@ -76,7 +108,10 @@ def test_keys(ci_cookie_value, hash, wordlist_file, threads=8):

cookies = []
if options.cookie is not None:
cookies = [options.cookie]
if os.path.exists(options.cookie):
f = open(options.cookie, "r")
cookies = f.readlines()
f.close()
else:
session = requests.Session()
session.get(options.url, verify=(not options.insecure))
Expand All @@ -92,8 +127,8 @@ def test_keys(ci_cookie_value, hash, wordlist_file, threads=8):
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(" | value: %s" % ci_cookie_value)
print(" | signature (%d bits): %s" % (hashlen*8, hexhash))

print("[+] Trying to find key...")
test_keys(
Expand All @@ -102,6 +137,5 @@ def test_keys(ci_cookie_value, hash, wordlist_file, threads=8):
wordlist_file=options.wordlist,
threads=options.threads
)

else:
print("[!] Could not parse CodeIgniter session cookie.")
49 changes: 45 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,56 @@
# CodeIgniter-session-unsign
![](./.github/banner.png)

## e
<p align="center">
A multithreaded bruteforcer of CodeIgniter ci_session cookies.
<br>
<img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/p0dalirius/CodeIgniter-session-unsign">
<a href="https://twitter.com/intent/follow?screen_name=podalirius_" title="Follow"><img src="https://img.shields.io/twitter/follow/podalirius_?label=Podalirius&style=social"></a>
<a href="https://www.youtube.com/c/Podalirius_?sub_confirmation=1" title="Subscribe"><img alt="YouTube Channel Subscribers" src="https://img.shields.io/youtube/channel/subscribers/UCF_x5O7CSfr82AfNVTKOv_A?style=social"></a>
<br>
</p>

## Features

- [x] Extract the `ci_session` cookie from an URL (with `--url`) or from a file (with `--cookie`)
- [x] Progress updated every second with the number of processed hashes per second.
- [x] Multithreaded bruteforce.

## Usage

```
$ ./CodeIgniter-session-unsign.py -h
CodeIgniter-session-unsign v1.1 - by @podalirius_
usage: CodeIgniter-session-unsign.py [-h] [-u URL | -c COOKIE] -w WORDLIST [-t THREADS] [-k] [--md5 MD5 | --sha1 SHA1 | --sha256 SHA256]
Description message
optional arguments:
-h, --help show this help message and exit
-u URL, --url URL URL of the CodeIgniter website.
-c COOKIE, --cookie COOKIE
CodeIgniter session cookie.
-w WORDLIST, --wordlist WORDLIST
Wordlist of keys to test.
-t THREADS, --threads THREADS
Number of threads (default: 8)
-k, --insecure Allow insecure server connections when using SSL (default: False)
--md5 MD5 Use MD5 algorithm.
--sha1 SHA1 Use SHA1 algorithm.
--sha256 SHA256 Use SHA256 algorithm.
```

## Example

```angular2html
./CodeIgniter-session-unsign.py --cookie $(cat ./example/cookie) -k -w pass
```
./CodeIgniter-session-unsign.py -c ./example/cookie -w ./example/wordlist
```

![](./.github/example.png)

## Contributing

Pull requests are welcome. Feel free to open an issue if you want to add other features.

## References
- https://www.websec.ca/publication/blog/insecure-session-data-CodeIgniter
Loading

0 comments on commit a5b18c5

Please sign in to comment.