服务器SSH被字典爆破时记录对方使用的密码
事情的起因是这样的:本人购(bai)买(piao)了一台华为云的云主机,有一天登录的时候日常查看安全日志,发现有人在用字典爆破我ssh登录的用户名和密码,奈何我早就做了安全加固(更改ssh端口、禁止root用户登录、使用fail2ban)对方并没有成功。由于我端口选的过于随机,用户名足够偏,密码强度足够,便放任他爆破。过了一个月发现还在继续,感叹对方执着的同时突然想到:这不正是一个构建自己密码字典的好机会吗?瞬间感觉自己错过了一个亿…
迄今为止对方可是已经尝试了四十多万次了啊!!!!于是动手开始部署,准备记录。
在网上找到了两种方法:一种是通过patch,也就是打补丁的方式。因为默认的ssh日志是不带密码记录功能的,于是可以重新编译openssh并打上补丁,使它能够记录,但尝试之后这种方法并没有成功,因为在打补丁的过程中报如下错误:
patch --dry-run < syslog.patch
checking file auth-passwd.c
patch: **** malformed patch at line 4: {
我对这方面不是很了解,也没有找到解决方法,遂放弃。
另一种方法是使用docker部署ssh蜜罐记录下爆破密码。但尝试之后发现效果不是很理想,因为对方并不仅仅针对单一端口进行爆破,而是不断变换爆破端口。这就导致docker端口与主机端口间的映射出现问题。举个例子:当docker的22端口映射主机的22端口时,对方如果针对22端口进行爆破,肯定能记录下密码,但要是对方针对33端口进行爆破呢?遂放弃。兜兜转转终于找到如下方法:
主机环境:Centos 7
1、到官网下载源码包(可以先去官网看看最新版本的版本号)
wget https://mirror.leaseweb.com/pub/OpenBSD/OpenSSH/portable/openssh-8.4p1.tar.gz
2、创建配置文件目录(也可以使用默认目录,下文中configure命令完成时会显示配置文件目录以及安装目录)
sudo mkdir -p /usr/local/ssh8.4p1/conf
3、安装依赖环境
sudo yum install gcc zlib-devel openssl-devel -y
4、解压之前下载的源码包
tar -zxvf openssh-8.4p1.tar.gz
5、修改源码
#进入解压目录
cd ./openssh-8.4p1
#编辑auth-passwd.c文件
vim ./auth-passwd.c
#找到函数auth_password,添加以下代码
logit("username: %s password: %s", authctxt->user, password);
6、编译安装
#编译
./configure --sysconfdir=/usr/local/ssh8.4p1/conf/ --without-zlib-version-check --with-md5-passwords --prefix=/usr/local/ssh8.4p1/
#参数说明
--sysconfdir #配置文件目录
--without-zlib-version-check
--with-md5-passwords
--prefix #安装目录
(Ps:此命令完成时会显示配置文件位置和安装位置,后面需要用到配置文件位置)
#make && make install
make && make install
7、登录测试,查看日志
#修改配置文件
sudo vim /usr/local/ssh8.4p1/conf/sshd_config
#修改ssh端口
Port 1234
#禁止root用户登录
PermitRootLogin no
#启动(必须使用绝对路径,这跟ssh服务自身有关)
/usr/local/ssh8.4p1/sbin/sshd
#如果启动失败请查看之前是否有安装openssh
#连接(如果连接不上请检查防火墙,查看端口是否开放)
ssh -p 1234 xxx@xxx.xxx.xxx.xxx
#查看日志
sudo grep username /var/log/secure
可以看到显示结果还是不够纯粹,还有一些其他信息,如果想要看到更纯粹的显示内容,可以再次利用管道符和grep进行过滤
sudo grep username /var/log/secure | grep password | grep sshd
(Ps:这里顺便记录一下,管道符的作用是将管道符前命令的输出作为管道符后命令的输入)
到这里爆破密码的记录已经完成,要想构建自己的密码字典还得将密码提取出来
#首先新建保存密码的文件
touch ./dir.txt
#使用grep与awk将内容提取出来
sudo cat /var/log/secure | grep -v '你的用户名' | grep -v '你的密码' | grep 'password:' |grep 'username:' |grep 'sshd'| awk -F ' ' '{print $7,$9}'>>dir.txt
管道符‘|’就像一道滤筛有木有…每使用一次就将结果过滤一次
grep的-v选项是反向选择,所有包含指定字符串的记录都将被过滤掉,因为日志文件中肯定包含了你自己登录的正确用户名和正确密码,你一定不想要自己的密码流出去是不是,毕竟只有自己知道的密码才相对安全嘛
awk命令的-F选项表示以何种符号分割, $n表示第n个参数(分割后的第n个参数),我这里使用“ ”也即是空格符进行分割
注意结尾 “>>dir.txt” 那里一定是两个">",因为“>”重定向输出时会覆盖文件中原有的内容,而“>>”则是会将内容追加在文件已有内容末尾
我这里不仅提取了密码,还顺便提取出了用户名,后续可以根据需要进行再次加工
至此密码也已经提取出来了
但是对方还在持续爆破,作为一名运维人员,我怎么可能定期手动执行上述命令提取密码?当然要自动化啦!
自动化提取密码
将命令转化为脚本
#新建dir.sh并写入如下内容:
vim ./dir.sh
#!/usr/bin/zsh
cat /var/log/secure | grep -v '你的用户名' | grep -v '你的密码' | grep 'password:' |grep 'username:' |grep 'sshd'| awk -F ' ' '{print $7,$9}'>>dir.txt
#给脚本赋予可执行权限
sudo chmod +x ./dir.sh
要想实现上述命令的自动化,有两个要点:
- root权限执行脚本
- 定时执行脚本
因为上述命令需要root权限才能执行,写成脚本之后自然也需要root权限。在网上查找之后选择expect。其原理也就是在输入su命令之后由expect自动填写密码
sudo yum install expect
#新建auto.sh并写入如下内容:
vim ./auto.sh
#!/usr/bin/expect
spawn su root
expect "Password:"
send "你的密码\r"
send "cd 脚本所在目录\r"
send "./dir.sh\r"
expect eof
exit
#给脚本赋予可执行权限
sudo chmod +x ./auto.sh
至此第一个问题解决了,第二个问题也很好解决。Linux中crontab是用来定期执行程序的命令。
#新建定时任务
crontab -e
#输入如下
0 0 */3 * * auto.sh脚本所在位置的绝对路径/auto.sh
#查看定时任务是否创建成功
crontab -l
上述命令的意思是每隔三天,在零点零分的时候定期执行auto.sh脚本(crontab命令的具体用法可自行百度或google)
新建任务格式详解(/etc/crontab)
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
至此全部过程就结束了,接下来就可以等着自己密码字典的成型啦!!!!