Notes / Web Security
예측 가능한 값과 약한 난수 (Weak Randomness)
시각·사용자 정보 기반 토큰, 순차 UUID, 고정 seed, 좁은 값 범위처럼 예측·전수조사가 가능한 난수 오용의 개념과, 수집·역산·전수 확인 구문을 정리합니다.
목차
비밀번호 재설정 토큰, 세션 ID, 쿠폰 코드, 파일명 같은 “추측되면 안 되는 값”을 약한 난수로 만들면, 공격자는 그 값을 예측하거나 전수조사해서 남의 자원에 닿는다.
개념
안전한 값은 암호학적 난수(CSPRNG)로, 충분히 넓은 범위에서 만들어야 한다. 흔한 오용:
- 시각 기반 —
time()·타임스탬프를 seed나 값으로 쓰면, 발급 시각을 알면 좁은 범위만 뒤지면 된다. - 사용자 정보 기반 —
md5(email)·id+날짜같은 값은 계산할 수 있으니 난수가 아니다. - 순차·약한 UUID — 순번이나 UUIDv1(시각+MAC 기반)은 예측 가능하다.
- 고정 seed —
srand(1)·Random(0)은 항상 같은 수열을 낸다. - 좁은 범위 — 4~6자리 OTP, 짧은 토큰은 전수조사가 가능하다.
token = hashlib.md5(f"{email}{int(time.time())}".encode()).hexdigest() # 이메일 + 초 단위 시각 = 계산 가능
otp = random.randint(1000, 9999) # 비CS 난수 + 1만 경우의 수
공격·우회 구문
허가된 범위, 테스트 계정으로 한다.
값 수집·패턴 분석
같은 기능을 여러 번 호출해 값 수집(토큰·ID·파일명)
연속 발급값의 '차이'를 봄: 순차(+1), 시각 비례, 사용자명 인코딩인지
Base64/hex 디코딩 → 내부 구조(타임스탬프·카운터) 드러나는지
시각 기반 역산
재설정 요청 시각을 알면(응답 Date 헤더·메일 수신 시각) seed 후보가 좁아짐
초/밀리초 단위로 time 범위를 좁혀 토큰 후보를 생성 → 대입
언어 PRNG(예: PHP mt_rand)는 출력 몇 개로 내부 상태 복원 가능(전용 도구)
좁은 범위 전수조사
4~6자리 OTP·짧은 토큰: 시도 제한이 없으면 전수조사
비밀번호 재설정 토큰이 짧으면 유효시간 안에 전 범위 시도
UUID·순번 열거
UUIDv1(시각+노드) 이면 인접 값 예측 → 다른 사용자 리소스 접근(IDOR 결합)
파일명·주문번호가 순차면 ±1 로 열거