阅读更多

19顶
0踩

企业架构

转载新闻 服务器被黑给我上了一课

2015-05-27 14:48 by 副主编 mengyidan1988 评论(6) 有11277人浏览
当你作为一个独立开发者的时候总要面临这样那样的问题,以前认为的小概率事件也总是某个时间点蜂拥而至考验你的耐心,前一阵阵刚刚经历了一次木马惊魂 (参见文章猎豹清理大师值得我们信任么? ),这次又遇到了服务器被黑。

部署服务器及一般的服务配置管理对于一个写代码的人自然不在话下,但是相对专业的运维人员程序员确少的却是一个安全意识,总以为服务器被攻击是一个小概率的事件。以前是这么考虑的“互联网上的主机那么多偏偏你的主机被骇客盯上? 这不跟重大奖一样么,我有那么幸运么?”虽然前一段时间自己的产品被当成木马已经是中了一次大奖了。所以心存侥幸心理,能省事就省事,先把服务部署起来能用就行,这也倒是符合我的极简主义行事风格。只有经历才能成长,这句话说的一点没错,感谢这个不太聪明的骇客给我上了一课,从此在做任何服务器部署和管理的时候我的脑袋里也多了一根弦儿“安全意识"。 事情是这样的。
前几日像往常一样,访问我的产品网站http://xbrowser.me , 突然页面出现了404页面未找到。奇怪,怎么会这样?我有检查了一下输入的域名,没错确实是自己的网站。这时我心理突然一惊,倒吸一口冷气,莫非是因为前几天发布了一篇文章纪念我要废弃的产品功能-一键翻 墙 这么快就被GFW注意到了? 给我来了一个DNS劫持? 为了验证这一想法我马上打开了电脑的VPN程序,通过VPN再次访问我的网站(这样可以避免GFW的DNS劫持) 。网页呈现出来的依然是“404页面未找到”,这说明不是DNS劫持的问题,GFW并没有注意到我。这时候我不知道是喜还是忧,但是这究竟是什么原因造成的呢?为了查找真相我立刻登录了自己的服务器。

首先我进入到了webserver根目录查看,果然看到网站文件被删掉了。还好我的程序有备份,这点损失我还是能够承受的,关键骇客的意图是什么呢?篡改主页?没有道理啊,对于我这个一没有知名度二没有影响力的小站点没有意义啊。好吧,不猜测原因了,这个哥们动作那么大我反而要庆幸,否则就凭我那点儿安全意识被当成肉鸡肯定毫无察觉。这时候我赶紧看看都有谁登录了服务器。
引用

$ last | more
chengkai pts/0        111.199.208.96   Mon May 18 14:41   still logged in  
chengkai pts/4        192.154.200.61   Mon May 18 12:39   still logged in  
chengkai pts/4        111.199.208.96   Sun May 10 02:40 - 14:39 (1+11:59)  
chengkai pts/4        111.199.208.96   Sat May  9 14:02 - 14:03  (00:00)   
chengkai pts/9        111.199.208.96   Sat May  9 00:15 - 02:31  (02:15)

从日志上看,都是我自己的用户名,但是很明显有一个不一样的IP地址来源,我赶紧查了一下ip地址来源, 处理了北京网通的IP另外一个不同的IP来着台湾。很显然骇客已经攻破了我的root密码然后为了掩人耳目使用我的用户名进行线上操作,但是更让人惊愕的是此时这哥们竟然正在线上。
引用

chengkai pts/4        192.154.200.61   Mon May 18 12:39   still logged in

尼玛这真是大姑娘出嫁头一遭啊,这是要现场对决啊。第一闪念我要先把这下家伙给踢下去,可是又一想不行,这家伙已经拿到了我的root权限,被我踢下去很可能会气急败坏的重新登录破坏系统,还是先修改root密码及看看有没有留下什么后门再说,先看看对方有没有启动什么特殊的服务进程。
引用

$ netstat -nl

80、22、1723 这些端口是我知道的webserver,ssh和vpn。剩下的几个大端口号尤其值得怀疑。
引用

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State     
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN    
tcp        0      0 0.0.0.0:1723            0.0.0.0:*               LISTEN    
tcp        0      0 127.0.0.1:48988         0.0.0.0:*               LISTEN    
tcp        0      0 127.0.0.1:52732         0.0.0.0:*               LISTEN

那么接下来我用"lsof" 命令来看看这几个大的端口号是什么进程启动的?
引用

