컬럼명 또는 인덱스로 데이터프레임 coulmn 삭제하기

 

아래와 같은 데이터 프레임이 있다고 가정하자.

Iris dataset

이때, 특정 컬럼을 추가하거나 삭제하고 싶다면?

 

컬럼명으로 삭제


'sepal width (cm)' 컬럼을 삭제하고 싶다면, 아래와 같이 코드를 구현하면 된다.

df.drop(columns=['sepal width (cm)'])

 

또는, columns= 을 쓰지 않는 대신, axis=1을 추가하면 된다.

참고로, axis=1은 column을 기준으로 연산하는 것, axis=0은 row를 기준으로 연산하는 것이다.

df.drop(['sepal width (cm)'], axis=1)

여러개의 컬럼을 한번에 삭제하고 싶을 땐 [] 안에 여러개의 컬럼을 입력하면 된다.

df.drop(['sepal length (cm)', 'petal width (cm)'],axis=1)

 

인덱스로 삭제


컬럼명을 일일이 작성하기 어렵거나, 쉽게 여러개의 column을 처리하고 싶다면 인덱스를 활용하면 된다.

df.drop(columns=df.columns[[1]])

데이터프레임.columns() 를 실행하면 해당 데이터프레임의 컬럼명 리스트를 확인할 수 있는데, 그걸 활용해서 몇번째 컬럼을 삭제할 지 선택할 수 있다. 

여러개의 컬럼을 한번에 삭제하고 싶을 땐 여러 인덱를 입력하면 된다.

df.drop(columns=df.columns[[0,2]])

그동안 학교 지메일과 구글 드라이브를 열심히 사용했는데, 앞으로 졸업생의 계정을 삭제한다고 한다.

대학원 졸업도 얼마 남지 않았을 뿐더러 나는 그동안 학부 계정을 열심히 사용해왔기 때문에..

드라이브 속 많은 파일들을 외장하드에 옮겨야만 했다.

 

이런 일도 있고 하니, 그동안 만들어왔던 파일들과 실험 내용들 중 일반적인 내용들을 블로그에 기록해두면 좋겠다는 생각이 들었다.

정말 나의 기록장, 마이 보안 다이어리답다.

 


오늘은 1탄!

GRR 설치 가이드이다.

 

GRR은 구글에서 나온 오픈소스 EDR 시스템이다. 

https://github.com/google/grr

 

GitHub - google/grr: GRR Rapid Response: remote live forensics for incident response

GRR Rapid Response: remote live forensics for incident response - GitHub - google/grr: GRR Rapid Response: remote live forensics for incident response

github.com

 

상세 내용은 독스에 잘 설명되어 있기도 하고, 그동안 연구했던 내용에 모두 포함되어 있다.

오늘은 설치 가이드를 위주로 작성하려고 한다.

 

설치는 VMware 가상머신에서 진행했고, 환경은 Ubuntu 18.04.4 LTS에서 진행했다.

이 외에도 20.04, 21.04 LTS에서도 실험해봤었는데 모두 성공적으로 설치할 수 있었다.

 

GRR은 서버, 클라이언트가 나누어져 있기 때문에 설치 과정에도 차이가 있다.

 

서버, 클라이언트 공통 설치 과정

0. 먼저 처음 가상머신을 설치했다면 아래 과정을 기본으로 진행해준다.

sudo apt-get install net-tools
sudo su
apt-get update -y

1. maria DB 설치

이 과정은 root 권한으로 변경 후 진행해야 한다.

apt-get install mariadb-server -y
mysql_secure_installation

위 과정을 진행하면, 아래와 같이 질문이 나오고 간단히 대답을 해주면 된다.

Enter current password for root (enter for none): enter
Set root password? [Y/n]: N
Remove anonymous users? [Y/n]: Y
Disallow root login remotely? [Y/n]: N
Remove test database and access to it? [Y/n]: Y
Reload privilege tables now [Y/n]: Y

그리고나서 아래 과정을 진행해준다.

mysql -u root -p
MariaDB [(none)] > CREATE DATABASE grr;
MariaDB [(none)] > GRANT ALL PRIVILEGES ON grr.* TO ‘grr’@’localhost’ IDENTIFIED BY ‘password’ WITH GRANT OPTION; (복사, 붙여넣기 하지말고 직접 입력하기)
MariaDB [(none)] > FLUSH PRIVILEGES;
MariaDB [(none)] > EXIT;

EXIT;을 하고 나서,

systemctl restart mariadb로 터미널에서 mariadb를 재시작해준다.

+) systemctl status mariadb로 현재 상태를 확인할 수 있다. 

 

서버 설치 과정

서버를 설치하기 위해, deb 파일을 다운로드 해야한다.

나는 그동안 3.4.0-1 버전을 사용했는데, 버전 업데이트가 되었다면 그에 맞게 설치해주어야 한다.

버전이 몇인지 모르겠다면 wget https://github.com/google/grr/releases에서 확인해볼 수 있다.

