안녕하세요. 이번에는 새로운 PYTHON SERIES 를 올려볼까 합니다. REVERSE SHELL 이라고 합니다. 처음 들어보는 분들도 계시겠지만, 개략적인 내용은 대부분 알고 있는 친숙한 개념입니다. 우선 아래 그림을 먼저 살펴볼까요? ▼
왼쪽 그림에서 A -> C 로 접속을 하려고 하는데 중간에 방화벽(Firewall)이 존재할 경우가 있습니다. 이는 사용자들이 특정 웹서버나 사이트에 접속하는데 어려움을 겪게 하는 요인이 되기도 합니다. 물론 보안상 혹은 다른 여타의 이유로 방화벽을 설정하기도 하지만, 기업체에서 단순히 접속을 막아두는 경우도 있습니다. 이럴 경우 VPN(Virtual Private Network: 가상 사설망)을 이용해서 우회하기도 하지만 이 역시 한계가 있습니다. 이럴때 사용하는 한 방법중 하나가 사용자가 대상 웹서버나, 웹사이트 혹은 다른 사용자 컴퓨터에 접속하는 것 대신에 대상 서버나 사이트 혹은 타인의 컴퓨터가 사용자 자신의 컴퓨터에 직접 접속하게끔 하는 방법입니다.
보통, 이런 방식은 해커(일반적으로 해커라 칭하지만, 크래커가 더 올바른 표현입니다. 편의상 해커라 칭하겠습니다.)들이 임의의 파일을 인터넷을 통해 배포하고, 이렇게 배포된 파일을 임의의 사용자가 자신의 컴퓨터에서 실행이 되면 그 컴퓨터는 해커에 의해 통제되는 숙주 컴퓨터로 사용하기 위한 방식으로 많이 활용이 되기도 합니다.
그러나 이런 윤리적인 혹은 법적인 부분에 지장이 없는 경우에는 아주 유용한 방식이기도 합니다. 혹여 이 글을 읽고 다른 컴퓨터를 크래킹 해보고자 한다면, 그 이전에 철컹철컹(쇠고랑)을 먼저 염두하시기 바랍니다.
리버스 쉘의 기본적인 설명은 위와 같습니다. 인터넷에서 찾은 리버스 쉘의 설명이 담긴 이미지를 아래에 올려보겠습니다. 별도의 해석은 하지 않겠습니다. ▼
자 그럼 이제부터 코딩을 통해 직접 시현을 시작해 보겠습니다.
우선 서버(내가 사용할 컴퓨터에서 실행할) 파일을 생성합니다. 그리고 클라이언트(다른 사람의 컴퓨터에서 실행할) 파일을 만듭니다.▼
서버 파일에서 아래와 같이 socket, sys 모듈을 불러옵니다.▼
여기서 기본적인 소켓의 개념을 살펴보자면, 아래와 같습니다.
네트워크 소켓(network socket)은 컴퓨터 네트워크를 경유하는 프로세스 간 통신의 종착점이다. 오늘날 컴퓨터 간 통신의 대부분은 인터넷 프로토콜을 기반으로 하고 있으므로, 대부분의 네트워크 소켓은 인터넷 소켓이다. 네트워크 통신을 위한 프로그램들은 소켓을 생성하고, 이 소켓을 통해서 서로 데이터를 교환한다. 소켓은 RFC 147에 기술사항이 정의되어 있다.
인터넷 소켓은 다음과 같은 요소들로 구성되어 있다.
- 인터넷 프로토콜 (TCP, UDP, raw IP)
- 로컬 IP 주소
- 로컬 포트
- 원격 IP 주소
- 원격 포트
인터넷 소켓은 크게 두 개의 타입으로 분류할 수 있다.
- UDP 프로토콜을 사용하는 경우
- TCP 프로토콜을 사용하는 경우
그럼 컴퓨터간 데이터를 주고 받는데, 이를 소켓을 통한다는 개념은 알게 되었습니다. 그래서 소켓을 만들어 줄 함수를 만들어 보고자 합니다.▼
아래와 같이 socket_create() 함수를 정의합니다.▼
try: 를 사용하여 host, port, s 변수를 global 로 설정해 주겠습니다.▼
임의로 각 값에 아래와 같은 값을 넣어주겠습니다. 포트는 일종의 문이라고 생각하시면 됩니다. 우리가 인터넷을 웹브라우저를 통해 데이터를 주고 받을 때는 80(http)번 포트를 사용합니다. SSH 는 22, FTP는 21번 https 는 443번 포트를 사용합니다.▼
그리고 만약 소켓을 생성하는데 있어서 에러가 발생한다면 그것을 msg라는 변수로 여기고, 이런 에러가 발생하면 아래와 같이 에러가 발생했다는 것을 사용자가 알 수 있게 에러발생 메시지를 출력하게 코딩하였습니다.▼
개략적인 개념은 내가(나의 컴퓨터를 통해) 타인(멀리 있는 남의 컴퓨터)의 컴퓨터를 CLI(Command Line Interface)를 통해 권한을 얻어 원하는 명령을 타인의 컴퓨터에 내려 마음대로 통제하려고 한다. 정도입니다.
이번 글은 여기까지 하겠습니다.
덧글.
상기의 포트번호는 2의 16제곱인 65536 포트까지만 존재합니다. 9999 를 쓰려고 하였는데, 한번 더 타이핑이 되었네요. 만약 99999를 넣었다면 추후에 에러메시지를 출력할 것입니다.