Mostrando entradas con la etiqueta Open Relay. Mostrar todas las entradas
Mostrando entradas con la etiqueta Open Relay. Mostrar todas las entradas
Open Relay Tester
Después de una semanita de vacaciones vuelvo al trabajo y a los posts.

En esta entrega les traigo una herramienta de desarrollé hace un par de meses para testear servidores SMTP y verificar si son Open Relay. Un servidor de mails es Open Relay si permite a cualquier usuario enviar e-mails sin previa autenticación, esto es, no hace falta ninguna credencial para poder enviar e-mails. Pueden encontrar un ejemplo sobre el uso (o abuso) de un servidor open relay en el post Dando pelea al SPAM: Sender Policy Framework (SPF), donde explico como es posible conectarnos a un servidor SMTP utilizando telnet y enviar e-mails.

La cuestión es que tener servidores Open Relay es feo feo, porque cualquier persona/programa los puede utilizar para enviar e-mails a nombre nuestro. Osea, alguien se podría conectar al servidor de empresa.com y enviar e-mails @empresa.com. El uso común de los Open Relay es enviar SPAM. El spammer se conecta a nuestro servidor y envia e-mails de forma masiva a cualquier parte, y todo a nombre de nuestro dominio emrpesa.com.
Algunas de las consecuencias de este problema es que usan nuestro ancho de banda, llenan nuestros logs, usan nuestro procesador, y lo peor de todo, es que ensucian nuestro nombre. Si nuestro dominio es conocido como spammer, distintos servicios nos listarán en sus listas negras, rebotando nuestros e-mails por ser considerados SPAM (aún en los casos que no es spam).
Obviamente todo esto es malo, y necesitamos hacer algo al respecto. Un punto de partida es revisar si nuestros servidores son Open Relay y configurarlos para que dejen de serlo. Es por eso que escribí este programa, para identificar aquellos servidores con este problema.

El programa está escrito en python y es muy simple. Uno puede indicarle la dirección del servidor a testear, o bien un archivo con una lista de servidores. Además debemos indicar qué dirección de e-mail utilizar para realizar las pruebas. El programa testea el/los servidores con algunas combinaciones de la dirección de e-mail entregada y devuelve 2 archivos: error.log donde se listan los errores encontrados y openrelay.log donde se listan los servidores que son Open Relay.

#!/usr/bin/python
# -*- coding: utf-8 -*-

######################################################
# Created by: d3m4s1@d0v1v0
# Date: 2009-11-27
# Modified: 2009-11-30
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License v2 as published by
# the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
######################################################

import os
import sys
import smtplib
from optparse import OptionParser
from time import strftime, gmtime
import socket

class smtptester:
def __init__(self):
#self.fromaddr = fromaddr
self.logfile = open("error.log", "w")
self.openrelay = open("openrelay.log", "w")
self.openrelay.write("The following configurations permits to send e-mails:\n")

def __del__(self):
self.logfile.close()
self.openrelay.close()

def set_logfile(self, logfile):
if (os.path.exists(logfile)):
self.logfile = open(logfile, "w")

def test_servers(self, filename, fromaddr, toaddr):
if(not os.path.exists(filename)):
print "file "+f+" doesn't exist!"
exit(-1)
f = open(filename)

for addr in f:
splitedaddr = addr.split(":")
if(len(splitedaddr) > 1):
port = splitedaddr[1]
else:
port = "25"
self.test_server(addr, fromaddr, toaddr, port)

def test_server(self, addr, fromaddr, toaddr, port="25"):
print "--------------------------------"
print "testing server "+addr
server_ip = socket.gethostbyname(addr)
(fromuser, fromdomain) = fromaddr.split("@")
(touser, todomain) = toaddr.split("@")

# the from addresses to test
fromlist = (fromaddr, fromuser+"@"+server_ip, "demasiadovivo@anything.com")
rcptlist = (toaddr, touser+"@"+server_ip, '"'+toaddr+'"'+"@"+server_ip, "@"+server_ip+":"+toaddr)

