Profile picture

[Linux] 열린 포트 검색 및 포트 스캔하기 [nmap / netcat(nc)]

JaehyoJJAng2023년 05월 21일

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

Loading script...