由于SSH默认是没有双因子认证的,暴力破解SSH服务是最常见的问题。Google的双因子认证设置又太繁琐了。
用Python的pam-python模块写一个简单的实现邮箱验证和记录登录失败密码的功能。
os: ubuntu 10.04
python版本:2.7
a) 安装libpam-python
root@ubuntu:~# apt-get install libpam-python root@ubuntu:~# usermod root -c '#[email protected]'
b) 复制脚本到/lib/security/
root@ubuntu:~# cp def_brute_ssh.py /lib/security/
实现代码如下:
import string,random,spwd import pwd,syslog,crypt import smtplib from email.mime.text import MIMEText from email.header import Header def auth_log(msg): syslog.openlog(facility=syslog.LOG_AUTH) syslog.syslog("SSH Attack: " + msg) syslog.closelog() def check_pw(user, password): hashed_pw = spwd.getspnam(user)[1] return crypt.crypt(password, hashed_pw) == hashed_pw def send2mail(random_num, reciver): sender = '[email protected]' subject = 'active num' username = '[email protected]' password = 'passwordofb' msg = MIMEText('hi, the number is: ' + random_num) msg['Subject'] = Header(subject, 'utf-8') smtp = smtplib.SMTP() smtp.connect('smtp.qq.com') smtp.login(username,password) smtp.sendmail(sender, reciver, msg.as_string()) smtp.quit() return 0 def get_mail(user): try: comments = pwd.getpwnam(user).pw_gecos return comments.split('#')[1] except Exception: return -1 def gen_pin(user,mail): random_num = ''.join([i for i in random.sample(string.digits+string.ascii_letters, 8)]) return random_num if send2mail(random_num, mail) == 0 else -1 def pam_sm_authenticate(pamh, flags, argv): try: user = pamh.get_user() mail = get_mail(user) except pamh.exception, e: return e.pam_result if user is None or mail == -1: msg = pamh.Message(pamh.PAM_ERROR_MSG, "user isn't exist or the comment is not correct") pamh.conversation(msg) return pamh.PAM_ABORT pin = gen_pin(user,mail) if pin == -1: msg = pamh.Message(pamh.PAM_ERROR_MSG, "Please check mail server") pamh.conversation(msg) return pamh.PAM_ABORT for attemp in range(0,3): msg = pamh.Message(pamh.PAM_PROMPT_ECHO_OFF, "Enter the random pin:") resp = pamh.conversation(msg) if resp.resp == pin: 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 else: continue return pamh.PAM_AUTH_ERR 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
c)设置/etc/pam.d/sshd
root@ubuntu:/etc/pam.d# grep -v '^#' sshd | sed /^$/d auth requisite pam_python.so def_brute_ssh.py account required pam_nologin.so @include common-account @include common-session session optional pam_motd.so # [1] session optional pam_mail.so standard noenv # [1] session required pam_limits.so session required pam_env.so # [1] session required pam_env.so user_readenv=1 envfile=/etc/default/locale @include common-password
d) 设置sshd配置文件(ChallengeResponseAuthentication 改为yes)
root@ubuntu:/etc/pam.d# grep -v '^#' /etc/ssh/sshd_config | sed '/^$/d' Port 22 Protocol 2 UsePrivilegeSeparation yes KeyRegenerationInterval 3600 ServerKeyBits 768 SyslogFacility AUTH LogLevel INFO LoginGraceTime 120 PermitRootLogin yes StrictModes yes PermitEmptyPasswords no ChallengeResponseAuthentication yes 这个是必须打开的 PasswordAuthentication no X11Forwarding yes X11DisplayOffset 10 PrintMotd no PrintLastLog yes TCPKeepAlive yes AcceptEnv LANG LC_* Subsystem sftp /usr/lib/openssh/sftp-server UsePAM yes
e) 重启ssh服务 service ssh restart
f) 与hostdeny共同抗拒ssh爆破
root@ubuntu:~#wget http://ftp.jaist.ac.jp/pub/sourceforge/d/de/denyhosts/denyhosts/2.6/DenyHosts-2.6.tar.gz root@ubuntu:~# tar xvf DenyHost-2.6.tar.gz && cd DenyHost-2.6 && python setup.py install root@ubuntu:/usr/share/denyhosts# cp denyhosts.cfg-dist denyhosts.cfg && cp daemon-control-dist daemon-control root@ubuntu:/usr/share/denyhosts# ./daemon-control start root@ubuntu:/usr/share/denyhosts# ln -s /usr/share/denyhosts/daemon-control /etc/init.d/denyhost root@ubuntu:~# echo "service denyhost start" >> /etc/rc.local
来个效果图:
记录的日志:
查看封掉的ip: root@ubuntu:~#cat -n /etc/hosts.deny
改改可以记录root的密码,也可以实现一个ssh后门。
参考链接:
http://pam-python.sourceforge.net/doc/html/
http://pam-python.sourceforge.net/
【作者:jianzhen-lab.com尖针实验室 投稿:cvAring 】