드라이버 보안 검사 목록
이 문서에서는 드라이버 개발자를 위한 드라이버 보안 검사 목록을 제공하여 드라이버가 손상될 위험을 줄입니다.
드라이버 보안 개요
보안 결함은 공격자가 시스템이 충돌하거나 사용할 수 없게 되는 방식으로 운전자가 오작동하도록 할 수 있는 결함입니다. 또한 드라이버 코드의 취약성을 통해 공격자가 커널에 액세스하여 전체 OS를 손상할 수 있습니다. 대부분의 개발자가 드라이버에서 작업할 때는 악의적인 공격자가 코드 내에서 취약성을 악용하려고 하는지 여부가 아니라 드라이버가 제대로 작동하도록 하는 데 중점을 두고 있습니다.
그러나 드라이버가 릴리스된 후 공격자는 보안 결함을 조사하고 식별하려고 시도할 수 있습니다. 개발자는 이러한 취약성의 가능성을 최소화하기 위해 디자인 및 구현 단계에서 이러한 문제를 고려해야 합니다. 목표는 드라이버가 릴리스되기 전에 알려진 모든 보안 결함을 제거하는 것입니다.
더 안전한 드라이버를 만들려면 시스템 설계자(드라이버에 대한 잠재적 위협을 의식적으로 생각), 코드를 구현하는 개발자(악용의 근원이 될 수 있는 일반적인 작업을 방어적으로 코딩) 및 테스트 팀(약점과 취약성을 사전에 찾으려고 시도)의 협력이 필요합니다. 이러한 모든 활동을 적절히 조정하면 드라이버의 보안이 크게 향상됩니다.
드라이버와 관련된 문제를 방지하는 것 외에도 커널 메모리를 보다 정확하게 사용하는 등 설명된 많은 단계를 수행하면 드라이버의 안정성이 향상됩니다. 이렇게 하면 지원 비용이 감소하고 제품에 대한 고객 만족도가 높아질 수 있습니다. 아래 검사 목록의 작업을 완료하면 이러한 모든 목표를 달성하는 데 도움이 됩니다.
보안 검사 목록: 이러한 각 항목에 설명된 보안 작업을 완료합니다.
BinSkim Binary Analyzer를 사용하여 코드 확인
Microsoft 취약 및 악성 드라이버 보고 센터를 사용하여 드라이버를 보고하는 방법 이해
커널 드라이버가 필요한지 확인
보안 검사 목록 항목 #1: 커널 드라이버가 필요하고 Windows 서비스 또는 앱과 같은 낮은 위험 접근 방식이 더 나은 옵션이 아닌지 확인합니다.
드라이버는 Windows 커널에 있으며 커널에서 실행할 때 문제가 발생하면 전체 운영 체제가 노출됩니다. 다른 옵션을 사용할 수 있는 경우 새 커널 드라이버를 만드는 것보다 비용이 낮고 관련 위험이 적을 수 있습니다. 기본 제공 Windows 드라이버를 사용하는 방법에 대한 자세한 내용은 드라이버를 작성해야 합니까?를 참조하세요.
백그라운드 작업 사용에 대한 자세한 내용은 백그라운드 작업으로 앱 지원을 참조하세요.
Windows 서비스 사용에 대한 자세한 내용은 서비스를 참조 하세요.
드라이버 프레임워크 사용
보안 검사 목록 항목 #2: 드라이버 프레임워크를 사용하여 코드 크기를 줄이고 안정성과 보안을 강화합니다.
Windows 드라이버 프레임워크를 사용하여 코드 크기를 줄이고 안정성과 보안을 강화합니다. 시작하려면 WDF를 사용하여 드라이버 개발을 검토합니다. 위험 수준이 낮은 UMDF(사용자 모드 프레임워크 드라이버)를 사용하는 방법에 대한 자세한 내용은 드라이버 모델 선택을 참조하세요.
오래된 방식으로 WDM(Windows 드라이버 모델) 드라이버를 작성하는 것은 시간이 많이 걸리고 비용이 많이 들며 거의 항상 드라이버 프레임워크에서 사용할 수 있는 코드를 다시 만드는 작업이 포함됩니다.
Windows 드라이버 프레임워크 소스 코드는 오픈 소스 GitHub에서 사용할 수 있습니다. Windows 10에서 제공되는 WDF 런타임 라이브러리가 빌드된 것과 동일한 소스 코드입니다. 드라이버와 WDF 간의 상호 작용을 따를 수 있는 경우 드라이버를 보다 효과적으로 디버그할 수 있습니다. 에서 https://github.com/Microsoft/Windows-Driver-Frameworks다운로드합니다.
소프트웨어 전용 드라이버에 대한 액세스 제어
보안 검사 목록 항목 #3: 소프트웨어 전용 드라이버를 만들려면 추가 액세스 제어를 구현해야 합니다.
소프트웨어 전용 커널 드라이버는 PnP(플러그 앤 플레이)를 사용하여 특정 하드웨어 ID와 연결되지 않으며 모든 PC에서 실행할 수 있습니다. 이러한 드라이버는 원래 의도한 드라이버가 아닌 다른 용도로 사용하여 공격 벡터를 만들 수 있습니다.
소프트웨어 전용 커널 드라이버에는 추가 위험이 있으므로 특정 하드웨어에서 실행하도록 제한되어야 합니다(예: 고유한 PnP ID를 사용하여 PnP 드라이버를 만들거나 SMBIOS 테이블에서 특정 하드웨어가 있는지 확인).
예를 들어 OEM Fabrikam이 시스템에 대해 오버클럭 유틸리티를 사용하도록 설정하는 드라이버를 배포하려고 하는 경우를 상상해 보십시오. 이 소프트웨어 전용 드라이버가 다른 OEM의 시스템에서 실행되는 경우 시스템 불안정 또는 손상이 발생할 수 있습니다. Fabrikam의 시스템에는 Windows 업데이트 통해 업데이트할 수 있는 PnP 드라이버를 만들 수 있도록 고유한 PnP ID가 포함되어야 합니다. 이것이 불가능하고 Fabrikam이 레거시 드라이버를 작성할 경우 해당 드라이버는 Fabrikam 시스템에서 실행되는지 확인하는 다른 방법을 찾아야 합니다(예: 기능을 사용하도록 설정하기 전에 SMBIOS 테이블을 검사하여).
프로덕션 서명 테스트 코드 안 함
보안 검사 목록 항목 #4: 커널 드라이버 코드를 개발, 테스트 및 제조하는 프로덕션 코드에 서명하지 마세요.
개발, 테스트 또는 제조에 사용되는 커널 드라이버 코드에는 보안 위험을 초래하는 위험한 기능이 포함될 수 있습니다. 이 위험한 코드는 Windows에서 신뢰할 수 있는 인증서로 서명해서는 안 됩니다. 위험한 드라이버 코드를 실행하기 위한 올바른 메커니즘은 UEFI 보안 부팅을 사용하지 않도록 설정하고, BCD "TESTSIGNING"을 사용하도록 설정하고, 신뢰할 수 없는 인증서(예: makecert.exe 생성됨)를 사용하여 개발, 테스트 및 제조 코드에 서명하는 것입니다.
신뢰할 수 있는 SPC(소프트웨어 게시자 인증서) 또는 WHQL(Windows 하드웨어 품질 랩) 서명으로 서명된 코드는 Windows 코드 무결성 및 보안 기술을 쉽게 무시할 수 없습니다. 신뢰할 수 있는 SPC 또는 WHQL 서명으로 코드를 서명하기 전에 먼저 신뢰할 수 있는 커널 모드 드라이버 만들기의 지침을 준수하는지 확인합니다. 또한 코드에는 아래 설명된 위험한 동작이 포함되어서는 안 됩니다. 드라이버 서명에 대한 자세한 내용은 이 문서의 뒷부분에 있는 릴리스 드라이버 서명을 참조하세요.
위험한 동작의 예는 다음과 같습니다.
- 임의의 커널, 물리적 또는 디바이스 메모리를 사용자 모드에 매핑하는 기능을 제공합니다.
- 포트 입력/출력(I/O)을 포함하여 임의의 커널, 물리적 또는 디바이스 메모리를 읽거나 쓰는 기능을 제공합니다.
- Windows 액세스 제어를 우회하는 스토리지에 대한 액세스 제공
- 드라이버가 관리하도록 설계되지 않은 하드웨어 또는 펌웨어를 수정하는 기능을 제공합니다.
위협 분석 수행
보안 검사 목록 항목 #5: 기존 드라이버 위협 모델을 수정하거나 드라이버에 대한 사용자 지정 위협 모델을 만듭니다.
보안을 고려할 때 일반적인 방법은 가능한 공격 유형을 설명하려는 특정 위협 모델을 만드는 것입니다. 이 기술은 개발자가 드라이버에 대한 잠재적인 공격 벡터를 미리 고려하도록 강제하기 때문에 드라이버를 디자인할 때 유용합니다. 잠재적인 위협을 식별한 드라이버 개발자는 드라이버 구성 요소의 전반적인 보안을 강화하기 위해 이러한 위협을 방어하는 방법을 고려할 수 있습니다.
이 문서에서는 간단한 위협 모델을 만들기 위한 드라이버별 지침인 드라이버에 대한 위협 모델링을 제공합니다. 이 문서에서는 드라이버의 시작점으로 사용할 수 있는 드라이버 위협 모델 다이어그램 예제를 제공합니다.
SDL(보안 개발 수명 주기) 모범 사례 및 관련 도구를 IHV 및 OEM에서 사용하여 제품의 보안을 향상시킬 수 있습니다. 자세한 내용은 OEM에 대한 SDL 권장 사항을 참조 하세요.
드라이버 보안 코딩 지침 준수
보안 검사 목록 항목 #6: 코드를 검토하고 알려진 코드 취약성을 제거합니다.
보안 드라이버를 만드는 핵심 활동은 알려진 소프트웨어 취약성을 방지하기 위해 변경해야 하는 코드의 영역을 식별하는 것입니다. 이러한 알려진 소프트웨어 취약성 중 상당수는 다른 사용자가 덮어쓰거나 드라이버에서 사용하는 메모리 위치를 구성하는 문제를 방지하기 위해 메모리 사용을 엄격하게 추적하는 작업을 처리합니다.
CodeQL 및 드라이버별 테스트와 같은 코드 검색 도구를 사용하여 이러한 취약성 중 일부(전부는 아님)를 찾을 수 있습니다. 이러한 도구 및 테스트는 이 항목의 뒷부분에 설명되어 있습니다.
메모리 버퍼
항상 입력 및 출력 버퍼의 크기를 확인하여 버퍼가 요청된 모든 데이터를 저장할 수 있는지 확인합니다. 자세한 내용은 버퍼 크기 확인 실패를 참조 하세요.
호출자에게 반환하기 전에 모든 출력 버퍼를 0으로 올바르게 초기화합니다. 자세한 내용은 출력 버퍼 초기화 실패를 참조 하세요.
가변 길이 버퍼의 유효성을 검사합니다. 자세한 내용은 가변 길이 버퍼 유효성 검사 실패를 참조 하세요. 버퍼를 사용하고 ProbeForRead 및 ProbeForWrite를 사용하여 버퍼 주소의 유효성을 검사하는 방법에 대한 자세한 내용은 버퍼 처리를 참조하세요.
IOCTL을 사용하여 데이터 버퍼에 액세스하는 데 적절한 방법 사용
Windows 드라이버의 주요 책임 중 하나는 사용자 모드 애플리케이션과 시스템 디바이스 간에 데이터를 전송하는 것입니다. 데이터 버퍼에 액세스하는 세 가지 방법은 다음 표에 나와 있습니다.
IOCTL 버퍼 형식 | 요약 | 자세한 내용 |
---|---|---|
METHOD_BUFFERED | 대부분의 시정에 권장됨 | 버퍼링된 I/O 사용 |
METHOD_IN_DIRECT 또는 METHOD_OUT_DIRECT | 일부 고속 HW I/O에 사용됨 | 직접 I/O 사용 |
METHOD_NEITHER | 가능하면 피하세요. | 버퍼링 또는 직접 I/O 사용 |
일반적으로 버퍼링된 I/O는 가장 안전한 버퍼링 메서드를 제공하기 때문에 권장됩니다. 그러나 버퍼링된 I/O를 사용하는 경우에도 완화해야 하는 포함된 포인터와 같은 위험이 있습니다.
IOCTL에서 버퍼를 사용하는 방법에 대한 자세한 내용은 데이터 버퍼에 액세스하기 위한 메서드를 참조 하세요.
IOCTL 버퍼링된 I/O 사용 오류
IOCTL 관련 버퍼의 크기를 확인합니다. 자세한 내용은 버퍼 크기 확인 실패를 참조 하세요.
출력 버퍼를 올바르게 초기화합니다. 자세한 내용은 출력 버퍼 초기화 실패를 참조 하세요.
가변 길이 버퍼의 유효성을 올바르게 검사합니다. 자세한 내용은 가변 길이 버퍼 유효성 검사 실패를 참조 하세요.
버퍼링된 I/O를 사용하는 경우 IO_STATUS_BLOCK 구조체 정보 필드에서 OutputBuffer의 적절한 길이를 확인하고 반환합니다. 읽기 요청에서 직접 길이를 반환하지 마세요. 예를 들어 사용자 공간에서 반환된 데이터가 4K 버퍼가 있음을 나타내는 상황을 고려합니다. 드라이버가 실제로 200바이트만 반환해야 하는 경우 정보 필드에서 4K만 반환하면 정보 공개 취약성이 발생했습니다. 이 문제는 이전 버전의 Windows에서는 I/O 관리자가 버퍼링된 I/O에 사용하는 버퍼가 0이 아니므로 발생합니다. 따라서 사용자 앱은 원래 200바이트 데이터와 버퍼에 있던 4K-200바이트(페이징이 아닌 풀 콘텐츠)를 다시 가져옵니다. 이 시나리오는 IOCTL뿐만 아니라 버퍼링된 I/O의 모든 용도로 발생할 수 있습니다.
IOCTL 직접 I/O의 오류
길이가 0인 버퍼를 올바르게 처리합니다. 자세한 내용은 직접 I/O의 오류를 참조 하세요.
사용자 공간 주소 참조 오류
버퍼링된 I/O 요청에 포함된 포인터의 유효성을 검사합니다. 자세한 내용은 사용자 공간 주소 참조의 오류를 참조 하세요.
적절한 경우 ProbeForRead 및 ProbeForWrite와 같은 API를 사용하여 사용하기 전에 사용자 공간의 주소에 대한 유효성을 검사합니다.
MSR 모델별 레지스터 읽기 및 쓰기
__readmsr 및 __writemsr 같은 컴파일러 내장 함수를 사용하여 모델별 레지스터에 액세스할 수 있습니다. 이 액세스가 필요한 경우 드라이버는 항상 읽거나 쓸 레지스터가 예상 인덱스 또는 범위로 제한되는지 확인해야 합니다.
자세한 내용 및 코드 예제는 Windows 드라이버 개발자를 위한 개발 보안 모범 사례에서 MSR을 읽고 쓰는 기능 제공을 참조하세요.
TOCTOU 취약성
직접 I/O(IOCTL 또는 읽기/쓰기)를 사용하는 경우 TOCTOU(사용 시간)에 대한 잠재적인 검사 시간이 있습니다. 드라이버가 사용자 데이터 버퍼에 액세스하고 있으며 사용자가 동시에 액세스할 수 있습니다.
이 위험을 관리하려면 사용자 데이터 버퍼에서 유효성을 검사해야 하는 매개 변수를 커널 모드(예: 스택 또는 풀)에서만 액세스할 수 있는 메모리로 복사합니다. 그런 다음, 사용자 애플리케이션에서 데이터에 액세스할 수 없으면 유효성을 검사한 다음 전달된 데이터에 대해 작동합니다.
드라이버 코드는 메모리를 올바르게 사용해야 합니다.
모든 드라이버 풀 할당은 NX(실행 불가능한) 풀에 있어야 합니다. NX 메모리 풀을 사용하는 것은 NP(실행 파일 비페이징) 풀을 사용하는 것보다 본질적으로 더 안전하며 오버플로 공격에 대한 더 나은 보호를 제공합니다.
디바이스 드라이버는 커널 I/O에 대한 커널뿐만 아니라 다양한 사용자 모드, 요청을 제대로 처리해야 합니다.
드라이버가 HVCI 가상화를 지원할 수 있도록 추가 메모리 요구 사항이 있습니다. 자세한 내용은 이 문서의 뒷부분에 있는 HVCI 호환 코드 구현을 참조하세요.
핸들
- 사용자 모드와 커널 모드 메모리 간에 전달된 핸들의 유효성을 검사합니다. 자세한 내용은 핸들 관리 및 개체 핸들 유효성 검사 실패를 참조하세요.
디바이스 개체
IRP
WDF 및 IRP
WDF를 사용하는 한 가지 이점은 WDF 드라이버가 일반적으로 IRP에 직접 액세스하지 않는다는 것입니다. 예를 들어 프레임워크는 읽기, 쓰기 및 디바이스 I/O 제어 작업을 나타내는 WDM IRP를 KMDF/UMDF가 I/O 큐에서 수신하는 프레임워크 요청 개체로 변환합니다.
WDM 드라이버를 작성하는 경우 다음 지침을 검토합니다.
IRP I/O 버퍼 제대로 관리
다음 문서에서는 IRP 입력 값의 유효성을 검사하는 방법에 대한 정보를 제공합니다.
버퍼링된 I/O를 사용하는 DispatchReadWrite
직접 I/O를 사용하는 DispatchReadWrite
버퍼 주소 및 길이와 같이 IRP와 연결된 값의 유효성을 검사하는 것이 좋습니다.
I/O를 사용하지 않도록 선택한 경우 읽기 및 쓰기와 달리 버퍼링된 I/O 및 Direct I/O와 달리 I/O IOCTL을 사용하지 않을 때는 I/O 관리자가 버퍼 포인터와 길이의 유효성을 검사하지 않는다는 점에 유의하세요.
IRP 완료 작업을 올바르게 처리
드라이버는 실제로 IRP를 지원하고 처리하지 않는 한 상태 값이 STATUS_SUCCESS IRP를 완료해서는 안 됩니다. IRP 완료 작업을 처리하는 올바른 방법에 대한 자세한 내용은 IRP 완료를 참조 하세요.
드라이버 IRP 보류 상태 관리
드라이버는 IRP를 저장하기 전에 보류 중인 IRP를 표시해야 하며, IoMarkIrpPending에 대한 호출과 할당을 연동 시퀀스에 모두 포함하는 것이 좋습니다. 자세한 내용은 디바이스가 일시 중지될 때 드라이버 상태를 확인하지 못하여 들어오는 IRP를 보유하는 방법을 참조하세요.
IRP 취소 작업을 올바르게 처리
취소 작업은 일반적으로 비동기적으로 실행되므로 제대로 코딩하기 어려울 수 있습니다. 이 코드는 일반적으로 실행 중인 시스템에서 자주 실행되지 않으므로 취소 작업을 처리하는 코드의 문제는 오랫동안 눈에 띄지 않을 수 있습니다. IRP 취소에 따라 제공된 모든 정보를 읽고 이해해야 합니다. IRP 취소 동기화 및 IRP 취소 시 고려할 사항에 특히 주의하세요.
취소 작업과 관련된 동기화 문제를 최소화하는 한 가지 권장 방법은 취소로부터 안전한 IRP 큐를 구현하는 것입니다.
IRP 정리 및 닫기 작업을 올바르게 처리
IRP_MJ_CLEANUP 요청과 IRP_MJ_CLOSE 요청 간의 차이점을 이해해야 합니다. 정리 요청은 애플리케이션이 파일 개체의 모든 핸들을 닫은 후에 도착하지만 때로는 모든 I/O 요청이 완료되기 전에 도착합니다. 파일 개체에 대한 모든 I/O 요청이 완료되거나 취소된 후 닫기 요청이 도착합니다. 자세한 내용은 다음 문서를 참조하세요.
DispatchCreate, DispatchClose 및 DispatchCreateClose 루틴
IRP를 올바르게 처리하는 방법에 대한 자세한 내용은 IRP 처리의 추가 오류를 참조 하세요.
기타 보안 문제
잠금 또는 연동 시퀀스를 사용하여 경합 상태를 방지합니다. 자세한 내용은 다중 프로세서 환경의 오류를 참조 하세요.
디바이스 드라이버가 커널 I/O 요청에 대한 커널뿐만 아니라 다양한 사용자 모드를 제대로 처리해야 합니다.
설치 또는 사용 중에 드라이버 또는 관련 소프트웨어 패키지에 의해 TDI 필터 또는 LSP가 설치되지 않았는지 확인합니다.
안전 함수 사용
안전한 문자열 함수를 사용합니다. 자세한 내용은 안전 문자열 함수 사용을 참조 하세요.
안전한 산술 함수를 사용합니다. 자세한 내용은 안전한 정수 라이브러리 루틴을 참조 하세요.
안전한 변환 함수를 사용합니다.
추가 코드 취약성
이 문서에서는 여기서 다루는 가능한 취약성 외에도 커널 모드 드라이버 코드 의 보안 강화에 대한 추가 정보인 신뢰할 수 있는 커널 모드 드라이버 만들기를 제공합니다.
C 및 C++ 보안 코딩에 대한 자세한 내용은 이 문서의 끝에 있는 보안 코딩 리소스를 참조하세요.
드라이버 액세스 제어 관리
보안 검사 목록 항목 #7: 드라이버를 검토하여 액세스를 제대로 제어하고 있는지 확인합니다.
드라이버 액세스 제어 관리 - WDF
드라이버는 사용자가 컴퓨터의 장치 및 파일에 부적절하게 액세스하지 못하도록 하기 위해 노력해야 합니다. 디바이스 및 파일에 대한 무단 액세스를 방지하려면 다음을 수행해야 합니다.
필요한 경우에만 디바이스 개체의 이름을 지정합니다. 명명된 디바이스 개체는 일반적으로 레거시 이유(예: 특정 이름을 사용하여 디바이스를 열 것으로 예상되는 애플리케이션이 있거나 PNP가 아닌 디바이스/제어 디바이스를 사용하는 경우)에만 필요합니다. WdfDeviceCreateSymbolicLink를 사용하여 기호 링크를 만들기 위해 WDF 드라이버는 PnP 디바이스 FDO의 이름을 지정할 필요가 없습니다.
디바이스 개체 및 인터페이스에 대한 액세스를 보호합니다.
애플리케이션 또는 다른 WDF 드라이버가 PnP 디바이스 PDO에 액세스할 수 있도록 하려면 디바이스 인터페이스를 사용해야 합니다. 자세한 내용은 디바이스 인터페이스 사용을 참조 하세요. 디바이스 인터페이스는 디바이스 스택의 PDO에 대한 기호 링크 역할을 합니다.
PDO에 대한 액세스를 제어하는 더 좋은 방법 중 하나는 INF에서 SDDL 문자열을 지정하는 것입니다. SDDL 문자열이 INF 파일에 없는 경우 Windows는 기본 보안 설명자를 적용합니다. 자세한 내용은 디바이스 개체 및 디바이스 개체에 대한 SDDL 보안 유지를 참조하세요.
액세스 제어에 대한 자세한 내용은 다음 문서를 참조하세요.
이름, 보안 설명자 및 디바이스 클래스 - 액세스할 수 있는 디바이스 개체 만들기... 및 SAFE 2017년 1월부터 OSR이 발행한 NT 참가자 뉴스레터입니다.
드라이버 액세스 제어 관리 - WDM
WDM 드라이버로 작업 중이고 명명된 디바이스 개체를 사용한 경우 IoCreateDeviceSecure를 사용하고 SDDL을 지정하여 보호할 수 있습니다. IoCreateDeviceSecure를 구현하는 경우 항상 DeviceClassGuid에 대한 사용자 지정 클래스 GUID를 지정합니다. 여기서 기존 클래스 GUID를 지정해서는 안 됩니다. 이렇게 하면 해당 클래스에 속한 다른 디바이스에 대한 보안 설정 또는 호환성이 손상될 수 있습니다. 자세한 내용은 WdmlibIoCreateDeviceSecure를 참조 하세요.
자세한 내용은 다음 문서를 참조하세요.
SID(보안 식별자) 위험 계층 구조
다음 섹션에서는 드라이버 코드에 사용되는 일반적인 SID의 위험 계층 구조를 설명합니다. SDDL에 대한 일반적인 내용은 디바이스 개체, SID 문자열 및 SDDL 문자열 구문에 대한 SDDL을 참조하세요.
낮은 권한 호출자가 커널에 액세스할 수 있는 경우 코드 위험이 증가한다는 것을 이해하는 것이 중요합니다. 이 요약 다이어그램에서는 드라이버 기능에 대한 낮은 권한 SID 액세스를 허용하면 위험이 증가합니다.
SY (System)
\/
BA (Built-in Administrators)
\/
LS (Local Service)
\/
BU (Built-in User)
\/
AC (Application Container)
일반 최소 권한 보안 원칙에 따라 드라이버가 작동하는 데 필요한 최소 액세스 수준만 구성합니다.
WDM 세분화된 IOCTL 보안 제어
사용자 모드 호출자가 IOCTL을 보낼 때 보안을 더욱 관리하기 위해 드라이버 코드에는 IoValidateDeviceIoControlAccess 함수가 포함될 수 있습니다. 이 함수를 사용하면 드라이버가 액세스 권한을 확인할 수 있습니다. IOCTL을 받으면 드라이버는 IoValidateDeviceIoControlAccess를 호출하여 FILE_READ_ACCESS, FILE_WRITE_ACCESS 또는 둘 다를 지정할 수 있습니다.
세분화된 IOCTL 보안 제어를 구현해도 위에서 설명한 기술을 사용하여 드라이버 액세스를 관리할 필요가 없습니다.
자세한 내용은 다음 문서를 참조하세요.
HVCI 호환 코드 구현
보안 검사 목록 항목 #8: 드라이버가 HVCI와 호환되도록 메모리를 사용하는지 확인합니다.
메모리 사용량 및 HVCI 호환성
HVCI는 하드웨어 기술 및 가상화를 사용하여 CI(코드 무결성) 의사 결정 함수를 나머지 운영 체제와 격리합니다. 가상화 기반 보안을 사용하여 CI를 격리하는 경우 커널 메모리가 실행될 수 있는 유일한 방법은 CI 확인을 통해서입니다. 즉, 커널 메모리 페이지는 쓰기 가능 및 실행 가능(W+X)일 수 없으며 실행 코드를 직접 수정할 수 없습니다.
HVCI 호환 코드를 구현하려면 드라이버 코드에서 다음을 수행해야 합니다.
- 기본적으로 NX에 옵트인
- 메모리 할당에 NX API/플래그 사용(NonPagedPoolNx)
- 쓰기 가능 및 실행 가능한 섹션을 사용하지 않습니다.
- 실행 파일 시스템 메모리를 직접 수정하지 않습니다.
- 커널에서 동적 코드를 사용하지 않음
- 데이터 파일을 실행 파일로 로드하지 않음
- 구역 맞춤은 0x1000(PAGE_SIZE)의 배수입니다. 예를 들어 DRIVER_ALIGNMENT=0x1000
도구 및 호환되지 않는 메모리 호출 목록을 사용하는 방법에 대한 자세한 내용은 HVCI 호환 코드 구현을 참조하세요.
관련 시스템 기본 사항 보안 테스트 에 대한 자세한 내용은 하이퍼바이저 코드 무결성 준비 테스트 및 HVCI(하이퍼바이저로 보호된 코드 무결성)를 참조하세요.
기술별 코드 모범 사례 따르기
보안 검사 목록 항목 #9: 드라이버에 대한 다음 기술별 지침을 검토합니다.
파일 시스템
파일 시스템 드라이버 보안에 대한 자세한 내용은 다음 문서를 참조하세요.
NDIS - 네트워킹
NDIS 드라이버 보안에 대한 자세한 내용은 네트워크 드라이버에 대한 보안 문제를 참조 하세요.
표시
디스플레이 드라이버 보안에 대한 자세한 내용은 보류 중인 콘텐츠를 참조 <하세요>.
프린터
프린터 드라이버 보안과 관련된 자세한 내용은 V4 프린터 드라이버 보안 고려 사항을 참조 하세요.
WIA(Windows 이미지 취득) 드라이버에 대한 보안 문제
WIA 보안에 대한 자세한 내용은 WIA(Windows 이미지 취득) 드라이버에 대한 보안 문제를 참조 하세요.
디바이스 설치 보안 강화
보안 검사 목록 항목 #10: 드라이버 inf 만들기 및 설치 지침을 검토하여 모범 사례를 따르고 있는지 확인합니다.
드라이버를 설치하는 코드를 만들 때 디바이스 설치가 항상 안전한 방식으로 수행되는지 확인해야 합니다. 보안 디바이스 설치는 다음을 수행합니다.
- 디바이스 및 해당 디바이스 인터페이스 클래스에 대한 액세스를 제한합니다.
- 디바이스에 대해 만들어진 드라이버 서비스에 대한 액세스를 제한합니다.
- 드라이버 파일을 수정 또는 삭제로부터 보호합니다.
- 디바이스의 레지스트리 항목에 대한 액세스를 제한합니다.
- 디바이스의 WMI 클래스에 대한 액세스를 제한합니다.
- SetupAPI 함수를 올바르게 사용
자세한 내용은 다음 문서를 참조하세요.
피어 코드 검토 수행
보안 검사 목록 항목 #11: 피어 코드 검토를 수행하여 다른 도구 및 프로세스에서 표시되지 않는 문제를 찾습니다.
지식이 있는 코드 검토자를 찾아 놓친 문제를 찾습니다. 눈의 두 번째 세트는 종종 당신이 간과 할 수있는 문제를 볼 수 있습니다.
내부적으로 코드를 검토하기에 적합한 직원이 없는 경우 이 목적을 위해 외부에 도움을 주는 것이 좋습니다.
적절한 릴리스 드라이버 서명 실행
보안 검사 목록 항목 #12: Windows 파트너 포털을 사용하여 배포를 위해 드라이버에 올바르게 서명합니다.
드라이버 패키지를 일반에 릴리스하기 전에 인증을 위해 패키지를 제출하는 것이 좋습니다. 자세한 내용은 성능 및 호환성 테스트, 하드웨어 프로그램 시작, 하드웨어 대시보드 서비스 및 퍼블릭 릴리스용 커널 드라이버 서명 증명을 참조하세요.
CodeQL을 사용하여 드라이버 코드 확인
보안 검사 목록 항목 #13: CodeQL을 사용하여 드라이버 코드의 취약성을 확인합니다.
GitHub의 CodeQL은 의미 체계 코드 분석 엔진이며, 강력한 플랫폼과 함께 광범위한 보안 쿼리 제품군을 조합하여 드라이버 코드를 보호하는 데 매우 중요한 도구가 됩니다. 자세한 내용은 CodeQL 및 정적 도구 로고 테스트를 참조하세요.
드라이버 코드에 SAL 주석 추가
보안 검사 목록 항목 #14: 드라이버 코드에 SAL 주석을 추가합니다.
SAL(소스 코드 주석 언어)은 함수가 매개 변수를 사용하는 방법, 매개 변수에 대해 가정하는 방법 및 완료 시 보장을 설명하는 데 사용할 수 있는 주석 집합을 제공합니다. 주석은 헤더 파일에 sal.h
정의됩니다. C++용 Visual Studio 코드 분석은 SAL 주석을 사용하여 함수 분석을 수정합니다. Windows 드라이버 개발을 위한 SAL 2.0에 대한 자세한 내용은 Windows 드라이버용 SAL 2.0 주석 및 SAL 주석을 사용하여 C/C++ 코드 결함을 줄이는 방법을 참조하세요.
SAL에 대한 일반적인 내용은 OSR에서 사용할 수 있는 이 문서를 참조하세요. https://www.osr.com/blog/2015/02/23/sal-annotations-dont-hate-im-beautiful/
드라이버 검증 도구를 사용하여 취약성 확인
보안 검사 목록 항목 #15: 드라이버 검증 도구를 사용하여 드라이버 코드의 취약성을 확인합니다.
드라이버 검증 도구는 인터페이스 규칙 집합과 운영 체제 모델을 사용하여 드라이버가 Windows 운영 체제와 올바르게 상호 작용하는지 여부를 결정합니다. DV는 드라이버 코드에서 잠재적인 버그를 가리킬 수 있는 결함을 찾습니다.
드라이버 검증 도구는 드라이버의 실시간 테스트를 허용합니다. 드라이버 검증 도구는 Windows 커널 모드 드라이버 및 그래픽 드라이버를 모니터링하여 시스템을 손상할 수 있는 잘못된 함수 호출 또는 작업을 감지합니다. 드라이버 검증 도구는 Windows 드라이버에 다양한 스트레스와 테스트를 적용하여 부적절한 동작을 찾을 수 있습니다. 자세한 내용은 드라이버 검증 도구를 참조하세요.
DV에서는 특정 유형의 드라이버만 지원됩니다. DV에서 확인할 수 있는 드라이버에 대한 자세한 내용은 지원되는 드라이버를 참조 하세요. 작업 중인 드라이버 유형에 사용할 수 있는 DV 테스트에 대한 자세한 내용은 다음 페이지를 참조하세요.
- WDM 드라이버에 대한 규칙
- KMDF 드라이버에 대한 규칙
- NDIS 드라이버에 대한 규칙
- Storport 드라이버에 대한 규칙
- 오디오 드라이버에 대한 규칙
- AVStream 드라이버에 대한 규칙
DV에 익숙해지려면 샘플 드라이버(예: 추천 토스터 샘플) https://github.com/Microsoft/Windows-driver-samples/tree/main/general/toaster/toastDrv/kmdf/func/featured중 하나를 사용할 수 있습니다.
BinSkim 이진 분석기를 사용하여 코드 확인
보안 검사 목록 항목 #16: 다음 단계에 따라 BinSkim을 사용하여 알려진 보안 문제를 최소화하기 위해 컴파일 및 빌드 옵션이 구성되어 있는지 다시 확인합니다.
BinSkim을 사용하여 이진 파일을 검사하여 잠재적으로 이진 파일을 취약하게 만들 수 있는 코딩 및 빌드 사례를 식별합니다.
BinSkim은 다음을 확인합니다.
- 오래된 컴파일러 도구 집합 사용 - 현재 컴파일러 수준 및 OS 제공 보안 완화의 사용을 최대화하려면 가능한 경우 가장 최근의 컴파일러 도구 집합에 대해 이진 파일을 컴파일해야 합니다.
- 안전하지 않은 컴파일 설정 - OS에서 제공하는 보안 완화를 사용하도록 설정하고 컴파일러 오류 및 실행 가능한 경고 보고를 최대화하기 위해 가능한 가장 안전한 설정으로 이진 파일을 컴파일해야 합니다.
- 서명 문제 - 서명된 이진 파일은 암호화된 강력한 알고리즘으로 서명해야 합니다.
BinSkim은 오픈 소스 도구이며 SARIF(정적 분석 결과 교환 형식) 형식을 사용하는 출력 파일을 생성합니다. BinSkim은 이전 BinScope 도구를 대체합니다.
BinSkim에 대한 자세한 내용은 BinSkim 사용자 가이드를 참조하세요.
다음 단계에 따라 배송 중인 코드에서 보안 컴파일 옵션이 올바르게 구성되었는지 확인합니다.
플랫폼 간 .NET Core SDK를 다운로드하고 설치합니다.
Visual Studio가 설치되어 있는지 확인합니다. Visual Studio 다운로드 및 설치에 대한 자세한 내용은 Visual Studio 설치를 참조 하세요.
NuGet 패키지와 같이 BinSkim을 다운로드하는 다양한 옵션이 있습니다. 이 예제에서는 Git 클론 옵션을 사용하여 여기에서 https://github.com/microsoft/binskim 다운로드하고 64비트 Windows PC에 설치합니다.
Visual Studio 개발자 명령 프롬프트 창을 열고 디렉터리를 만듭니다. 예를 들면 다음과 같습니다
C:\binskim-master
.C:\> Md \binskim-master
방금 만든 디렉터리로 이동합니다.
C:\> Cd \binskim-master
git clone 명령을 사용하여 필요한 모든 파일을 다운로드합니다.
C:\binskim-master> git clone --recurse-submodules https://github.com/microsoft/binskim.git
복제 명령이 만든 새
binskim
디렉터리로 이동합니다.C:\> Cd \binskim-master\binskim
BuildAndTest.cmd 실행하여 릴리스 빌드가 성공하고 모든 테스트가 통과하는지 확인합니다.
C:\binskim-master\binskim> BuildAndTest.cmd Welcome to .NET Core 3.1! --------------------- SDK Version: 3.1.101 ... C:\binskim-master\binskim\bld\bin\AnyCPU_Release\Publish\netcoreapp2.0\win-x64\BinSkim.Sdk.dll 1 File(s) copied C:\binskim-master\binskim\bld\bin\AnyCPU_Release\Publish\netcoreapp2.0\linux-x64\BinSkim.Sdk.dll 1 File(s) copied ...
빌드 프로세스는 BinSkim 실행 파일을 사용하여 디렉터리 집합을 만듭니다. win-x64 빌드 출력 디렉터리로 이동합니다.
C:\binskim-master\binskim> Cd \binskim-master\bld\bin\AnyCPU_Release\Publish\netcoreapp2.0\win-x64>
분석 옵션에 대한 도움말을 표시합니다.
C:\binskim-master\binskim\bld\bin\AnyCPU_Release\Publish\netcoreapp2.0\win-x64> BinSkim help analyze
BinSkim PE/MSIL Analysis Driver 1.6.0.0
--sympath Symbols path value, e.g., SRV*http://msdl.microsoft.com/download/symbols or Cache*d:\symbols;Srv*http://symweb. See
https://learn.microsoft.com/windows-hardware/drivers/debugger/advanced-symsrv-use for syntax information. Note that BinSkim will clear the
_NT_SYMBOL_PATH environment variable at runtime. Use this argument for symbol information instead.
--local-symbol-directories A set of semicolon-delimited local directory paths that will be examined when attempting to locate PDBs.
-o, --output File path to which analysis output will be written.
--verbose Emit verbose output. The resulting comprehensive report is designed to provide appropriate evidence for compliance scenarios.
...
기호 경로 설정
BinSkim을 실행하는 동일한 컴퓨터에서 분석하는 모든 코드를 빌드하는 경우 일반적으로 기호 경로를 설정할 필요가 없습니다. 이는 컴파일한 로컬 상자에서 기호 파일을 사용할 수 있기 때문입니다. 더 복잡한 빌드 시스템을 사용하거나 기호를 컴파일된 이진 파일과 함께 있지 않은 다른 위치로 리디렉션하는 경우 기호 파일 검색에 이러한 위치를 추가하는 데 사용합니다 --local-symbol-directories
.
코드가 코드의 일부가 아닌 컴파일된 이진 파일을 참조하는 경우 이러한 코드 종속성의 보안을 확인하기 위해 창 디버거를 사용하여 기호를 검색할 수 있습니다. 이러한 종속성에서 문제가 발견되면 문제를 해결할 수 없을 수 있습니다. 그러나 이러한 종속성을 사용하여 수락할 수 있는 보안 위험을 인식하는 것이 유용할 수 있습니다.
팁
네트워크 기호 서버를 참조하는 기호 경로를 추가할 때 로컬 캐시 위치를 추가하여 기호를 캐시할 로컬 경로를 지정합니다. 이렇게 하지 않으면 BinSkim의 성능이 크게 손상됩니다. 다음 예제에서는 d:\symbols에서 로컬 캐시를 지정합니다.
--sympath Cache*d:\symbols;Srv*http://symweb
동조에 대한 자세한 내용은 Windows 디버거의 기호 경로를 참조 하세요.
다음 명령을 실행하여 컴파일된 드라이버 이진 파일을 분석합니다. 준수 드라이버 .sys 파일을 가리키도록 대상 경로를 업데이트합니다.
C:\binskim-master\binskim\bld\bin\AnyCPU_Release\Publish\netcoreapp2.0\win-x64> BinSkim analyze "C:\Samples\KMDF_Echo_Driver\echo.sys"
자세한 내용은 다음과 같이 자세한 정보 표시 옵션을 추가합니다.
C:\binskim-master\binskim\bld\bin\AnyCPU_Release\Publish\netcoreapp2.0\win-x64> BinSkim analyze "C:\Samples\KMDF_Echo_Driver\osrusbfx2.sys" --verbose
참고 항목
--verbose 옵션은 모든 검사에 대해 명시적 통과/실패 결과를 생성합니다. 자세한 정보를 제공하지 않으면 BinSkim에서 감지한 결함만 표시됩니다. --verbose 옵션은 일반적으로 로그 파일의 크기가 증가하여 실제 자동화 시스템에 권장되지 않으며, 개별 오류가 발생할 때 개별 오류를 선택하기가 더 어렵기 때문에 많은 수의 '통과' 결과에 포함되기 때문입니다.
명령 출력을 검토하여 가능한 문제를 찾습니다. 이 예제 출력은 통과한 세 가지 테스트를 보여 줍니다. BA2002와 같은 규칙에 대한 추가 정보는 BinSkim 사용자 가이드에서 확인할 수 있습니다.
Analyzing... Analyzing 'osrusbfx2.sys'... ... C:\Samples\KMDF_Echo_Driver\osrusbfx2.sys\Debug\osrusbfx2.sys: pass BA2002: 'osrusbfx2.sys' does not incorporate any known vulnerable dependencies, as configured by current policy. C:\Samples\KMDF_Echo_Driver\Debug\osrusbfx2.sys: pass BA2005: 'osrusbfx2.sys' is not known to be an obsolete binary that is vulnerable to one or more security problems. C:\Samples\KMDF_Echo_Driver\osrusbfx2.sys: pass BA2006: All linked modules of 'osrusbfx2.sys' generated by the Microsoft front-end satisfy configured policy (compiler minimum version 17.0.65501.17013).
이 출력은 도구가 드라이버가 ELF 이진 파일이 아님을 나타내기 때문에 테스트 BA3001이 실행되지 않음을 보여줍니다.
... C:\Samples\KMDF_Echo_Driver\Debug\osrusbfx2.sys: notapplicable BA3001: 'osrusbfx2.sys' was not evaluated for check 'EnablePositionIndependentExecutable' as the analysis is not relevant based on observed metadata: image is not an ELF binary.
이 출력은 테스트 BA2007에 대한 오류를 표시합니다.
... C:\Samples\KMDF_Echo_Driver\Debug\osrusbfx2.sys: error BA2007: 'osrusbfx2.sys' disables compiler warning(s) which are required by policy. A compiler warning is typically required if it has a high likelihood of flagging memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, enable the indicated warning(s) by removing /Wxxxx switches (where xxxx is a warning id indicated here) from your command line, and resolve any warnings subsequently raised during compilation.
Visual Studio에서 이러한 경고를 사용하도록 설정하려면 프로젝트의 속성 페이지의 C/C++에서 특정 경고 사용 안 함에서 제외하지 않으려는 값을 제거합니다.
드라이버 프로젝트에 대한 Visual Studio의 기본 컴파일 옵션은 다음과 같은 경고를 사용하지 않도록 설정할 수 있습니다. 이러한 경고는 BinSkim에 의해 보고됩니다.
C4603 - 'name': 미리 컴파일된 헤더 사용 후 매크로가 정의되지 않았거나 정의가 다릅니다.
C4627 - 'description': 미리 컴파일된 헤더 사용을 검색할 때 건너뛰기
C4986 - 'declaration': 예외 사양이 이전 선언과 일치하지 않습니다.
컴파일러 경고에 대한 자세한 내용은 컴파일러 버전별 컴파일러 경고를 참조하세요.
하드웨어 호환성 프로그램 테스트를 사용하여 코드 확인
보안 검사 목록 항목 #17: 보안 관련 하드웨어 호환성 프로그램 테스트를 사용하여 보안 문제를 확인합니다.
하드웨어 호환성 프로그램에는 코드 취약성을 찾는 데 사용할 수 있는 보안 관련 테스트가 포함되어 있습니다. Windows 하드웨어 호환성 프로그램은 Windows HLK(하드웨어 랩 키트)의 테스트를 활용합니다. HLK 디바이스 기본 사항 테스트는 명령줄에서 드라이버 코드를 실행하고 약점을 조사하는 데 사용할 수 있습니다. 디바이스 기본 사항 테스트 및 하드웨어 호환성 프로그램에 대한 일반적인 내용은 Windows 하드웨어 랩 키트를 참조 하세요.
다음 테스트는 드라이버 코드에서 코드 취약성과 관련된 일부 동작을 확인하는 데 유용할 수 있는 테스트의 예입니다.
DF - 퍼지 길이가 0인 버퍼 FSCTL 테스트(안정성)
드라이버 검증 도구에 포함된 커널 동기화 지연 퍼지를 사용할 수도 있습니다.
CHAOS(동시 하드웨어 및 운영 체제) 테스트는 다양한 PnP 드라이버 테스트, 장치 드라이버 퍼지 테스트 및 전원 시스템 테스트를 동시에 실행합니다. 자세한 내용은 CHAOS 테스트(디바이스 기본 사항)를 참조하세요.
디바이스 기본 사항 침투 테스트는 보안 테스트의 중요한 구성 요소인 다양한 형태의 입력 공격을 수행합니다. 공격 및 침투 테스트는 소프트웨어 인터페이스의 취약성을 식별하는 데 도움이 될 수 있습니다. 자세한 내용은 침투 테스트(디바이스 기본 사항)를 참조하세요.
이 문서에 설명된 다른 도구와 함께 Device Guard - 준수 테스트를 사용하여 드라이버가 HVCI와 호환되는지 확인합니다.
사용자 지정 및 도메인별 테스트 도구
사용자 지정 도메인별 보안 테스트 개발을 고려합니다. 추가 테스트를 개발하려면 소프트웨어의 원래 디자이너와 개발 중인 특정 유형의 드라이버에 익숙한 관련 없는 개발 리소스 및 보안 침입 분석 및 방지에 익숙한 한 명 이상의 사용자로부터 입력을 수집합니다.
디버거 기술 및 확장 검토
보안 검사 목록 항목 #18: 이러한 디버거 도구를 검토하고 개발 디버깅 워크플로에서 사용하는 것을 고려합니다.
보안 관련 디버거 명령
!acl 확장은 ACL(액세스 제어 목록)의 내용을 서식으로 지정하고 표시합니다. 자세한 내용은 개체 및 !acl의 ACL 확인 을 참조하세요.
!token 확장은 보안 토큰 개체의 서식이 지정된 보기를 표시합니다. 자세한 내용은 !token을 참조하세요.
!tokenfields 확장은 액세스 토큰 개체(TOKEN 구조) 내에 있는 필드의 이름과 오프셋을 표시합니다. 자세한 내용은 !tokenfields를 참조 하세요.
!sid 확장은 지정된 주소에 SID(보안 식별자)를 표시합니다. 자세한 내용은 !sid를 참조하세요.
!sd 확장은 지정된 주소에 보안 설명자를 표시합니다. 자세한 내용은 !sd를 참조하세요.
Microsoft 취약 및 악성 드라이버 보고 센터
누구나 Microsoft 취약 및 악성 드라이버 보고 센터를 사용하여 의심스러운 드라이버를 제출할 수 있습니다. 분석을 위해 드라이버를 제출하는 방법에 대한 자세한 내용은 이 블로그 항목을 참조하세요. - 새로운 Microsoft 취약 및 악성 드라이버 보고 센터를 사용하여 커널 보안 향상
Reporting Center는 x86 및 x64 아키텍처용으로 빌드된 Windows 드라이버를 검색하고 분석할 수 있습니다. 취약한 드라이버와 악의적인 검사된 드라이버는 Microsoft의 취약한 드라이버 팀에서 분석 및 조사를 위해 플래그가 지정됩니다. 취약한 드라이버가 확인되면 적절한 알림이 발생하며 취약한 드라이버 차단 목록에 추가됩니다. 자세한 내용은 Microsoft 권장 드라이버 블록 규칙을 참조하세요. 이러한 규칙은 기본적으로 HVCI(하이퍼바이저로 보호된 코드 무결성) 사용 디바이스 및 S 모드의 Windows 10에 적용됩니다.
보안 코딩 리소스 검토
보안 검사 목록 항목 #19: 이러한 리소스를 검토하여 드라이버 개발자에게 적용되는 보안 코딩 모범 사례에 대한 이해를 확장합니다.
드라이버 보안에 대해 자세히 알아보려면 이러한 리소스를 검토하세요.
커널 모드 드라이버 코딩 지침 보호
보안 코딩 조직
Carnegie Mellon University SEI CERT C 코딩 표준: 안전하고 신뢰할 수 있는 보안 시스템 개발 규칙(2016 버전).
MITRE - CERT C 보안 코딩 표준에 의해 해결된 약점
BSIMM(Maturity Model) 보안 빌드 - https://www.bsimm.com/
SAFECode - https://safecode.org/
OSR
OSR 은 드라이버 개발 교육 및 컨설팅 서비스를 제공합니다. OSR 뉴스레터의 이러한 문서는 드라이버 보안 문제를 강조 표시합니다.
이름, 보안 설명자 및 디바이스 클래스 - 액세스할 수 있는 디바이스 개체 만들기... 및 SAFE
보호를 사용해야 합니다. 드라이버 및 디바이스 보안 내부
사례 연구
경고에서 드라이버 취약성까지: Microsoft Defender ATP 조사로 권한 상승 결함 발굴
책
소프트웨어 보안의 24 치명적인 죄 : 프로그래밍 결함과 마이클 하워드, 데이비드 르블랑과 존 비에가에 의해 그들을 해결하는 방법
소프트웨어 보안 평가의 예술: 소프트웨어 취약성 식별 및 방지, Mark Dowd, John McDonald 및 Justin Schuh
보안 소프트웨어 두 번째 버전 작성, 마이클 하워드와 데이비드 르블랑
소프트웨어 보안 평가의 예술: 소프트웨어 취약성 식별 및 방지, Mark Dowd 및 John McDonald
C 및 C++의 보안 코딩(소프트웨어 엔지니어링의 SEI 시리즈) 제2판, Robert C. Seacord
Microsoft Windows 드라이버 모델 프로그래밍(2판), Walter Oney
Windows 드라이버 파운데이션(개발자 참조), 페니 오윅 및 가이 스미스를 사용하여 드라이버 개발
학습
Windows 드라이버 클래스룸 교육은 다음과 같은 공급업체에서 사용할 수 있습니다.
보안 코딩 온라인 교육은 다양한 소스에서 사용할 수 있습니다. 예를 들어 이 과정은 다음의 coursera에서 사용할 수 있습니다.
SAFECode는 다음과 같은 무료 교육도 제공합니다.
전문 인증
CERT는 보안 코딩 전문가 인증을 제공합니다.
주요 내용 요약
드라이버 보안은 많은 요소를 포함하는 복잡한 작업이지만 고려해야 할 몇 가지 주요 사항은 다음과 같습니다.
드라이버는 Windows 커널에 있으며 커널에서 실행할 때 문제가 발생하면 전체 운영 체제가 노출됩니다. 이 때문에 보안을 염두에 두고 드라이버 보안 및 설계에 세심한 주의를 기울여야 합니다.
최소 권한 원칙을 적용합니다.
a. 엄격한 SDDL 문자열을 사용하여 드라이버에 대한 액세스를 제한합니다.
b. 개별 IOCTL의 추가 제한
위협 모델을 만들어 공격 벡터를 식별하고 추가로 제한할 수 있는지 여부를 고려합니다.
usermode에서 전달되는 포함된 포인터와 관련하여 주의해야 합니다. 버퍼 값을 캡처하고 비교하지 않는 한, 검색하고, try 내에서 액세스해야 하며, 사용 시간(ToCToU) 문제가 발생하기 쉽습니다.
확실하지 않은 경우 METHOD_BUFFERED IOCTL 버퍼링 방법으로 사용합니다.
코드 검사 유틸리티를 사용하여 알려진 코드 취약성을 찾고 식별된 문제를 해결합니다.
지식이 있는 코드 검토자를 찾아 놓친 문제를 찾습니다.
드라이버 검증 도구를 사용하고 코너 케이스를 포함하여 여러 입력으로 드라이버를 테스트합니다.