1580, 5/79 회원가입  로그인  
   twinz
   - [보안팁] 프로그래밍 코드보호 (2)

http://www.hackerschool.org/HS_Boards/zboard.php?id=Free_Lectures&no=845 [복사]


5. Crypto 코드 주의
이제 우리가 잘 알고 있는 사항에 대해 살펴봅니다. 우리가 검토하는 보안 코드의 30% 이상에 보안상의 결함이 있습니다. 가장 일반적인 결함은 현지 암호화 코드로서 이 코드는 대체로 매우 취약하여 공격당하기 쉽습니다. 사용자 자신의 암호화 코드를 올바르게 사용할 수 없으므로 작성하지 말아야 합니다. 사람들이 이해하지 못하는 암호화 알고리즘을 작성했기 때문은 아닙니다. 공격자들은 디버거에 액세스하고 시간 및 지식을 들여 시스템이 정확히 어떻게 작동하는지 결정하며 몇 시간만에 시스템을 공격하는 경우가 있습니다. 따라서 Win32 응용 프로그램용 CryptoAPI를 사용하여 System.Security.Cryptography 네임스페이스에 제대로 작성되고 올바르게 테스트된 암호화 알고리즘이 있도록 해야 합니다.
6. 사용자의 공격 프로필 감소
클라이언트 중 90%가 필요로 하지 않는 기능은 기본적으로 설치되어서는 안됩니다. 인터넷 정보 서비스(IIS) 6.0은 이러한 설치 계획을 따릅니다. 이에 대한 자세한 내용은 이달에 발행된 Wayne Berry의 기사 "Innovations in Internet Information Services Let You Tightly Guard Secure Data and Server Processes"를 참조하십시오. 이 설치 방법 이면에 있는 생각은 사용하지 않는 서비스를 실행하여 사용자가 관심을 두지 않는 서비스를 활용할 수 있다는 것입니다. 이 기능이 기본적으로 설치된 경우, 최소한의 권한 원칙 아래 작동되어야 합니다. 다시 말해, 관리 권한이 필요하지 않으면 관리 권한으로 응용 프로그램을 실행할 필요는 없습니다. 이 주의 사항을 유념해야 합니다.
7. 최소한의 권한 원칙 사용
운영 체제 및 공용 언어 런타임(CLR)에는 몇 가지 이유로 인한 보안 정책이 있습니다. 많은 사람들이 보안 정책이 존재하는 이유는 사용자가 의도적으로 유해한 일 즉, 액세스가 허용되지 않는 파일에 액세스하고 필요에 따라 임의로 네트워크를 재구성하거나 기타 유해한 행위를 하지 못하도록 방지하는 것이라고 생각합니다. 일반적인 내부 공격을 방지해야 한다는 것도 한 가지 이유가 될 수 있지만 보안 정책을 강력히 유지해야 하는 또 다른 이유가 있습니다. 보안 정책은 코드 주변에 방어벽을 쌓아 사용자가 고의 또는 흔히 실수로 네트워크에 해를 주지 않도록 하는 것입니다. 예를 들어, Alice라는 사람의 시스템에서 전자 메일을 통해 다운로드하여 실행한 첨부 파일은 Alice가 액세스할 수 있는 리소스에만 액세스할 수 있도록 제한됩니다. 첨부 파일에 트로이 목마가 있는 경우 좋은 보안 정책이 시스템의 손상을 제한하게 됩니다.
서버 응용 프로그램을 설계, 작성 및 배포할 때, 적합한 사용자만 요청을 보낼 수 있는 것은 아닙니다. 공격자가 악의를 가지고 잘못된 요청을 보내면 사용자의 코드가 오동작을 일으키는 경우, 사용자는 손상을 제한하기 위해 응용 프로그램에 가능한 모든 방어벽을 쌓아야 합니다. 회사가 보안 정책을 실행하는 이유가 그저 사용자 또는 사용자의 코드를 신뢰하지 않기 때문만이 아니라는 것입니다. 외부인에 의해 이용되는 코드에 대해 보호하려는 목적도 있습니다.
최소한의 권한 원칙이란 주어진 권한은 최소한 필요한 만큼의 시간동안 최소한 필요한 만큼의 코드에만 허용되어야 한다는 것입니다. 다시 말해, 언제든지 지정된 시간에 가능한 코드에 방어벽을 많이 쌓아야 합니다. 문제가 발생했을 때 미리 쌓아놓은 이러한 방어벽이 도움이 될 것입니다. 따라서 최소한의 권한으로 코드를 실행하는 데 대한 몇 가지 구체적인 생각을 설명하겠습니다.
작업을 완료하는 데 필요한 리소스에만 액세스를 허용하는 서버 코드에 대한 보안 컨텍스트를 선택합니다. 일부 코드에 더 많은 권한이 필요하면 해당 코드를 계수화하여 더 높은 수준의 권한으로 실행합니다. 다른 운영 체제 자격 증명으로 실행하는 코드를 안전하게 분리하려면 더 많은 권한이 부여된 보안 컨텍스트에서 실행되는 별도의 프로세스로 이 코드를 실행하면 됩니다. 즉, COM 또는 Microsoft .NET 원격 등과 같은 프로세스 간 통신이 필요하며 최소한의 왕복을 유지하기 위해 해당 코드에 대한 인터페이스를 디자인해야 합니다.
.NET Framework를 사용하여 코드를 어셈블리에 계수화하는 경우, 각 코드 조각에 필요한 수준의 권한을 고려해야 합니다. 높은 권한이 필요한 코드를 더 많은 사용 권한을 허용할 수 있는 별도의 어셈블리에 쉽게 분리할 수 있습니다. 이렇게 하면 적은 권한으로도 대부분의 어셈블리를 실행할 수 있어 코드에 더 많은 방어벽을 추가할 수 있습니다. 그림 1과 같이 어셈블리 수준 사용 권한 요청을 통해 특정 어셈블리의 권한을 쉽게 제한할 수 있습니다. 그림 2는 이러한 사용 권한 요청에 사용하는 XML 파일을 작성하는 방법을 보여줍니다. 이 작업을 하는 경우, 코드 액세스 보안(CAS) 스택 워크로 인해 사용자 자신의 어셈블리의 사용 권한만 제한하는 것이 아니라 호출한 모든 어셈블리의 사용 권한도 제한하는 것입니다.
많은 사람들이 제품이 테스트되고 배달된 후에 새로운 구성 요소가 플러그 인될 수 있도록 응용 프로그램을 작성합니다. 버그 및 보안 허점을 찾기 위해 모든 코드 경로를 테스트할 수 있는 방법은 없기 때문에 이러한 응용 프로그램을 보호하는 것은 매우 어려운 일입니다. 하지만 응용 프로그램이 관리되는 경우에는 CLR이 제공하는 기능을 사용하여 이러한 확장성을 잠급니다. 사용 권한 개체 또는 사용 권한 집합을 선언하고 PermitOnly 또는 Deny를 호출하여, 호출하는 모든 코드에 허용된 사용 권한을 제한하는 스택에 표식을 추가합니다. 일부 플러그 인을 호출하기 전에 이 작업을 실행하여 플러그 인이 할 수 있는 작업을 제한할 수 있습니다. 예를 들어, 지불 계산을 해야 하는 플러그 인은 파일 시스템에 액세스할 필요가 없습니다. 이것은 최소한의 권한의 다른 예로서 사용자 자신을 미리 보호할 수 있습니다. 이러한 제한 사항을 문서화하고 많은 권한이 주어진 플러그 인은 어셜션 문이 있는 이러한 제한을 극복할 수 있다는 것을 명심해야 합니다.
8. 실패 모드에 주의
오류 처리 코드를 작성하기 싫어하는 것을 인정해야 합니다. 코드가 실패하는 경우는 많습니다. 코드가 실패하면 실망하는 것은 당연한 것입니다. 우리 자신을 포함해서 대부분의 프로그래머들은 일반적인 실행 경로에 초점을 맞추려 합니다. 실제 작업이 그 곳에서 이루어지기 때문입니다. 가능한 신속하고 손쉽게 오류를 처리한 다음 실제 코드의 다음 줄로 이동하는 것은
아쉽게도 안전한 사고 방식이 아닙니다. 우리는 코드의 실패 모드에 많은 주의를 기울여야 합니다. 이러한 코드 조각들은 세부적인 사항에 주의를 기울이지 않고 작성한 것으로서 완전히 테스트되지 않습니다. 모든 사소한 오류 처리기를 포함하여 함수의 모든 코드 줄에서 디버거를 단계별로 실행한 때가 마지막으로 언제인지 생각해 보십시오.
테스트되지 않은 코드는 보안 취약성을 유발시킬 수 있습니다. 이 문제를 완화할 수 있는 세 가지 방법이 있습니다. 첫째, 일반 코드에 대해 많은 신경을 쓰는 만큼 사소한 오류 처리기에도 많은 관심을 두어야 합니다. 오류 처리 코드가 실행되었을 때의 시스템 상태를 생각해 보십시오. 시스템을 보안 상태로 두시겠습니까  둘째, 함수를 작성하면 함수에서 단계별로 디버거를 실행하여 모든 오류 처리기를 확실히 찾아야 합니다. 이 기술로도 미묘한 시간 오류는 해결하지 못할 수도 있습니다. 유해한 인수를 함수에 전달하거나 오류 처리기를 실행하도록 하는 방법으로 시스템 상태를 조정해야 하는 경우도 있습니다. 충분한 시간적 여유를 가지고 코드를 단계별로 실행하여, 시스템이 실행될 때 시스템 상태 및 코드를 천천히 살펴보십시오. 디버거의 코드를 단계별로 실행하여 프로그래밍 논리에서 많은 결함을 찾아 왔습니다. 따라서 이 기술은 입증된 기술입니다. 이 기술을 사용하십시오. 셋째, 테스트로 인해 함수가 실패하도록 하십시오. 테스트가 함수에 있는 모든 코드 줄마다 실행하도록 하십시오. 이러한 작업을 통해, 특히 테스트를 자동화하여 모든 빌드 후에 실행하면 회귀를 찾는 데 도움이 됩니다.
실패 모드에 대한 매우 중요한 사실이 하나 더 있습니다. 코드가 실패할 경우, 시스템은 최상의 보안 상태에 있게 됩니다. 다음은 유해 코드의 예입니다.
bool accessGranted = true; // 낙관적
try {
    // c:test.txt에 액세스했는지 확인합니다.
    new FileStream(@"c:test.txt",
                    FileMode.Open,
                    FileAccess.Read).Close();
}
catch (SecurityException x) {
    // 액세스가 거부되었습니다.
    accessGranted = false;
}
catch (...) {
    // 다른 일이 발생했습니다.
}

