Estou usando um módulo pam_python
para registrar nomes de usuário e senhas usados em tentativas de SSH.
em /etc/pam.d/sshd
, adicionei esta linha:
auth requisite pam_python.so /lib64/security/pwreveal.py
Isso é /lib64/security/pwreveal.py
:
import crypt, spwd, syslog
def auth_log(msg):
"""Send errors to default auth log"""
syslog.openlog(facility=syslog.LOG_AUTH)
syslog.syslog("SSH Attack Logged: " + msg)
syslog.closelog()
def check_pw(user, password):
auth_log("User: " + user + " Password: " + password)
"""Check the password matches local unix password on file"""
# try:
hashed_pw = spwd.getspnam(user)[1]
# except KeyError,e:
# return False
return crypt.crypt(password, hashed_pw) == hashed_pw
def pam_sm_authenticate(pamh, flags, argv):
try:
user = pamh.get_user()
except pamh.exception, e:
return e.pam_result
if not user:
return pamh.PAM_USER_UNKNOWN
try:
resp = pamh.conversation(pamh.Message(pamh.PAM_PROMPT_ECHO_OFF, 'Password:'))
except pamh.exception, e:
return e.pam_result
if not check_pw(user, resp.resp):
auth_log("Remote Host: %s (%s:%s)" % (pamh.rhost, user, resp.resp))
return pamh.PAM_AUTH_ERR
return pamh.PAM_SUCCESS
def pam_sm_setcred(pamh, flags, argv):
return pamh.PAM_SUCCESS
def pam_sm_acct_mgmt(pamh, flags, argv):
return pamh.PAM_SUCCESS
def pam_sm_open_session(pamh, flags, argv):
return pamh.PAM_SUCCESS
def pam_sm_close_session(pamh, flags, argv):
return pamh.PAM_SUCCESS
def pam_sm_chauthtok(pamh, flags, argv):
return pamh.PAM_SUCCESS
Isso funciona até certo ponto, vejo a seguinte saída em /var/log/messages
após uma tentativa falha de SSH (neste caso, eu de outro servidor dev local):
Mar 3 14:35:59 localhost sshd: SSH Attack Logged: Remote Host: 192.168.1.7 (root:root123)
Meu problema é que, independentemente de a combinação de nome de usuário / senha estar correta, o script sempre gera o mesmo erro em / var / log / secure e não autentica (assim, o SSH é efetivamente quebrado enquanto estou usando este script python ):
Mar 3 14:50:41 localhost /lib64/security/pwreveal.py[13328]: Traceback (most recent call last):
Mar 3 14:50:41 localhost /lib64/security/pwreveal.py[13328]: File "/lib64/security/pwreveal.py", line 32, in pam_sm_authenticate
Mar 3 14:50:41 localhost /lib64/security/pwreveal.py[13328]: if not check_pw(user, resp.resp):
Mar 3 14:50:41 localhost /lib64/security/pwreveal.py[13328]: File "/lib64/security/pwreveal.py", line 13, in check_pw
Mar 3 14:50:41 localhost /lib64/security/pwreveal.py[13328]: hashed_pw = spwd.getspnam(user)[1]
Mar 3 14:50:41 localhost /lib64/security/pwreveal.py[13328]: KeyError: getspnam(): name not found
Eu sei que 'spwd' é o banco de dados de senhas shadow e encontrei algumas informações on-line que sugeriam que, nesse caso, "nome não encontrado" foi descrito com mais precisão como "permissão negada".
Então, como um teste, certifiquei-me de que o usuário do sshd tivesse acesso de leitura ao / etc / shadow - mas isso não ajudou.
Não tenho certeza se estou pesquisando as linhas certas ou não. Alguma ajuda?
Nota: Eu percebo que o log de senhas SSH não é uma coisa desejável para ter em execução em um servidor. Eu estou fazendo isso em uma caixa de desenvolvimento pessoal que só eu tenho acesso. Este é um projeto 'apenas para diversão'.
Editar - como teste, criei um script python autônomo que simplesmente faz isso:
import spwd
test = spwd.getspnam("myusername")[1]
print test
A execução deste script como root extraiu a senha com hash para a senha 'myusername'. Se intencionalmente teclar errado esse nome de usuário, estou tentando efetivamente procurar um nome de usuário que não exista no arquivo de sombra, recebo este erro:
KeyError: 'getspnam(): name not found'
O mesmo erro exato.
Então, a partir disso, posso supor que quando spwd.getspnam()
é executado dentro de pwreveal.py
via pam, não é possível localizar o usuário. Embora quando é executado de forma independente em um script separado, pode.
Por que isso seria?