SSH Port Forwarding & Tunneling

"안전한" 해킹은 단순히 타겟에 연결하여 말웨어를 설치한 다음 데이터를 손상시키는 것 뿐이 아니다.

예를 들어보자.

당신은 타겟 머신 내부에서 실행되고있는 내부 시스템을 침투하여러 한다. 하지만 보통 이러한 경우 외부에서 오는 무차별적인 연결 시도를 막고자 중간 방화벽이 일정포트만 열어놓는다. 랜덤포트로 타겟 머신에 쓰이지 않는 포트를 백도어 포트로 사용하여 해킹을 시도해야 하는데 현실적으로 방화벽이나 여러 방어 보호막은 이러한 비정상적 포트 사용을 막기때문에 연결이 쉽지않다. 만약에 타겟의 실수로 불필요한 오픈 포트를 열어 놓아 공격자가 수월하게 해킹을 할수 있도록 도와 준다 하더라도 공격자와 타겟 사이의 연결 트래픽이 암호화 ( Encryption )가 되어있다는 보장이 없다.

이럴때는 어떻게 해야 할까? 아래의 2가지 SSH 터널의 종류를 통해 알아보자.

SSH 터널이란?

일단 SSH 터널이란 무엇일까? SSH Tunneling 또는 Port Forwarding이라고도 부르는 개념으로 암호화된 SSH 연결을 통해 데이터를 안전하게 전송하는 방법이다. 또한 SSH 터널을 사용하면 로컬 포트(즉, 현재 자신의 PC에 있는 포트)에 대한 연결을 안전한 터널을 통해 원격 시스템으로 전달할 수 있다.

예를 들어, SSH 터널링을 사용하여 인터넷을 통해 접속할 수 없는 내부 서버에 접근할 수 있으며, 로컬 머신에서 원격 서버의 애플리케이션을 실행할 수 있다. 더 나아가자면 귀찮지만 SSH 터널링은 VPN의 대안으로 사용될 수 있다.

로컬 포트 포워딩을 사용한 SSH 터널

로컬 포트 포워딩이란 말그대로 로컬포트를 리모트포트로 "포워딩" 시켜주는 방식이다.

로컬 포트 ​​포워딩의 일반적인 용도는 다음과 같다.

  • Jump server ( 클라이언트와 서버 사이의 중간 서버) 를 통한 터널링 세션 및 파일 전송

  • 외부에서 리모트 머신 내부 네트워크의 서비스에 연결

  • 인터넷을 통해 원격 파일 공유에 연결

보통 로컬 포워딩 방식은 회사에서 다중 서비스를 연결할 때 쓰인다. 아래와 같이 당신은 여러 고객을 두고 있는 MSSP서비스를 제공하고 있다 생각해 보자.

고객이 하나 일때는 문제가 없겠지만 100개의 고객의 서비스를 관리하는 서비스 제공자 입장에선 리모트로 운영되고 있는 고객 서비스를 메뉴얼하게 접근해 관리하는 방식은 매우 비효율적이다. 대신에 아래와 같이 고객의 시스템을 로컬에서 관리하기 위해 로컬 포워딩을 해준다면 훨씬 더 편한 삶을 살수있다.

또한 레드팀 SMTP GoPhish 구축법에서도 배웠듯 Ubuntu 서버는 그래픽을 제공하지 않으므로 로컬 포워딩을 해주면 로컬 시스템에서 리모트 서버에서 실행되는 GoPhish를 로컬에서 접근할수있다.

공격자 관점 시나리오

사실 로컬 포워딩 방식은 공격 시나리오에서 딱히 쓰인다 말하긴 어렵다. 하지만 로컬 포워딩의 개념을 이해하면 여러 목적으로 사용할수있다. 예를 들면 당신은 급히 회사 인트라넷에서 실행되는 서버에 접근해야 한다 해보자. 필자가 사는 곳은 회사에 가려면 차로 최소 20KM를 달려야 하기때문에 기름값도 비싼 요즘에 그런 뻘짓은 하지 않는다.

