메인 콘텐츠로 건너뛰기
블로그컴퓨팅로그인 API 무차별 대입 공격 방어하기

로그인 API 무차별 대입 공격 방어하기

다음 텍스트가 포함된 빨간색 블록 기호입니다: "로그인 API 무차별 대입 공격 방어: 방심하면 무력화될 수 있기 때문입니다."

중요한 릴리스 마감일을 맞추기 위해 서두르다 보면 대충 일을 처리하게 됩니다. 테스트 커버리지가 엉망이 되고, 코드가 엉망이 되고, 예외 처리는 기술 부채의 무덤, 즉 백로그로 보내집니다. 우리 모두 경험해 보셨을 겁니다.

그러나 비용을 절감해야 할 때 '최대 로그인 시도 실패 횟수' 보호 기능을 구현하는 것을 포기해서는 안 됩니다. 로그인 API에 적절한 안전 장치가 마련되어 있지 않은 경우, 요즘에는 무차별 대입을 통해 사용자 계정에 액세스하는 것이 비교적 쉽습니다.

이 글에서는 공격자가 로그인 API를 무차별 대입하는 방법을 보여드리겠습니다. 그런 다음 시스템을 방어하기 위해 취할 수 있는 대응책에 대해 설명합니다.

로그인 API 예시

데모를 위해 Node.js 및 Express를 사용하여 매우 기본적인 API 서버를 구축했습니다. 이 서버는 단일 엔드포인트에 대한 POST 요청을 수신 대기합니다, /login. 요청 본문에는 usernamepassword. 자격 증명이 성공적으로 제공되면 API는 다음을 반환합니다. 200 OK. 그렇지 않으면 반환됩니다. 401 UNAUTHORIZED.

다음은 간단한 Express 서버의 코드입니다:

const express = require('express');
const users = require('./users.json');

const app = express();
const PORT = 3000;

// Middleware to parse JSON bodies
app.use(express.json());

app.post('/login', (req, res) => {
    const { username, password } = req.body;

    // Check if the username exists and the password matches
    if (users[username] && users[username] === password) {
        return res.status(200).send('OK');
    } else {
        return res.status(401).send('UNAUTHORIZED');
    }
});

// Start the server
app.listen(PORT, () => {
    console.log(`Server is listening on port ${PORT}`);
});

이 간단한 데모에서는 사용자 이름과 비밀번호 목록을 다음과 같은 파일에 보관합니다. users.json.

리노드에 서버를 배포하고 포트에서 수신 대기 중입니다. 3000. 요청을 시도해 보겠습니다:

~$ curl -i \        -X POST \        --header "Content-type:application/json" \        --data '{"username":"user08","password":"testpassword"}' \         172.233.153.34:3000/login

HTTP/1.1 401 UnauthorizedX-Powered-By: ExpressContent-Type: text/html; charset=utf-8Content-Length: 12ETag: W/"c-MvHJP5yPj49I/9tX+wGrvHWbTRk"Date: Sat, 25 May 2024 19:17:34 GMTConnection: keep-aliveKeep-Alive: timeout=5
UNAUTHORIZED

로그인 API가 실행 중입니다!

이제 API를 무차별 대입하고 싶다면 다음과 같은 스크립트를 작성할 수 있습니다:

#!/bin/sh

API_ENDPOINT="http://172.233.153.34:3000/login"

USERNAME="user5"

echo "Attempting to login at $API_ENDPOINT as \"$USERNAME\""

for i in {1..8}
do
  PASS="password${i}"
  RESULT=$(curl --silent -X POST --header "Content-type:application/json" --data "{\"username\":\"$USERNAME\",\"password\":\"$PASS\"}" $API_ENDPOINT)
  echo "\"$PASS\": $RESULT"

  if [[ $RESULT == 'OK' ]]; then
    echo "!!! Password for \"$USERNAME\" found: \"$PASS\""
    break
  else
    sleep 1
  fi
done

초보적인 무차별 대입 스크립트를 실행하면 다음과 같이 표시됩니다:

$ source bruteforce.sh
Attempting to login at http://172.233.153.34:3000/login as "user5"
"password1": UNAUTHORIZED
"password2": UNAUTHORIZED
"password3": UNAUTHORIZED
"password4": UNAUTHORIZED
"password5": OK
!!! Password for user5 found: "password5"

공격자가 정말 비밀번호를 추측할 수 있나요?

따라서 주어진 사용자 아이디에 대해 최소한 몇 가지 비밀번호를 순환할 수 있는 스크립트를 작성하는 것이 얼마나 쉬운지 살펴봤습니다. "흥미로운 인위적인 예시네요. 하지만 공격자가 정말 비밀번호를 추측할 수 있을까요?"라고질문할수 있습니다.

다음은 가장 일반적인 비밀번호 10,000개의 목록입니다. 공격자 입장에서는 꽤나 좋은 출발점입니다. 'password123'이나 '쿼티'를 사용하는 사람을 본 적이 있나요? 여러분일 수도 있습니다!

공격자가 시스템의 사용자 이름 몇 개를 알고 있고 이러한 일반적인 비밀번호를 반복하는 스크립트를 실행하면 공격에 성공할 수 있습니다.

