Advanced Nmap

KyungH·2025년 4월 17일

Cyber-Security

목록 보기
31/32

📝Nmap?

Nmap은 오픈소스 네트워크 스캔 도구로, 다양한 기능을 제공하는 도구이다.
CTF나 실제 PenTest에서 네트워크 기본 정보수집을 위해 자주 사용하며,
옵션을 통해 다양한 스캔 방법을 시도할 수 있다

Nmap의 대부분의 기능에 대해서 알아봤었는데 상황별/목적별로 매우 다양하고
옵션이 복잡하기 때문에 이 글에서 대부분의 옵션에 대해 정리해보려 한다


📌 Nmap의 목적은?

Nmap을 통해 얻으려는 정보는 크게 두가지로 나눌 수 있다.

1️⃣ 네트워크 범위 내에서 온라인인 호스트 찾기
2️⃣ 온라인 호스트의 열린 포트에서 실행중인 서비스 찾기

위 두가지 목적을 단계별로 수행하여 스캔을 시도한다. 온라인인 호스트를
찾는 과정을 핑 스캔 이라고 하며, 열린 포트를 찾는 과정을 포트 스캔이라고 한다


📌 온라인 호스트 찾기

가장 먼저 주어진 네트워크의 범위 내에서 온라인 호스트를 찾는다.
이 범위는 현재 위치하는 로컬 네트워크일 수도 있고 외부 네트워크일 수도 있다.