CLR의 경우 해당 파일에 대한 액세스를 허용했다고 가정해 봅시다. 이 경우, SecurityException이 throw되지 않습니다. 하지만 파일의 임의 액세스 컨트롤 목록(DACL)에 액세스할 수 없는 경우를 예로 들어 봅시다. 이러한 경우 다른 유형의 예외가 throw됩니다. 하지만 첫 번째 코드 줄에서 낙관적 가정을 했기 때문에 이 사실을 알 수가 없습니다.
더 좋은 방법은 이 코드를 비관적으로 작성하는 것입니다.
bool accessGranted = false; // 비관적
try {
    // c:test.txt에 액세스했는지 확인합니다.
    new FileStream(@"c:test.txt",
                    FileMode.Open,
                    FileAccess.Read).Close();
     // 이 모드에 계속 있는 경우 성공한 것입니다.      
    accessGranted = true;
}
catch (...) {}

이 방법은 실패를 하더라도 가장 안전한 모드로 다시 이동하기 때문에 훨씬 더 확실한 방법입니다.
9. 취약한 가장
서버 응용 프로그램을 작성할 때 가장이라고 하는 Windows의 편리한 기능을 직접적으로나 간접적으로 사용하는 경우가 있습니다. 가장이라는 기능을 사용하면 프로세스의 각 스레드를 별도의 보안 컨텍스트(일반적으로 클라이언트의 보안 컨텍스트)에서 실행할 수 있습니다. 예를 들어, 파일 시스템 리디렉터가 네트워크를 통해 파일 요청을 받으면, 파일 시스템 리디렉터가 원격 클라이언트를 인증하고 클라이언트의 요청이 공유 DACL에 위배되지 않는지 확인한 다음, 요청을 처리하는 스레드에 클라이언트 토큰을 첨부하여 클라이언트를 가장합니다. 이 스레드는 클라이언트의 보안 컨텍스트를 사용하여 서버의 로컬 파일 시스템에 액세스할 수 있습니다. 이 방법은 로컬 파일 시스템이 안전하게 되므로 편리합니다. 또한 요청할 액세스 유형, 파일의 DACL, 스레드의 가장 토큰을 고려하여 액세스 확인을 합니다. 액세스 확인이 실패하면 로컬 파일 시스템은 이 사항을 파일 시스템 리디렉터에게 보고합니다. 파일 시스템 리디렉터는 이 결함을 다시 원격 클라이언트에게 보냅니다. 이 기능은 로컬 파일 시스템에 책임을 전가하여 마치 클라이언트가 로컬인 것처럼 로컬 파일 시스템이 액세스 확인을 하도록 하기 때문에 파일 시스템 리디렉터에게는 매우 편리한 기능입니다.
이 기능은 파일 시스템 리디렉터와 같은 간단한 게이트웨이에 유용합니다. 하지만, 가장은 좀 더 복잡한 응용 프로그램에서 다르게 사용되는 경우가 있습니다. 웹 응용 프로그램을 예로 들어 봅시다. Web.config 파일에 아래와 같이 지정하는 관리되지 않는 기본 ASP 응용 프로그램, ISAPI 확장명 또는 ADP.NET 응용 프로그램을 작성하는 경우이다

