Created
February 19, 2025 08:57
-
-
Save kotobukid/5aae67554cbbf8181076039a33dfd0c6 to your computer and use it in GitHub Desktop.
trying to extract django session manually
This file contains hidden or 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
from django.conf import settings | |
import base64 | |
import json | |
from django.core.management.base import BaseCommand | |
from django.core.signing import Signer, BadSignature | |
from django.conf import settings | |
class Command(BaseCommand): | |
help = "Extract and decode session data from django_session table or session ID string." | |
def add_arguments(self, parser): | |
""" | |
コマンド引数を定義する | |
""" | |
pass | |
# parser.add_argument( | |
# "session_data", | |
# type=str, | |
# help="Raw session data string from the Django session table", | |
# ) | |
# parser.add_argument( | |
# "--secret", | |
# type=str, | |
# default=None, | |
# help="Optional secret key for manual unsigned verification (default: Django SECRET_KEY)", | |
# ) | |
def handle(self, *args, **options): | |
session_data = "eyJudW0iOjB9:1tkbpN:Z-LnQJetmMWEDEiwCAD-FthyF2EvtsUTg4CZkjP0O2Q" | |
# session_data = options["session_data"] | |
# secret_key = options["secret"] # SECRET_KEYを指定可能 | |
# secret_key = settings.SECRET_KEY # SECRET_KEYを指定可能 | |
# if not secret_key: | |
# from django.conf import settings | |
# | |
# secret_key = settings.SECRET_KEY | |
print(f"SECRET_KEY: {settings.SECRET_KEY}") | |
secret_key = settings.SECRET_KEY | |
try: | |
decoded_data = self.extract_session_data(session_data, secret_key) | |
self.stdout.write(self.style.SUCCESS("Decoded session data:")) | |
self.stdout.write(json.dumps(decoded_data, indent=2, ensure_ascii=False)) | |
except ValueError as e: | |
self.stderr.write(self.style.ERROR(f"Error decoding session data: {e}")) | |
def extract_session_data(self, session_data, secret_key): | |
""" | |
セッションデータを抽出し、署名の確認とデコードを行う | |
""" | |
# `:`で右から1回だけ分割し、署名を分離 | |
if ":" not in session_data: | |
raise ValueError("Invalid session format: missing ':' separator") | |
value, sig = session_data.rsplit(":", 1) | |
self.stdout.write(f"1. Value: {value}") | |
self.stdout.write(f"2. Signature: {sig}") | |
# 署名を検証 | |
signer = Signer(key=secret_key) | |
try: | |
unsigned_value = signer.unsign(f"{value}:{sig}") # データ+署名全体の検証 | |
except BadSignature as e: | |
raise ValueError(f"Invalid signature: {e}") | |
self.stdout.write("3. Signature verification successful!") | |
# Base64デコード(パディング補正後) | |
try: | |
decoded_data = base64.b64decode(self.fix_base64_padding(unsigned_value)) | |
except base64.binascii.Error as e: | |
raise ValueError(f"Error in Base64 decoding: {e}") | |
self.stdout.write(f"4. Decoded base64 data: {decoded_data}") | |
# JSONデコード | |
try: | |
session_dict = json.loads(decoded_data.decode("utf-8")) | |
except json.JSONDecodeError as e: | |
raise ValueError(f"Error decoding session as JSON: {e}") | |
self.stdout.write("5. Successfully decoded JSON!") | |
return session_dict | |
@staticmethod | |
def fix_base64_padding(encoded_data): | |
""" | |
Base64パディングを修正(文字数が4の倍数になるよう補正) | |
""" | |
missing_padding = len(encoded_data) % 4 | |
if missing_padding != 0: | |
encoded_data += "=" * (4 - missing_padding) | |
return encoded_data | |
# class Command(BaseCommand): | |
# help = "Extract and decode session data from django_session table" | |
# | |
# def handle(self, *args, **options): | |
# print(f"SESSION_COOKIE_NAME: {settings.SESSION_COOKIE_NAME}") | |
# print(f"SECRET_KEY: {settings.SECRET_KEY}") | |
# # セッションデータの確認対象(仮のテストデータ) | |
# session_data = ".eJxVjMsOwiAURP-FtSHA5SEu3fsN5F4eUjWQlHZl_HfbpAtdzpwz82YB16WGdeQ5TIldmGSn344wPnPbQXpgu3cee1vmifiu8IMOfuspv66H-3dQcdRtTRRROCu01-6MQNaDLUJriaIYoiRUQSJQEgz46LQtBbTZQrE-Kojs8wXWvjdh:1tkcFa:S3ACKYM5m3OV0Xefq3ctkEzVgfxLcL1aIBkoDoT82uw" # django_sessionテーブルから取得した値 | |
# | |
# # セッションデータのデコード | |
# try: | |
# session_dict = extract_session_data(session_data) | |
# self.stdout.write(f"Decoded session data: {session_dict}") | |
# except ValueError as e: | |
# self.stderr.write(f"Error: {e}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
現在未完成です