(현재는 3.4.6.0이 최신이라고 나온다.)

wget https://storage.googleapis.com/releases.grr-response.com/grr-server_3.4.0-1_amd64.deb
sudo apt install -y ./grr-server_3.4.0-1_amd64.deb

이후에는 계속 엔터를 치면서 넘어가고, IP를 입력하는 부분이 나오면 서버의 IP를 입력해준다.

그리고 Please enter password for user 'admin' 에서는 GRR에 접속할 때 사용할 비밀번호를 입력해주면 된다.

 

설치를 완료했다면, systemctl restart grr-server로 서버를 재실행해준다.

 

재실행을 한 다음, 웹 페이지에서 서버의 IP주소:8000 로 접속하면 로그인 창이 나오는데, 

이때는 admin/비밀번호(이전에 설정한 것)을 입력하면 접속할 수 있다.

GRR 접속 화면

 

클라이언트 설치 과정

클라이언트의 경우, 공통 설치 과정을 거친 후에 진행한다.

그리고 웹 페이지에서 위에서와 같이 서버IP:8000에 접속한다.

그리고 왼쪽의 Binaries 탭에 들어간 다음, linux/installers/grr_3.4.0-1_amd64.deb 버전을 다운로드 하면 된다.

이때, 단순하게 다운로드만 하는 것이 아니라, 다운로드 한 파일을 실행시켜서 install로 설치해줘야 한다!

 

이 과정을 마무리하면, 서버 페이지에서 search box를 누르면 온라인 상태의 클라이언트를 확인할 수 있다!

 

처음 설치 가이드를 만드는 것은 어렵지만, 한번 만들어보면 다른 걸 설치할 때도 두려움이 없어진다.

그리고 한번 만들어두면 굉장히 편하다!

오늘도 간단한 공격을 snort로 탐지해보려고 한다.

 

공격자는 칼리리눅스이고, 피해자는 IP가 192.168.48.165인 우분투이다.

 

1) Snort3로 탐지할 준비하기

스노트 탐지 방법은 점점 손에 익어가는 것 같다.

순서는 늘 똑같다.

이전 log 파일 삭제 -> 탐지 룰 수정(새로운 탐지룰 넣어주기) -> 탐지 -> 로그분석 순이다.

2-1. 이전 log 파일 삭제

