비정상적 접근 제어 (IDOR)

사이버 보안Beginner
지금 연습하기

소개

비정상적 직접 객체 참조 (Insecure Direct Object References, IDOR) 는 애플리케이션이 사용자가 제공한 입력을 사용하여 객체에 직접 접근할 때 발생하는 접근 제어 취약점의 일종입니다. 애플리케이션이 객체를 요청하는 사용자가 해당 객체에 접근할 권한이 있는지 적절히 검증하지 않으면, 공격자는 참조 (URL 의 데이터베이스 ID, 파일 이름, 사용자 ID 등) 를 조작하여 다른 사용자의 민감한 데이터에 접근할 수 있습니다.

중요한 점은 참조 그 자체가 취약점이 아니라는 것입니다. 취약점은 현재 사용자가 해당 참조를 따를 권한이 있는지 확인하지 않고 그 참조를 신뢰하는 데 있습니다.

이 실습에서는 로컬 웹 애플리케이션 API 를 평가하는 보안 테스터 역할을 수행합니다. 먼저 일반 사용자로 인증하고, 애플리케이션이 사용자 프로필을 참조하는 방식을 분석한 다음, IDOR 취약점을 악용하여 관리자를 포함한 다른 사용자의 개인 데이터에 접근해 보겠습니다.

일반 사용자로 인증

이 단계에서는 포트 5000에서 실행 중인 로컬 웹 API 와 상호 작용합니다. 애플리케이션의 취약점을 테스트하기 위해 먼저 일반 사용자로 인증하여 유효한 세션 토큰을 획득해야 합니다.

Alice 라는 일반 사용자의 자격 증명이 제공되었습니다. 사용자 이름은 alice이고 비밀번호는 password123입니다.

curl 명령줄 도구를 사용하여 로그인 엔드포인트에 HTTP POST 요청을 보냅니다. curl은 서버와 데이터를 주고받는 데 사용되는 강력한 도구입니다.

터미널에서 다음 명령을 실행하여 로그인합니다:

curl -X POST http://localhost:5000/api/login \
  -H "Content-Type: application/json" \
  -d '{"username": "alice", "password": "password123"}'

이 명령을 분석해 보겠습니다:

  • -X POST: 로그인 자격 증명과 같은 데이터를 제출할 때 일반적으로 사용되는 POST 요청을 보냄을 지정합니다.
  • -H "Content-Type: application/json": 전송하는 데이터가 JSON 형식임을 서버에 알립니다.
  • -d '...': 사용자 이름과 비밀번호가 포함된 실제 JSON 데이터 페이로드입니다.

자격 증명이 올바르면 다음과 유사한 출력이 표시됩니다:

{"token": "Bearer alice_token", "user_id": "1001"}

token과 user_id를 기록해 두세요. 토큰 (Bearer alice_token) 은 디지털 신분증 역할을 합니다. 인증되었음을 증명하기 위해 향후 요청에 이 토큰을 포함해야 합니다. user_id(1001) 는 애플리케이션 데이터베이스 내의 고유 식별자입니다.

객체 참조 (URL/API) 분석

이제 Alice 로 인증되었으므로 그녀의 사용자 프로필에 접근할 수 있습니다. 많은 웹 애플리케이션에서 사용자 프로필은 인증 토큰과 보려는 특정 객체 (이 경우 사용자 프로필) 에 대한 참조가 필요한 API 엔드포인트를 통해 접근됩니다.

다시 curl을 사용하되, 이번에는 /api/profile 엔드포인트로 GET 요청을 보냅니다. HTTP 헤더에 인증 토큰을 포함하고 URL 에 user_id를 지정해야 합니다.

이는 실제 API 에서 나타나는 전형적인 패턴입니다. 토큰은 세션이 존재함을 증명하고, 매개변수는 가져올 객체를 선택합니다. 안전한 애플리케이션은 이 두 가지 개념을 권한 부여 확인과 함께 결합해야 합니다.

다음 명령을 실행하여 Alice 의 프로필을 확인합니다:

curl -H "Authorization: Bearer alice_token" \
  "http://localhost:5000/api/profile?user_id=1001"

이 명령에서:

  • -H "Authorization: Bearer alice_token": 디지털 신분증을 서버에 전달합니다.
  • ?user_id=1001: URL 뒤에 붙는 쿼리 매개변수입니다. 이것이 바로 **직접 객체 참조 (Direct Object Reference)**입니다. 서버에 어떤 데이터베이스 레코드를 가져와야 하는지 정확히 알려줍니다.

Alice 의 프로필 정보가 포함된 JSON 응답을 받아야 합니다:

{"name": "Alice", "role": "user", "email": "alice@example.com", "secret": "alice_secret_123"}