try:
smtp = smtplib.SMTP(addr, port)
except:
print "can't connect to server: "+str(sys.exc_info()[1])+"\n"
self.logfile.write("can't connect to server: "+str(sys.exc_info()[1])+"\n")
return

msg = ("From: d3m4s1/-\d0v1v0 <%s>\r\nTo: %s \r\nSubject: d3m4s1@d0v1v0 smtp relay test!\r\n\r\nthis is an open relay test\r\n\r\n" %(fromaddr, toaddr))

for rcpttest in rcptlist:
for fromtest in fromlist:
try:
print "testing from: "+fromtest+" to: "+rcpttest+"... ",
smtp.sendmail(fromtest, rcpttest, msg)
smtp.docmd("RSET")

self.openrelay.write("-server address="+addr+", FROM: "+fromtest+", TO: "+rcpttest+"\n")
print "[OK]"

except:
self.logfile.write("["+str(strftime("%Y-%m-%d %H:%M:%S", gmtime()))+"] the mail couldn't be send from: "+fromtest+" to: "+rcpttest+" | error: "+str(sys.exc_info()[1])+"\n")
print "[FAIL]"
smtp.quit()
print ""

# set command line options
parser = OptionParser(usage="usage: %prog <-a|-f> <address|filename> -s <sender> -r <receiver> [options]", version="%prog 0.2")
parser.add_option("-a", "--address",
metavar="SERVER", dest="server", help="server address (test a single server)")
parser.add_option("-p", "--port",
metavar="PORT", dest="port", help="server port (default 25)")
parser.add_option("-f", "--file",
metavar="FILE", dest="filename", help="file containing the address of the servers to test")
parser.add_option("-s", "--sender",
metavar="FROM", dest="sender", help="sender address (e.g. demasiadovivo@example.com)")
parser.add_option("-r", "--receiver",
metavar="RCPT", dest="receiver", help="receiver address (e.g. other@example.com)")


(options, args) = parser.parse_args()

if((not options.server) and (not options.filename)):
parser.print_help()
exit(-1)

tester = smtptester()
if(options.sender and options.receiver):
if(options.server):
tester.test_server(options.server, options.sender, options.receiver, options.port)
elif(options.filename):
tester.test_servers(options.filename, options.sender, options.receiver)
else:
parser.print_help()
else:
parser.print_help()


Un ejemplo del uso del programa es:
# ./smtp-tester.py -a 192.168.1.25 -s test@test.com -r open@empresa.com
--------------------------------
testing server 192.168.1.25
testing from: test@test.com to: open@empresa.com... [OK]
testing from: test@192.168.1.25 to: open@empresa.com... [OK]
testing from: demasiadovivo@anything.com to: open@empresa.com... [OK]
testing from: test@test.com to: test@192.168.1.25... [FAIL]
testing from: test@192.168.1.25 to: test@192.168.1.25... [FAIL]
testing from: demasiadovivo@anything.com to: test@192.168.1.25... [FAIL]
testing from: test@test.com to: "open@empresa.com"@192.168.1.25... [FAIL]
testing from: test@192.168.1.25 to: "open@empresa.com"@192.168.1.25... [FAIL]
testing from: demasiadovivo@anything.com to: "open@empresa.com"@192.168.1.25... [FAIL]
testing from: test@test.com to: @192.168.1.25:open@empresa.com... [FAIL]
testing from: test@192.168.1.25 to: @192.168.1.25:open@empresa.com... [FAIL]
testing from: demasiadovivo@anything.com to: @192.168.1.25:open@empresa.com... [FAIL]

donde se testea la posibilidad de enviar e-mails a open@empresa.com desde la cuenta test@test.com. Vale aclarar que los e-mails son realmente enviados en la prueba, osea, traten de poner como destinatario una cuenta que ustedes posean.

El programa dista de ser optimo, dado que algunas combinaciones de e-mails no son necesarias una vez que una de las pruebas anteriores falló... es algo a corregir en alguna próxima versión.
Espero que les sea de utilidad.