크게 분류하면 다음 4가지의 프로토콜을 사용해 호스트를 스캔한다

  • ARP (Link Layer)
  • ICMP (Network Layer)
  • TCP (Transport Layer
  • UDP (Transport Layer)

위 4가지 프로토콜을 활용하여 다양한 스캔을 하는데, 스캔하는 시나리오는
같은 서브넷/외부 서브넷 과 권한이있는지/없는지의 여부로 나누어진다

➕특정 타겟을 스캔하기 전, nmap은 위와 같은 핑 스캔을 먼저 진행하고
자동으로 살아있는 호스트들의 포트 스캔을 시작한다. 이때 포트 스캔은
진행하지 않고 살아있는 호스트만 찾아내기 위해서는 -sn
사용한다

Using ARP

권한 유무와 상관없이 스캔 범위가 같은 서브넷의 경우 우선적으로
ARP 요청을 활용하여 호스트를 찾는다. 이는 3계층으로의 접근이
필요가 없기 때문에 2계층의 ARP 요청만으로도 같은 서브네트워크 내에
해당 요청을 브로드캐스트하고 응답을 받는 호스트가 온라인임을 확인한다.

Nmap은 로컬 네트워크인 경우 자동으로 ARP를 사용하지만 네트워크에
상관없이 이를 강제하기 위해선 -PR옵션을 활용할 수 있다

ARP Scan - sudo nmap -PR -sn MACHINE_IP/24

Using ICMP

우리는 모든 IP 주소를 ping할수있고, 응답으로 ICMP Ping Reply
받는지의 여부를 확인하여 온라인 호스트를 찾을 수 있다

ICMP는 IP 레벨(L3)에서 동작하기 때문에 OS에서 ICMP 패킷을 만드려면
관리자권한이 필요하다. 즉, 아래의 스캔은 권한이 있는 사용자가
외부의 다른 서브넷으로 핑 스캔을 시도할 때 사용하는 방법이다.

같은 네트워크 내에서는 ARP Request가 ICMP Request를 선행한다

가장 직관적이고 간단한 방법으로 사용되나, 항상 가능한 것은 아니다.
대부분의 방화벽이 ICMP echo를 기본으로 차단하기 때문이다.

ICMP echo Request를 사용하기 위해선 -PE옵션을 활용할 수 있고,
이 역시 -sn을 추가하면 온라인인 호스트만 찾고 이후의 포트 스캔은
제외할 수 있다

ICMP echo Request가 자주 차단되기 때문에, 그 대안으로 ICMP Timestamp를
사용할 수 있다. Nmap은 timestamp request (ICMP Type 13)을 보내 타겟으로
부터 timestamp reply (ICMP Type 14)를 받는지 확인한다. 이 과정은 옵션
-PP를 통해 실행할 수 있다

그 외에도 Type17인 Address mask queries를 통해 Type18인 mask reply를
받는지 확인하여 스캔을 진행할 수도 있다. 이는 -PM으로 실행한다

ICMP Echo Scan - sudo nmap -PE -sn MACHINE_IP/24
ICMP Timestamp Scan - sudo nmap -PP -sn MACHINE_IP/24
ICMP Address Mask Scan - s udo nmap -PM -sn MACHINE_IP/24

Using TCP/UDP

TCP SYN Ping

TCP 80번 포트에 SYN 플래그를 보내 포트가 열려있을 경우 SYN/ACK를 통해
응답한다. 포트가 닫혀있는 경우 RST를 받게 된다

TCP SYN ping을 nmap에서 사용하려면 -PS옵션을 통해 지정한다. 옵션 바로
뒤에는 포트번호, 범위, 리스트가 따라오며 -PS21은 21번 포트로 요청을 보낸다
(자주 열려있는 포트를 사용하는 것이 좋다, ex. 80번, 443번)

권한이 있는 사용자(root, sudo)는 TCP 3방향 핸드셰이크를 끝내지 않고도
포트로부터 오는 첫 응답을 보고 빠르게 호스트가 온라인임을 판단할 수 있다
권한이 없는 경우 포트가 열려있으면 3방향 핸드셰이크를 끝내야 한다

TCP ACK Ping

이 스캔은 권한이 있는 사용자만이 사용할 수 있으며 패킷에 ACK 플래그를
추가하여 보낸다. 옵션은 -PA를 사용하며 TCP SYN과 동일하게 뒤에 포트번호를
지정해 줄 수 있다. 지정하지 않을 경우 기본으로 80번이 사용된다

ACK 플래그를 설정한 패킷을 보내고 온라인인 타겟은 해당 ACK에 맞는 연결이
없기 때문에 RST 플래그를 응답으로 보낸다. 이를 통해 온라인임을 확인한다

UDP Ping

TCP SYN Ping과는 다르게 UDP에서는 타겟으로부터의 응답을 기다리지 않는다.
UDP 패킷을 닫혀있는 포트로 보낼 경우 ICMP Port Unreachable 패킷을 받게되어
이를 통해 해당 타겟이 오프라인임을 알 수 있다

UDP 스캔은 -PU를 통해 진행할 수 있다

TCP SYN Ping Scan - sudo nmap -PS22,80,443 -sn MACHINE_IP/30
TCP ACK Ping Scan - sudo nmap -PA22,80,443 -sn MACHINE_IP/30
UDP Ping Scan - sudo nmap -PU53,161,162 -sn MACHINE_IP/30


📌 온라인 호스트의 열린포트 찾기

네트워크에서 온라인인 호스트를 핑 스캔을 통해 찾았으면, 해당 호스트에서
실행중인 서비스, 즉 열린포트를 찾아야 한다.

포트 스캔에 대해 알아보기 전에 포트에 대해서 생각해보면 단순하게
포트가 열리고 닫힌경우만 고려하나, 실제 상황에선 방화벽의 차단을 고려하므로
포트의 상태는 다음과 같이 6가지로 구분할 수 있다

  1. Open : 특정 포트에서 서비스가 실행되고 있음

  2. Closed : 어떠한 서비스도 실행되고 있지 않음, 방화벽에 차단되지 않고
    포트로의 접근은 가능한 상태

  3. Filtered : nmap이 포트가 열려있는지 닫혔는지 식별할 수 없음, 방화벽의
    차단으로 인해 포트에 접근할 수 없다

  4. Unfiltered : 포트에 접근할 수 있으나 포트가 열려있는지 닫혀있는지
    확인이 불가능, ACK scan (-sA) 사용시 발생할 수 있음

  5. Open | Filtered : Nmap이 포트가 열린건지 필터링된건지 식별 불가능

  6. Closed | Filtered : Nmap이 포트가 닫힌건지 필터링된건지 식별 불가능

➕포트가 열려있다는 것은 어떠한 서비스던 해당 포트를 열어 bind 되면서
실행하는 것을 말한다. 즉 열려있는 포트는 해당 포트를 Listen하고있는 서비스가
무조건 존재한다. 또한 Closed는포트자체의 “접근”은 가능하나 bind된 서비스가
존재하지 않고, 응답은 가능한 상태를 말한다

자주 사용하는 포트 스캔은 다음과 같이 3가지로 분류할 수 있다

  • TCP Connect Port Scan
  • TCP SYN Port Scan
  • UDP Port Scan

TCP Connect Scan

TCP Connect Scan은 TCP의 3 방향 핸드셰이크를 활용한다. 클라이언트가
TCP SYN을 보내면 서버는 SYN/ACK로 응답하고 다시 클라이언트가 ACK
응답하면서 핸드셰이크의 과정이 완료된다

우리의 목적은 TCP 연결을 확립하는 것이아니라 TCP 포트를 스캔하는 것이기
때문에 연결이 완료되면 RST/ACK를 보내 바로 연결을 해제한다

권한이 없는 사용자의 경우 TCP 포트를 스캔하려면 TCP Connect Scan 밖에 없음

TCP Connect Scan은 -sT를 통해 실행할 수 있다. 기본으로 실행할 경우
가장 자주 사용하는 1000개의 포트를 스캔하며 -F를 사용하면 더 빠른스캔을
위해 자주 사용하는 100개의 포트를 스캔한다. 또한 -r을 통해 포트를 랜덤이
아닌 순서대로 스캔할 수 있다. (타겟이 부팅 시 사용, 방화벽 탐지가능성 높아짐)

TCP SYN Scan

권한이 있는 사용자만 실행할 수 있으며, 이는 3방향 핸드셰이크를 끝내지 않고
서버로 부터 응답을 받는 즉시 RST를 보내 연결을 종료하는 방식으로, 더
빠르고 간결하며, 해당 과정의 기록을 줄인다

TCP SYN Scan은 -sS를 통해 실행할 수 있다. 권한이 있는 사용자가 nmap을
사용할 경우 TCP SYN Scan이 기본으로 사용된다

UDP Scan

UDP 스캔은 TCP 처럼 핸드셰이크의 과정을 거치지 않기 때문에 열려있는
포트로부터 응답을 받기를 기다릴 수 없다. 그대신 UDP 패킷이 닫혀있는 포트
전송될 경우, ICMP port unreachable error (Type 3) 을 응답받기 때문에 이를
통해 해당 포트가 닫혀있음을 확인할 수 있다.

UDP Scan은 -sU를 통해 실행하며 open | filtered가 나올 수 있다

TCP Connect Scan - nmap -sT 10.10.191.32
TCP SYN Scan - sudo nmap -sS 10.10.191.32
UDP Scan - sudo nmap -sU 10.10.191.32


📌 열린 포트에 대한 추가 정보 얻어내기

열린 포트를 찾았으면 해당 포트에서 실행중인 서비스를 식별하는 것외에도
Nmap은 서비스의 버전이나 타겟의 OS, 네트워크 경로 및 취약점까지 스캔하는
기능을 제공한다

Service Detection

-sV를 추가하여 열러있는 포트에서 실행중인 서비스를 식별하고 그 서비스의
버전정보를 확인할 수 있다. --version-Intensity_LEVEL을 통해 0부터 9까지
스캔하는 수준을 정할 수 있다. (ex, --version-light, --version-all)

-sV는 Nmap이 TCP 3방향 핸드셰이크를 통해 연결을 수립시키도록 한다. 연결을
확립하는 이유는 완전한 통신없이는 버전 정보를 가져올 수 없기 때문이다. 즉,
핸드셰이크를 끝내지 않는 -sS-sV를 같이 사용할 경우 -sS의 스텔스성이
깨질 수 있다. 그럼에도 불구하고 빠르고 정확한 탐지를 위해 자주 같이 사용됨

Nmap의 실행 결과에서 SERVICE 컬럼은 자주 사용하는 포트의 경우 TCP 연결을
통해 정보를 얻어오는 것이 아니라 자체적으로 해당 포트에서 자주 사용하는
서비스를 임의로 가정하여 제공한다. 그와 다르게 -sV 사용 시 출력되는 VERSION
컬럼은 실제 TCP 연결을 통해 정보를 가져오므로 다른 컬럼과 다르게 추정값이 아님

OS Detection

Nmap은 운영체제의 정보도 출력할 수 있다. 이는 -O를 추가하여 사용할 수 있다

OS의 정보는 정확하게 탐지하여 출력할 수 있으나 같이 출력되는 커널버전은
추측된 값으로, 틀리는 경우가 많다

편리한 기능이지만, 정확도에 영향을 주는 요소가 있다. Nmap이 최소한 하나의
열린 포트와 닫힌 포트를 찾아야 올바른 추측이 가능하다. 또한 최근에는 가상화와
비슷한 기술로 인해 사용자의 OS 지문이 훼손되는 경우가 많아 OS에 버전에 대한
정보는 참고로 확인하고 넘기는 것이 좋다

Traceroute

Nmap이 나와 타겟의 경로를 탐색하도록 하고 싶으면 --traceroute를 사용한다.
기존에 사용하던 traceroute와는 살짝 다른 동작을 수행하는데, 기존에는 낮은
TTL을 사용하여 타겟에 도달할 때까지 TTL을 증가시키며 탐색을 하였다면, Nmap은
높은 TTL을 사용하여 점차 감소하는 방식으로 진행한다

Nmap Scripting Engine (NSE)

Nmap에서는 Lua 언어를 사용한 스크립트를 제공한다. Nmap Scripting
Engine(NSE)
는 Lua 언어를 해석하여 Nmap이 이를 실행시킬 수 있도록하는
인터프리터이다. 기본적으로 600개가 넘는 스크립트를 제공한다
/usr/share/nmap/scripts (수많은 .nse파일을 확인할 수 있음)

특정 스크립트를 지정하여 그것만 실행하도록 할 수 있고, 카테고리로 정리된
스크립트들 중에서 기본으로 사용하는 --script=default를 사용할 수 있다.
또한, 이 기본 스크립트는 -sC를 추가하여 간단하게 사용할 수 있다

--script "SCRIPT-NAME"을 통해 사용하고싶은 스크립트를 지정할 수 있으며,
해당 스크립트의 동작을 잘 모르겠다면, less나 다른 텍스트 뷰어로 해당
스크립트 파일을 열어서 확인할 수 있다. 어떤 스크립트들은 공격을 수행하거나
브루트 포싱을 시도하기 때문에 사용에 주의해야 하는 것들도 있다. 또 어떠한
스크립트는 특정 환경에서만 유용할 수 있기 때문에 사용전에 올바른 환경인지
확인하여 시간을 낭비하는 일이 없도록 해야 한다

외부에서 만들어진 스크립트를 가져와서 사용할 수도 있다. 이는 신뢰하는
출처가 아닌 이상 절대 실행해서는 안되며, 매우 주의해야 함

-sV - determine service/version info on open ports
-sV --version-light - try the most likely probes (2)
-sV --version-all - try all available probes (9)
-O - detect OS
--traceroute - run traceroute to target
--script=SCRIPTS - Nmap scripts to run
-sC or --script=default - run default scripts
-A - equivalent to -sV -O -sC --traceroute

📌 세부적인 옵션 정리

자주사용하는 포트 1000개를 기본적으로 스캔할 수 있으나, 원하는 포트를
-p22,80,443과 같이 지정할 수 있고, -p1-1023과 같이 범위를 설정할 수도 있다.

-p-는 모든 65535개의 포트를 스캔하며 -F는 자주 사용하는 100개,
--top-ports10은 자주 사용하는 10개를 스캔한다

-T<0-5>까지 스캔 시간을 지정할 수 있으며 -T5가 가장 빠르다.
IDS의 탐지를 우회하기 위해선 -T0-T1을 사용해야 한다. 아무 옵션도 지정
하지 않을 경우 nmap은 기본으로 -T3의 속도로 수행한다. -T5는 가장 공격적인
방법으로, 패킷 손실이 발생할 수 있어 정확도가 떨어질 수 있다

더 세부적으로는 초당 보내는 패킷의 수를 지정할 수도 있으며 이는
--min-rate <number>, --max-rate <number>로 지정할 수 있다

마지막으로 과정의 병렬처리는 --min/max-parallelism <numprobes>를 통해
지정하여 한번에 보낼 패킷(프로브)의 수를 지정하여 병렬로 처리한다

-p- - all ports
-p1-1023 - scan ports 1 to 1023
-F - 100 most common ports
-r - scan ports in consecutive order
-T<0-5> - -T0 being the slowest and T5 the fastest
--max-rate 50 - rate <= 50 packets/sec
--min-rate 15 - rate >= 15 packets/sec
--min-parallelism 100 - at least 100 probes in parallel

📌 정리

그래서 뭘 써야하나?

위에서 소개한 스캔외에도 더 많은 방식이 있으나 그러한 스캔들은
매우 특수한 환경, 특수한 목적을 가지고 실행되는 스캔들 이므로 필요할 때만
사용하면 된다. 다음은 대부분의 목적에서 사용하는 조합을 정리한 것이다.

호스트 생존 확인 (핑 스캔 전용)

sudo nmap -sn 192.168.0.0/24

-sn: 포트 스캔 없이 호스트만 살아있는지 확인
로컬이면 ARP Ping, 외부면 ICMP 등 자동으로 씀

서비스 식별 + 기본 스크립트 스캔 (정찰)

sudo nmap -sS -sV -sC -T4 -Pn TARGET

-sS: 스텔스 SYN 스캔 (빠르고 은밀함)
-sV: 서비스 버전 식별
-sC: 기본 NSE 스크립트 실행 (보안취약점, 인증우회 등 확인)
-T4: 빠르게 (과격하진 않음)
-Pn: Ping 생략 (방화벽 회피용)

빠른 포트 스캔 (눈치 보기)

sudo nmap -sS -p- --min-rate 1000 -T4 TARGET

-p-: 1~65535 전체 포트
--min-rate: 빠르게 쏘기 (너무 높이면 탐지될 수 있음)
빠르게 포트 어떤 게 열렸는지 보고 싶을 때

취약점 스캔 (NSE 활용)

sudo nmap --script vuln -p 80,443 TARGET

--script vuln: 보안취약점 관련 스크립트 실행
-p: HTTP나 특정 서비스 포트 지정

탐지 회피 + 천천히 스캔

sudo nmap -sS -sV -sC -T1 --max-retries 3 --scan-delay 1s TARGET

-T1: 느리게 (탐지 회피 목적)
--scan-delay, --max-retries: IDS 우회/우회 테스트용


Conclusion

이 글에서 소개한 수많은 옵션을 전부 외워서 사용하는 것은 불가능하다.

어떠한 환경이 주어지고, Nmap을 사용해야 하는 목적이 명확할 때
그것에 맞게 얼마나 방어 기술의 탐지를 회피하면서 정확한 값을 얻어내도록
조합을 구성할 수 있냐에 따라 Nmap의 사용 실력이 정해지는 것 같다

0개의 댓글