0과 1을 공부하다.

[E-Mail] Telnet과 OpenSSL을 이용한 SMTP 메일 발송 본문

Study/ETC

[E-Mail] Telnet과 OpenSSL을 이용한 SMTP 메일 발송

Developer_Jay 2022. 2. 3. 17:27
728x90

본 게시물에서는 Telnet과 OpenSSL를 이용하여 SMTP 메일 발송을 실습한다. 

실습하기에 앞서 게시물에서 다루는 환경은 Linux(Rocky)에서 실습한다. 

 

SMTP

SMTP(simple mail transfer protocol) 프로토콜은 인터넷 상에서 이메일을 전송할 때  쓰이는 표준 프로토콜이다. 기본 포트(Port)는 25번 포트를 사용하며, MUA-MTA 또는 MTA-MTA 전송간 사용하게 된다. 기본적으로 ASCII 텍스트를 보내는 프로토콜이지만 ASCII의 7bit 문자열을 초과하는 데이터는 MIME(Multipurpose Internet Mail Extension) 포맷으로 변환하여 전송한다. 

 

 

Telnet

가. Telnet

  • Telnet은 원격지의 컴퓨터를 인터넷을 통해 접속하여 자신의 컴퓨터처럼 사용할 수 있는 원격 접속 서비스다.
  • TCP/IP 기반으로 기본적인 포트는 23번을 이용한다. 
  • 취약점은 모든 데이터를 평문으로 전송하기 때문에 데이터와 ID/PW, 실행 명령어가 노출된다.
  • 본 실습에 앞서 대부분의 OS에서는 보안성의 이유로 비활성화 되어 있는 경우가 많기 때문에 별도로 Telnet 환경을 활성화 시키도록 한다.

 

나. nslookup 질의를 이용한 메일 서버 찾기

 

 (1) DNS 질의 명령어인 nslookup을 입력하고 메일 레코드(mx)를 지정한다.

$ nslookup
> set type=mx

 

 (2) 본인이 찾고자하는 메일 도메인을 입력한다. (예시로 구글 메일서버를 이용한다.)

> google.com

[그림] nslookup

 google.com에 대한 질의를 하면 위와 같은 결과를 얻게 되는데 mail perfernce가 높은 exchanger를 이용하면 된다. 필자는 aspmx.l.google.com을 이용한다. 

 

 

다. Telnet을 이용한 메일 발송

 

 (1) telnet을 이용하여 smtp 메일 서버에 접속한다.

$ telnet "메일 서버" 25
$ telnet aspmx.l.google.com 25

 

 (2) helo 도메인 주소

helo 도메인 주소를 입력한다. 정상적인 입력을 수행하면 '250'을 반환한다. 

> helo google.com

[그림] helo

 

 (3) mail from:<발신자 주소>

  mail from:<발신자 주소>를 입력한다. 해당 메일주소는 봉투 발신자에 해당 되는 내용으로 실질적인 전송하는 발신자를 뜻한다. 해당 실습에서는 인증과정을 거치지 않은 메일 전송을 수행하기 때문에 임의의 메일을 입력하여도 발송은 가능한다. 정상적인 입력을 수행하면 '250'을 반환한다. 

> mail from:<pgh6444@naver.com>

[그림] mail from

 

 (4) rcpt to:<수신자 주소>

  rcpt to:<수신자 주소>를 입력한다. 해당 항목의 메일 주소는 실질적인 수신자를 뜻한다. 즉, 임의의 주소를 입력하면 수신자는 수신을 정상적으로 받지 못한다. 정상적인 입력을 수행하면 '250'을 반환한다. 

> rcpt to:<pjh6444@gmail.com>

[그림] rcpt to

 

 (5) data (헤더 및 메일 본문 작성)

  메일의 헤더와 메일의 본문을 작성한다. 메일의 헤더에는 아래 항목 이외에도 인증과정과 필터링에 관한 내용을 포함할 수 있지만 해당 실습에서는 subject(메일 제목), from(송신자), to(수신자)만 기입하여 발송한다. 여기서 from과 to는 헤더 발/수신자로 MUA에 보여지는 발/수신자이다. 

 메일 본문 작성은 헤더와 구분짓기 위해 1줄 공백을 두고 메일 본문 내용을 작성한다. 이후 마지막 행에 .(dot)을 입력하고 마무리하면 발송이 완료된다. 정상적인 발송을 완료한 후에는 '250'을 반환한다.

