웹 해킹 & 보안

[웹 모의해킹] Weak Session ID 취약점 실습

ahhyun98 2025. 6. 8. 14:19

이번 실습에서는 웹 애플리케이션에서 흔히 발생할 수 있는 취약한 세션 식별자(Weak Session ID) 생성 방식에 대해 실습을 진행했다. DVWA 환경을 기반으로 보안 레벨에 따른 세션 생성 로직을 분석하였고, 보안적으로 적절하지 않은 구현이 어떻게 공격에 악용될 수 있는지를 확인해 보았다. 


1. Low - 단순 증가하는 정수 기반 세션 ID

if ($_SERVER['REQUEST_METHOD'] == "POST") {
    if (!isset ($_SESSION['last_session_id'])) {
        $_SESSION['last_session_id'] = 0;
    }
    $_SESSION['last_session_id']++;
    $cookie_value = $_SESSION['last_session_id'];
    setcookie("dvwaSession", $cookie_value);
}
  • 위 코드는 세션 쿠키를 서버 내 증가하는 정수값을 기반으로 생성한다. 
  • 외부 사용자는 dvwaSession=1, dvwaSession=2 등 예상 가능한 값을 통해 다른 사용자의 세션을 탈취할 수 있다. 
  • 취약점 : 세션 ID에 예측 가능한 순차값을 사용하는 것은 치명적인 보안 문제를 가져올 수 있다. 

2. Medium -  time() 기반 세션 ID

if ($_SERVER['REQUEST_METHOD'] == "POST") {
    $cookie_value = time();
    setcookie("dvwaSession", $cookie_value);
}
  • time() 함수유닉스 타임스탬프(초 단위)를 반환한다. 
  • 로그인 요청 시점의 시간이 세션 ID로 사용되므로, 공격자는 해당 시간 근처의 값을 추정해 세션을 탈취할 수 있다. 
  • 취약점 : 시간 기반 세션 ID는 짧은 시간 안에 반복적으로 요청을 보내는 공격에 매우 취약하다. 

3. High - md5(증가값) 기반 세션 ID

if ($_SERVER['REQUEST_METHOD'] == "POST") {
    if (!isset ($_SESSION['last_session_id_high'])) {
        $_SESSION['last_session_id_high'] = 0;
    }
    $_SESSION['last_session_id_high']++;
    $cookie_value = md5($_SESSION['last_session_id_high']);
    setcookie("dvwaSession", $cookie_value, time()+3600, "/vulnerabilities/weak_id/", $_SERVER['HTTP_HOST'], false, false);
}
  • last_session_id_high의 값에 대해 md5 해시를 적용하여 세션 ID를 생성한다. 
  • 단순한 숫자에 해시를 씌운다고 해도, 공격자는 해시 레인보우 테이블 등을 통해 원본 값을 유추하거나 추정할 수 있다. 
  • 취약점 : 해시만 사용했을 뿐 본질적으로 랜덤성은 확보되지 않았다. 

4. 사용자 입력 + 시간 기반 해시  조합

import hashlib
import time

value = input("Enter a Number")
hashed = hashlib.md5(value.encode()).hexdigest()
unix_time = str(int(time.time()) + 3600)
hashed_unix_time = hashlib.md5((unix_time + hashed).encode()).hexdigest()
cookie_str = f"cookie_name={hashed_unix_time};"
print(cookie_str)
  • 이 코드는 사용자 입력 값과 현재 시간에 1시간을 더한 값으로 세션 ID를 생성한다. 
  • 이론 상으로는 더 안전해 보일 수도 있지만, 입력값이 단순하거나 예측 가능한 경우 여전히 취약하다.
  • 분석
    • 1. 사용자 입력을 해시
    • 2. 현재 시간 + 3600초
    • 3. 두 값을 결합해 다시 해시 => 쿠키 문자열 생성

5. Impossible - mt_rand() + time() + 문자열을 SHA-1 해시

if ($_SERVER['REQUEST_METHOD'] == "POST") {
    $cookie_value = sha1(mt_rand() . time() . "Impossible");
    setcookie("dvwaSession", $cookie_value, time()+3600, "/vulnerabilities/weak_id/", $_SERVER['HTTP_HOST'], true, true);
}
  • 난수(mt_rand()), 현재 시간, 문자열을 조합하여 SHA-1 해시로 변환한 값으로 세션 ID를 생성한다. 
  • 기존 단계보다 훨씬 예측이 어렵고 공격 난이도가 높아지고 보안성이 높아진 구현이다. 
  • 보안 수준 : Impossible 단계에서는 세션 예측이 사실상 어렵기 때문에 공격이 거의 불가능하다. 

6. 마무리

  • 세션 ID는 인증 정보를 식별하는 중요한 요소이므로 예측이 불가능하고 충분히 복잡한 값으로 생성되어야 한다. 
  • 단순한 정수, 시간 기반 값, 사용자 입력 기반 값 등은 절대 세션 ID로 사용되어서는 안 된다. 
  • PHP에서는 session_start()와 같이 기본 세션 기능을 사용하는 것이 보안상 더 안전하다. 
  • 안전한 세션 ID 생성을 위해서는 적절한 난수 생성기, 충분한 비트 수, 해시 알고리즘 사용이 필수적이다. 

 

 

 

이 블로그는 불법 해킹 및 악의적인 활동을 지양하며, 그런 행위는 절대 권장하지 않습니다.

모든 실습은 허가된 환경에서만 진행해야 하며, 법적 책임은 사용자 본인에게 있습니다.