물론 정상적인? 회사라면 회사 VPN으로 리모트로 연결이 되어 있겠지만 여기서 그런 딴지를 걸면 필자는 할말이 없다.

대신 아래와 같이 필자의 IP는 10.0.0.1, 회사 내부 중요 서버 IP는 10.0.0.5이다. 중요한 서버다 보니 포트는 22와 443만 열여놨다. 따라서 10.0.0.5 서버 3333 포트는 리모트로 접근 불가다.

그렇다면 리모트 서버에서 로컬로 실행되는 서비스를 10.0.0.1이 볼려면 어떻게 해야할까? 여기서 사용되는 개념이 로컬 포워딩이다.

다행이도 10.0.0.5는 22 포트 접근이 가능하다. 때에 따라 다르겠지만 포트 22와 443은 대부분의 서버에서 오픈 포트로 사용한다.

따라서, 다음 커맨드를 통해 안쓰는 포트 2222로 로컬 포워딩을 해주면 아래와 같은 연결이 완성된다.

ssh -L 2222:10.0.0.5:3333 <타겟 username>@10.0.0.5

이로써, 10.0.0.1은 10.0.0.5 3333 포트에서 실행되는 서비스를 로컬에서 2222 포트로 접근할 수 있다.

SSH 로컬 포워딩 커맨드 포멧은 다음과 같다:

ssh -L <LOCAL_HOST>:<LOCAL_PORT>:<REMOTE_HOST>:<REMOTE_PORT> <[USER@]SERVER_IP> 
  • LOCAL_HOST:LOCAL_PORT - 로컬 호스트의 아이피 및 포트 번호다. LHOST가 생략되면 SSH 클라이언트는 LOCALHOST에 바인딩 된다. 위의 예제에선 LOCAL_HOST가 생략 되었기 때문에 10.0.0.1의 로컬 호스트로 자동으로 바인딩 된다.

  • REMOTE_HOST:REMOTE_PORT - 원격 타겟 호스트의 IP 및 포트 넘버이다.

  • [USER@]SERVER_IP - 원격 타겟 SSH 사용자 및 서버 IP 주소 이다. 위의 예제에선 REMOTE_HOST로 10.0.0.5 이다.

물론 위와 같은 방식을 사용해서 여러가지 리모트 리소스를 로컬에서 실행할수 있지만 회사나 학교 인트라넷은 인트라넷이 사용하도록 허가하는 덴 다 그만한 이유가 있으므로 필요하다면 꼭 허가를 맡고 연결하길 바란다.

리모트 포트 포워딩을 사용한 SSH 터널

로컬 포트 포워딩에 이어 리모트포트 포워딩에 대해 알아보자.

리모트 포트 ​​포워딩의 일반적인 용도는 다음과 같다.

  • 리모트 서버에서 공용 인터넷으로 서비스를 노출한다.

  • 해킹한 타겟 머신의 내부서비스를 의도적으로 외부에 노출한다.

  • 그리고 ... 몇 가지 난해한 예를 생각할 수 있지만 머리가 아프다.

원격 포트 포워딩은 로컬 포트 ​​포워딩의 반대 개념으로 원격(SSH 서버) 시스템의 포트를 로컬(SSH 클라이언트) 시스템의 포트로 전달한 다음 목적 시스템의 포트로 전달한다. 예를 들어, 외부 공간에 의도적으로 로컬 서비스를 노출하려고 한다 가정하자. 물론 이를 위해서는 Public 게이트웨이 서버가 필요하다.

말이 좀 어려우니 아래 다이어그램으로 설명해 본다.

