G2H

보안 리서치 · 레드팀/블루팀 · DFIR · Cloud · Tooling

최신 글 보기

최근에 작성된 글들을 확인해보세요.

Local Port Forwarding

Pentest/Pentest

Port Forwarding

포트포워딩은 NAT의 한 응용 프로그램으로, 패킷이 라우터 혹은 방화벽과 같은 네트워크 게이트웨이를 통과하는 동안

하나의 주소와 포트번호 조합에서 다른 주소와 포트 번호로  통신 요청을 리다이렉션을 하는 과정이다.

이로인해 내부망에 존재하는 호스트의 서비스를 게이트웨이 반대편 즉, 외부 네트워크에 존재하는 호스트가 접근할 수 있도록 사용된다.

Local Port Forwarding 

로컬 포트 포워딩 (ssh -L) : 로컬에서 실행 중인 것처럼 원격 서비스에 접속

가장 일반적인 포트 포워딩 유형으로, 사용자가 로컬 컴퓨터에서 다른 서버로 연결할 수 있도록 하는데 사용된다.

즉, 동일한 컴퓨터에서 SSH 프로토콜을 사용하여 다른 클라이언트 애플리케이션에 데이터를 전송할 수 있게된다. 

 

즉, 쉽게말해 사용자의 로컬 컴퓨터에서 특정 포트를 개방하고 그 포트로 들어오는 트래픽을 SSH를 통해 원격 서버로 암호화 전송하여, 최종적으로 원격 서버가 지정된 목적지 호스트:포트로 트래픽을 중계해주는 기법이다.

이러한 로컬 포트 포워딩은 아래와 같은 이점을 가진다.

  1. 방화벽 접근 우회 : 방화벽에 의해 차단된 서비스에 접근해야 하는 경우 로컬 포트 포워딩을 통해 보안을 유지하면서 이러한 접근제어를 우회할 수 있다.
  2. 데이터 암호화 : SSH 프로토콜을 사용하여 터널을 생성 후 데이터를 전송하므로, 데이터 전송을 암호화하게 된다.
  3. 웹 애플리케이션 액세스 : 마치 로컬 컴퓨터에 있는 것처럼 원격 서버에서 실행되는 웹 애플리케이션에 액세스 할 수 있다.

작동 원리 및 메커니즘

일반적으로 클라이언트 <-> 서버 모델로 이해할 수 있다. 

사용자가 ssh 클라이언트로 원격 ssh 서버에 접속할 때 -L 옵션을 지정하면, 로컬 호스트에 특정 포트 리스너가 생성된다.

예를 들어 ssh -L 8000:10.0.1.10:80 user@ssh_server1 명령을 싱행하게 되면, 자신의 TCP 포트 8000번에서 리스닝을 시작하고, 자신의 8000번 포트로 들어오는 연결을 원격 서버(ssh_server1)의 10.0.1.10 의 80번 포트로 전달하도록 터널링 한다.

 

이 과정에서 해당 트래픽을 ssh 세션 안에 마련된 암호화 채널로 캡슐화 하여 원격 ssh 서버로 보낸다.

이러한 ssh 포워딩은 세션 내 멀티플렉싱으로 구현되기에 하나의 ssh 연결에서 여러 개의 포트 터널을 동시에 열거나 다중 접속을 처리할 수 있다. 

 


또한 Windows 환경에서도 최신 Windows 10+ 에서는  OpenSSH 클라이언트가 내장되어 있어 리눅스와 동일한 SSH 명령을 사용할 수 있다. GUI 도구인 PuTTY 의 경우 Connection > SSH > Tunnels 메뉴에서 소스 포트와 대상 (<호스트>:<포트>)을 설정하여 로컬/원격/동적 포워딩을 손쉽게 구성할 수 있다. PuTTY의 커맨드라인 툴인 plink.exe 역시 -L, -R, -D 옵션을 지원하여 스크립트나 배치 작업에 활용된다.

정리하면, 로컬 포트 포워딩은 로컬에서 SSH 서버까지 안전한 "파이프"를 만들고, 그 파이프 양 끝단에서 소켓을 열어 원하는 위치로 트래픽을 이어주는 과정으로 작동한다.

다단계 네트워크에서 SSH 로컬 포트 포워딩 활용

다단계 네트워크는 일반적으로 외부망 -> DMZ -> 내부망 -> DB, 민감데이터망과 같이 계층적으로 구성된다.

외부 인터넷과 직접 연결된 DMZ에는 배스천 호스트(Bastion Host)라는 점프 서버를 배치하고, 민감한 내부 자원은 내부망에 두어 직접 노출하지 않도록 설계한다.

이로 인해 공격자가 내부망에 직접 침투하기 어렵게 설계되어 있으며, dmz의 배스천 호스트 혹은 공개 서버를 공격 표적으로 삼고 

이러한 배스천 호스트를 통한 SSH 터널링을 통해 통과해야한다. 이 때 사용되는 기법이 로컬 포트 포워딩(Local Port Forwarding)가 가장 많이 사용된다. 이 과정에서 배스천 호스트를 jump 서버라고도 부른다.

 

이렇게 SSH 접속이 허용된 배스천 호스트가 공격에 성공할 경우 피벗 포인트가 되어 내부망으로의 통로가 열리게 되는 것이다.

즉, 배스천 호스트(또는 jump호스트)서버 계정이 탈취되면 외부와 내부를 연결해주는 보안 게이트웨이 서버가 되며, 공격자는 SSH 터널을 통해 내부 네트워크의 서비스들에 접속하여 방화벽 규칙을 우회할 수 있게된다.

