Proxychains 를 이용한 동적 포트 포워딩

사이버 보안Beginner
지금 연습하기

소개

모의 해킹 및 레드 팀 활동을 수행하다 보면, 외부에서 접근 가능한 서버를 침투한 후, 공격자의 머신에서 직접 접근할 수 없는 내부 네트워크에 해당 서버가 연결되어 있음을 발견하는 경우가 많습니다. 이러한 내부 시스템을 공격하려면 침투한 서버를 통해 트래픽을 라우팅할 방법이 필요합니다. 이 기술을 "피보팅 (Pivoting)"이라고 합니다.

피보팅은 관점을 전환하는 것입니다. 더 이상 원래 머신의 네트워크 위치에서만 테스트하는 것이 아니라, 침투한 호스트를 새로운 관찰 및 접근 지점으로 활용하는 것입니다.

가장 강력하고 일반적인 피보팅 기술 중 하나는 SSH 동적 포트 포워딩을 사용하여 SOCKS 프록시를 생성하고, 이를 proxychains라는 도구와 결합하는 것입니다. 이 조합을 사용하면 Nmap, Nikto, Metasploit 과 같은 거의 모든 외부 네트워크 도구를 침투한 호스트를 통해 원활하게 라우팅할 수 있습니다.

이번 실습에서는 Docker 컨테이너에서 실행되는 전용 피벗 호스트에 SSH 로 접근할 수 있는 시나리오를 시뮬레이션합니다. 동일한 사설 Docker 네트워크에 있는 두 번째 컨테이너는 숨겨진 내부 웹 서비스를 호스팅합니다. 이 서비스는 LabEx VM 에 직접 노출되지 않으므로 SSH 피벗 호스트를 통해서만 접근해야 합니다. SSH 동적 포트 포워딩을 설정하고, proxychains를 구성하며, 이를 사용하여 피벗 호스트를 통해 숨겨진 서비스에 접근하는 방법을 배웁니다.

SSH 동적 포트 포워딩 설정 (-D)

이 단계에서는 컨테이너화된 피벗 호스트에 SSH 연결을 설정하고 로컬 SOCKS 프록시를 생성합니다.

동적 포트 포워딩을 사용하면 공격 머신에서 로컬 포트를 지정할 수 있습니다. SSH 클라이언트는 이 포트에서 대기하며, 애플리케이션이 이 포트에 연결할 때마다 해당 연결은 보안 SSH 채널을 통해 SSH 서버로 전달됩니다. 그러면 SSH 서버가 프록시 역할을 하여 트래픽을 최종 목적지로 전달합니다.

이는 단일 포트 포워딩보다 유연합니다. SOCKS 프록시는 하나의 터널을 통해 다양한 목적지 요청을 처리할 수 있기 때문입니다.

이를 설정하기 위해 SSH 명령에서 -D 플래그를 사용합니다. 또한 연결이 백그라운드에서 원활하게 실행되도록 몇 가지 다른 플래그를 함께 사용합니다.

실습 환경은 ~/project/pivot_key에 개인 키를 생성하고 피벗 호스트의 SSH 서비스를 로컬 포트 2222에 노출했습니다. 터미널에서 다음 명령을 실행하여 로컬 포트 9050에 SOCKS 프록시를 생성하십시오.

ssh -f -D 9050 -q -C -N \
  -o StrictHostKeyChecking=no \
  -o UserKnownHostsFile=/dev/null \
  -i ~/project/pivot_key -p 2222 pivot@127.0.0.1

