Skip to content

Instantly share code, notes, and snippets.

@kotobukid
Created February 19, 2025 08:57
Show Gist options
  • Save kotobukid/5aae67554cbbf8181076039a33dfd0c6 to your computer and use it in GitHub Desktop.
Save kotobukid/5aae67554cbbf8181076039a33dfd0c6 to your computer and use it in GitHub Desktop.
trying to extract django session manually
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}")
@kotobukid
Copy link
Author

現在未完成です

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