소스코드 보안약점 진단 // 소프트웨어 보안약점 진단 // SW 보안약점 진단과 같이 다양한 이름으로 불리는 진단 과업 중 하나이다.
SW개발보안은 해킹 등 사이버공격의 원인인 보안약점을 SW개발단계에서 사전에 제거하고 SW 개발 생명주기의 각 단계별로 수행하는 일련의 보안활동을 통하여 안전한 SW를 개발·운영하기 위한 목적으로 적용하는 개발체계이다.
해당 내용은 KISA에서 발간하는 취약점 진단 가이드 항목을 기준으로 작성한다.
제2절 보안기능
보안기능(인증, 접근제어, 기밀성, 암호화, 권한관리 등)을 부적절하게 구현시 발생할 수 있는 보안 약점으로 적절한 인증 없는 중요기능 허용, 부적절한 인가 등이 포함된다.
9. 적절하지 않은 난수값 사용
가. 개요
예측 가능한 난수를 사용하는 것은 시스템에 보안약점을 유발한다. 예측 불가능한 숫자가 필요한 상황 에서 예측 가능한 난수를 사용한다면, 공격자는 SW에서 생성되는 다음 숫자를 예상하여 시스템을 공격하는 것이 가능하다.
나. 보안대책
컴퓨터의 난수발생기는 난수 값을 결정하는 시드(Seed)값이 고정될 경우, 매번 동일한 난수값이 발생한다. 이를 최대한 피하기 위해 Java에서는 Random()과 Math.random() 사용 시 java.util. Random 클래스에서 기본값으로 현재시간을 기반으로 조합하여 매번 변경 되는 시드(Seed)값을 사용하며, C에서는 rand()함수 사용 시 매번 변경되는 기본 시드(Seed)값이 없으므로, srand()를 통해 매번 변경되는 현재시간 기반 등으로 시드(Seed)값을 설정 하여야 한다.
그러나 세션 ID, 암호화키 등 보안결정을 위한 값을 생성하고 보안결정을 수행하는 경우에는, Java 에서 Random()과 Math.random()을 사용 하지 말아야 하며, 예측이 거의 불가능하게 암호학적으로 보호된 java.security.SecureRandom 클래스를 사용하는 것이 안전하다.
다. 코드예제
- 안전하지 않은 코드의 예 JAVA -
java.util.Random 클래스의 random() 메소드 사용시, 고정된 seed를 설정하면 동일한 난수 값이 생성되어 안전하지 않다. 매번 변경되는 seed를 설정하더라도 보안결정을 위한 난수 이용시에는 안전하지 않다.
1: import java.util.Random;
2: ...
3: public Static int getRandomValue(int maxValue) {
//고정된 시드값을 사용하여 동일한 난수값이 생성되어 안전하지 않다.
4: Random random = new Random(100);
5: return random.nextInt(maxValue);
6: }
7: public Static String getAuthKey() {
//매번 변경되는 시드값을 사용하여 다른 난수값이 생성되나 보안결정을 위한 난수로는
안전하지 않다.
8: Random random = new Random();
9: String authKey = Integer.toString(random.nextInt());
- 안전한 코드의 예 JAVA -
java.util.Random 클래스는 setSeed를 통해 매번 변경되는 시드값을 설정 하거나, 현재 시간 기반으로 매번 변경되는 별도 seed를 설정하지 않는 기본값을 사용한다. 보안결정을 위해 난수 사용시에는 java.security.SecureRandom 클래스를 사용하는 것이 보다 안전하다.
1: import java.util.Random;
2: import java.security.SecureRandom;
3: ...
4: public Static int getRandomValue(int maxValue) {
//setSeed를 통해 매번 변경되는 시드값을 설정 하거나, 기본값인 현재 시간 기반으로 매번
변경되는 시드값을 사용하도록 한다.
5: Random random = new Random();
6: return random.nextInt(maxValue);
7: }
8: public Static String getAuthKey() {
//보안결정을 위한 난수로는 예측이 거의 불가능하게 암호학적으로 보호된 SecureRandom을
사용한다.
9: try{
10: SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
11: MessageDigest digest = MessageDigest.getInstance("SHA-256");
12: secureRandom.setSeed(secureRandom.generateSeed(128));
13: String authKey = new String(digest.digest((secureRandom.nextLong() + "").getBytes()));
14: ...
15: } catch (NoSuchAlgorithmException e) {
라. 진단방법
Math.random() 메소드를 사용하는지 확인한다.(①), Math.random()을 사용하는 경우 취약하다. 난수값을 세션ID로 설정하여 보안결정에 사용하는지 확인한다(②). 보안 결정인 경우 java.security. SecureRandom을 사용하면 안전하다.
1: …
2: public void setSessionID() {-------------------------------②
3: if (!Get_Cookie(‘SessionID’))
4: Set_Cookie(‘SessionID’,Math.random());-------------------------①
5: }
- 정탐코드의 예 -
Math.random() 함수를 사용하여 난수 값을 발생시켰을 경우 취약하다
1: public static int[] insertRandom(int[] Cnt, int i ,int scope) {
2: int ran = (int) (Math.random() * scope) - 1;
3: if (checkDigit(ran,Cnt)) {
4: Cnt[i] = ran;
5: } else {
6: insertRandom(Cnt,i,scope);
7: }
8: return Cnt;
9: }
- 오탐코드의 예 -
자체 랜덤 키 생성으로 취약점 보완하는 경우, 즉 다음의 예제와 같이 Date 요소들로 취약점을 보완 하는 경우는 안전하다고 판정한다
1: 1: long rand = ((r.nextLong()>>>1)%( endDate.getTimeInMillis()-beginDate.getTimeInMillis() + 1)) + beginDate.getTimeInMillis();
'보안 공부 > 소스코드 보안약점 진단' 카테고리의 다른 글
소스코드 보안약점 진단 - 사용자 하드디스크에 저장되는 쿠키를 통한 정보노출 (0) | 2022.01.17 |
---|---|
소스코드 보안약점 진단 - 취약한 비밀번호 허용 (0) | 2022.01.14 |
소스코드 보안약점 진단 - 충분하지 않은 키 길이 사용 (0) | 2022.01.11 |
소스코드 보안약점 진단 - 하드코드된 비밀번호 (0) | 2022.01.10 |
소스코드 보안약점 진단 - 중요정보 평문전송 (0) | 2022.01.07 |