>data
subject: 메일 제목
from: 송신자
to: 수신자

메일 본문내용 작성
.

[그림] data

 

 (5) telnet Quit

  •   입력을 마친 후 텔넷을 종료하기 위해서는 Control + ] 를 누르고 quit를 입력하면 종료된다.

 

 

라. 메일 확인

 메일 본문 작성을 완료하고 수신자의 메일함(구글)으로 들어가면 스팸함으로 분류되어 메일이 도착 했을 것이다. 

스팸함으로 분류된 이유는 spf, arc, dkim 등 다양한 필터링 기법이 있는데 적법한 인증 절차와 인증에 필요한 헤더정보를 포함하지 않은 상태로 발송했기 때문이다. 그러나 telnet을 이용하여 테스트 한 결과 동일한 메일서버로 전송할 경우 봉투발신자와 헤더 발신자가 위/변조 되어도 전송 및 수신 가능했고, 외부 메일서버로 차단되는 모습을 보였다. 각 메일 서비스마다 차이가 있겠지만 기본적으로 SMTP 수신 단계에서부터 차단을 수행하는 것 같다.  

[그림] 도착 메일 확인 (스팸함)

 

위에서 알아본 것과 같이 Telnet을 이용하여 메일을 발송할 경우 어떠한 인증 절차도 거치지 않고 발신자를 위/변조하여 발송할 수 있는 모습을 보였다. 또한 두서에서 알아본 바와 같이 telnet은 평문으로 발송하기 때문에 모든 정보가 노출된 가능성을 보인다.

 

 

 

OpenSSL

가. OpenSSL

    • OpenSSL은 네트워크를 통한 데이터 통신에 쓰이는 프로토콜인 TLS와 SSL의 오픈 소스 구현판이다.
    • SSL(Secure Sockets Layer)은 보안 소켓 계층을 이르는 말로, 인터넷에서 데이터를 안전하게 전송하기 위한 인터넷 통신 규약 프로토콜이다.

 

나. OpenSSL 설치

 

 (1) 아래 링크에 접속하여 OpenSSL 다운로드 파일 주소 복사 

[그림] OpenSSL URL 복사

 

 (2) wget을 이용하여 다운로드 

$ wget https://www.openssl.org/source/openssl-1.1.1m.tar.gz

# wget이 없다면 사전에 설치해야 함. yum install wget(레드햇 계열) / apt-get install wget(데비안 계열)

 

 

 (3) tar xvfz로 압축해제

$ tar xvfz openssl-1.1.1m.tar.gz
$ cd openssl-1.1.1m    # 압축해제 후 디렉터리 이동

 

 (4) 명령어 실행

$ ./config shared

 

 (5) make

# 순차적으로 실행
$ make
$ make install

# gcc make를 사전에 설치해야 함. yum install gcc make(레드햇 계열) / apt-get install gcc make(데비안 계열)

 

 

 (6) 버전 확인 및 실행

$ openssl version    # 버전확인
$ openssl     # 실행

 

 

 

 

다. OpenSSL를 이용한 메일 발송 (Google)

 

 (1) Gmail Setting

  • IMAP 사용함 설정: Link
  • 보안 수준이 낮은 앱 허용: Link

 (2) Base 64 Encoding 암호 확인

$ openssl enc -base64 <<< 'email'
$ openssl enc -base64 <<< 'password'

openssl로 전송하기 위해서는 base64로 인코딩된 ID/PW가 필요하다. 위의 명령어를 입력하면 base64로 인코딩된 문자열이 반환된다. 별도의 인코딩 사이트를 이용하여 변환하여도 된다.

 

 (3) openssl 접속

$ openssl s_client -connect smtp.gmail.com:465 -crlf

구글의 smtp.gmail.com에 465 포트로 접속한다. 정상적인 입력을 수행하면 '220'을 반환한다.

 

 (4) helo

