웹 해킹 & 보안
[웹 모의해킹] 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 생성을 위해서는 적절한 난수 생성기, 충분한 비트 수, 해시 알고리즘 사용이 필수적이다.
이 블로그는 불법 해킹 및 악의적인 활동을 지양하며, 그런 행위는 절대 권장하지 않습니다.
모든 실습은 허가된 환경에서만 진행해야 하며, 법적 책임은 사용자 본인에게 있습니다.