피벗 호스트(Pivot Host)는 보통 침해 사고나 모의해킹 관점에서 사용되며, 공격자가 획득한 중간 거점 시스템을 의미한다. 피벗팅(pivoting)은 공격자가 한 대의 장비를 넘어 또 다른 내부망으로 횡적이동을 하는 기술이다. 이 때 이용되는 손ㅅ강된 머신을 피벗 호스트 또는 점프 호스트라고 부른다,.

이러한 과정을 거치면 결과적으로 내 PC의 localhost:8080 으로 접속하면 내부망의 10.0.1.10:80 웹 서비스에 접속하는 것과 같은 효과를 낼 수 있다.

여러 대의 배스천 호스트(Jump Host) 가 존재할 경우

네트워크 구조상 한 번의 점프만으로 접근할 수 없고 여러 대의 점프 호스트를 연쇄적으로 거쳐야 한다면, 로컬 포트 포워딩을 다단계로 체인 형태로 접근할 수 있다.

예를 들어, DMZ에 배치된 1차 점프 서버와 내부망의 2차 점프 서버를 차례로 거쳐 최종 DB 서버에 접근하는 시나리오를 생각해보자

  1. 첫 번째 SSH 세션을 열어 로컬 포트를 2차 점프 서버로 포워딩 한다. 
    • ssh -N -L 10022:jump2.internal:22 user@jump 명령을 통해서 내 PC의 10022 포트로 접속시 jump1을 통해 jump2의 ssh(22)로 전달되는 터널이 생성된다.
  2. 두 번째 SSH 세션은 -p  옵션으로 localhost의 10022 포트(jump2의 ssh)을 사용한다.
    • ssh -N -L 13306:db.internal:3306 -p 10022 user@localhost 명령을 통해 이미 열린 1단계 터널을 통해 jump2에 접속하며, jump2에 접속하면서 로컬 13306 포트를 최종 DB 서버의 3306 포트로 포워딩 한다.
    • 최종적으로 내 PC의 localhost:13306에 접속하는 것이 jump2를 통해 DB 서버의 3306 포트에 접속하는 경로가 된다.
    • 즉, 로컬 -> jump1( SSH1터널 ) -> jump2 ( SSH2터널 ) -> DB 서버로 트래픽이 흐르게 된다.

이 과정에서 OpenSSH 7.3+ 에서는 ,(콤마)를 통해 여러 점프 호스트( ProxyJump )를 지정할 수 있다.

ssh -J user1@jump1.example.com,user2@jump2.internal.com -L 13306:db.internal.com:3306 user_db@desthost

위 명령어와 같이 jump1을 통해 jump2로 점프한 후 jump2 내부의 db.internal.com:3306으로 로컬 포트 포워딩을 설정할 수 있다. 

윈도우의 경우 windows 10 이후 제공되는 OpenSSH 및 PuTTY 그리고 PuTTY 커맨드라인 버전인 Plink를 통해 동일하게 SSH Local Port Forwarding이 가능하다.

서비스별 포트 포워딩

  1. 웹 서비스 (HTTP/HTTPS): 내부 웹 서버에 접근하기 위해 로컬 포트를 웹 포트(80 또는 443)에 연결하면 브라우저를 통해 직접 접속할 수 있다.
  2. 데이터베이스(DB) 서비스: 데이터베이스 서버들은 일반적으로 전용 포트(예: MySQL 3306, PostgreSQL 5432, MSSQL 1433 등)를 사용한다. DB 포트는 외부에 노출되지 않도록 하는 경우가 많아, 개발자나 DBA는 로컬 포워딩으로 접근하는 경우가 흔하다.
  3. 원격 데스크톱 (RDP): 앞서 다룬 대로, RDP(포트 3389)를 SSH로 포워딩하면 원격 데스크톱 연결을 암호화된 터널로 실행할 수 있다. 예를 들어 본사 내부망의 Windows 서버에 접속해야 하는 경우, VPN 대신 배스천을 통한 SSH 터널링 + RDP 조합으로도 업무가 가능하다. mstsc (원격 데스크톱 앱)나 Mac의 Microsoft Remote Desktop에서도 대상 PC 이름에 localhost:포트 형식으로 지정하면 연결된다.
  4. 파일 공유 (SMB/CIFS): 윈도우 파일 공유 프로토콜인 SMB는 기본 포트가 445이며, 보안상 이 포트를 외부에 열어두는 일은 극히 위험하여, 간혹 내부 파일 서버에 접근해야 할 때도 SSH 터널을 활용할 수 있다. Linux 또는 Mac에서 ssh -L 445:fileserver.internal:445 user@bastion을 실행하면, 로컬 시스템에서 //localhost/공유이름으로 SMB 접속 시 터널을 통해 내부 파일서버에 연결된다. 다만 Windows에서 SMB 터널링은 제약이 있다.

이 밖에도 내부 SMTP 서버(25번), Redis/Memcached(6379/11211) 등 어떤 TCP 서비스든 포트 포워딩이 가능하다.

요약하면, 클라이언트에서 포트만 지정할 수 있으면 대부분의 서비스를 로컬 포트 포워딩으로 활용할 수 있으며, 다만 UDP 기반 서비스(예: DNS 53/udp, 일부 VoIP 등)는 SSH가 TCP 터널만 지원하므로 이 방식으로 처리할 수 없다.