이 명령에 사용된 플래그를 살펴보겠습니다. -D 9050 플래그는 동적 포트 포워딩을 지정하고 로컬 수신 포트를 9050으로 설정합니다. -q 플래그는 조용한 (quiet) 모드를 의미하며 경고 및 진단 메시지를 억제합니다. -C 플래그는 모든 데이터의 압축을 요청하여 연결 속도를 높일 수 있습니다. -N 플래그는 SSH 에게 원격 명령을 실행하지 말라고 지시하며, 포트 포워딩만 수행할 때 유용합니다. -f 플래그는 인증 후 SSH 클라이언트를 백그라운드로 보내므로 동일한 터미널 세션을 계속 사용할 수 있습니다. -o StrictHostKeyChecking=no 및 -o UserKnownHostsFile=/dev/null 옵션은 첫 연결 시 호스트 키 확인 프롬프트가 실습 워크플로우를 방해하지 않도록 합니다. -i 플래그는 사용할 개인 키를 지정하며, -p 2222는 LabEx VM 의 기본 SSH 서비스가 아닌 피벗 호스트 컨테이너에 연결하도록 지시합니다.

명령을 실행한 후, 소켓 통계를 출력하는 ss 명령을 사용하여 포트가 열려 있고 수신 대기 중인지 확인할 수 있습니다.

ss -tuln | grep 9050

다음과 유사한 출력이 표시되어야 하며, 이는 머신이 포트 9050에서 수신 대기 중임을 나타냅니다.

tcp   LISTEN 0      128        127.0.0.1:9050       0.0.0.0:*
tcp   LISTEN 0      128            [::1]:9050          [::]:*

Proxychains 구성 (/etc/proxychains.conf)

이 단계에서는 proxychains의 구성을 검사합니다.

이제 포트 9050에서 SOCKS 프록시가 실행 중이지만, Nmap 과 같은 대부분의 명령줄 도구는 SOCKS 프록시를 통해 트래픽을 라우팅하는 방법을 기본적으로 알지 못합니다. 이때 proxychains가 필요합니다. 이는 특정 애플리케이션이 생성하는 모든 TCP 연결을 프록시를 거치도록 강제하는 도구입니다.

실제로 proxychains는 단일 수동 테스트에서 수행하던 터널링을 여러 도구에 걸쳐 재사용 가능한 운영자 워크플로우로 확장해 줍니다.

proxychains의 구성 파일은 /etc/proxychains4.conf에 있습니다. 이 실습의 경우, 프록시 항목은 방금 생성한 SSH 동적 포트 포워딩과 일치하는 127.0.0.1 포트 9050의 SOCKS5 프록시를 가리켜야 합니다.

구성 파일의 하단을 확인하여 이 설정을 확인해 보겠습니다. tail 명령을 사용하여 파일의 마지막 10 줄을 출력합니다.

tail -n 10 /etc/proxychains4.conf

다음과 유사한 출력이 표시되어야 합니다.

[ProxyList]
## add proxy here ...
## meanwile
## defaults set to "tor"
socks5  127.0.0.1 9050

[ProxyList] 섹션은 프록시가 정의되는 곳입니다. socks5 127.0.0.1 9050 줄은 proxychains에게 로컬 포트 9050을 통해 트래픽을 라우팅하도록 지시합니다. SSH -D 명령이 정확히 이 포트에 프록시를 생성했으므로, 프로토콜 유형을 업데이트한 후에는 추가 구성이 필요하지 않습니다.

다른 포트나 다른 유형의 프록시를 사용해야 하는 경우 nano와 같은 텍스트 편집기를 사용하여 이 파일을 편집하면 됩니다.

SOCKS 프록시 테스트

이 단계에서는 숨겨진 내부 웹 서비스에 접근하여 프록시 설정이 올바르게 작동하는지 테스트합니다.

172.30.0.20:80의 숨겨진 내부 컨테이너에서 웹 서비스가 실행 중임을 기억하십시오. 실제 시나리오에서는 외부 인터넷에서 직접 접근할 수 없는 내부 인트라넷 사이트를 나타냅니다.

proxychains를 사용하려면 실행하려는 도구 앞에 proxychains4 명령을 붙이기만 하면 됩니다. curl을 사용하여 웹 페이지를 가져와 보겠습니다.

다음 명령을 실행하십시오.

proxychains4 curl http://172.30.0.20