> helo google.com

구글의 도메인을 입력한다.

 

 (5) 로그인

>auth login
334 VXNlcm5hbWU6 (Username:)
> ID 입력
334 UGFzc3dvcmQ6 (Password:)
> PW 입력

auth login을 입력하면 알 수 없는 문자열 VXNlcm5hbWU6을 반환한다. 해당 문자열을 Base64로 decoding 하면 'Username:'을 의미한다. 앞서 인코딩한 자신의 이메일을 입력한다. 입력을 마치면 눈치챘듯이 'Password:'를 의미하는 문자열을 반환한다. 역시 이전에 인코딩한 자신의 이메일을 입력한다. 로그인에 성공하면 235와 Accepted를 반환한다.

 

 (6) mail from:<발신자 주소>

> mail from:<pgh6444@naver.com>

이후 내용은 앞선 telnet과 같다. 봉투 발신자를 입력하는 항목인데 앞서 인증절차를 거쳤기 때문에 임의로 수정하여도 반영되지 않는다. 정상적인 발송을 완료한 후에는 '250'을 반환한다.

 

 

 (4) rcpt to:<수신자 주소>

> rcpt to:<pjh6444@gmail.com>

동일하게 봉투 수신자를 입력하는 항목이다. 실질적인 전송을 하는 대상으로 바르게 입력해야 한다. 정상적인 발송을 완료한 후에는 '250'을 반환한다.

 

 (5) data (헤더 및 메일 본문 작성)

>data
subject: 메일 제목
from: 송신자
to: 수신자

메일 본문내용 작성
.

  메일의 헤더와 메일의 본문을 작성한다. 앞서 동일하게 subject(메일 제목), from(송신자), to(수신자)만 기입하여 발송할 수 있지만. from과 to는 위/변조하여 전송해도 봉투 발신자로 전송되어 MUA에서는 정상적으로 보여지기 때문에 생략해도 된다.

 메일 본문 작성은 헤더와 구분짓기 위해 1줄 공백을 두고 메일 본문 내용을 작성한다. 이후 마지막 행에 .(dot)을 입력하고 마무리하면 발송이 완료된다. 정상적인 발송을 완료한 후에는 '250'을 반환한다

 

 

 (6) OpenSSL Quit

  • ccontrol + C 를 입력한다.

 

 

라. 메일 확인

  메일 본문 작성을 완료하고 수신자의 메일함(구글/네이버)으로 들어가면 일반 보관함으로 분류되어 메일이 도착 했을 것이다. 앞서 telnet을 통해 가능했던 발송자 위/변조도 헤더와 봉투를 변경해도 반영되지 않았고, 타 메일서버로 전송해도 정상적으로 가능했다. 이와 같이 가능한 이유는 아래 "telnet과 OpenSSL 원본메일 비교"에서 알아본다.

 

 

[그림] google gmail으로 발송
[그림] naver로 발송

 

 

 

Telnet과 OpenSSL 원본메일 비교

 수신받은 메일을 원본보기로 보면 아래와 같다.(내용이 방대하여 큰 이미지로 다루지 않는다.) OpenSSL로 발송한 메일에는 DKIM, SPF, ARC의 내용을 담아 발송하게 된다. 반면에 Telnet에서 발송된 메일은 DKIM에 대한 내용은 헤더에 존재하지 않고 SPF(메일 서버 등록제)가 Softfail(발송이 허용되지 않았지만 과도기)로 정상적으로 인증되지 않은 모습을 볼 수 있다. 그렇기 때문에 Telnet을 이용하여 발송을 하였을 때는 스팸함에 분류되고 OpenSSL일반 보관함에 분류되고 타서버로 전송이 가능한 것이다. 

# 각 필터링의 기능에 대한 내용은 따로 다룰 예정

[그림] OpenSSL 메일원본(좌) / Telnet 메일원본(우) 

 

 

 

참고 사이트

 

 

 

 

 

※ 본 게시글의 정보가 잘못 되었거나 부족한 부분에 대한 피드백을 환영합니다.

 

 

* CopyRight 2022. Jay Park All rights reserved.

728x90
Comments