
멀티홉 tty 세션 또는 포트쉘을 위한 종단간 암호화 + TCP/UDP 포트 포워딩
이 프로젝트는 자매 프로젝트인 crash와 함께, 적대적인 검열 환경에서 완전히 작동하는 암호화된 셸과 TCP/UDP 포워딩을 설정할 수 있게 해주는 제 반검열 도구 세트에 속합니다. 또한 포렌식에서 UART나 adb를 통해 장치에서 데이터를 덤프할 때 다른 수단이 없을 때 유용합니다.
DNS 조회 및 SSH 세션이 UART 연결을 통해 Pi로 전달됨
PSC는 셸 세션을 단일 또는 다중 홉으로 종단 간 암호화할 수 있으며,
기반 전송에 대해 agnostic합니다. 단, 전송이 안정적이고 Base64 인코딩된 데이터를
수정/필터링 없이 송수신할 수 있어야 합니다. (예: 포트 셸 내에서) 받은 종단 간 pty와 함께,
OpenSSH의 -L 파라미터와 유사하게 TCP 및 UDP 연결을 전달할 수 있습니다.
이는 투명하게 작동하며 시작 지점에서 로컬에 IP 주소가 할당될 필요가 없습니다.
따라서 포렌식 분석가와 침투 테스터는 예를 들어 다음을 통해 네트워크 연결을 생성할 수 있습니다:
adbd가 TCP 포워딩을 지원하지 않는 경우 adb shell 세션마치 셸 세션 내에 보이지 않는 ppp 세션이 있는 것처럼 상상해보세요. 원격 피어가 실제로 ppp를 지원하지 않아도 말이죠.
Linux, Android, OSX, Windows, FreeBSD, NetBSD 및 (가능하면) OpenBSD에서 실행됩니다.
PSC는 또한 SOCKS4 및 SOCKS5 프록시 지원을 포함하여, 포트 셸이나 모뎀 다이얼업을 통해 원격으로 실제 웹 브라우징 세션을 가질 수 있게 합니다.
Makefile을 편집하여 Makefile 상단에 정의된 사전 공유 키를 반영하세요.
그런 다음 Linux 및 OSX에서는 make를 입력하기만 하면 됩니다.
BSD에서는 GNU make를 설치하고 대신 gmake를 호출해야 합니다.
Windows에서는 cygwin을 설치하고
적절한 gcc, gcc-g++, make 및 git 패키지를 선택해야 합니다.
Linux에서 PSC는 Unix98 의사 터미널을 사용하고, 다른 시스템에서는 POSIX pty를 사용하지만 이는 사용자에게 투명해야 합니다. 한때 4.4BSD pty 및 SunOS 지원을 특별한 이유로 고대 시대에 추가했기 때문에 Solaris에서도 빌드될 수도 있고 아닐 수도 있습니다.
자랑스럽게 후원:
간단하고 명확합니다. 로컬 상자에서 pscl을 실행하고, 원격 사이트 에서 특정 주소로 전달하려는
TCP 또는 UDP 포트를 전달합니다. 예:
linux:~ > ./pscl -T 1234:[192.168.0.254]:22 -U 1234:[8.8.8.8]:53
PortShellCrypter [pscl] v0.60 (C) 2006-2020 stealth -- github.com/stealth/psc
pscl: set up local TCP port 1234 to proxy to 192.168.0.254:22 @ remote.
pscl: set up local UDP port 1234 to proxy to 8.8.8.8:53 @ remote.
pscl: Waiting for [pscr] session to appear ...
linux:~ >
[ UART / SSH / ... login to remote side ... ]
원격 사이트(마지막 홉)에서 셸 세션(포트 셸, SSH, 콘솔 로그인 등)에서 pscr을 실행합니다:
linux:~ > ./pscr
PortShellCrypter [pscr] v0.60 (C) 2006-2020 stealth -- github.com/stealth/psc
pscl: Seen STARTTLS sequence, enabling crypto.
linux:~ >
pscr을 실행하면 양쪽 끝이 암호화 핸드셰이크를 설정하고 기존 세션 위에 추가 프로토콜을
추가합니다. 이는 사용자에게 투명합니다. 그런 다음 로컬 상자에서 127.0.0.1:1234에 연결하여
TCP를 통해 192.168.0.254:22에 도달하거나 UDP를 통해 8.8.8.8 해석기에 도달할 수 있습니다.
원격 사이트에 IPv6 연결이 있는 경우 [IPv6] 주소에서도 작동합니다. 실제로,
항상 로컬 측에서 127.0.0.1에 연결하기 때문에 IPv4 소프트웨어를 IPv6로 변환하는 데 사용할 수도 있습니다.
여러 -T 및 -U 파라미터를 전달할 수 있습니다. 세션이 이미 종단 간 암호화되었는지
추적을 잃은 경우, 로컬 pscl 프로세스에 SIGUSR1을 보내면 알려줍니다.
PSC는 또한 원격 SSH 셸에서 tor를 사용하려는 경우 유용합니다. socks5 및 DNS 포트를
원격 호스트의 127.0.0.1 주소로 전달할 수 있습니다. SSH는 UDP 패킷을 전달하지 않으므로
일반적으로 tor 노드를 통해 해석하려면 두 개의 socat 커넥터 등을 사용해야 합니다.
PSC는 UDP 데이터그램 경계를 유지하는 반면, SSH -L을 통한 socat은 데이터그램 경계를
파괴하고 잘못된 DNS 요청을 생성할 수 있습니다.
세션은 Makefile에서 선택한 PSK의 aes_256_ctr로 암호화됩니다.
이 암호화 방식은 가단성이 있지만, AAD 또는 OAD 데이터를 추가하면 패킷 크기가 커집니다.
대화형 세션 및 Base64 인코딩으로 인해 입력된 각 문자는 이미 훨씬 더 많은 데이터를
전송하게 되므로 모든 바이트가 중요합니다.
UART 세션은 screen을 통해 사용할 수 있지만, 예를 들어 minicom을 통해서는 사용할 수 없습니다.
minicom은 상태 줄이 있는 보이지 않는 창을 만들고 PSC의 프로토콜을 파괴하는 필터처럼 작동하기 때문입니다.
PSC는 필터링을 감지하려고 시도하며 일정량의 데이터 변조를 견딜 수 있지만,
일부 상황에서는 복구가 불가능할 수 있습니다. tmux도 비슷합니다.
PSC와 함께 들어오는 데이터를 너무 많이 처리/조작하는 pty 핸들러를 쌓지 않아야 합니다.
SHELL 환경 변수는 PSC가 pty에서 실행할 셸을 알기 위해 pscl 및 pscr 모두에 대해 설정되어야 합니다.
대부분의 환경에서 SHELL은 기본적으로 설정되어 있지만, 그렇지 않은 경우
SHELL=/bin/bash pscl 등으로 실행해야 합니다.
pscl은 SOCKS4 (-4 port) 및 SOCKS5 (-5 port)를 통한 TCP 연결 전달도 지원합니다.
이렇게 하면 침투 테스트 중에 다른 연결을 열 필요 없이 포트 셸 세션에서 원격 네트워크를
탐색할 수 있습니다. pscl에 -N을 전달하면 원격 측에서 DNS 이름 확인을 활성화하므로
chrome과 함께 사용할 수도 있습니다. 그러나 브라우저가 시작 시 제어할 수 없는 일련의
DNS 이름을 확인하려고 시도하는 개인정보 보호 문제가 있습니다. 또한 원격 측의 DNS 설정이
손상된 경우 DNS 응답 패킷이 누락되면 입력 셸이 몇 초 동안 차단될 수 있습니다.
임베드 가능하고 이식 가능한 좋은 비동기 해석기 함수가 없기 때문에 단일 스레드에서
getaddrinfo()에 의존해야 했으며, DNS 문제가 있는 경우 몇 초 동안 차단될 수 있습니다.
따라서 이름 확인은 명시적으로 활성화해야 합니다. pscr은 DNS 조회 캐시를 통해 이 잠재적인 문제를
최소화하려고 하므로 대부분의 상황에서 문제 없이 작동해야 합니다.
-X IP-address (첫 번째 인수여야 함)를 전달하면 로컬 프록시를 127.0.0.1과 다른 주소에
바인딩할 수 있으므로 로컬 네트워크에서 프록시를 공유할 수 있습니다.
psc 기능을 사용하면 원격 사이트에 pscr 바이너리를 설치할 수 없는 경우에도
여러 홉을 거쳐 TCP 연결 또는 이진 데이터 블롭을 원격 장치에서/로 전달할 수 있습니다.
이는 포렌식 목적으로 매우 유용합니다. 다른 방법으로 장치에서 아티팩트를 다운로드할 수 없거나
(UART로 연결된 전화기 등) 시스템에서 증거를 파괴하지 않기 위해 FS를 건드리지 않고
연결을 전달해야 하거나 루트 FS가 읽기 전용으로 마운트되어 도구 세트를 업로드할 수 없는 경우에
사용됩니다.
정말 멋진 기능입니다. 로컬 tty를 통해 TCP 연결이 원격 상자로 이동하는 것을 볼 수 있으며 원격에 아무것도 설치할 필요가 없습니다.
이는 로컬 pty 펑크락과 pscl에 바운스 명령을 전달하여 (pscr 없이) 원격 셸에 드롭하고,
로컬 측에서 데이터를 필터링하고 처리하는 상태 엔진 마법을 통해 작동합니다. 일반적으로
먼저 원격 pty를 raw 모드로 설정한 다음 실제 명령을 내리고 -B에 전달되는 몇 가지 다른
세부 정보가 필요합니다. 인수는 다음 부분으로 나뉩니다:
:으로 구분, 예: 1234:.stty -echo raw 또는
python -c "import tty;tty.setraw(0)" (따옴표 처리에 주의하세요. -B도 인용해야 함) 등.pscl에 데이터 전송을 시작하라고 알리는 "GO" 마커, stty가 실제로 발생하고
명령 시작 사이의 경합을 피하기 위해 echo GO가 완벽합니다.nc 127.0.0.1 22pscl이 tty 상태를 재설정할 수 있습니다.
echo FIN이 적합합니다. 권장됩니다. 그렇지 않으면 명령 종료를 인식하는 데 문제가 있을 수 있습니다.;으로 구분되고 대괄호로 묶입니다.예:
TCP 연결을 전달하려는 경우, 이 예제는 장치에 stty 및 nc가 설치되어 있어야 하지만,
이론적으로는 동등한 기능을 수행하는 다른 것으로 대체될 수 있습니다.
로컬 세션 시작:
./pscl -B '1234:[stty -echo raw;echo GO;nc example.com 22;echo FIN]'
이렇게 하면 로컬에서 포트 1234에 연결할 때 원격 장치에 명령 stty -echo raw;echo GO;nc example.com 22;echo FIN을
실행하고 그 후에 보이는 모든 데이터를 앞뒤로 전달하며 장치의 tty 속도(기본값 115200)를 초과하지 않도록
트래픽을 속도 제한합니다.
pscl 세션이 시작되면 UART, ssh -e none ... 등으로 원격 장치에 연결하고 원격 셸을 얻으면
로컬에서도 다음을 입력합니다:
ssh [email protected] -p 1234 로컬 상자에서 원격 장치를 통해 example.com 대상으로 SSH 연결을 바운스합니다.
물론 pscr 변형이 선호됩니다. -B는 한 번에 하나의 연결만 바운스할 수 있지만 (여러 포워드에 대해
여러 -B 명령을 전달할 수 있음) TCP 세션 후 셸이 멈출 가능성이 있습니다. pty가 raw -echo 모드에 있고
최종 원격 피어가 연결을 닫는지 여부에 따라 셸이 그 후에 멈출 수 있습니다. pscl 알림이 연결 완료를
표시하고 프롬프트가 보이면 reset 명령을 실행하여 새 연결을 시작할 수 있습니다.
데이터가 전달되는 동안 pscl에 7비트 ASCII < 및 > 알림이 표시됩니다. 이는 디버깅 및 진행 상황
감지를 위한 로컬 전용입니다.
원격 사이트에 대한 연결은 8비트 클린이어야 합니다. 즉, ssh, telnet, UART 또는 기타 채널에서
이스케이프 시퀀스를 처리하지 않아야 합니다 (pscr 사용 시와 달리). ssh 연결의 경우
pscl 세션에서 ssh -e none을 사용해야 합니다.
다음으로, rfile이 원격 파일, lfile이 로컬 파일을 나타내는 이진 파일 전송을 처리하는 예제입니다.
원격 파일을 드롭하는 세션을 시작하려면 로컬에서:
./pscl -B '1234:[stty -echo raw;echo GO;dd of=rfile.bin bs=1 count=7350;echo FIN]'
여기서 원격 측이 예상하는 데이터 양을 지정해야 합니다. cat>...와 같이 사용해도 작동하지만
전송 완료 후 cat이 계속 입력을 기다리므로 세션이 멈춥니다. dd count=...를 사용하면
깨끗하게 종료되고 FIN 마커로 알림을 받습니다.
그런 다음 ssh 등으로 방금 시작한 pscl 세션 내에서 원격 장치에 셸을 얻습니다.
로컬의 두 번째 터미널에서:
dd if=lfile.bin|nc 127.0.0.1 1234
이렇게 하면 pscl의 로컬 포트 1234에 연결되고 원격 측에서 덤프 명령이 트리거되어
로컬 lfile.bin의 이진 데이터를 원격의 rfile.bin으로 전달합니다. 속도 제한으로 인해
시간이 걸릴 수 있으며, 전송 완료 여부는 psc 진행 화면만 신뢰해야 합니다.
로컬 dd ...|nc ... 명령은 로컬 상태만 표시하며 로컬 TCP 버퍼로 인해 파일이 밀리초 단위로
소비될 수 있지만 실제 파일은 여전히 pty를 통해 전송 중입니다. 따라서 pscl 화면이 완료되었다고
알리거나 dd ...|nc ... 세션에 FIN 종료 마커가 에코백될 때만 Ctrl-C를 눌러야 합니다.
마찬가지로, 유사한 명령을 사용하여 포렌식 목적으로 원격 장치에서 로컬 상자로 이진 데이터를 전송할 수 있습니다. 다시 로컬에서 세션 시작:
./pscl -B '1234:[stty -echo raw;echo GO;dd if=rfile.bin]' 또는
./pscl -B '1234:[stty -echo raw;echo GO;cat rfile.bin]'
그런 다음 ssh로 원격 장치에 연결하여 셸을 얻고, 다시 로컬에서:
nc 127.0.0.1 1234|dd of=lfile.bin bs=1 count=7350
rfile.bin (크기 7350)을 로컬 파일 lfile.bin으로 복사합니다.
장치에서 stty -echo raw를 사용할 수 없는 경우
python -c "import tty;tty.setraw(0)"도 작동합니다. 바운스 명령을 사용할 때는
원격 장치에 tty(포트 셸이 아닌)가 있어야 합니다. raw 모드 설정을 위한 stty 명령은
실제 tty가 필요하기 때문입니다.
psc가 직렬 연결을 통해 실행되는 경우 비트 손실이 모든 재미를 망칠 수 있습니다.
HW 흐름 제어 없이 실행하면 특히 바운스 명령 사용 시 장치가 사용자 방향으로 데이터를 보낼 때
조절이 없기 때문에 비트 손실 및 연결 중단을 경험할 수 있습니다. 장치로 데이터를 덤프하는 것은
이 데이터가 pscl 속도 제한을 통과하기 때문에 더 잘 작동합니다.
그러나 장치에서 pscr 및 HW 흐름 제어를 사용할 수 없는 상황에서 저에게 효과가 있었던
몇 가지 팁이 있습니다. 이는 잠재적으로 신뢰할 수 없는 전송 채널인 UART를 사용할 때만 적용됩니다.
pscr을 사용하여 사용자 방향으로 전송되는 데이터에 속도 제한을 설정하십시오.
장치 방향으로의 데이터는 항상 속도 제한되므로 바운스 명령을 사용하여 크로스 컴파일된
pscr 바이너리를 장치에 덤프하고 양방향 속도 제한 세션을 시작할 수 있습니다.tio -o 1 또는 -o 2를 사용하여 전송 출력 바이트 사이에 지연을 추가하십시오.115200으로 설정되어 있어도 38400 선호).-DRESPECT_UART_BUFSIZE=4096으로 psc를 컴파일하십시오. 그러나 이렇게 하면 세션이 매우 느려집니다.contrib 폴더 안에는 이스케이프 문자 처리를 비활성화하는 tio-noprefix 패치도 있습니다.
하지만 이 패치는 더 이상 필요하지 않습니다. 업스트림에서 이미 이 패치를 수락하고 통합했기 때문입니다.
UART를 사용할 때는 tio 사용을 적극 권장합니다.
tio를 통해 바운스 명령을 사용할 때는 ~/.tioconfig 파일에 다음을 추가해야 합니다:
[default]
prefix-ctrl-key = none
이렇게 하면 ESC 처리가 비활성화되고 8비트 클린 채널이 제공됩니다.
pscl에 SIGUSR1을 보내면 세션이 암호화되었는지 알려줍니다. 원격 pscr이 죽거나
로컬 부분에 신호를 보낼 수 없이 종료되면 pscl은 암호화 모드로 남아 있게 되어 중단됩니다.
이 경우 SIGUSR2를 보내서 일반 텍스트 모드로 강제 재설정할 수 있으므로 새 세션을 시작할 수 있습니다.
버전 0.64부터 psc는 스크립팅 소켓을 지원하므로 더 이상 screen을 사용하여 파일을 가져오거나
보내거나 원격 콘솔에 붙여넣기 버퍼를 덤프할 필요가 없습니다. 대신 로컬 세션을 다음과 같이 시작합니다:
~ > ./pscl -S ~/psc.script_sock
그런 다음 이전과 같이 사용하면 됩니다. 무언가를 '붙여넣기'해야 하는 경우 다음과 같이 합니다:
~ > ./pscsh -S ~/psc.script_sock -f script_/helloworld
이렇게 하면 script_/helloworld의 내용이 콘솔에 '입력'됩니다. 스크립팅 중에는
pscl의 stdin이 차단되어 주입된 입력이 타이핑과 혼합되지 않습니다.
pscsh에서 -S를 생략하면 ~/psc.script_sock이 자동으로 사용됩니다.
안전을 위해 스크립트는 script_ 접두사로 시작해야 합니다.
추가로, pscr에는 이제 CR 포함 문자도 편리하게 처리하는 base64 인코딩/디코딩 기능이 포함되어 있습니다.
이는 uuencode -m과 호환됩니다.