이 명령을 실행하면 proxychains가 curl이 생성한 네트워크 요청을 가로채어 포트 9050의 SSH SOCKS 프록시를 통해 터널링합니다. 그러면 피벗 호스트가 내부 Docker 네트워크의 172.30.0.20:80으로 요청을 보내고 결과를 반환합니다.

다음과 유사한 출력이 표시되어야 합니다.

[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.14
[proxychains] Strict chain  ...  127.0.0.1:9050  ...  172.30.0.20:80  ...  OK
Secret Internal Data: You have successfully pivoted

OK 메시지는 프록시 연결이 성공했음을 나타내며, 마지막 줄에는 내부 웹 서버의 비밀 데이터가 표시됩니다.

피벗을 통한 외부 도구 실행

마지막 단계에서는 더 고급 외부 도구인 Nmap 을 사용하여 설정한 피벗을 통해 내부 네트워크를 스캔합니다.

proxychains와 Nmap 을 함께 사용할 때는 이해해야 할 중요한 기술적 제한 사항이 있습니다. SOCKS 프록시는 전체 TCP 연결만 지원합니다. ICMP(ping) 나 (Nmap 이 sudo와 함께 실행될 때 기본적으로 사용하는) 절반만 열린 SYN 스캔은 지원하지 않습니다.

따라서 proxychains를 통해 Nmap 을 실행할 때는 전체 TCP Connect 스캔을 사용하도록 강제하고 ping 검색을 비활성화해야 합니다.

다음 Nmap 명령을 실행하여 포트 80에서 내부 웹 서비스를 스캔하십시오.

proxychains4 nmap -sT -Pn -p 80 172.30.0.20

여기서 사용된 Nmap 플래그를 살펴보겠습니다. -sT 플래그는 TCP Connect 스캔을 강제합니다. SOCKS 프록시는 원시 패킷이나 SYN 스캔을 처리할 수 없으므로 이는 필수입니다. -Pn 플래그는 호스트 검색 (ping) 을 비활성화합니다. SOCKS 프록시는 ICMP 에코 요청을 라우팅할 수 없으므로, 이 플래그를 생략하면 Nmap 이 호스트가 다운된 것으로 잘못 판단하게 됩니다. 마지막으로 -p 80 플래그는 스캔할 정확한 포트를 지정합니다.

proxychains가 연결 시도를 기록하고 이어 Nmap 스캔 결과가 표시되는 것을 볼 수 있습니다.

[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.14
Starting Nmap 7.91 ( https://nmap.org ) at 2024-01-01 12:00 UTC
[proxychains] Strict chain  ...  127.0.0.1:9050  ...  172.30.0.20:80  ...  OK
Nmap scan report for 172.30.0.20
Host is up (0.0020s latency).

PORT     STATE SERVICE
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 0.10 seconds

이는 침투한 호스트를 통해 복잡한 보안 도구를 성공적으로 라우팅하여 내부 네트워크 세그먼트와 상호 작용할 수 있음을 확인시켜 줍니다.

요약

축하합니다! Proxychains 를 이용한 동적 포트 포워딩 실습을 성공적으로 완료했습니다.

이번 실습에서는 SSH 동적 포트 포워딩 (-D) 을 사용하여 로컬 SOCKS 프록시를 생성하는 방법을 배웠습니다. 또한 proxychains의 구성을 이해하고 검사하는 방법도 배웠습니다. 나아가 프록시를 통해 기본적인 HTTP 요청을 라우팅하여 숨겨진 내부 서비스에 접근하는 데 성공했습니다. 마지막으로 TCP Connect 스캔 (-sT) 을 활용하고 ping 검색 (-Pn) 을 비활성화하여 Nmap 과 같은 고급 스캔 도구가 SOCKS 프록시를 통해 작동하도록 조정했습니다.

이러한 피보팅 기술은 모의 해킹 및 보안 평가 중에 복잡한 네트워크 환경을 탐색하는 데 필수적인 기술입니다.