[파이썬 보안] 넷캣(Netcat)

애플망고·2023년 5월 29일
0
post-thumbnail

🔑 넷캣이란

넷캣은 마치 다리와 같은 존재이다. 거가대교가 한반도와 거제도를 연결하듯 서버와 클라이언트를 연결해줄 수 있는 다리같은 역할을 한다.

넷캣을 만들어 시스템에 접속할 경우 마치 SSH에 접속한 것 같이 시스템을 사용할 수 있다.

방어자의 입장에서 시스템에서 넷캣 역할을 하는 프로그램을 비활성화 하거나 제거한다. 하지만 공격자의 입장에서는 방어자의 시스템에 침투해야 하기 때문에 넷캣이 필요 할 수도 있다.
만약 방어자의 컴퓨터에 파이썬이 설치되어 있다면 우리는 방어자의 시스템에 접근 할 방법이 생긴다.

📁 넷캣 제작

server.py

import socket
import subprocess

class Server:
    def __init__(self):
        self.IP = "localhost"
        self.PORT = 10101

    def receiver(self):
        server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        server.bind((self.IP, self.PORT))
        print("수신부: 명령 대기 중...")

        try:
            while True:
                data, address = server.recvfrom(1024)
                if not data:
                    break
                command = data.decode()
                print(f"수신부: 수신된 명령 : {command}")
                result = self.run_command(command=command)
                print("수신부: 명령 실행 완료")

                server.sendto(result.encode(), address)
                print("수신부: 명령 전송 완료")

        except KeyboardInterrupt:
            server.close()
            print("수신부: 연결 종료")

    def run_command(self, command):
        try:
            output = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT, universal_newlines=True)
            return output
        except subprocess.CalledProcessError as e:
            return f"오류: {e.output}"



if __name__ == '__main__':
    server = Server()
    server.receiver()

client.py

import socket

class Client:
    def __init__(self):
        self.IP = 'localhost'
        self.PORT = 10101

    def command(self):
        while True:
            input_command = str(input("> "))
            if not input_command:
                print("입력값이 존재하지 않습니다. 다시 입력해주세요.")
            else:
                return input_command

    def sender(self):
        client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        try:
            while True:
                client.sendto(self.command().encode(), (self.IP, self.PORT))
                print("발신부: 명령 전송 중...")
                result, address = client.recvfrom(1024)
                print(f"발신부: 데이터 수신 완료\n{result.decode()}")
        except KeyboardInterrupt:
            client.close()
            print("발신부: 연결이 종료 되었습니다.")

if __name__ == '__main__':
    client = Client()
    client.sender()

개요

두개의 터미널을 실행 한 후 server.py와 client.py를 각각 순서대로 실행한다.

python server.py
python client.py

이렇게 하면 server.py에서는 UDP 통신 대기상태로 들어가며, client.py에서는 입력을 대기하게 된다.

client.py에서 시스템 명령을 실행하면 server.py의 run_command() 함수에서 해당 명령이 전달되고 시스템에서 실행 후 결과값을 반환한다. 이를 다시 client.py로 전달한다.

보통 넷캣에는 argparse 라이브러리를 사용해서 커맨드 라인 인터페이스를 만들어 사용하고, 더 많은 기능을 내장시킬 수 있다.
예시를 들자면 -p 명령을 사용해서 포트를 지정할 수 있다던가 -h 명령을 사용해서 도움말을 볼 수 있거나 하는 등 다양하게 사용이 가능하다.

주의사항

혹시나 넷캣을 SSH처럼 사용하려는 사람이 있을까봐 작성한다.
SSH는 보안 연결을 하기 때문에 안전하지만 넷캣은 그렇지 않다. 만약 스니핑을 당할 경우 IP 주소나 포트, 데이터 등이 유출 당할 수 있으므로 보안 연습용으로 사용하고 절대로 SSH처럼 사용하지 말이야 한다.

profile
비전공자의 코딩 도전기

0개의 댓글