사용자 아이디와 비밀번호 조합을 시도할 때마다 계정이 유출될 가능성이 높아집니다.

이는 인증이 깨지는 대표적인 사례로, OWASP 상위 10가지 API 보안 위험 중 2위를 차지합니다. 애플리케이션이 자동화된 공격으로부터 제대로 보호하지 못한다면 문제가 발생할 수 있습니다. 안전장치가 없으면 사용자 계정이 심각한 위험에 처하게 됩니다.

비밀번호는 시스템 보안에서 가장 취약한 고리인 경우가 많습니다:

  • 사용자는 여러 사이트에서 비밀번호를 재사용합니다.
  • 사용자는 기억하기 쉽고 추측하기 쉬운 비밀번호를 선택합니다.
  • 사용자는 비밀번호를 거의 업데이트하지 않습니다.

이러한 모든 요소가 무차별 대입 공격의 무서운 효과를 만들어냅니다.

다시 질문으로 돌아가 보겠습니다: 공격자가 정말 비밀번호를 추측할 수 있을까요? 물론입니다. 그리고 적절한 예방 조치를 취하지 않는다면 생각보다 더 빨리 유출될 수 있습니다.

API를 보호하려면 어떻게 해야 하나요?

로그인 API에 대한 무차별 암호 대입 공격을 방어하는 방법에는 여러 가지가 있습니다.

최대 로그인 실패 시도 횟수 설정하기

각 사용자에게 허용할 로그인 실패 횟수에 제한을 설정합니다. 사용자에 대한 로그인 시도가 발생하면 로그인 실패 횟수를 계속 기록합니다. 이 한도에 도달하면 계정을 일시적으로 잠그거나 발신자의 IP 주소로부터의 후속 요청을 차단하세요. 이렇게 하면 공격자가 무차별 암호 대입을 통해 침입하기가 훨씬 어려워집니다.

웹 애플리케이션 방화벽(WAF) 사용

WAF는 악성 활동을 탐지하고 차단하여 API를 보호하는 데 도움이 될 수 있습니다.

  • 봇 활동: 우수한 WAF는 합법적인 사용자와 봇을 구분하여 자동화된 무차별 대입 공격을 차단할 수 있습니다.
  • 토르 배후에서 의심스러운 로그인 요청: 많은 공격자가 자신의 신원을 숨기기 위해 토르 네트워크를 사용합니다. 토르 노드의 요청을 차단하거나 거부하면 공격의 위험을 줄일 수 있습니다.

Linode Marketplace 에서 사용할 수 있는 WAF인 Haltdos는 이러한 보호 기능 등을 제공합니다. 이러한 도구를 통합하면 API의 방어를 크게 강화할 수 있습니다.

구현 속도 제한

주어진 시간 내에 단일 IP 주소로부터의 API 요청 횟수를 제한합니다. 이렇게 하면 무차별 암호 대입 공격의 속도가 느려지고 공격의 실현 가능성이 낮아집니다. 속도 제한은 로그인 API뿐만 아니라 모든 API와 엔드포인트에 적용하는 것이 좋습니다.

다단계 인증(MFA) 사용 설정

MFA와 같은 추가 보안 계층을 추가하면 공격자가 비밀번호를 정확하게 추측하더라도 무차별 암호 대입 공격을 막을 수 있습니다. 전체 인증 과정을 성공적으로 통과하려면 사용자가 알고 있는 것(비밀번호) 가지고 있는 것(휴대폰 또는 하드웨어 토큰)이 필요합니다.

로그인 시도 모니터링 및 분석

API 요청 모니터링 솔루션을 설정하여 로그인 시도를 주시하세요. 공격을 나타낼 수 있는 패턴을 찾아보세요. 이를 통해 의심스러운 활동에 신속하게 대응할 수 있습니다.

이러한 조치를 구현하면 무차별 대입 공격으로부터 API를 보호하고 사용자 계정을 안전하게 보호할 수 있습니다.

결론

무차별 암호 대입 공격으로부터 로그인 API를 보호하는 것은 매우 중요합니다. 비밀번호를 추측하는 것은 생각만큼 어렵지 않으며, 추측을 자동화하는 것은 아주 쉬운 일입니다. 시스템이 취약한가요? 시스템을 강화하기 위해 할 수 있는 몇 가지 방법을 소개해드렸습니다. 이러한 단계를 통해 보안 태세를 크게 강화할 수 있습니다.

애플리케이션과 API를 구축하느라 정신없이 바쁘다 보면 여기저기서 손해를 보더라도 용서해 드리겠습니다. 누구나 그렇게 하죠. 하지만 로그인 API를 보호하지 않고 방치해서는 안 됩니다! 공격이 발생할 때까지 기다리지 말고 지금 바로 조치를 취하여 시스템과 사용자를 보호하세요. 로깅 및 시스템 모니터링에 대한 자세한 안내는 Linode 문서를 참조하세요. Apache 사용하여 애플리케이션을 서비스할 계획이라면 서버가 DoS/DDoS 공격으로부터 살아남을 수 있도록 mod_evasive를 구성하는 방법에 대한 가이드를 확인하세요.

안전하세요!

내용

댓글 남기기

이메일 주소는 게시되지 않습니다. 필수 필드가 표시됩니다 *