애플리케이션이 어떤 데이터를 반환할지 결정하기 위해 URL 의 user_id=1001 매개변수에 의존하는 방식에 주목하세요. 안전한 애플리케이션이라면 Bearer alice_token과 연결된 사용자가 실제로 user_id=1001에 대한 데이터를 볼 권한이 있는지 확인해야 합니다. 애플리케이션이 이러한 권한 확인을 수행하지 못하면 IDOR 에 취약한 것입니다.

사용자 ID 조작

이 단계에서는 애플리케이션이 접근 제어를 적절하게 시행하는지 테스트합니다. 현재 Alice 로 인증되어 있지만, 다른 사용자의 데이터를 서버에 요청하면 어떻게 될까요?

이것이 권한 부여의 핵심 질문입니다. "로그인했는가?"와 "이 객체를 읽을 권한이 있는가?"는 서로 다른 확인 절차이며, 이를 혼동하면 직접적으로 IDOR 로 이어집니다.

Bob 이라는 다른 일반 사용자가 있고 그의 사용자 ID 가 1002라고 가정해 봅시다. 애플리케이션이 IDOR 에 취약하다면, Alice 가 Bob 의 프로필을 볼 권한이 있는지 확인하지 않고 URL 의 user_id 매개변수를 맹목적으로 신뢰할 것입니다.

이전 명령의 user_id 매개변수를 1001에서 1002로 수정합니다. 다음 명령을 실행하세요:

curl -H "Authorization: Bearer alice_token" \
  "http://localhost:5000/api/profile?user_id=1002"

서버에서 반환된 출력을 확인합니다:

{"name": "Bob", "role": "user", "email": "bob@example.com", "secret": "bob_secret_456"}

Alice 로 인증된 상태에서 Bob 의 이메일과 비밀 키를 포함한 개인 정보를 성공적으로 가져왔습니다!

이는 비정상적 직접 객체 참조 (IDOR) 취약점이 존재함을 확인시켜 줍니다. 서버는 (토큰을 검증하여) 로그인 여부는 확인했지만, 요청한 특정 객체 (Bob 의 프로필) 에 접근할 권한이 있는지 확인하는 데는 실패했습니다.

권한 없는 데이터 접근

IDOR 취약점을 확인했으므로, 이제 공격을 확대하여 매우 민감한 정보에 접근할 수 있습니다. 많은 시스템에서 관리자 사용자는 1, 0, 또는 9999와 같이 예측 가능한 ID 를 가집니다.

이 애플리케이션의 관리자 사용자 ID 는 9999입니다. 동일한 IDOR 취약점을 악용하여 비밀 플래그가 포함된 관리자 프로필을 추출할 수 있습니다.

결과를 기록하기 위해 curl 명령의 출력을 현재 작업 디렉토리 (~/project) 내의 flag.txt라는 파일로 리다이렉트합니다.

다음 명령을 실행하여 관리자 프로필을 가져와 저장합니다:

curl -H "Authorization: Bearer alice_token" \
  "http://localhost:5000/api/profile?user_id=9999" > ~/project/flag.txt

> 기호는 일반적으로 화면에 출력될 내용을 지정된 파일로 리다이렉트합니다.

관리자의 데이터를 성공적으로 캡처했는지 확인하려면 cat 명령을 사용하여 파일 내용을 읽어보세요:

cat ~/project/flag.txt

비밀 플래그를 포함한 관리자의 프로필 데이터가 보여야 합니다:

{"name": "Admin", "role": "admin", "email": "admin@example.com", "secret": "FLAG{IDOR_VULN_EXPLOITED}"}

축하합니다! IDOR 취약점을 성공적으로 악용하여 접근 제어를 우회하고 민감한 관리자 데이터를 추출했습니다.

요약

이 실습에서는 중요한 접근 제어 결함인 비정상적 직접 객체 참조 (IDOR) 의 메커니즘을 살펴보았습니다. 일반 사용자로 인증하고 애플리케이션이 URL 매개변수를 통해 사용자 데이터를 참조하는 방식을 분석하는 것으로 시작했습니다. 이러한 매개변수를 조작하여 권한 확인을 성공적으로 우회하고 다른 사용자의 개인 프로필을 확인했습니다. 마지막으로 공격을 확대하여 민감한 관리자 데이터를 추출했습니다.

이 연습은 서버 측에서 강력한 권한 확인을 구현하는 것이 얼마나 중요한지 보여줍니다. 애플리케이션은 객체에 대한 접근 권한을 부여할 때 사용자가 제공한 입력에만 의존해서는 안 되며, 항상 인증된 사용자가 요청된 리소스에 접근할 명시적인 권한이 있는지 확인해야 합니다.