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

소스코드 보안약점 진단 - 반복된 인증시도 제한 기능 부재

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

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

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

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

 

제2절 보안기능

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


16. 반복된 인증시도 제한 기능 부재

가. 개요

일정 시간 내에 여러 번의 인증을 시도하여도 계정잠금 또는 추가 인증 방법 등의 충분한 조치가 수행되지 않는 경우, 공격자는 예상 ID와 비밀번호들을 사전(Dictionary)으로 만들고 무차별 대입(brute-force)하여 로그인 성공 및 권한획득이 가능하다.

나. 보안대책

인증시도 횟수를 적절한 횟수로 제한하고 설정된 인증실패 횟수를 초과했을 경우 계정을 잠금하거나 추가적인 인증과정을 거쳐서 시스템에 접근이 가능하도록 한다.

다. 코드예제

다음 예제는 로그인 정보를 잘못 입력하였을 경우 다시 입력을 시도하는데 있어 제한이 없다. 따라서 공격자는 여러 가지 비밀번호로 인증을 재시도하여 올바른 비밀번호를 알아내고 로그인에 성공할 수 있다.

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

1: private static final String SERVER_IP = "127.0.0.1";
2: private static final int SERVER_PORT = 8080;
3: private static final int FAIL = -1;
4: public void login() {
5: String username = null;
6: String password = null;
7: Socket socket = null;
8: in t result = FAIL;
9: try {
10: socket = new Socket(SERVER_IP, SERVER_PORT);
//인증 실패에 대해 제한을 두지 않아 안전하지 않다.
11: while (result == FAIL) {
12: ...
13: result = verifyUser(username, password);
14: }
15: }

 

- 안전한 코드의 예 JAVA -

다음 예제는 사용자 인증시도 횟수를 기록하는 MAX_ATTEMPTS 변수를 정의하고, 이를 인증시도 횟수를 제한하는 카운터로 사용함으로써 무차별 공격에 대응하는 코드이다.

1: private static final String SERVER_IP = "127.0.0.1";
2: private static final int SERVER_PORT = 8080;
3: private static final int FAIL = -1;
4: private static final int MAX_ATTEMPTS = 5;
5: public void login() {
6: String username = null;
7: String password = null;
8: Socket socket = null;
9: int result = FAIL;
10: int count = 0;
11: try {
12: socket = new Socket(SERVER_IP, SERVER_PORT);
//인증 실패 및 시도 횟수에 제한을 두어 안전하다.
13: while (result == FAIL && count < MAX_ATTEMPTS) {
14: ...
15: result = verifyUser(username, password);
16: count++;
17: }
18: }

 

라. 진단방법

인증을 위한 함수를 호출하는 경우, 이 함수의 호출 횟수를 확인하고 함수의 호출을 제한하는 코드가 존재하는지 확인한다. 그렇지 않은 경우는 취약하다고 판단한다.

다음 예제는 인증을 시도를 할 때, 인증 시도에 대한 제한 없이 반복문 안에서 계속 인증 시도를 하는 코드이다. 인증 시도 회수에 대한 검사 루틴이 존재하지 않으므로 보안약점이 존재하는 코드라고 진단할 수 있다.

1: int validateUser(char *host, int port)
2: {
3: int socket = openSocketConnection(host, port);
4: if (socket < 0)
5: {
6: printf(“Unable to open socket connection”);
7: return(FAIL);
8: }
9:
10: int isValidUser = 0;
11: char username[USERNAME_SIZE];
12: char password[PASSWORD_SIZE];
13: while (isValidUser == 0)
14: {
15: if (getNextMessage(socket, username, USERNAME_SIZE) > 0)
16: {
17: if (getNextMessage(socket, password, PASSWORD_SIZE) > 0)
18: {
19: isValidUser = AuthenticateUser(username, password);
20: }
21: }
22: }
23: return(SUCCESS);
24: }
728x90
반응형