sudo rm /var/log/snort/*

1-2. 탐지 룰 수정

sudo gedit /usr/local/etc/rules/local.rules

이번에는 icmp 패킷들을 탐지하는 룰로 수정해주려고 한다.

alert icmp any any -> $HOME_NET any (msg: "ICMP Flooding"; sid:1000025;)

1-3. 간단하게 실행시켜보기

간단히 실행해보고, 에러가 나진 않는지 확인한다.

snort -c /usr/local/etc/snort/snort.lua -R /usr/local/etc/rules/local.rules

1-4. 탐지

에러가 안나는 것을 확인해주었다면, 탐지한 뒤 이를 로그파일로 저장할 수 있도록 한다.

sudo /usr/local/bin/snort -c /usr/local/etc/snort/snort.lua -s 65535 \
-k none -l /var/log/snort -i ens33 -m 0x1b

 

2) Land attack

칼리리눅스에서 hping3를 사용해 간단히 공격을 시도할 수 있다.

아래 명령어를 터미널에 입력해주면 된다.

hping3 192.168.48.165 -a 192.168.48.165 --flood --icmp

192.168.48.165 부분은 피해자 IP주소를 입력해주면 되는 것이다.

그럼 아래와 같이 나온다.

 

3) 로그 분석하기

조금 시간이 흐르면, ctrl+C를 눌러서 공격을 멈춘다.

그리고 우분투에서도 탐지를 멈춘 뒤, 로그 파일이 저장되는 폴더를 확인해보자.

이전에는 alert_json.txt 파일만 생겼었는데, 이번에는 엄청나게 많은 로그파일이 생성된 것을 알 수 있다.

아무래도 flooding 공격이다 보니 많은 것들이 탐지된 것 같다.

 

alert_json.txt 파일을 확인해보면,

대충 봐도 엄청나게 많은 로그가 쌓인 것을 알 수 있다.

몇가지 살펴보면, dst_addr과 dst_ap가 192.168.48.165이고, ICMP 패킷이 탐지된 것을 알 수 있다.

그리고 same src/dst IP 메세지도 꽤나 보인다.

다음에는 Splunk로 더 자세한 분석을 해보려고 한다!

EXIF를 활용해 이미지의 메타데이터를 확인하고, 수정해보려고 한다.

 

환경은 Ubuntu 20.04 가상머신이다.

 

1. 간단한 툴 이용하기

먼저, 터미널에 아래 명령어로 exiftool을 설치해준다.

sudo apt-get install exif

sudo apt install libimage-exiftool-perl

 

이미지 파일을 구글에서 하나 다운받아와서, 파일명을 dog2.jpeg로 변경해줬다.

그리고 아래 명령어를 입력한다.

exiftool dog2.jpeg

그럼 아래 그림과 같이 이 이미지 파일에 대한 메타데이터를 확인할 수 있다.

이번엔 이미지의 메타데이터를 수정해보자. 

exiftool -artist=me dog2.jpeg

 

그럼 현재 디렉터리에 dog2.jpeg(메타데이터 바뀐 것), dog2.jpeg_original(수정 전 이미지)가 생긴다.

그리고 다시 dog2.jpeg의 메타데이터를 확인해보면, 

메타데이터 내용이 더 추가됨으로써 파일 사이즈와 mtime, ctime, atime이 변한 것을 확인할 수 있다.

그리고 artist가 me로 변경된 것을 확인할 수 있다.

 

2. 파이썬 코드 활용하기

위와 유사하게, 파이썬으로도 가능하다.

먼저, exif를 설치해준다.

pip install exif

 

그리고 gedit read_exif.py을 한 다음, 아래 내용을 넣고 저장한다.

from exif import Image

original = 'dog2.jpeg'

with open(original, 'rb') as original:
    img = Image(original)

print(dir(img))

dir()은 원본 이미지의 exif 속성들을 확인할 수 있는 함수이다.

그럼 아래와 같은 결과를 얻을 수 있다. 

 

read_exif.py 파일을 조금 수정해서 몇가지 속성들에 대해 확인해보면,

from exif import Image

original = 'dog2.jpeg'

with open(original, 'rb') as original:
    img = Image(original)

print("img.artist: ", img.artist)
print("img.delete: ", img.delete)
print("img.get: ", img.get)
print("img.y_and_c_positioning: ", img.y_and_c_positioning)
print("img.y_resolution: ", img.y_resolution)

아래와 같이 나오는 것을 확인할 수 있다. 

보면, y_and_c_positioning, y_resolution 같은 경우엔 숫자이고, artist는 문자열인 것으로 보인다.

 

이번엔 파이썬 코드로 메타데이터를 수정해보자.

gedit revise_exif.py를 한 다음, 아래 내용을 입력하고 저장해준다.

from exif import Image

original = 'dog2.jpeg'

with open(original, 'rb') as original:
    img = Image(original)

img.artist = 'me2'

with open('modified_original', 'wb') as new:
    new.write(img.get_file())

dog2.jpeg의 artist 부분을 me2로 바꾼 다음, 이를 modified_original 파일로 저장하라는 의미이다.

 

python3 revise_exif.py로 이 코드를 실행시킨 뒤, modified_original을 확인해보면 아래와 같이 artist가 me2로 변경된 것을 확인할 수 있다.

그리고 이미지를 확인해보면,

이렇게 육안으로 보기에는 원본(dog2.jpeg)과 동일한 강아지 사진임을 확인할 수 있다.

오늘은 머신러닝에서 특징 추출에 많이 사용되는 PCA(Principle Component Analysis)로 데이터 셋의 특징 추출을 해보려고 한다.

 

사용할 데이터 셋은 IoT 환경에서 수집한 네트워크 트래픽 데이터 셋인 UNSW-NB15이다.

데이터 셋 링크: https://research.unsw.edu.au/projects/unsw-nb15-dataset

이 데이터 셋 중 CSV형식으로 된 학습 데이터만 사용해볼 것이다.

 

0. Ubuntu 20.04에 아나콘다, 주피터 노트북 실행

conda activate
source ~/.bashrc
jupyter notbook

 

1. PCA

 

그동안 설치 및 실습해봤던 snort를 활용해, arp spoofing 공격을 실습하고 이를 탐지해보려고 한다.

 

snort는 피해자 pc(우분투)에 설치했고, 공격자 pc는 칼리 리눅스로 설치했다.

피해자 ip: 192.168.48.165

공격자 ip: 192.168.48.163

gateway: 192.168.48.2 (피해자 pc에 arp -a 명령어로 확인할 수 있다)

 

그럼 먼저 arp spoofing 실습을 먼저 진행해보자.

 

1) ARP Spoofing

우선, 스푸핑을 위한 도구인 fragrouter를 설치해준다.

설치를 완료해준 뒤, fragrouter를 터미널에 입력하면, 사용 방법에 대해 나온다.

첫번째 옵션으로 아래와 같이 명령어를 입력해주고,

fragrouter -B1

위 터미널은 그대로 열어둔 채로, 새로운 터미널을 연다.

그리고 root 모드로 전환한 뒤, 아래와 같이 명령어를 입력한다.

arpspoof -i eth0 -t 피해자IP Gateway (칼리리눅스에서 ifconfig를 해보면, eth0인지 ens33인지 나온다)

arpspoof -i eth0 -t 192.168.48.165 192.168.48.2

그럼 사진에서처럼 계속해서 arp replay 패킷을 반복적으로 보내게 된다.

 

이렇게 여러차례 arp replay 패킷을 보낸 뒤, 피해자 PC에서 확인해보면, 달라진 것을 확인할 수 있다.

공격 받기 전
공격 받은 후

전후를 확인하기 위해 date 명령어로 시간도 찍어줬다.

공격 받은 후, arp -a를 입력하면 공격자 ip주소인 192.168.48.163이 찍히는 것을 알 수 있다.

 

그리고 다시 칼리 리눅스로 돌아와보면, fragrouter -B1을 입력했던 터미널에서 아래와 같은 모습을 확인할 수 있다.

UDP 패킷으로 ARP Spoofing을 한 걸까?

피해자 PC에서 UDP 패킷을 Snort로 탐지해봐야겠다!

 

2) Snort로 arp spoofing 탐지

먼저, 이전 실습 내용을 로그로 저장했던 내용을 삭제해준다.

sudo rm /var/log/snort/*

 

그리고 udp 패킷 탐지를 위해 새롭게 rule을 설정해준다.

sudo gedit /usr/local/etc/rules/local.rules

나는 블로그를 참고해 아래와 같이 설정해줬다. (https://ast-216.tistory.com/25)

alert udp any any -> any any (msg:"UDP packet"; sid:1000011;)

 

그리고 간단히 실행해보았다.

snort -c /usr/local/etc/snort/snort.lua -R /usr/local/etc/rules/local.rules

 

그랬더니 아래와 같은 패킷들이 탐지되었다.

뒤쪽 이미지를 보면, 192.168.48.2, 192.168.48.165 도 보이고, arp_spoof도 보이는 것 같다.

 

제대로 확인해보기 위해, 로그로 저장해보았다.

sudo /usr/local/bin/snort -c /usr/local/etc/snort/snort.lua -s 65535 \
-k none -l /var/log/snort -i ens33 -m 0x1b

 

그리고 log 파일을 확인해보면, 그림과 같다.

아주 많은 정보가 들어있는 것 같다.

쉽게 확인하기 위해, splunk도 활용해보려고 한다.

 

3) Splunk로 arp spoofing 탐지

3-1) 시도 ①

파이어폭스에 IP주소:8000를 입력한 뒤, 저번에 설정했던 admin 계정의 아이디와 비밀번호를 입력해준다.

그리고 검색하는 곳으로 들어가서, 기본적으로 alert가 왔던 패킷의 개수를 세본다.

sourcetype="snort3:alert:json"
| stats count by dest

그럼, 공격자 IP주소인 192.168.48.163이 8개, 피해자 IP 주소인 192.168.48.165가 15개, Gateway인 192.168.48.2가 12개이다. 

 

3-2) 시도 ②

그리고, fragrouter -B1 터미널에서, 192.168.48.2.53에서 53이 포트번호일까? 싶어서

splunk에 dest_port=53을 추가해 검색해보았다.

sourcetype="snort3:alert:json" dest_port = 53
| stats count by dest

그랬더니 아래와 같은 결과가 나왔다!

dest 주소도 192.168.48.2가 맞으니, 탐지를 한거라고 봐도 되는걸까?!

 

3-3) 시도 ③

개수를 count하는 부분을 빼고, 아래와 같이 쿼리문을 입력해봤다.

sourcetype="snort3:alert:json"

그랬더니 각 로그의 여러 정보에 대해 보기 좋게 나열되었다. (json 형식의 로그 파일을 정리해준 것 같다)

그 중 UDP packet이 눈에 띄어서, 아래와 같이 명령어를 입력했더니, msg가 UDP packet인 것들만 정렬해주었다.

sourcetype="snort3:alert:json" msg="UDP packet"

그리고 왼쪽 필드들을 눌러보면, 이 패킷들 중 dest_port(destination port)가 어떤 것들이 있는지를 확인할 수 있다.

53번 포트의 경우, 칼리 리눅스에서 보냈던 패킷들의 대부분인 것 같다.

그런데 다 UDP 패킷이 사용하는 포트라면, 이걸로 공격을 탐지했다고 보기는 어려울 것 같다.

 

3-4) 시도 ④

포트번호 개수를 카운트해서 시각화를 시도해봤다.

sourcetype="snort3:alert:json"
| stats count by dest

육안으로 보기에는 0번, 1900번, 53번이 가장 많았다.

3-5) 시도 ⑤

이번엔 메세지에 arp_spoof가 있던 패킷을 검색해봤다.

sourcetype="snort3:alert:json" msg = "(arp_spoof) unicast ARP request"

그랬더니 조금 특이한 점이 보였다.

아까 msg="UDP packet"으로 검색했을 때는, b64_data(base 64로 인코딩된 결과)의 종류가 23개였다.

그런데 msg = "(arp_spoof) unicast ARP request"의 경우, b64_data의 종류가 한 개뿐이고, 이것도 AAAAAA.. 였다.

 

Snort와 Splunk의 사용법은 점점 손에 익는데, 탐지를 어떻게 더 잘할 수 있을지는 rule과 쿼리문에 따라 달라지는 것 같다.

검색해보기로는 arp spoofing을 탐지하는 실습은 많이 진행하지 않는 것 같기도 하다.

더 다양한 공격 실습을 진행하면서 탐지 능력을 길러봐야겠다!!

이번엔 대표적인 SIEM(Security information and event management)인 Splunk를 사용해보고자 한다.

SIEM으로는 ELK만 사용해봤는데, Splunk를 사용하는 곳도 많은 것 같다.

 

Splunk는 snort의 모든 알람에 대해 웹 인터페이스로 그래픽적으로 디스플레이를 해주고, 이 알람들에 대해 이해하고 검색할 수 있도록 도와주는 도구이다.

그럼 이제 설치와 사용을 해보자!

 

0) 현재 경로 확인

pwd 명령어로 현재 디렉터리를 확인할 수 있다.

현재 모든 것들이 진행되는 경로는 /root/snort_src이다.

 

1) splunk 설치

Splunk 설치를 위해서는, 우선 사이트에 가입을 해야한다.

https://www.splunk.com/ 에 접속한 뒤, Free Splunk를 눌러서 가입해준다.

로그인을 한 뒤, download 페이지에서 enterprise의 60일 사용-리눅스-.deb 파일을 다운로드 해준다.

다운로드를 완료했다면, 이를 snort_src 폴더로 옮겨준다.

그리고 아래 명령어로 설치해주면, /opt/splunk 경로에 Splunk가 설치된다.

#splunk 설치
cd ..
cd .. #snort_src 디렉터리로 가도록
sudo dpkg -i splunk-8.*.deb
sudo chown -R splunk:splunk /opt/splunk

그런데.. 첫번째 명령어 실행 시 curl: command not found 에러가 발생했다.

그래서 apt install curl 로 설치하려고 했으나, 용량이 부족하다는 에러가 발생했다.

처음 가상머신 설정 시 20GB로 설정했는데, 부족했던 듯 하다.

그래서 용량이 큰 가상머신을 새로 만들고 지금까지의 과정을 재진행했다..💦

 

다시 돌아와서!

apt install curl

이렇게 curl을 설치해준 뒤, 다시 splunk를 설치해준다.

그럼 아래 그림과 같이 잘 설치되는 것을 알 수 있다.

splunk 설치 완료

 

2) Splunk 첫 실행

Splunk를 위한 새로운 admin 계정을 생성하고 splunk를 처음으로 실행하려고 한다.

sudo /opt/splunk/bin/splunk start --answer-yes --accept-license

위 명령어를 입력하면, 아래와 같이 관리자 계정을 설정하도록 나온다.

username과 password를 입력하고 나면, 아래 그림과 같이 나온다.

그럼 이제 파이어 폭스로 들어가서, url에 ip주소:8000 를 입력해 접속하면 아래 그림과 같이 나온다.

그럼 방금 전 설정한 admin 계정과 비밀번호를 입력하면, 

이렇게 나온다!

ELK가 생각나는 모습이다.. 다 비슷하게 생겼나보다.

 

아무튼, splunk를 자동으로 시작하도록 하고싶으면, splunk의 systemD를 활성화시키고 이를 시작해주면 된다.

sudo /opt/splunk/bin/splunk stop
sudo /opt/splunk/bin/splunk enable boot-start -systemd-managed 1
sudo chown -R splunk:splunk /opt/splunk
sudo service Splunkd start

60일 밖에 못쓰지만.. 최대한 활용해보자!

 

3) Configuring Splunk

Snort3로부터 생성한 로그를 쉽게 수집하고 이걸 정규화하기 위해, "Add-on" 이라고 불리는 Splunk 플러그인을 설치해줘야 한다.

여기서 Find More Apps를 누른 뒤,

Snort를 검색하면, Snort 3 JSON Alerts가 나온다.

Install을 눌러 이걸 설치해준다.

그리고 CyberChef도 검색해 설치해준다.

 

두가지 앱 설치가 끝났다면, 터미널로 돌아와준다.

그리고 configuration을 수정해준다.

sudo mkdir /opt/splunk/etc/apps/TA_Snort3_json/local
sudo touch /opt/splunk/etc/apps/TA_Snort3_json/local/inputs.conf
sudo gedit /opt/splunk/etc/apps/TA_Snort3_json/local/inputs.conf

inputs.conf에 아래 내용을 입력한 뒤, 저장한다.

[monitor:///var/log/snort/*alert_json.txt*]
sourcetype = snort3:alert:json

그리고 Splunk를 다시 시작해준다.

sudo service Splunkd restart

그럼 이제 /var/log/snort 디렉터리의 json 파일들을 스캔할 수 있다.

 

4) Splunk 사용해보기

이제 splunk를 사용할 준비를 마쳤다!

Splunk에서 search & reporting을 클릭해준 뒤, 아래 내용을 검색해보자.

sourcetype="snort3:alert:json"

그리고 검색을 누르면, 아래와 같이 잘 정리된 결과를 볼 수 있다.

 

몇가지 사용 예시를 더 실습해보려고 한다.

먼저, 시간, source, destination, message를 보기 위해 아래와 같이 검색한다.

sourcetype="snort3:alert:json"
| table _time src_ap dst_ap msg

그럼 이렇게 원하는 부분만 가져와서 테이블을 만들어준다.

약간 데이터베이스 검색하는 느낌이기도 하다.

 

목적지로부터 모든 이벤트를 세려면 아래 내용을 검색한다.

sourcetype="snort3:alert:json"
| stats count by dest

그럼 아래와 같이 나온다. 

어떤 destination일 때 몇개의 패킷이 전송되었는지를 세준 것인데, 이상행위 탐지에 유용하게 쓰일 것 같다는 생각이 든다.

다음으로, map에 모든 이벤트 sources를 보기 위해서는 아래 내용을 검색한다.

sourcetype="snort3:alert:json"
| iplocation src_addr
| stats count by Country
| geom geo_countries featureIdField="Country"

그럼 이런식으로 결과가 나온다.

마지막으로, base64로 인코딩된 페이로드 데이터가 있다면, 그걸 "cyberchef" 함수로 읽어오고 싶다면 아래 내용을 검색한다.

sourcetype="snort3:alert:json" dest_port=80
2 | cyberchef infield='b64_data' outfield=decrypted operation="FromBase64"
3 | table src_addr, dst_addr, rule, msg, decrypted

그런데.. 에러가 발생했다.

base64로 인코딩된게 없어서 그런가..??

이 부분은 다른 실습과 함께 하면서 해결해봐야겠다!

 

그리고 다른 실습을 하면서 splunk와 snort로 더 제대로 된 분석을 해보고 싶다 :)

오늘은 snort를 자동으로 시작하기 위해 systemD 스크립트를 생성해줄 것이다.

그리고 보안을 위해, 시작 후에 루트가 아닌 일반 사용자로서 snort가 실행되도록 할 것이다.

 

1) 스노트 사용자와 그룹 생성

sudo groupadd snort
sudo useradd snort -r -s /sbin/nologin -c SNORT_IDS -g snort

 

2) 이전에 실습했던 예전 로그파일들 삭제

sudo rm /var/log/snort/*

 

3) 로그 경로에 'snort' 사용자에게 권한 부여

sudo chmod -R 5775 /var/log/snort
sudo chown -R snort:snort /var/log/snort

4) systemD 파일 생성

sudo gedit /lib/systemd/system/snort3.service

파일을 연 뒤, 아래 내용을 입력해준다.

[Unit]
Description=Snort3 NIDS Daemon
After=syslog.target network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/snort -c /usr/local/etc/snort/snort.lua -s 65535 \
-k none -l /var/log/snort -D -u snort -g snort -i ens33 -m 0x1b --create-pidfile \
--plugin-path=/usr/local/etc/so_rules/
[Install]
WantedBy=multi-user.target

위 내용들의 flag에 대한 설명은 다음과 같다.

eth0 -> ens33으로 생각하면 된다.

5) Snort systemD 서비스 활성화 및 시작

sudo systemctl enable snort3
sudo service snort3 start

 

6) 상태 확인

service snort3 status

이 명령어를 입력했을 때, 아래와 같이 나오면 성공한 것이다.

확인했으면, ctrl+z로 빠져나와준다.

 

*) 문제가 생겼다면, 서비스의 전체 결과를 확인할 수 있다.

sudo journalctl -u snort3.service

 

마지막 내용은 Splunk에 관한 내용으로, 오늘 작성한 내용과 분리해 작성하는게 좋을 것 같다.

원래 가이드라인 순서대로라면 PulledPork가 우선이지만, 이건 snort 사이트에 가입한 뒤에 가능하다.

그래서 일단 다음 장(플러그인 configuration, json형식으로 저장)부터 진행하려고 한다. 

 

1) Configuring snort plugins

snort.lua 파일을 구성해주기 위해 파일을 연다.

sudo gedit /usr/local/etc/snort/snort.lua

HOME_NET 변수를 설정해준다.

가이드라인에서는 10.0.0.0/24였지만, 나는 192.168.~의 IP주소이기 때문에 아래와 같이 설정했다.

그래도 되는 건지는 잘 모르겠지만.. 안된다면 다시 수정해야지!

수정 전
수정 후

그리고나서, hyperscan을 enable로 설정해준다. 

enable hyperscan

reputation blocklist는 아래와 같이 수정해주면 된다.

reputation blocklist

snort.lua 파일을 수정할 때마다 파일을 validate 해준다.

snort -c /usr/local/etc/snort/snort.lua

 

2) JSON Alerts Output Plugin

Splunk같은 SIEM에 Snort3 alert 로그 파일을 쉽게 import하기 위해, alert_json output plugin을 사용할 수 있다.

이걸 위해 또 snort.lua 파일을 수정해줄 것이다.

 

그동안 가이드라인에서와 동일한 라인에 작성해주었었는데, 이번에는 230 라인에 적으라고 되어 있었지만, 그 자리에는 다른 내용이 있었다..

그래서 그 아래 부분에 다음과 같이 적어주었다.

 alert_json =
{
 file = true,
 limit = 100,
 fields = 'seconds action class b64_data dir dst_addr dst_ap dst_port eth_dst eth_len \
 eth_src eth_type gid icmp_code icmp_id icmp_seq icmp_type iface ip_id ip_len msg mpls \
 pkt_gen pkt_len pkt_num priority proto rev rule service sid src_addr src_ap src_port \
 target tcp_ack tcp_flags tcp_len tcp_seq tcp_win tos ttl udp_len vlan timestamp',
 }

이때 tab 대신 스페이스바 4번으로 공백을 설정해줘야 한다.

 

alert_json 플러그인에서, 3가지 옵션을 지정해주어야 한다.

1. (콘솔 대신) file 옵션을 사용해 json 형식의 파일로 alert를 출력한다.

2. limit 옵션을 사용해 snort에게 새 파일로 롤 오버 할 시기를 알려준다.

출력 파일이 10MB가 되면 새 파일이 생기고, 현재 unixtime으로 파일명이 설정된다.

(테스트 용으로는 100MB로 설정했지만, 이 부분은 원하면 수정 가능하다.)

3. fields 옵션을 사용해 json 출력에 포함되어야 하는 alert로부터 특정 필드를 식별한다.

 

테스트 후, 몇몇 필드를 삭제해도 되지만, 추후에 Splunk를 사용하기 위해서는 seconds 필드는 삭제하면 안된다.

 

이제 Snort를 실행시키는 동안 alerts를 발생시킬 수 있다.

이 알람들은 /var/log/snort에 저장될 것이다.

sudo /usr/local/bin/snort -c /usr/local/etc/snort/snort.lua -s 65535 \
-k none -l /var/log/snort -i ens33 -m 0x1b

ens33은 늘 내가 ens33인지 eth0인지를 확인하고 입력해야 한다!

 

위 명령어를 실행시키면, 지난번 처럼 계속 탐지 모드인 상태로 나온다.

결과를 확인해보기 위해 ping을 보내봤다.

근데... 탐지가 안된다.

 

명령어를 이리저리 조합해본 결과, -A alert_fast 옵션을 주지 않아서 빠르게 보이지 않았던 것 같다.

그래서 아래와 같이 수정하고, ping을 보냈다.

sudo /usr/local/bin/snort -c /usr/local/etc/snort/snort.lua -s 65535 \
-k none -l /var/log/snort -i ens33 -m 0x1b -A alert_fast

 

그랬더니 아래 그림과 같이 바로 탐지되었다.

 

그럼 이제 탐지 내용이 json파일로 잘 쓰여졌는지 확인해보자.

cat /var/log/snort/alert_json.txt

그럼 아래와 같이 json 형식으로 잘 저장된 것을 알 수 있다. 

자세히 살펴보면, ens33, IPv4 option set, icmp_type, timestamp등 여러 정보를 확인할 수 있다.

 

조금 더 쉽게 확인하려면 gedit 명령어를 통해 파일을 열어봐도 된다.

이 파일은 위쪽이 가장 최근(시간상 가장 늦은 것)이 입력되는 구조인 듯 하다.

이 내용을 보고 규칙을 설정해서 필터링 할 수 있을 것 같다는 생각이 든다.

뒤쪽에 나올 것 같기도!

 

다음에는 Snort Startup Script부터 이어서 진행해야겠다.

어제에 이어서, configuring network cards를 진행해보려고 한다.

 

최신 네트워크 카드들은 LRO와 같은 오프로딩을 사용한다. 

이는 하드웨어에서 네트워크 패킷 재조립을 다루기 위해서인데, NIDS를 위해 여기서는 더 긴 패킷을 truncate할 수 있을 때까지 LRO, GRO를 활성화하지 않으려 한다.

 

이 설정을 변경하기 위해서는 systemD 서비스를 생성해야 한다.

우분투 20에서는 ip address show 명령어를 사용해 인터페이스 이름을 결정한다.

그리고 나서, LRO(Large receive offload)와 GRO(Generic receive offload)의 상태를 확인한다.

 

1) Configuring network cards

내 환경에서 ip address show 명령어를 치면, 아래와 같은 결과가 나온다.

가이드 라인에서는 ens3으로 했고, eth0이나 ens160으로 보일거라고 했는데, 나는 ens33으로 결과가 나왔다.

그래도 ens33으로 아래 명령어를 입력해봤다.

sudo ethtool -k ens33 | grep receive-offload

그랬더니 아래와 같은 정상적인 결과를 확인할 수 있었다.

GRO는 enable, LRO는 disable인 상태

앞서 설명했듯이, LRO, GRO 모두 disable 상태로 변경해주어야 한다.

그러기 위해서는 시스템이 부팅될 때마다 설정되도록 하는 systemD 스크립트를 생성해주어야 한다.

그 방법은 아래와 같다.

#systemD 스크립트 생성
sudo gedit /lib/systemd/system/ethtool.service

gedit 명령어를 통해 파일을 생성해준다.

vi 명령어를 사용할 수도 있지만, 개인적으로 gedit이 편한 것 같다.

아무튼, ethool.service 파일에 아래 내용을 넣고 저장해준다.

[Unit]
Description=Ethtool Configration for Network Interface
[Service]
Requires=network.target
Type=oneshot
ExecStart=/sbin/ethtool -K ens33 gro off
ExecStart=/sbin/ethtool -K ens33 lro off
[Install]
WantedBy=multi-user.target

그리고 서비스를 다시 시작해준다.

sudo systemctl enable ethtool
sudo service ethtool start

그리고, 아까 입력했던 명령어를 다시 입력해보면, LRO, GRO 모두 off로 변경된 것을 확인할 수 있다.

 

2) Configuring Snort

snort rule을 위해 필요한 파일들과 폴더를 생성해준다.

sudo mkdir /usr/local/etc/rules
sudo mkdir /usr/local/etc/so_rules/
sudo mkdir /usr/local/etc/lists/
sudo touch /usr/local/etc/rules/local.rules
sudo touch /usr/local/etc/lists/default.blocklist
sudo mkdir /var/log/snort

그리고 local.rules 파일을 생성해준다.

sudo gedit /usr/local/etc/rules/local.rules

 

ICMP 트래픽을 탐지하고, 알람을 주는 규칙을 생성해볼 것이다.

아래 내용을 local.rules 파일에 넣고 저장해준다.

alert icmp any any -> any any ( msg:"ICMP Traffic Detected"; sid:10000001; metadata:policy security-ips alert; )

 

-R 플래그를 사용해서 실행시켜본다.

snort -c /usr/local/etc/snort/snort.lua -R /usr/local/etc/rules/local.rules

 

결과는 아래 그림과 같다.

마지막에 Snort successfully validated the configuration이 나오면 에러 없이 성공한 것이다!

이 아래에도 network, dnp3, ftp_client 등등 이것저것 나오지만 일단 그냥 잘랐다..

 

3) 인터페이스에서 탐지 모드로 Snort 실행시키기. ICMP 탐지

이번에는 아래 명령어로 인터페이스에서 탐지 모드로 Snort를 실행시켜보려고 한다.

ens33은 자신의 인터페이스 이름으로 변경해주면 된다.

sudo snort -c /usr/local/etc/snort/snort.lua -R /usr/local/etc/rules/local.rules \
-i ens33 -A alert_fast -s 65535 -k none

나는 아래 그림과 같은 결과가 나왔다. (위쪽에 여러가지 나열된 것들은 있지만 이 부분이 중요해보인다.)

패킷 송수신을 하면 아래에 뭔가 바뀌는걸까? 싶어서 파이어폭스 접속도 해보고, ping을 보내봤는데 변화는 없었다.

그래서 데스크탑에서 ping을 보내봤더니 아래와 같은 변화가 생겼다!

데스크탑에서 ping 보낸 것
ping을 보냈더니 탐지 결과를 보여준다

위쪽에 IP주소들이 있는 부분은 ping을 보낼 때 실시간으로 나타났고, 아래 내용들은 조금 후에 나타났다.

192.168.48.164는 가상머신의 IP 주소였고, 192.168.48.1은 뭘까? 싶어서 확인해보니,

데스크탑에서 ipconfig 하면 나오는 결과 중 일부분

가상머신에서 IPv4 주소가 192.168.48.1이라서 그런 것 같다.

 

Flag 규칙은 아래와 같다. 

Snort3 flag 규칙

 

4) decoder, inspector 탐지 및 알람 설정

이번에는 deconder와 inspector 알람을 enable하려고 한다.

스노트로 악성 트래픽을 탐지할 수 있는데, rule이 별로 복잡하지 않다.

 

먼저, snort.lua 파일을 수정해준다.

sudo gedit /usr/local/etc/snort/snort.lua

파일을 열어서 171번째쯤 라인을 보면, 아래 그림과 같이 설정되어 있다.

snort.lua 원래 설정

이 부분을 아래 그림과 같이 변경해주고, 저장한다.

snort.lua 설정 바꾸기

그리고 테스트를 한번 해준다.

snort -c /usr/local/etc/snort/snort.lua

위 명령어 실행 결과

그리고 설정한 규칙에 대해 탐지하려면 아래 명령어를 입력해준다.

sudo snort -c /usr/local/etc/snort/snort.lua -i ens33 -A alert_fast -s 65535 -k none

 

이번에도 ICMP 탐지했던 것처럼 결과가 나온다.

이번에는 별다른 ping을 보내주지 않아도, 조금 기다리면 아래와 같은 결과가 나왔다.

arp_spoof는 뭐지...?

다음에 ARP 스푸핑 같은 간단한 실험을 해보면서 탐지가 정말 되는지 확인해봐야겠다.

 

그리고 다음 번에는 PuuledPork 부분을 진행하려고 한다.

+ Recent posts