$ sudo iptables -A PREROUTING -t nat -j DNAT -p icmp -d 192.168.100.10 --to-destination 10.10.11.10
-t nat nat 테이블에 규칙 추가
-j DNAT 일치하면 DNAT 기능 사용 ( SNAT, MASQUERADE 도 가능 )
--dport 포트가 있다면 기재. 생략가능
-d 목적지 주소
--to-destination 목적지 주소를 무엇으로 바꿀것인가 --to 로 축약가능
( + MASQUERADE 는 사용할 NIC만 명시하고 IP 주소 명시하지 않아도 되는 장점이 있다 )
외부에서 ping 192.168.100.10 하면
$ sudo iptables -t nat -nvL
Chain PREROUTING (policy ACCEPT 76 packets, 5952 bytes)
pkts bytes target prot opt in out source destination
생략
1 60 DNAT icmp -- * * 0.0.0.0/0 192.168.100.10 to:10.10.11.10
Chain POSTROUTING (policy ACCEPT 6 packets, 334 bytes)
pkts bytes target prot opt in out source destination
67 4378 SNAT all -- * ens160 10.10.11.10 0.0.0.0/0 to:192.168.100.10
2 148 SNAT all -- * ens160 10.10.11.11 0.0.0.0/0 to:192.168.100.11
pkts 1 찍혀있음
그런데 ping이 한번에 4번 요청이 갈텐데 한번만 찍히는건 모아서 보내는 걸까? ...
( * 패킷 포워딩 설정
/etc/sysctl.conf 파일에 커널 파라미터값 설정 (vi 사용)
net.ipv4.ip_forward = 1 )
중요한 설정
1. iptables의 nat 테이블 PREROUTING 체인에 ICMP 프로토콜 외부공인IP -> 내부 IP로 포워딩
2. iptables의 filter 테이블 FORWARD 체인에 NFQUEUE 룰 설정
Chain FORWARD (policy ACCEPT) target prot opt source destination NFQUEUE all -- 0.0.0.0/0 0.0.0.0/0 /* SNORT */ NFQUEUE num 0 |
3. snort 실행을 위해 -Q 인라인 모드 옵션 사용
( * NFQUEUE : 커널 패킷 필터로 패킷 큐(대기열)에 대한 접근 권한을 주는 라이브러리. Suricata가 활성화되어 있지 않은 경우, NFQUEUE가 패킷 큐를 잡고 있는(홀딩) 상태이기 때문에 내부에서 인터넷 등 패킷이 전달되지 않음(인터넷 사용 불가)
ex)
1. 직접설정
$ sudo iptables -A FORWARD -j NFQUEUE -m comment --comment SNORT
2. 아래 설정파일에서 설정
참고 : https://hammieunseo.tistory.com/8 )
인라인모드로 실행 후 ping 결과 출력
# snort -A console -q -u snort -g snort -c /etc/snort/snort.conf -Q
09/07-14:36:57.287457 [**] [1:1000001:1] ICMP ping test! [**] [Priority: 0] {ICMP} 10.10.11.10 -> 192.168.100.1
09/07-14:36:57.287457 [**] [1:408:5] ICMP Echo Reply [**] [Classification: Misc activity] [Priority: 3] {ICMP} 10.10.11.10 -> 192.168.100.1
... 하략
특정 메시지를 차단하고 싶다면?
# grep 'ICMP Echo' /etc/snort/rules/*
/etc/snort/rules/community.rules:# alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"PROTOCOL-ICMP Echo Reply"; icode:0; itype:0; metadata:ruleset community; classtype:misc-activity; sid:408; rev:8;)
/etc/snort/rules/icmp-info.rules:alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"ICMP Echo Reply"; icode:0; itype:0; classtype:misc-activity; sid:408; rev:5;)
grep으로 검색하고 찾아서 해당 룰을 주석처리
vim /etc/snort/rules/local.rules 명령어로 로컬에 룰을 지정해줄 수도 있다
로그
09/07-14:36:57.287457 [**] [1:1000001:1] ICMP ping test! [**] [Priority: 0] {ICMP} 10.10.11.10 -> 192.168.100.1
로그가 기록된시간 | | | | 출발지 -> 목적지
경고등급:고유식별번호:리비전번호 | | 프로토콜종류
경고메세지 |
이벤트우선순위 (높아질수록 우선)
패킷을 차단하려면
alert를 drop으로 변경한다
cmd >ping 192.168.100.10
Ping 192.168.100.10 32바이트 데이터 사용:
10.10.11.10의 응답: 대상 포트에 연결할 수 없습니다.
10.10.11.10의 응답: 대상 포트에 연결할 수 없습니다.
10.10.11.10의 응답: 대상 포트에 연결할 수 없습니다.
10.10.11.10의 응답: 대상 포트에 연결할 수 없습니다.
192.168.100.10에 대한 Ping 통계:
패킷: 보냄 = 4, 받음 = 4, 손실 = 0 (0% 손실)
=> cmd에서 ping 실패하고
# snort -A console -q -u snort -g snort -c /etc/snort/snort.conf -Q
09/07-15:20:59.173459 [Drop] [**] [1:1000001:2] !!ICMP ping test!! [**] [Priority: 0] {ICMP} 192.168.100.1 -> 10.10.11.10
snort 쪽에도 Drop 으로 찍힘
단, Drop은 Inline 모드일때만 가능하다
snort 룰을 재설정 할때
1) restart : 프로세스를 종료하고 다시 시작
2) reload : 프로세스를 종료하지 않고 설정과 룰을 다시 로드한다
# ps aux | grep snort
root 1896 0.0 5.2 210980 93916 pts/0 Sl+ 15:29 0:00 snort -A console -q -u snort -g snort -c /etc/snort/snort.conf -Q
root 1971 0.0 0.0 222016 1264 pts/1 S+ 15:31 0:00 grep --color=auto snort
( + 또는 pidof 사용.
pidof
=> 특정 프로세스 이름에 해당하는 pid를 반환한다
# pidof snort
1896
응용 : # kill -1 $(pidof snort) )
snort 프로세스 id를 확인한 후
# kill -SIGHUP 1896
-SIGHUP 또는 -1로 PID를 지정하여 리로드 해준다
응용
# alias svirules='vim /etc/snort/rules/local.rules && kill -1 `pidof snort`'
local.rules를 저장하고 나왔을때 자동으로 리로드
(단, 스노트 룰에 에러가 나면 스노트가 중단되므로 위험할수도 있음)
SSH Brute Force Attack
SSH 서비스 무차별 대입 공격
공격 툴
hydra
dnf -y install rsyslog
systemctl enable --now rsyslog
rsyslog를 설치하고 등록한다
web1 클라이언트에tail -f /var/log/secure 모니터링을 걸어놓는다
칼리 리눅스에서 hydra를 이용하여 단발성 공격
(현재 dmz web1 클라이언트는 nids 클라이언트를 경유중이므로 nids쪽에 iptables -t nat -A PREROUTING -d 192.168.100.10 -p tcp --dport 22 -j DNAT --to 10.10.11.10:22 해당 룰 등록이 되어야 전달됨)
authentication failure
session opened
사전파일을 이용하여 여러 건의 공격 하기
-L 유저리스트 파일
-P 비밀번호리스트 파일
많아서 잘렸는데, 대충 이런식으로 user id만 바꾸어서 로그인 시도가 진행됨
공격 중 성공할 경우
session opened
해당 공격을 탐지하기위한 snort 룰
alert tcp $EXTERNAL_NET any -> $HOME_NET 22 (msg:"SSH Brute Force Attack Detected"; \
flow:to_server,established; content:"SSH-"; \
threshold:type threshold, track by_src, count 5, seconds 60; sid:1000001; rev:1;)
=> 60초동안 5번의 카운트가 달성될 때마다 msg 를 기록한다
$EXTERNAL_NET any : 모든 출발지 ip 주소
$HOME_NET 22 : 현재서버의 ssh 22포트
msg : 탐지되었을 때 출력, 기록되는 문자열
flow : 어떤 흐름인가? to_server는 서버로, established는 연결된것을 의미
content : 탐지할 내용
threshold : 트리거 빈도 (특정 시간내 규칙이 감지되는 횟수) 제어시 사용되는 옵션.
1) type :
threshold(s초 안에 count 달성할때마다 액션)
limit(s초 안에 count 까지만 감지하여 액션. 즉, count를 초과하는 횟수는 감지X)
both(s초 안에 count 달성시 단 한번의 액션)
2) track : by_src(출발지기준), by_dst(목적지기준)
3) count : 이 횟수를 초과하면 경고(출력, 기록, 차단 등)
4) seconds : ~초 안에 count만큼 감지한다
snort 룰을 drop으로 변경하자 snort와 모니터링 로그 둘 다 아무것도 뜨지 않음
공격쪽에서는 socket error 뜸
paramiko (python)를 이용한 SSH Brute Force Attack
sudo apt install python3.11-venv
(에러날 경우 sudo apt-get update 해보고 진행)
설치한 후에
python -m venv pythonWorkspace
가상환경 생성
source pythonWorkspace/bin/activate
가상환경으로 변경
pip install --upgrade pip
패키지를 설치하는 pip의 버전을 업그레이드하고
pip install paramiko
pip를 통해 paramiko 설치
.py 파이썬으로 된 소스파일을 만든다( 내용 : 사전파일을 이용해 다량의 공격 )
소스코드는 대충 이런 느낌
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
연결시도
try: ssh.connect(ip, username="", password="")
except paramiko.AuthenticationException:
" 실패
except paramiko.SSHException:
" SSH Error
except paramiko.NoValidConnectionsError:
" SSH stop Error
파일 오픈은
with open(파일담을변수명, "r") as file:
변수명 = file.read().splitlines()
이런 방식
┌──(pythonWorkspace)(kali㉿kali)-[~]
└─$ tree pythonWorkspace/ -L 4
pythonWorkspace/
├── bin 파이썬 실행파일 위치
│ ├── activate 가상환경을 실행하는 명령어 source
│ ├── activate.csh
│ ├── activate.fish
│ ├── Activate.ps1
│ ├── pip
│ ├── pip3
│ ├── pip3.11
│ ├── python -> /usr/bin/python
│ ├── python3 -> python
│ └── python3.11 -> python
├── hello.py
├── include
│ └── python3.11
├── lib
│ └── python3.11
│ └── site-packages
│ ├── bcrypt
│ ├── bcrypt-4.2.0.dist-info
│ ├── cffi
│ ├── cffi-1.17.1.dist-info
│ ├── _cffi_backend.cpython-311-x86_64-linux-gnu.so
│ ├── cryptography
│ ├── cryptography-43.0.1.dist-info
│ ├── _distutils_hack
│ ├── distutils-precedence.pth
│ ├── nacl
│ ├── paramiko
│ ├── paramiko-3.4.1.dist-info
│ ├── pip
│ ├── pip-24.2.dist-info
│ ├── pkg_resources
│ ├── pycparser
│ ├── pycparser-2.22.dist-info
│ ├── PyNaCl-1.5.0.dist-info
│ ├── setuptools
│ └── setuptools-68.1.2.dist-info
├── lib64 -> lib
└── pyvenv.cfg
26 directories, 14 files
pythonWorkspace 밑의 bin 폴더에는 가상환경 설정들이 있음
bin 폴더 밑의 activate는 가상환경을 실행하는 명령어
가상환경 해제시 deactivate 명령어 사용
필요없어진 경우 rm -rf로 가상환경 폴더를 삭제하면 된다
가상환경을 사용하는 이유?
서로 다른 버전의 패키지로 개발하거나 테스트할 필요가 있을때, 가상환경을 이용하면 버전충돌 없이 활용가능