Threat Stack은 이제 F5 Distributed Cloud App Infrastructure Protection (AIP)입니다. 오늘부터 팀과 함께 분산 클라우드 AIP를 사용해 보세요.
운영/엔지니어링/보안 분야에서 일한 사람이라면 누구나 예상치 못한 동작을 보이는 서버를 경험해 본 적이 있을 것입니다. 이상한 프로세스가 실행되거나, 예상보다 많은 메모리를 사용하거나, 요청을 수락하거나, GitHub에 연결을 시도하는 등의 문제가 있을 수 있습니다.
사건을 분류하기 위한 첫 번째 단계는 사건이 발생했다는 것을 아는 것입니다. 특정 호스트 서버를 가리킬 수 있는 여러 데이터 소스가 있습니다.
이 시점에서 우리가 가서 더 많은 정보를 얻고 싶은 서버가 있습니다. 모든 시스템 데이터가 반드시 SIEM에 맞지 않는다고 가정하면 다음 논리적 단계는 호스트에 연결하고 운영 체제에 직접 쿼리를 보내서 무엇을 하고 있는지 확인하는 것입니다. 환경에 대한 익숙도 수준에 따라 uname과 vmstat와 같은 도구부터 ps와 lsof와 같은 보다 구체적인 항목까지 광범위할 수 있습니다. 어느 경우든 호스트가 현재 무엇을 하고 있는지 볼 수 있습니다. 이 과정에는 다음과 같은 문제가 있습니다. 사실 당신은 현재 상태에 관심이 없습니다. 당신은 무엇이 바뀌었는지 알고 싶어합니다. Git에서 풀 리퀘스트를 받는 것과 마찬가지로 전체 코드 베이스를 검토하고 싶지 않습니다. 수정된 부분만 검토하면 됩니다.
Threat Stack Cloud SecOps Program℠에서 SOC의 보안 분석가는 고객의 이러한 유형의 질문에 답하는 데 도움이 되는 솔루션을 개발했습니다. Threat Stack Cloud Security Platform®에는 데이터 이동성이라는 멋진 기능이 있습니다. 높은 수준에서 보면, 이를 통해 호스트에서 수집한 원격 측정 데이터(실행 중인 실행 파일, 사용자, 명령줄 인수, 연결 등)를 가져와 S3 버킷에 저장할 수 있습니다.
S3 블롭의 장점은 많은 양의 데이터를 저렴하게 저장할 수 있다는 점입니다. 문제는 인덱싱되지 않은 데이터를 엄청나게 많이 활용하는 것입니다. 그러한 목적을 달성하기 위해, 우리는 Amazon EMR을 사용하여 Jupyter PySpark 노트북을 만들고, Apache Spark DataFrames와 Python pandas DataFrames를 사용하여 머신의 현재 상태를 우리가 보관하고 있는 이전 상태와 비교하는 강력한 도구를 만들었습니다.
코드 예제를 살펴보기 전에 몇 가지 참고 사항이 있습니다. 테이블과 스키마 참조는 AWS Glue에 보관되며 Linux 시스템에 대한 Threat Stack의 원시 이벤트 형식과 일치합니다. 이 데이터를 기존 데이터 레이크에 추가할 수 있습니다. 그런 다음 Spark 클러스터에 대해 Glue에서 읽어서 사용 가능한 테이블과 열을 파악하도록 정의되어 있습니다. 그러면 클러스터가 생성되면 JupyterLab 노트북 내에서 테이블을 참조할 수 있습니다.
메모: 다음 코드는 완전히 실제적인 코드입니다. 상황이 조작된 것입니다. 보안 분석가가 발렌타인 데이 어느 때 우리 에이전트가 실행 중인 호스트를 손상시켜 달라는 요청을 받았습니다. 목표는 무슨 일이 일어났는지 알아내는 것이었습니다.
우리가 가장 먼저 만들어야 할 것은 SparkSession과 SparkContext입니다. 다행히도 PySpark 노트북을 사용하면 첫 번째 셀을 실행할 때 자동으로 인스턴스화됩니다.
PySpark 노트북을 설정합니다.
나중에 참조할 객체 spark와 spark 컨텍스트인 sc도 얻었습니다. 그런 다음 이를 사용하여 pandas 와 Matplotlib을 로드할 수 있습니다.
패키지 설치.
다음 단계에서는 Glue 테이블을 기반으로 spark.table()을
생성하여 열 이름을 확인한 다음 상속받은 스키마를 표시하겠습니다.
AWS Glue에서 로드된 열의 구조를 읽습니다.
좋습니다. 이제 SQL 쿼리를 실행할 수 있는 열과 유형이 무엇인지 확인할 수 있습니다. 이제 원하는 서버, 원하는 시간 범위를 가져와서 비교할 수 있게 됐습니다. 여기서 두 개의 Spark DataFrames를 생성하여 사고 전 조사와 사고 후 포렌식을 수행하는 데 필요한 데이터를 수집합니다.
SELECT date_key, 타임스탬프, tsEventType, syscall, 연결, 사용자, 명령, exe, 인수 FROM compact.audit_v4 WHERE date_key >= '2020-02-05-00' AND date_key < '2020-02-14-00' AND organization_id = '5a8c4a54e11909bd290021ed' AND agent_id = 'b0f6bdb2-9904-11e9-b036-25972ec55a45' GROUP BY date_key, 타임스탬프, tsEventType, syscall, 연결, 사용자, 명령, exe, 인수 SELECT date_key, 타임스탬프, tsEventType, syscall, 연결, 사용자, 명령, exe, 인수 FROM compact.audit_v4 WHERE date_key >= '2020-02-14-00' AND date_key < '2020-02-17-00' AND organization_id = '5a8c4a54e11909bd290021ed' AND agent_id = 'b0f6bdb2-9904-11e9-b036-25972ec55a45' 그룹화 BY date_key, timestamp, tsEventType, syscall, connection, user, command, exe, args
2월 14일이라는 침해 날짜를 중심으로 데이터를 그룹화합니다. (가독성을 위해 일부 노트북 셀을 GitHub Gist로 표시했습니다.)
이제 내가 수집한 데이터 양을 빠르게 확인해 보겠습니다.
조사에 적합한 양을 확보하기 위해 두 Spark DataFrames의 레코드 수를 세어 봅니다.
맞는 것 같습니다. 저는 preCompromiseDf
와 postCompromiseDf
에 대해 훨씬 더 넓은 시간 범위를 가지고 있습니다. ("Df"는 이것들이 Spark DataFrame 객체라는 것을 기억하는 데 도움이 됩니다. 단순한 명명 규칙입니다.)
Apache Spark DataFrames는 클러스터 전체에 걸쳐 전체 DataFrame을 저장하기 때문에 좋습니다. 이 기능은 방대한 데이터 세트에 적합하지만, 이 경우 실제로 비교하려는 레코드의 수는 비교적 적습니다. 그러한 목적을 달성하기 위해 toPandas()를
실행하여 해당 데이터를 노트북 컴퓨터의 메모리로 옮겼습니다. 이를 통해 계산 속도가 더 빨라졌습니다.
이 경우 "빅 데이터"를 다루지 않으므로 나머지 분석은 로컬에서 실행하는 것이 더 빠릅니다.
이제 2월 14일 자정 이후 이 서버에서 실행 중인 새로운 실행 파일이 무엇인지 확인하는 등 강력한 작업을 시작할 수 있습니다.
/tmp/흥분하는 동안 /usr/bin/wget /tmp/전면 런 /tmp/비상 빗 /tmp/서라운드 잠금 /tmp/nmap /usr/bin/scp /tmp/슬리버 /tmp/슬리버2 /tmp/PROUD_THUMB
해당 밤에 서버에서 실행되었던 실행 파일 목록입니다.
안녕하세요, 무작위로 대문자로 시작하는 실행 파일 이름입니다: nmap, scp, wget, 그리고 sliver라 불리는 것들입니다. 약간 구글링해보니 슬리버는 https://github.com/BishopFox/sliver 와 연관이 있을 가능성이 가장 높고, 여러 프로토콜에 대한 명령과 제어를 지원하는 임플란트 프레임워크라는 걸 알 수 있었습니다.
제 서버가 손상되었다는 증거는 있지만, 실제로 이 실행 파일에 무슨 일이 일어났는지 주의 깊게 조사하고 싶습니다. 동일한 DataFrame에 대한 필터로 내 목록을 사용하면 기타 세부 정보와 손상 지표(IoC)를 추출할 수 있습니다.
exe 인수 80 /tmp/EXCITED_WHILE ./EXCITED_WHILE 162 /usr/bin/wget wget https://github.com/andrew-d/static-binari... 255 /tmp/흥분하는 동안 ./흥분하는 동안 256 /tmp/전면 런 ./전면 런 359 /tmp/이상한_콤브 ./이상한_콤브 360 /tmp/서라운드_락 ./서라운드_락 464 /tmp/nmap 494 /tmp/서라운드_락 ./서라운드_락 533 /tmp/흥분하는 동안 ./흥분하는 동안 589 /tmp/전면 런 ./전면 런 603 /tmp/흥분하는 동안 ./흥분하는 동안 658 /tmp/흥분하는 동안 ./흥분하는 동안 660 /tmp/전면 런 ./FRONT_RUN 671 /usr/bin/scp scp -t /tmp/ 699 /tmp/서라운드 잠금 ./서라운드 잠금 738 /tmp/비정상적인_콤브 ./비정상적인_콤브 762 /tmp/슬리버 ./슬리버 816 /tmp/서라운드 잠금 ./서라운드 잠금 834 /tmp/슬리버2 ./슬리버2 878 /tmp/nmap /tmp/nmap 909 /tmp/흥분하는_동안 ./흥분하는_동안 937 /tmp/FRONT_RUN ./FRONT_RUN 992 /tmp/FRONT_RUN ./FRONT_RUN 1023 /tmp/FRONT_RUN 1040 /usr/bin/scp scp -t /tmp/ ...
의심스러운 실행 파일 목록과 관련된 모든 인수를 추출합니다.
따라서 scp는 파일을 이동하는 데 사용되었고, wget은 GitHub에서 일부 코드를 가져왔습니다(해당 행으로 가면 nmap이 시스템에 들어온 경로를 알 수 있습니다). 그리고 다른 파일의 실행 세부 정보는 명령줄 인수를 받지 않았기 때문에 파일 자체 내에 포함되어 있습니다. 이 시점에서는 증거에 대한 호스트 스냅샷을 찍고 인스턴스를 종료하는 것이 합리적입니다.
마지막 단계는 환경 내의 다른 호스트가 손상되지 않았는지 확인하는 것입니다. 이를 위해 이전 IoC 목록에서 몇 가지 항목을 가져와 모든 서버에서 확인해보겠습니다.
SELECT date_key, 타임스탬프, tsEventType, syscall, 연결, 사용자, 명령, exe, 인수, agentId, tty, 세션, cwd FROM compact.audit_v4 WHERE date_key >= '2020-01-01' AND date_key <= '2020-02-29' AND organization_id = '5a8c4a54e11909bd290021ed' AND tsEventType = 'audit' AND syscall = 'execve' GROUP BY date_key, 타임스탬프, tsEventType, syscall, 연결, 사용자, 명령, exe, 인수, agentId, tty, 세션, cwd
52
해당 쿼리는 의심스러운 nmap 및 sliver 활동에 대해 전체 환경에서 52개의 결과를 반환합니다. pandas DataFrame으로 이동하고 각 서버별로 결과를 그룹화하면 이 보기를 더욱 좁힐 수 있습니다.
이 글을 통해 저와 함께해주셔서 감사합니다. 저는 이 데이터가 제공하는 가능성에 대해 매우 기대하고 있으며, 이를 탐구할 새로운 방법을 찾는 것을 좋아합니다. 현재 Threat Stack 플랫폼을 활용하고 있다면 이 문서를 가이드로 활용하여 자체 데이터 이동성을 설정할 수 있습니다. 장점은 귀사의 비즈니스 요구에 맞춰 보관할 적절한 수준의 데이터를 결정할 수 있다는 것입니다.
Threat Stack Oversight℠ 서비스를 활용하는 분들을 위해 저희는 30일 분의 이벤트 데이터를 보유하고 있으며, 데이터 레이크가 없는 경우에도 이 툴셋을 활용하여 사용자 환경에 대한 심층적인 포렌식을 제공하기 위해 기꺼이 협력해 드리겠습니다.
Threat Stack 보안 운영팀의 다음 단계는 데이터 과학 노트북을 사용하여 다음 분석의 일부로 데이터를 시각적으로 구문 분석하는 데 도움이 되는 더 많은 그래픽과 차트를 통합하는 것을 고려하는 것입니다. 이에 대해서는 앞으로 더 많은 내용이 있지만, 여기서는 지리적으로 위치한 일부 IP에 대한 첫 번째 예를 들어보겠습니다(각 원의 밀도는 연결 수를 나타냄).
Threat Stack 보안팀은 곧 더 많은 분석 시각화를 선보일 예정입니다!
Threat Stack은 이제 F5 Distributed Cloud App Infrastructure Protection (AIP)입니다. 오늘부터 팀과 함께 분산 클라우드 AIP를 사용해 보세요.