lsof -i :48988
ruby    13727 chengkai    9u  IPv4 98307068      0t0  TCP localhost:58185 (LISTEN)
lsof -i  :52732
ruby    18258 chengkai    9u  IPv4 97802878      0t0  TCP localhost:52732 (LISTEN)

还好都是ruby进程,我猜想应该是passenger 转发http请求到rails的监听端口,为了证明我的猜想我停掉了nginx服务,果然ruby进程占用的端口号没有了。

排除了骇客监听端口的嫌疑后,接下来看看会不会拿我的服务器当"肉鸡"使用,检测这一问题的最好办法就是查看外面的流量出口,这时候我想到了iftop命令。
引用

$ sudo iftop -np

                                   195kb                               391kb                              586kb                               781kb                          977kb
└──────────────────────────────────┴───────────────────────────────────┴──────────────────────────────────┴───────────────────────────────────┴───────────────────────────────────
96.126.127.11:7000                                                          => 101.219.21.98:50726                                                         30.1kb  6.03kb  1.51kb
                                                                            <=                                                                             1.12kb   230b     57b
96.126.127.11:ssh                                                           => 111.199.216.183:63446                                                       5.09kb  5.91kb  6.13kb
                                                                            <=                                                                              416b    291b    250b
96.126.127.11:7000                                                          => 101.219.21.98:54488                                                         25.3kb  5.06kb  1.27kb
                                                                            <=                                                                             1.12kb   230b     58b
96.126.127.11:7000                                                          => 101.219.21.98:36312                                                         24.3kb  4.87kb  1.22kb
                                                                            <=                                                                             1.12kb   230b     58b
96.126.127.11:ssh                                                           => 222.186.21.250:56628                                                        5.20kb  2.61kb   668b
                                                                            <=                                                                             3.14kb  1.44kb   368b
96.126.127.11                                                               => 187.184.246.118                                                             8.39kb  3.65kb  3.65kb
                                                                            <=                                                                                0b      0b      0b
96.126.127.11:7000                                                          => 101.219.21.98:34993                                                         15.8kb  3.17kb   811b
                                                                            <=                                                                             1.13kb   231b     58b
96.126.127.11:7000                                                          => 103.254.203.177:58825                                                       8.54kb  1.71kb   437b

在这里面,并没有发现什么异常的流量和往外的出口连接,又进行了一些常规检查,也没有发现特别异常的问题。
引用

# 查看有无异常进程
$ ps aux
......
# 查看系统资源占用有无异常
$ top
......
# 有没有新增异常用户
$ cat /etc/passwd
......
#查看了root用户的命令历史记录,当然这个对稍有经验家伙是没有意义的,拿到了root权限后可以清理任何痕迹
# history
......

我知道接下来需呀做的两件事情,修改root及我当前用户的用户名密码及把入侵者踢下去。在修改了服务器的密码后,我在终端上输入了下面两个命令。
引用

$ write chengkai pts/4
what are you fuc king about
#结束消息
ctrl+d
# 踢掉在线终端
$ pkill -kill -t pts/4

第一个命令是向入侵者发送一条信息“what are you fuc king about”,而第二条命令紧接着把入侵者踢了下去。这时候不免有了一丝满足感,可以想象对方收到消息并被我踢下终端时的表情,当然我想他可能不会这么容易善罢甘休。(其实我知道这种挑衅是蛮危险的,对方曾经拿到了root用户权限,如果在某个地方设置了一些后门会非常难以发现,系统很容易会被再次攻破)。 我打开了认证日志静静等待对方的再次破解登录,果然对方很快就来了,而且是发动了不同的主机进行ssh暴力破解。
引用

$ sudo tail -f /var/log/auth.log

Received disconnect from 222.186.21.243: 11:  [preauth]
May 18 14:36:52 localhost sshd[16428]: PAM 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=222.186.21.243  user=root
May 18 14:36:54 localhost sshd[16432]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=222.186.21.243  user=root
May 18 14:36:56 localhost sshd[16432]: Failed password for root from 222.186.21.243 port 56722 ssh2
May 18 14:37:01 localhost sshd[16432]: message repeated 2 times: [ Failed password for root from 222.186.21.243 port 56722 ssh2]
May 18 14:37:01 localhost sshd[16432]: Received disconnect from 222.186.21.243: 11:  [preauth]
May 18 14:37:01 localhost sshd[16432]: PAM 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=222.186.21.243  user=root
May 18 14:37:03 localhost sshd[16438]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=222.186.21.243  user=root
May 18 14:37:05 localhost sshd[16438]: Failed password for root from 222.186.21.243 port 45780 ssh2
May 18 14::42:26 localhost sshd[18573]: Received disconnect from 222.186.21.244: 11:  [preauth]
May 18 14::42:26 localhost sshd[18573]: PAM 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=222.186.21.244  user=root
May 18 14::42:29 localhost sshd[18579]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=222.186.21.244  user=root
May 18 14::42:30 localhost sshd[18579]: Failed password for root from 222.186.21.244 port 38062 ssh2
May 18 14::42:35 localhost sshd[18579]: message repeated 2 times: [ Failed password for root from 222.186.21.244 port 38062 ssh2]
May 18 14::42:35 localhost sshd[18579]: Received disconnect from 222.186.21.244: 11:  [preauth]
May 18 14::42:35 localhost sshd[18579]: PAM 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=222.186.21.244  user=root
May 18 14::42:39 localhost sshd[18585]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=222.186.21.244  user=root
May 18 14::42:41 localhost sshd[18585]: Failed password for root from 222.186.21.244 port 50864 ssh2
May 18 14::42:47 localhost sshd[18585]

