보안 공부/소스코드 보안약점 진단

소스코드 보안약점 진단 - 취약한 암호화 알고리즘 사용

H.J.World 2022. 1. 5. 10:10
728x90
반응형

소스코드 보안약점 진단 // 소프트웨어 보안약점 진단 // SW 보안약점 진단과 같이 다양한 이름으로 불리는 진단 과업 중 하나이다.

SW개발보안은 해킹 등 사이버공격의 원인인 보안약점을 SW개발단계에서 사전에 제거하고 SW 개발 생명주기의 각 단계별로 수행하는 일련의 보안활동을 통하여 안전한 SW를 개발·운영하기 위한 목적으로 적용하는 개발체계이다.

해당 내용은 KISA에서 발간하는 취약점 진단 가이드 항목을 기준으로 작성한다.

 

제2절 보안기능

보안기능(인증, 접근제어, 기밀성, 암호화, 권한관리 등)을 부적절하게 구현시 발생할 수 있는 보안 약점으로 적절한 인증 없는 중요기능 허용, 부적절한 인가 등이 포함된다.


4. 취약한 암호화 알고리즘 사용

가. 개요

SW 개발자들은 환경설정 파일에 저장된 패스워드를 보호하기 위하여 간단한 인코딩 함수를 이용 하여 패스워드를 감추는 방법을 사용하기도 한다. 그렇지만 base64와 같은 지나치게 간단한 인코딩 함수로는 패스워드를 제대로 보호할 수 없다. 정보보호 측면에서 취약하거나 위험한 암호화 알고리즘을 사용해서는 안 된다.

표준화되지 않은 암호 화 알고리즘을 사용하는 것은 공격자가 알고리즘을 분석하여 무력화시킬 수 있는 가능성을 높일 수도 있다. 몇몇 오래된 암호화 알고리즘의 경우는 컴퓨터의 성능이 향상됨에 따라 취약해지기도 해서, 예전에는 해독하는데 오랜 시간이 걸릴 것이라고 예상되던 알고리즘이 며칠이나 몇 시간 내에 해독 되기도 한다. RC2, RC4, RC5, RC6, MD4, MD5, SHA1, DES 알고리즘이 여기에 해당된다.

나. 보안대책

자신만의 암호화 알고리즘을 개발하는 것은 위험하며, 학계 및 업계에서 이미 검증된 표준화된 알고 리즘을 사용한다. 기존에 취약하다고 알려진 DES, RC5 등의 암호알고리즘을 대신하여, 3DES, AES, SEED 등의 안전한 암호알고리즘으로 대체하여 사용한다. 또한, 업무관련 내용, 개인정보 등에 대한 암호 알고리즘 적용시, IT보안인증 사무국이 안전성을 확인한 검증필 암호모듈을 사용해야한다.

다. 코드예제

다음 예제는 취약한 DES 알고리즘으로 암호화하고 있다.

- 안전하지 않은 코드의 예 JAVA -

1: import java.security.*;
2: import javax.crypto.Cipher;
3: import javax.crypto.NoSuchPaddingException;
4: public class CryptoUtils {
5: public byte[] encrypt(byte[] msg, Key k) {
6: byte[] rslt = null;
7: try {
//키 길이가 짧아 취약함 암호와 알고리즘인 DES를 사용하여 안전하지 않다.
8: Cipher c = Cipher.getInstance("DES");
9: c.init(Cipher.ENCRYPT_MODE, k);
10: rslt = c.update(msg);
11: }

 

- 안전한 코드의 예 JAVA -

아래 코드처럼 안전하다고 알려진 AES 알고리즘 등을 적용해야 한다.

1: import java.security.*;
2: import javax.crypto.Cipher;
3: import javax.crypto.NoSuchPaddingException;
4: public class CryptoUtils {
5: public byte[] encrypt(byte[] msg, Key k) {
6: byte[] rslt = null;
7: try {
//키 길이가 길어 강력한 알고리즘인 AES를 사용하여 안전하다.
8: Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
9: c.init(Cipher.ENCRYPT_MODE, k);
10: rslt = c.update(msg);
11: }

 

라. 진단방법

정적분석 도구 및 진단원이 각 언어에서 제공하는 암호화 함수가 취약한 암호화 알고리즘 사용 여부 는 확인가능하나, 자체 암호화 알고리즘을 사용하는 경우 알고리즘의 적절성 여부를 판단하는 것은 어려우며, 수동진단이 필요하다.

자체 구현한 암호화 관련 알고리즘을 사용하는지 확인하고 자체 구현한 암호알고리즘을 사용할 경우 취약함으로 판단한다. 만약, 암호전문가가 존재할 경우 해당 암호함수의 암호알고리즘의 적절성을 판단하여 보증하는 것은 가능하다.

특정언어에서 제공하는 암호관련 함수를 호출하는지 식별한다.

- 취약한 알고리즘 : RC2, RC4, RC5, RC6, MD4, MD5, SHA1, DES 등

- 안전한 알고리즘 : SHA-256, AES, SEED, ARIA 등

1: try {
2: MessageDigest md = MessageDigest.getInstance(“SHA1”);
3: md.update(msg.getBytes());
4: return md.digest();
5: } catch (NoSuchAlgorithmException e) {

 

- 정탐코드의 예 -

패스워드를 Base64로 인코딩하여 configuration 파일에 저장한 경우이다. Base64 인코딩 기법 자체가 가지는 취약점 때문에 이 경우 패스워드를 안전하게 보호할 수 없다.

Base64 encoding의 경우는 암호화가 아닌 인코딩이다. 개발 시 Base64 encoding을 사용하는 경우는 암호화 목적이 아닌 가시성과 보관성을 위해서이다. 그러므로 Base64 encoding을 사용 하였을 때 취약한 암호화 알고리즘이라 하기 어렵다. 하지만 개발자가 암호화를 위해 Base64 encoding 을 사용하였다면 취약하다고 판정한다.

1: public boolean DBConnect() {
2: String url = “DBServer”;
3: String usr = “Scott”;
4: Connection con = null;
5:
6: FileInputStream fis = null;
7: try {
8: Properties prop = new Properties();
9: fis = new FileInputStream(“config.properties”);
10:
11: // 패스워드를 64bit로 decoding한다.
12: byte password[] = Base64.decode(prop.getProperty(“password”));
13:
14: // 유효성 점검없이 패스워드를 문자열로 읽는다.
15: con = DriverManager.getConnection(url, usr, password.toString());
16: } catch (FileNotFoundException e) {
17: …
18: } catch (SQLException e) {
19: …
20: }

 

- 정탐코드의 예 -

MD5 등의 낮은 보안 수준의 알고리즘을 사용하는 경우는 안전하지 않다.

1: public static EgovFormBasedUUID nameUUIDFromBytes(byte[] name) {
2: MessageDigest md = null;
3: try {
4: md = MessageDigest.getInstance(“MD5”);
5: } catch (NoSuchAlgorithmException e) {
6: throw new InternalError(“MD5 not supported”);
7: }
8: byte[] md5Bytes = md.digest(name);
9: md5Bytes[6] &= 0x0f; /* clear version */
10: md5Bytes[6] |= 0x30; /* set to version 3 */
11: md5Bytes[8] &= 0x3f; /* clear variant */
12: md5Bytes[8] |= 0x80; /* set to IETF variant */ 
13: return new EgovFormBasedUUID(md5Bytes); 
14: }

 

728x90
반응형