출저 - songhs33 님의블로그

  Hit : 7491     Date : 2007/08/28 10:55



    
1500   - [리눅스팁] 리눅스 자동실행     twinz
08/28 7587
1499   - [보안팁] 프로그래밍 코드보호 (1)     twinz
08/28 9904
  - [보안팁] 프로그래밍 코드보호 (2)     twinz
08/28 7490
1497   - [보안팁] 리눅스     twinz
08/28 7289
1496   - [보안노트] 쿠키[4]     twinz
08/28 8604
1495   - [보안노트] 포트스캐닝 (1)     twinz
08/28 7591
1494   - [보안노트] 포트스캐닝 (2)     twinz
08/28 9001
1493   - [보안노트] 봇[1]     twinz
08/28 7219
1492   - 컴퓨터 바이러스의 종류[1]     twinz
08/27 8223
1491   - 다이하드 4.0 파이어세일 현실 가능[2]     twinz
08/25 8214
1490   - 도청 , 해킹 불가능한 세상이온다     twinz
08/25 7560
1489   - 백업명령어의 종류     twinz
08/27 8662
1488   - 무시되는 오프 스탠더드보안     twinz
08/27 6623
1487   - 서버관리자를 위한 50가지 비법     twinz
08/27 8790
1486   - 시스템 보안     twinz
08/27 6638
1485   - 어셈블리어 1[1]     twinz
08/27 8531
1484   - 어셈블리어 2     twinz
08/27 8387
1483   - 어셈블리어 3[1]     twinz
08/27 6622
1482   0번섹터 베드섹터일경우..[2]     ROK.AF
03/02 7552
1481   1[1]     백민준천재
08/31 4346
[1][2][3][4] 5 [6][7][8][9][10]..[79]

Copyright 1999-2023 Zeroboard / skin by Hackerschool.org / Secure Patch by Hackerschool.org & Wowhacker.com