某种意义上来讲这是好事,因为这说明对方并还没有来得及安置后门程序,只能采取暴力破解的方式。那么接下来我要做的事情就是把对方IP加入到 "hosts.deny"
引用

$ sudo vi /etc/hosts.deny

ALL:110.164.67.47
ALL:222.89.166.12
ALL:221.229.166.30
ALL:58.218.205.69   
ALL:58.218.204.239   
ALL:58.218.211.155   
ALL:222.186.21.236   
ALL:58.218.204.225   
ALL:58.218.204.241   
.......

由于暴力破解骇客首先会尝试root 用户,所以还要禁止root ssh登录,修改sshd_conf文件。
引用

$ sudo vi /etc/ssh/sshd_config
#把PermitRootLogin 属性 yes 改为 no
PermitRootLogin no

到此,我能想到的检测及阻止对方的手段已经差不多了,是时候对一个最起码的安全意识做个总结了。
  • 设置用户名密码一定要大小写字母数字及一些特殊符号的组合,增加暴力破解的难度,有可能的话可以定期更换密码。
  • 禁止ssh root 登录
  • 定期维护hosts.deny文件,可以选择安装一些第三方的工具自动根据一些规则维护hosts.deny 比如 "DenyHosts"
  • 为了避免骇客扫描已知服务器程序端口漏洞,修改服务程序的默认端口好,比如ssh服务不使用22端口
  • 设置 iptables 开启一些通用的防火墙规则,ubuntu系统可以使用 ufw

以下为一些网友建议及补充:
  • 止密码登陆,同样修改 sshd_config 设置属性“PasswordAuthentication no” ,然后公钥和私钥的方式进行登陆。
  • 使用fail2ban ,fail2ban可以监视你的系统日志,然后匹配日志的错误信息(正则式匹配)执行相应的屏蔽动作(一般情况下是调用防火墙屏蔽),如:当有人在试探你的SSH、SMTP、FTP密码,只要达到你预设的次数,fail2ban就会调用防火墙屏蔽这个IP,而且可以发送e-mail通知系统管理员,是一款很实用、很强大的软件!

还好这次事件也没有给我造成太大的影响和损失,反而让我加强了一些安全意识,对于菜鸟级的骇客还是能够抵挡一阵子的。欢迎跟帖讨论,你了解的一些入侵监测手段和防范方法,谢谢。

来自:简书-chengkai
来自: 简书
19
0
评论 共 6 条 请登录后发表评论
6 楼 afuer 2015-05-28 19:44
安全最终还是模式问题,要想安全必须模式安全,比如增加手机认证,人脸识别等等。要不然不可能安全。
5 楼 在下个路口 2015-05-28 14:39
怎么跟今天的携程被黑这么像呢!
4 楼 java-007 2015-05-28 13:17
居然直接将root暴漏在外面,我也是醉了。
3 楼 dsjt 2015-05-28 10:03
XBrowser ,名字听着有点熟悉,下载一个试用一下。
2 楼 o0rid0o 2015-05-27 18:38
像我们是EC2,只能远程登录
于是需要
禁止密码登录,启用证书登录(定期更换证书)
安装DenyHosts
配置防火墙,除了允许的端口(22、80、443等),其他的都不允许访问
配置防火墙,使22端口只允许某个IP访问(当然前提是有固定IP)
安装不同于openssh的访问工具,开启另外的ssh端口,允许任意IP访问,但是在EC2控制台那里禁止掉,需要的时候临时开启(防止22我们自己访问不上去产生杯具...)
数据库禁止远程访问,需要远程访问的,走SSH通道,定期更换密码
数据库用户权限,能给多小就给多小....

