nmap
nmap(network map) 명령은 시스템이 네트워크에 연결되어 있는지 확인하고 열려 있는 포트를 찾는데 많이 사용됨.
발견된 열린 포트를 확인하면 대상 시스템에 실행 중인 서비스를 추측 해볼 수 있다.
$ nmap [스캔 종류] [대상 IP] [대상포트(선택적)]
실행 구문은 어렵지 않다. nmap에 -sT
옵션으로 지정된 TCP 연결을 스캔할 수 있다. 따라서 현재 서버에서 IP 주소 192.168.121.171을 TCP 스캔 수행할 때 22번 포트(SSH 기본포트)를 살펴보고자 한다면 다음과 같이 하면 된다
$ nmap -sT 192.168.121.132 -p 22
Starting Nmap 7.94 ( https://nmap.org ) at 2023-08-09 10:05 KST
Nmap scan report for 192.168.121.132
Host is up (0.000047s latency).
PORT STATE SERVICE
22/tcp open ssh
Nmap done: 1 IP address (1 host up) scanned in 0.03 seconds
netcat(nc)
Netcat(ornc)은 TCP 또는 UDP 프로토콜을 사용하여 네트워크 연결을 통해 데이터를 읽고 쓰는 명령줄 유틸리티이다.
Netcat은 교차 플랫폼이며 리눅스, MacOS, 윈도우즈 및 BSD에서 사용할 수 있다. Netcat을 사용하여 네트워크 연결을 디버그 및 모니터링하고, 열린 포트를 검사하고, 데이터를 전송하고, 프록시로 사용하는 등의 작업을 수행할 수 있다.
Netcat 패키지는 MacOS 및 Ubuntu, Debian 또는 CentOS와 같은 널리 사용되는 Linux 배포에 미리 설치되어 있다.
Netcat 유틸리티 사용방법은 아래와 같다
$ nc [options] host port
기본적으로 Netcat은 지정된 호스트 및 포트에 대한 TCP 연결을 시작한다. UDP 연결을 설정하려면 -u 옵션을 사용한다.
$ nc -u host port
포트 검색
포트 검색은 Netcat의 가장 일반적인 용도 중 하나이다. 단일 포트 또는 포트 범위를 검색할 수 있다.
예를 들어 20-80 범위의 열린 포트를 검색하려면 다음 명령을 사용하면 된다.
$ nc -z -v 192.168.121.1 20-80
nc: connect to 10.10.8.8 port 20 (tcp) failed: Connection refused
nc: connect to 10.10.8.8 port 21 (tcp) failed: Connection refused
Connection to 10.10.8.8 22 port [tcp/ssh] succeeded!
nc: connect to 10.10.8.8 port 23 (tcp) failed: Connection refused
# ...
nc: connect to 10.10.8.8 port 79 (tcp) failed: Connection refused
Connection to 10.10.8.8 80 port [tcp/http] succeeded
-z
옵션은 nc에 데이터를 보내지 않고 열린 포트만 검색하도록 지시하고 -v
옵션은 보다 자세한 정보를 제공한다.
열린 포트가 있는 라인만 인쇄하려는 경우 grep 명령을 사용하여 결과를 필터링할 수도 있다.
nc -z -v 10.10.8.8 20-80 2>&1 | grep succeeded
UDP 포트를 검색하려면 아래 나온 것처럼 명령에 -u 옵션을 추가하면 된다.
nc -z -v -u 10.10.8.8 20-80
간단한 스캐너 만들기
전체를 스캔하는 대신 먼저 로컬 영역 네트워크에서 포트 22을 스캔하여 스크립트가 실제로 작동하는지 확인하는 스크립트를 작성해보도록 하자.
scanner.sh
#!/bin/bash
FIRST_IP='192.168.121.0'
PREFIX=24
PORT=22
OUTPUT_FILE='SSHscan'
# This script is designed to find hosts with SSH installed
nmap -sT "${FIRST_IP}/${PREFIX}" -p "${PORT}" >/dev/null -oG "${OUTPUT_FILE}"
cat "${OUTPUT_FILE}" | grep 'open' > "${OUTPUT_FILE}2"
cat "${OUTPUT_FILE}2"
nmap 명령을 사용하여 LAN에서 포트 22을 찾는 TCP 스캔을 요청하는 스크립트이다.
>/dev/null
의 경우 nmap의 출력이 터미널 상에 보여지지 않도록 표준 출력을 /dev/null로 보내게끔 리다이렉션 기호를 사용하였다.
-OG
옵션의 경우 nmap에서 제공하는 옵션으로 스캔 결과를 파일로 저장한다.
스캐너 개선
사용자에게 변수를 입력받도록 수정하여 프로그램의 완성도를 조금 더 높여보자
#!/bin/bash
OUTPUT_FILE='ScanOutput'
echo "Enter the starting IP address : "
read FirstIP
echo "Enter the last octet of the last IP address : "
read LastOctetIP
echo "Enter the port number you want to scan for : "
read port
nmap -sT "${FirstIP}-${LastOctetIP}" -p "${port}" >/dev/null -oG "${OUTPUT_FILE}"
cat "${OUTPUT_FILE}" | grep 'open' > "${OUTPUT_FILE}2"
cat "${OUTPUT_FILE}2"
포트 스캔 스크립트
로컬 서버에서 31000 ~ 32000번 포트 중 열려있는 포트들을 찾고 거기서 선별된 포트 중 SSL 통신을 하는 포트를 찾는 스크립트를 작성 해보자.
스크립트 작성
#!/bin/bash
serverIP='127.0.0.1'
srcPort='31000'
dstPort='32000'
# 열려있는 포트 스캔
PORTS=$(nc -nv -w 1 -z "${serverIP}" "${srcPort}"-"${dstPort}" 2>&1 | grep 'succeeded' | awk '{print $5}')
# SSL 통신 포트 스캔
scan_check='Extended master secret: yes'
for port in ${PORTS}
do
result=$(openssl s_client -connect "${serverIP}:${port}")
if [[ "${result}" == *"${scan_check}"* ]]
then
echo -e "find ssl port! - ${port}번"
exit 0
fi
echo -e "Port not found"
exit 1
done
옵션 살펴보기
-nv
:-n
옵션은 DNS 조회를 비활성화하고,-v
옵션은 자세한 정보 표시하라는 의미-w 1
: 연결 시도 타임아웃을 1초로 설정-z
: 포트 스캔 모드로, 실제 데이터 전송 없이 포트의 상태만 확인2>&1
: 표준 오류 출력을 표준 출력으로 리다이렉트
한 줄 스크립트 작성
간단하게 한 줄 스크립트로 작성해보자
for port in $(nc -nv -w 1 -z 127.0.0.1 31000-32000 2>&1 | grep 'succeeded' | awk '{print $4}'); \
do openssl s_client -connect 127.0.0.1:${port}; done