일찍이 시원 포럼 세미나에 참가해서 기업의 보안 체계와 대응은 Splunk 에서 책임진다고 들었다. 이거간다고 버스타고 난리났다.

1번빠따구리
Splunk는 ELK 역할을 같이 수행한다는 점에서 우리의 보안 솔루션의 상위 호환(...)이라는 느낌을 받았다. 하지만 굉장한 비용때문에 체급 있는 기업에서만 쓰이고 있다고 한다.
그렇다면 무거운 비용을 감당할 수 없는 기업들을 대상으로 하는 수요가 많지 않을까.
클라우드상의 웹서비스 취약점 검출 로직
간단하게 SQL Injection 취약점에 대해서 소개하고, 제품에서 어떻게 검출하도록 하는지 프로세스를 소개하겠다.
SQL prepared statement와 statement의 차이점
SQL문장을 미리 컴파일하고 실행 시간동안 인수 값을 위한 공간을 확보할 수 있다
- Statement 객체의 SQL 수행은 실행될때마다 매번 서버에서 분석해야하지만, PreparedStatement는 한번 분석되면 재사용이 용이한 장점
- 캐시 사용의 유무
- 선처리 방식의 PreparedStatement는 처음 한번만 과정(쿼리 문장 분석→컴파일→실행) 단계를 거치고, 이후는 캐싱한다.
SQL Server의 SP를 불러오거나 ‘admin”;—’ 같은 주석 처리를 통한 SQL Injection 검출 등 방법이 많기에 주기적으로 업데이트해야한다.
XSS도 마찬가지.. 이런 방식으로 취약점을 10개 가까이 분석해서 진행중이다.
취약점 검출 로직 구현 프로세스
그러니까 SQL Injection에 예시를 들자면, 일부러 statement를 통해서 요청을 보내는 시뮬레이션용 웹서버를 구현해야한다.
1. 공격한 뒤, 클라우드에서 로그를 확인하는 과정을 거친다.
2. 해당 로그를 분석해서 취약점 검출 로직을 설계한다.
3. 검증을 위해서 재차 공격 후, SIEM에서 검출되는지 확인한다.
서비스의 고가용성을 유지하기 위한 시도
AWS 클라우드의 공격으로 인한 피해는 신경 쓸 필요 없다. 클라우드 벤더사가 공격받을 정도면 나보다 벌써 넷플릭스나 배달의 민족에서 먼저 피해받았을거다...ㅎ
클라우드 서비스 공격으로 인한 피해를 걱정할 필요없다고 하는 표면적인 이유는 다음과 같다.
일단 SIEM에서 사용하는 서비스들은 분산 시스템으로 가용성을 유지하거나, 셀프힐링으로 복구하는 서비스들만 사용한다. (찾아봄)
그럼 제품(나)만 잘하면 가용성이 무너질 일은 없다는 소리인데, 어떻게 가용성을 유지할 수 있을까?
비정상적으로 제품이 종료되거나 피해를 받는 경우에도 데이터와 작업중인 내용을 잃지 않도록 하는게 최우선이다.
그래서 생각했던게 아예 작업을 배치 형태로 돌리고 대용량 데이터 처리에 용이한 방식을 고민하려 했다.
하지만..... Spring Batch는 Reactive stream을 제공하지 않는다.
직접 삽질했는데 ReactiveCrudRepository가 작업을 완료하기 전에 ItemWriter 작업이 종료되면서 Commit이 안되는거 같다.
Reactive Streams는 데이터 스트림-무한한 데이터 처리용으로 만든 것이고, 스프링 배치는 정해진 크기의 데이터를 처리하는 프레임워크이기 때문이다
Spring Batch and Reactive Streams · Issue #1008 · spring-projects/spring-batch
Christian Trutz opened BATCH-2596 and commented Hello Spring Batch team, are there any plans to incorporate Reactive Streams (https://projectreactor.io/) in Spring Batch? I think about concepts lik...
github.com
개발자가 직접 'Spring Batch에서의 반응형 지원은 실제 프레임워크의 80% 이상을 완전히 다시 작성해야하는 만큼, 도입할 수 있는 기능이 아니다' 라고 언급했으니 포기하는게 맞는거 같다.
그래서 직접 구현했다.
각 log-group에 해당하는 데이터의 작업을 얼마나 했는지 기록하는 metadata와 검출한 취약점을 각각 저장하는 데이터베이스를 구축했다.
그리고 스프링 스케쥴러를 통해 일정 시간마다 OpenSearch로 방대한 양의 데이터를 쪼개서 받아오고, 더 작은 작업 단위로 다시 쪼개서 작업을 수행하도록 했다.
어디까지 작업했는지에 대한 기록을 metadata에 기록해두고 있으므로, 비정상적인 종료에도 다시 실행하면 작업을 이어서 진행할 수 있다.
HTTP 메시지의 헤더, 본문 데이터 수집하기
아 AWS에서는 네트워크 트래픽에 대해서 헤더나 본문(body)처럼 자세한 정보는 수집하지 않는다.
굉장히 화가 나는 부분인데, ALB의 Access Logs 데이터만 CloudWatchLogs로 수집하면서 편하게 생각했다가 큰코 다치고 있다.
ALB AccessLogs는 HTTP 요청의 흐름과 성능 지표를 추적하기 위한 목적으로 제공하며 S3 서비스로 수집하도록 지원한다. 이를 통해 Lambda 함수를 이용해서 일정 기간마다 AccessLog를 수집하는 S3의 버킷에서 CloudWatch 로그 그룹으로 가져오도록 설계했다.
그렇게 받아온 데이터의 구조는 처참했다.
"GET http://www.example.com:80/ HTTP/1.1" "curl/7.46.0" - -
arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067
"Root=1-58337262-36d228ad5d99923122bbe354" "-" "-"
0 2018-07-02T22:22:48.364000Z "forward" "-" "-" "10.0.0.1:80" "200" "-" "-"
알 수 있는건 url 주소와 엔드포인트. 요청한 클라이언트의 주소 등이다. 자세한 헤더와 본문 데이터는 제공하지 않으면 여러 보안 요소를 검출해낼 수 없다.
Application Load Balancer에 대한 액세스 로그 - Elastic Load Balancing
Application Load Balancer에 대한 액세스 로그 Elastic Load Balancing은 로드 밸런서에 전송된 요청에 대한 자세한 정보를 캡처하는 액세스 로그를 제공합니다. 각 로그에는 요청을 받은 시간, 클라이언트의
docs.aws.amazon.com
Elastic Load Balancing은 최선의 노력으로 요청을 기록한다. 모든 요청을 완벽하게 기록하기 위한 용도가 아니라 요청 특성을 이해하는 데 액세스 로그를 사용하는 것이 좋다고 한다.
그래서 고민 끝에 Lambda 함수를 다시 작성해서 ALB의 라우팅 규칙으로 등록해봤다.
[INFO] 2024-08-20T14:25:15.824Z 12345678-90ab-cdef-1234-567890abcdef X-Amzn-Trace-Id: Root=1-66bdd4f1-12345abcdef1234567890ab, Request Headers:
{
"accept": "application/json,text/html;q=0.9,*/*;q=0.8",
"accept-encoding": "gzip, deflate, br",
"accept-language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7",
"connection": "keep-alive",
"host": "example.com",
"referer": "http://example.com/api-docs",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36",
"x-amzn-trace-id": "Root=1-66bdd4f1-12345abcdef1234567890ab",
"x-forwarded-for": "203.0.113.5",
"x-forwarded-port": "443",
"x-forwarded-proto": "https"
}, Request Body: "{\"key\":\"value\"}"
Lambda 함수의 모든 로그는 cloudwatch 로그 그룹으로 수집하기에, 중간에 거치면서 다음과 같이 로깅만 해줘서 데이터를 수집할 수 있다. 각 메시지의 트레이스 ID인 x-amzn-trace-id를 동일하게 설정해서 ALB AccessLog와 함께 비교하도록 설계했었다.
하지만......... 세상이 내 맘대로 안돌아간다...

로드밸런서의 리스너는 Port당 하나씩만 등록 가능하고, 해당 리스너의 규칙을 여러 개 설정한들 라운드 로빈 방식으로 1개 선택해서 라우팅한다(...)
이러면 규칙을 추가해봤자, 원래 라우팅하던 로드밸런서 그룹으로 온전히 요청이 가지 않는다.
그러니까 50% 확률로 http 데이터만 수집하거나, 원래 고객의 웹서비스의 비즈니스만 작업한다는 말이다.
난 웹서비스의 HTTP 요청하는 과정에서 데이터만 잠깐 수집하려는건데 이게 안된다.
웃긴게 가끔 Lambda 함수의 그룹이 아니라 web-instance-group으로 라우팅되는데도 람다 함수가 실행되면서 로그를 수집하는 경우가 있다.
라우팅.. 이씽...
나처럼 AWS 상에서 HTTP 데이터를 수집하고 싶은 사람이 어딘가 분명히 있을거라고 생각해서 자료를 찾아봤다.
ALB forward traffic to two target groups (IP & Lambda) at the same time
I have an ALB forwarding traffic into IP target group and I'm trying to forward the traffic beside the IP target group into a Lambda function at the same time. In other words, the requests receieve...
stackoverflow.com
트래픽 미러링 관련해서 키워드를 주긴 하는데, 결론은 안돼
난 그래도 한다.
어떻게든 몸을 비틀어서 해결하고자 발버둥쳤다...
API Gateway를 달고, 이 게이트웨이에 Lambda 함수를 등록하는 방식으로 선회했다.

제품을 이용하려는 고객이 필수적으로 API Gateway 서비스까지 이용해야한다는 제약 조건이 생기기에 꺼려했지만 뭐 어쩔 수 있나. 기능이 안되는거보다 낫다고 생각한다.
어차피 보안 환경 구축을 위한 리소스는 IaC로 편하게 생성하도록 할려고 했기에, 크게 지장가진 않을 거라 합리화하겠다.
결국 해냈다는 점에 의의를 두겠도다
'project > SIEMple' 카테고리의 다른 글
심플(SIEMple) - 2024년 쿠시스 프로젝트 마무리 (1) | 2024.12.17 |
---|---|
2024 사이버 시큐리티 해커톤 수상 회고 (0) | 2024.11.17 |
으악 OpenSearch 비용이 왜이래 (0) | 2024.11.17 |
Global Region 의심 이벤트 수집과 OpenSearch 설정 (0) | 2024.11.17 |
2024년도 KUCIS 프로젝트 - 클라우드 SIEM 솔루션 (0) | 2024.11.17 |