我也是程序员,但是我们公司根本就没有运维人员,于是你知道的...什么都得自己上...
1 楼 勇敢红豆沙 2015-05-27 17:23
之前一个项目内测上线的第一天服务器就被黑掉了。检查发现时struts2的远程命令漏洞,紧接着修复漏洞,但是与此同时服务器已经被整个黑掉了。一些安全问题平常考虑到的真的不多,但是遇到一次之后就极其重视。现在已经养成测试的时候顺便连安全测试一块进行了。尝试一些已知的攻击手段。

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • SqlParameter类

    表示 SqlCommand 的参数,也可以是它到 DataSet 列的映射。无法继承此类。下表列出了由 SqlParameter 类型公开的成员。  公共构造函数   名称  说明     SqlParameter  已重载。初始化 SqlParameter 类的新实例。 页首  公共属性   名称  说明    CompareInfo  获取或设置 CompareInfo 对象,该对象定义应如何

  • 问题解决:SqlParameterCollection只接受非空的SqlParameter类型对象,不接受SqlParameter[]对象

    做.net个人版机房收费系统时,遇到了这样一个问题:   既然提到了SqlParameter,那就意味着设置参数处出现了问题,但是到底是哪里出了问题呢,之前运行的时候也没有出错呀,怎么现在又出现了这样的错误。仔细研究提示的错误:只接受非空的SqlParameter类型对象。也就是说我给函数传入的参数为空呗,但是自己的代码里明明传入了参数,怎么会提示传入的为空呢??那一定是没有传入成功;虽然

  • C#知识|SqlParameterCollection 只接受非空的 SqlParameter 类型对象,不接受 SqlParameter[] 对象

    哈喽,你好啊,我是雷工!今天在练习C#时遇到报错:SqlParameterCollection 只接受非空的 SqlParameter 类型对象,不接受 SqlParameter[] 对象。

  • 解决异常“SqlParameterCollection 只接受非空的 SqlParameter 类型对象。”

    public void DataList_UpdateCommand(Object sender, DataListCommandEventArgs e) { string strName = ((Label)e.Item.FindControl("lblName")).Text; int intChinese = Int32.Parse(((T

  • 向SqlCommand对象的ParameterCollections集合添加参数时犯的低级错误

    今天写代码遇到了一个小小的问题看来是基础不过关啊,嘿嘿.          上图中注释的几种向ParameterCollection集合添加参数的方式程序都能正确执行, 并能成功的向数据库添加数据 为什么只有comm.Parameters.Add(&quot;@password&quot;,SqlDbType.VarChar,50,password); 这种方式向ParameterCollection集合...

  • Oracle集合的初始化与赋值

    对于集合类型,与单一的数据类型相比较而言,应该以一个整体的观念来考虑集合,即是一批类型相同的数据组合而非单一的数据。因此集 合类型集合的声明、赋值、初始化较之单一类型而言,有很大的不同。尤其是嵌套表与变长数组,在赋值之前必须先初始化。当嵌套表和变长数 组在声明时,它们都会自动地被设置成NULL值。也就是嵌套表和变长数组中集合不存在任何元素,并不是针对它所拥有的元素。可以使用系统定 义的与集合

  • [导入]实例化SqlParameterCollection的方法是

    实例化SqlParameterCollection的方法文章来源:http://blog.csdn.net/yanlixin4csdn/archive/2004/06/30/30576.aspx 转载于:https://www.cnblogs.com/yanlixin/archive/2005/11/22/281897.html

  • 另一个SqlParameterCollection 中已包含 SqlParameter[解决方案]

    转自:http://www.cnblogs.com/yank/archive/2008/04/01/1132825.html 本着代码重用,减少变量的创建,希望参数能够重复使用 Main Code            //查询该目录下的邮件总数            string strSum = &quot;select count(F_ID) from dbo.T_TLMail_receiver ...

  • ADO.NET基础必备之SqlParameterCollection 类

    SqlParameterCollection 类 表示与 SqlCommand 相关联的参数的集合以及各个参数到 DataSet 中列的映射。无法继承此类。 语法: [ListBindableAttribute(false)] public sealed class SqlParameterCollection : DbParameterCollection SqlParamet...

  • ParameterCollection 类

    ParameterCollection 类表示数据源控件在高级数据绑定方案中使用的 Parameter 对象的集合。 当检索、更新、删除及插入信息时,使用 Parameter 对象将局部 Page 变量、HTTP cookie、会话变量和其他控件的值绑定到数据源控件。使用 Par

Global site tag (gtag.js) - Google Analytics