Choi는 내부 192.168.137.136 포트 80에서 웹 서버가 실행되어 있는것을 확인했다. Choi는 외부에서 Groot 팀원이 내부 서버를 접근할 수 있게 리모트 VPS 게이트웨이에 리모트 포트 포워딩을 해주어 외부에서도 Choi가 있는 로컬 서비스를 외부에있는 Groot가 접근할 수 있게 해준다.

데모를 위해 Digital Ocean 또는 AWS로 간단히 Gateway 호스트를 준비한다. 본 데모에서는 기본 Ubuntu 서버를 만들었다. 따로 설치할 라이브러리는 없고 퍼블릭 IP만 기억해 준다.

공격자는 로컬 서버 192.168.137.136 에서 다음과 같은 Admin Panel이 실행되는것을 확인한다.

공격자는 같은 내부 네트워크에 있는 192.168.137.136 웹 서버 포트를 외부 리모트 VPS의 8889 포트에 포워딩을 해주어 내부 서버를 외부에 노출시킨다. 이를 위한 리모트 포트 포워딩 SSH 커맨드는 다음과 같다:

ssh -N -R 8889:192.168.137.136:80 root@209.38.242.65

내부 서버가 리모트 VPS 공용 IP와 포트넘버 8889으로 외부로 노출 된것을 확인할 수 있다.

공격자 관점 시나리오

앞서 언급한 난해한 예를 생각하자면 다음과 같을 수 있다. 공격자는 타겟 중요 서버에 일부러 리버스 쉘 리스너를 로컬 포트 87에 열어 놓는다. 그리고 리모트 포워딩을 통해 리모트 VPS의 포트 1111에 연결하는 외부 트래픽을 SSH 터널을 통해 87로 포워딩이 되어 결국 Groot는 192.168.137.136의 리버스 쉘을 얻게 된다.

SSH 리모트 포워딩 커맨드 포멧은 다음과 같다:

ssh -R [REMOTE:]REMOTE_PORT:DESTINATION:DESTINATION_PORT [USER@]SSH_SERVER
  • [REMOTE:]REMOTE_PORT - 원격 SSH 서버의 IP 및 포트 번호입니다. REMOTE가 생략되면 SSH 클라이언트는 모든 인터페이스에 바인딩됨을 의미한다 . 위의 예제에선 REMOTE가 생략 되었기 때문에 모든 인터페이스에 바인딩 된다.

  • DESTINATION:DESTINATION_PORT - 목표 호스트의 IP 또는 호스트 이름 및 포트다.

  • [USER@]SERVER_IP - 원격 SSH 사용자 및 서버 IP 주소다.

마치며

SSH 연결은 트래픽을 암호화해줄 뿐만 아니라 간단하게 데이터를 주고 받을때는 편리하고, 안전하게 사용할 수 있다는 장점이 있다 (단점은 속도가 느릴순 있다).

SSH 포트 포워딩은 강력한 기능이므로 신중하게 관리해야 한며, 높은 보안 표준은 전체 프로세스에서 유지되어야 한다. 이번 실습에서는 SSH 로컬 및 리모트 포워딩, 사용해야 하는 명령 및 시스템에서 이를 구현하는 방법을 배웠다.

이 모든 실습을 요약하자면 다음과 같다:

  • 로컬 포트 포워딩(ssh -L)은 로컬 포트에서 수신하는 SSH 클라이언트임을 의미한다. 로컬 포트 포워딩은로컬포 트를 리모트 포트로 "포워딩" 시켜주는 방식이다.

  • 리모트 포트 포워딩(ssh -R)은 리모트 포트에서 수신하는 SSHD 서버임을 의미한다. 리모트 포트 포워딩은 리모트 포트를 로컬 포트로 "포워딩" 시켜주는 방식이다.

다음 실습에서는 Dynamic 포트 포워딩에 대해 다룬다.

레퍼런스

https://www.ired.team/offensive-security/lateral-movement/ssh-tunnelling-port-forwarding https://www.ssh.com/academy/ssh/tunneling-example https://www.ssh.com/academy/ssh/tunneling-example

Last updated